Coverage Report

Created: 2025-08-25 07:06

/src/igraph/fuzzing/vertex_separators.cpp
Line
Count
Source
1
/*
2
   IGraph library.
3
   Copyright (C) 2021-2024  The igraph development team
4
5
   This program is free software; you can redistribute it and/or modify
6
   it under the terms of the GNU General Public License as published by
7
   the Free Software Foundation; either version 2 of the License, or
8
   (at your option) any later version.
9
10
   This program is distributed in the hope that it will be useful,
11
   but WITHOUT ANY WARRANTY; without even the implied warranty of
12
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
   GNU General Public License for more details.
14
15
   You should have received a copy of the GNU General Public License
16
   along with this program; if not, write to the Free Software
17
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18
   02110-1301 USA
19
*/
20
21
#include <igraph.h>
22
#include <cstdlib>
23
24
1.45k
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
25
1.45k
    igraph_t graph;
26
1.45k
    igraph_vector_int_t edges;
27
28
1.45k
    igraph_set_warning_handler(igraph_warning_handler_ignore);
29
30
    /* We work with small, up-to 16-vertex graphs, as the algorithms
31
     * tested here can be slow. Each byte is interpreted as an edge.
32
     * A simple graph can have at most 120 edges, but we allow up
33
     * to 240, as the fuzzer usually generates multigraphs. */
34
35
1.45k
    if (Size > 240) {
36
15
        return 0;
37
15
    }
38
39
1.44k
    igraph_vector_int_init(&edges, 2*Size);
40
1.44k
    size_t j = 0;
41
31.2k
    for (size_t i=0; i < Size; ++i) {
42
29.8k
        VECTOR(edges)[j++] = Data[i] / 16;
43
29.8k
        VECTOR(edges)[j++] = Data[i] % 16;
44
29.8k
    }
45
46
1.44k
    if (igraph_create(&graph, &edges, 0, IGRAPH_UNDIRECTED) == IGRAPH_SUCCESS) {
47
1.44k
        igraph_vector_int_list_t ivl;
48
1.44k
        igraph_vector_int_t iv1, iv2;
49
1.44k
        igraph_bool_t is_separator, is_minimal_separator;
50
51
1.44k
        igraph_vector_int_list_init(&ivl, 0);
52
1.44k
        igraph_vector_int_init(&iv1, 0);
53
1.44k
        igraph_vector_int_init(&iv2, 0);
54
55
1.44k
        igraph_all_minimal_st_separators(&graph, &ivl);
56
57
        // Check that all returned sets are indeed separators.
58
32.5k
        for (igraph_integer_t i=0; i < igraph_vector_int_list_size(&ivl); i++) {
59
31.1k
            igraph_is_separator(
60
31.1k
                &graph,
61
31.1k
                igraph_vss_vector(igraph_vector_int_list_get_ptr(&ivl, i)),
62
31.1k
                &is_separator);
63
31.1k
            IGRAPH_ASSERT(is_separator);
64
31.1k
        }
65
66
1.44k
        igraph_minimum_size_separators(&graph, &ivl);
67
68
        // Simplification is necessary for cohesive_blocks() and
69
        // enables a straightforward check for complete graphs below.
70
1.44k
        igraph_simplify(&graph, true, true, NULL);
71
72
1.44k
        const igraph_integer_t vcount = igraph_vcount(&graph);
73
1.44k
        const igraph_integer_t ecount = igraph_ecount(&graph);
74
75
1.44k
        if (ecount != vcount*(vcount-1)/2) {
76
            // minimum_size_separators() returns all size n-1 subsets
77
            // of the complete graph K_n. is_minimal_separator() does not
78
            // consider these to be separators. Therefore we skip complete
79
            // graphs. For non-complete graphs we check that all results
80
            // are minimal separators.
81
10.0k
            for (igraph_integer_t i=0; i < igraph_vector_int_list_size(&ivl); i++) {
82
8.64k
                igraph_is_minimal_separator(
83
8.64k
                    &graph,
84
8.64k
                    igraph_vss_vector(igraph_vector_int_list_get_ptr(&ivl, i)),
85
8.64k
                    &is_minimal_separator);
86
8.64k
                IGRAPH_ASSERT(is_minimal_separator);
87
8.64k
            }
88
1.39k
        }
89
90
1.44k
        {
91
1.44k
            igraph_t g;
92
1.44k
            igraph_cohesive_blocks(&graph, &ivl, &iv1, &iv2, &g);
93
1.44k
            igraph_destroy(&g);
94
1.44k
        }
95
96
1.44k
        igraph_vector_int_destroy(&iv2);
97
1.44k
        igraph_vector_int_destroy(&iv1);
98
1.44k
        igraph_vector_int_list_destroy(&ivl);
99
1.44k
        igraph_destroy(&graph);
100
1.44k
    }
101
102
1.44k
    igraph_vector_int_destroy(&edges);
103
104
1.44k
    IGRAPH_ASSERT(IGRAPH_FINALLY_STACK_EMPTY);
105
106
1.44k
    return 0;  // Non-zero return values are reserved for future use.
107
1.44k
}