Coverage Report

Created: 2025-08-25 07:11

/src/harfbuzz/test/fuzzing/hb-set-fuzzer.cc
Line
Count
Source (jump to first uncovered line)
1
#include "hb-fuzzer.hh"
2
3
#include <stdlib.h>
4
#include <stdio.h>
5
#include <string.h>
6
#include <assert.h>
7
8
#include "hb.h"
9
10
// Only allow ~5,000 set values between the two input sets.
11
// Arbitrarily long input sets do not trigger any meaningful
12
// differences in behaviour so there's no benefit from allowing
13
// the fuzzer to create super large sets.
14
88
#define MAX_INPUT_SIZE 20000
15
16
enum set_operation_t : uint8_t
17
{
18
  INTERSECT = 0,
19
  UNION = 1,
20
  SUBTRACT = 2,
21
  SYMMETRIC_DIFFERENCE = 3
22
};
23
24
struct instructions_t
25
{
26
  set_operation_t operation;
27
  uint32_t first_set_size;
28
};
29
30
static hb_set_t *create_set (const uint32_t *value_array, int count)
31
0
{
32
0
  hb_set_t *set = hb_set_create ();
33
0
  for (int i = 0; i < count; i++)
34
0
    hb_set_add (set, value_array[i]);
35
0
  return set;
36
0
}
37
38
39
extern "C" int LLVMFuzzerTestOneInput (const uint8_t *data, size_t size)
40
104
{
41
104
  alloc_state = _fuzzing_alloc_state (data, size);
42
43
104
  if (size < sizeof (instructions_t))
44
16
    return 0;
45
46
88
  if (size > MAX_INPUT_SIZE)
47
26
    return 0;
48
49
62
#pragma GCC diagnostic push
50
62
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
51
62
  const instructions_t &instructions = reinterpret_cast<const instructions_t &> (data);
52
62
#pragma GCC diagnostic pop
53
62
  data += sizeof (instructions_t);
54
62
  size -= sizeof (instructions_t);
55
56
62
  const uint32_t *values = reinterpret_cast<const uint32_t *> (data);
57
62
  size = size / sizeof (uint32_t);
58
59
62
  if (size < instructions.first_set_size)
60
62
    return 0;
61
62
0
  hb_set_t *set_a = create_set (values, instructions.first_set_size);
63
64
0
  values += instructions.first_set_size;
65
0
  size -= instructions.first_set_size;
66
0
  hb_set_t *set_b = create_set (values, size);
67
68
0
  switch (instructions.operation)
69
0
  {
70
0
  case INTERSECT:
71
0
    hb_set_intersect (set_a, set_b);
72
0
    break;
73
0
  case UNION:
74
0
    hb_set_union (set_a, set_b);
75
0
    break;
76
0
  case SUBTRACT:
77
0
    hb_set_subtract (set_a, set_b);
78
0
    break;
79
0
  case SYMMETRIC_DIFFERENCE:
80
0
    hb_set_symmetric_difference (set_a, set_b);
81
0
    break;
82
0
  default:
83
0
    break;
84
0
  }
85
86
0
  hb_set_destroy (set_a);
87
0
  hb_set_destroy (set_b);
88
89
0
  return 0;
90
0
}