Coverage Report

Created: 2025-10-28 07:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ndpi/fuzz/fuzz_ds_tree.cpp
Line
Count
Source
1
#include "ndpi_api.h"
2
#include "fuzz_common_code.h"
3
4
#include <stdint.h>
5
#include <stdio.h>
6
#include <assert.h>
7
#include "fuzzer/FuzzedDataProvider.h"
8
9
static int __compare(const void *a, const void *b)
10
382k
{
11
382k
  u_int32_t *entry_a, *entry_b;
12
13
382k
  entry_a = (u_int32_t *)a;
14
382k
  entry_b = (u_int32_t *)b;
15
16
382k
  return *entry_a == *entry_b ? 0 : (*entry_a < *entry_b ? -1 : +1);
17
382k
}
18
static void __free(void * const node)
19
8.83k
{
20
8.83k
  u_int32_t *entry = (u_int32_t *)node;
21
8.83k
  ndpi_free(entry);
22
8.83k
}
23
static void __walk(const void *a, ndpi_VISIT which, int depth, void *user_data)
24
44.1k
{
25
44.1k
  (void)which;
26
44.1k
  (void)depth;
27
28
44.1k
  assert(user_data == NULL && a);
29
44.1k
}
30
31
222
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
32
222
  FuzzedDataProvider fuzzed_data(data, size);
33
222
  u_int16_t i, num_iteration, is_added = 0;
34
222
  void *root = NULL;
35
222
  u_int32_t *entry, value_added, e, *e2;
36
37
  /* Just to have some data */
38
222
  if (fuzzed_data.remaining_bytes() < 1024)
39
18
    return -1;
40
41
  /* To allow memory allocation failures */
42
204
  fuzz_set_alloc_callbacks_and_seed(size);
43
44
204
  num_iteration = fuzzed_data.ConsumeIntegral<u_int8_t>();
45
23.6k
  for (i = 0; i < num_iteration; i++) {
46
23.4k
    entry = (u_int32_t *)ndpi_malloc(sizeof(u_int32_t));
47
23.4k
    if (!entry)
48
1.71k
      continue;
49
21.7k
    *entry = fuzzed_data.ConsumeIntegral<u_int32_t>();
50
    
51
21.7k
    if(ndpi_tfind(entry, &root, __compare) == NULL) {
52
17.1k
      if(ndpi_tsearch(entry, fuzzed_data.ConsumeBool() ? &root : NULL, __compare) == NULL) {
53
7.50k
        ndpi_free(entry);
54
9.69k
      } else {
55
        /* Keep one random entry really added */
56
9.69k
        if (is_added == 0 && fuzzed_data.ConsumeBool()) {
57
136
          value_added = *entry;
58
136
          is_added = 1;
59
136
        }
60
9.69k
      }
61
17.1k
    } else {
62
4.52k
      ndpi_free(entry);
63
4.52k
    }
64
21.7k
  }
65
66
  /* "Random" search */
67
204
  num_iteration = fuzzed_data.ConsumeIntegral<u_int8_t>();
68
8.39k
  for (i = 0; i < num_iteration; i++) {
69
8.19k
    e = fuzzed_data.ConsumeIntegral<u_int32_t>();
70
71
8.19k
    ndpi_tfind(&e, fuzzed_data.ConsumeBool() ? &root : NULL, __compare);
72
8.19k
  }
73
  /* Search of an added node */
74
204
  if (is_added) {
75
136
    ndpi_tfind(&value_added, &root, __compare);
76
136
  }
77
78
204
  ndpi_twalk(root, __walk, NULL);
79
80
  /* "Random" delete */
81
204
  num_iteration = fuzzed_data.ConsumeIntegral<u_int8_t>();
82
12.9k
  for (i = 0; i < num_iteration; i++) {
83
12.7k
    e = fuzzed_data.ConsumeIntegral<u_int32_t>();
84
85
12.7k
    e2 = (u_int32_t *)ndpi_tdelete(&e, &root, __compare);
86
12.7k
    ndpi_free(e2);
87
12.7k
  }
88
  /* Delete of an added node */
89
204
  if (is_added) {
90
136
    e2 = (u_int32_t *)ndpi_tdelete(&value_added, &root, __compare);
91
136
    ndpi_free(e2);
92
136
  }
93
94
204
  ndpi_twalk(root, __walk, NULL);
95
96
204
  ndpi_tdestroy(root, __free);
97
98
204
  return 0;
99
222
}