Coverage Report

Created: 2025-07-01 07:03

/src/harfbuzz/test/fuzzing/hb-draw-fuzzer.cc
Line
Count
Source
1
#include <assert.h>
2
#include <stdlib.h>
3
4
#include <hb-ot.h>
5
6
#include "hb-fuzzer.hh"
7
8
struct _draw_data_t
9
{
10
  unsigned path_len;
11
  float path_start_x;
12
  float path_start_y;
13
  float path_last_x;
14
  float path_last_y;
15
};
16
17
#include <cstdio>
18
static void
19
_move_to (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data_,
20
    hb_draw_state_t *st,
21
    float to_x, float to_y,
22
    void *user_data HB_UNUSED)
23
134k
{
24
134k
  _draw_data_t *draw_data = (_draw_data_t *) draw_data_;
25
134k
  assert (!st->path_open);
26
134k
  draw_data->path_start_x = draw_data->path_last_x = to_x;
27
134k
  draw_data->path_start_y = draw_data->path_last_y = to_y;
28
134k
}
29
30
static void
31
_line_to (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data_,
32
    hb_draw_state_t *st,
33
    float to_x, float to_y,
34
    void *user_data HB_UNUSED)
35
786k
{
36
786k
  _draw_data_t *draw_data = (_draw_data_t *) draw_data_;
37
786k
  assert (st->path_open);
38
786k
  ++draw_data->path_len;
39
786k
  draw_data->path_last_x = to_x;
40
786k
  draw_data->path_last_y = to_y;
41
786k
}
42
43
static void
44
_quadratic_to (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data_,
45
         hb_draw_state_t *st,
46
         float control_x HB_UNUSED, float control_y HB_UNUSED,
47
         float to_x, float to_y,
48
         void *user_data HB_UNUSED)
49
474k
{
50
474k
  _draw_data_t *draw_data = (_draw_data_t *) draw_data_;
51
474k
  assert (st->path_open);
52
474k
  ++draw_data->path_len;
53
474k
  draw_data->path_last_x = to_x;
54
474k
  draw_data->path_last_y = to_y;
55
474k
}
56
57
static void
58
_cubic_to (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data_,
59
     hb_draw_state_t *st,
60
     float control1_x HB_UNUSED, float control1_y HB_UNUSED,
61
     float control2_x HB_UNUSED, float control2_y HB_UNUSED,
62
     float to_x, float to_y,
63
     void *user_data HB_UNUSED)
64
290k
{
65
290k
  _draw_data_t *draw_data = (_draw_data_t *) draw_data_;
66
290k
  assert (st->path_open);
67
290k
  ++draw_data->path_len;
68
290k
  draw_data->path_last_x = to_x;
69
290k
  draw_data->path_last_y = to_y;
70
290k
}
71
72
static void
73
_close_path (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data_,
74
       hb_draw_state_t *st,
75
       void *user_data HB_UNUSED)
76
134k
{
77
134k
  _draw_data_t *draw_data = (_draw_data_t *) draw_data_;
78
134k
  assert (st->path_open && draw_data->path_len != 0);
79
134k
  draw_data->path_len = 0;
80
134k
  assert (draw_data->path_start_x == draw_data->path_last_x &&
81
134k
    draw_data->path_start_y == draw_data->path_last_y);
82
134k
}
83
84
/* Similar to test-ot-face.c's #test_font() */
85
static void misc_calls_for_gid (hb_face_t *face, hb_font_t *font, hb_set_t *set, hb_codepoint_t cp)
86
201k
{
87
  /* Other gid specific misc calls */
88
201k
  hb_face_collect_variation_unicodes (face, cp, set);
89
90
201k
  hb_codepoint_t g;
91
201k
  hb_font_get_nominal_glyph (font, cp, &g);
92
201k
  hb_font_get_variation_glyph (font, cp, cp, &g);
93
201k
  hb_font_get_glyph_h_advance (font, cp);
94
201k
  hb_font_get_glyph_v_advance (font, cp);
95
201k
  hb_position_t x, y;
96
201k
  hb_font_get_glyph_h_origin (font, cp, &x, &y);
97
201k
  hb_font_get_glyph_v_origin (font, cp, &x, &y);
98
201k
  hb_font_get_glyph_contour_point (font, cp, 0, &x, &y);
99
201k
  char buf[64];
100
201k
  hb_font_get_glyph_name (font, cp, buf, sizeof (buf));
101
102
201k
  hb_ot_color_palette_get_name_id (face, cp);
103
201k
  hb_ot_color_palette_color_get_name_id (face, cp);
104
201k
  hb_ot_color_palette_get_flags (face, cp);
105
201k
  hb_ot_color_palette_get_colors (face, cp, 0, nullptr, nullptr);
106
201k
  hb_ot_color_glyph_get_layers (face, cp, 0, nullptr, nullptr);
107
201k
  hb_blob_destroy (hb_ot_color_glyph_reference_svg (face, cp));
108
201k
  hb_blob_destroy (hb_ot_color_glyph_reference_png (font, cp));
109
110
201k
  hb_ot_layout_get_ligature_carets (font, HB_DIRECTION_LTR, cp, 0, nullptr, nullptr);
111
112
201k
  hb_ot_math_get_glyph_italics_correction (font, cp);
113
201k
  hb_ot_math_get_glyph_top_accent_attachment (font, cp);
114
201k
  hb_ot_math_is_glyph_extended_shape (face, cp);
115
201k
  hb_ot_math_get_glyph_kerning (font, cp, HB_OT_MATH_KERN_BOTTOM_RIGHT, 0);
116
201k
  hb_ot_math_get_glyph_variants (font, cp, HB_DIRECTION_TTB, 0, nullptr, nullptr);
117
201k
  hb_ot_math_get_glyph_assembly (font, cp, HB_DIRECTION_BTT, 0, nullptr, nullptr, nullptr);
118
201k
}
119
120
extern "C" int LLVMFuzzerTestOneInput (const uint8_t *data, size_t size)
121
27.7k
{
122
27.7k
  alloc_state = _fuzzing_alloc_state (data, size);
123
124
27.7k
  hb_blob_t *blob = hb_blob_create ((const char *) data, size,
125
27.7k
            HB_MEMORY_MODE_READONLY, nullptr, nullptr);
126
27.7k
  hb_face_t *face = hb_face_create (blob, 0);
127
27.7k
  hb_font_t *font = hb_font_create (face);
128
129
27.7k
  unsigned num_coords = 0;
130
27.7k
  if (size) num_coords = data[size - 1];
131
27.7k
  num_coords = hb_ot_var_get_axis_count (face) > num_coords ? num_coords : hb_ot_var_get_axis_count (face);
132
27.7k
  int *coords = (int *) calloc (num_coords, sizeof (int));
133
27.7k
  if (size > num_coords + 1)
134
36.0k
    for (unsigned i = 0; i < num_coords; ++i)
135
8.33k
      coords[i] = ((int) data[size - num_coords + i - 1] - 128) * 10;
136
27.7k
  hb_font_set_var_coords_normalized (font, coords, num_coords);
137
27.7k
  free (coords);
138
139
27.7k
  unsigned glyph_count = hb_face_get_glyph_count (face);
140
27.7k
  glyph_count = glyph_count > 16 ? 16 : glyph_count;
141
142
27.7k
  _draw_data_t draw_data = {0, 0, 0, 0, 0};
143
144
27.7k
  hb_draw_funcs_t *funcs = hb_draw_funcs_create ();
145
27.7k
  hb_draw_funcs_set_move_to_func (funcs, (hb_draw_move_to_func_t) _move_to, nullptr, nullptr);
146
27.7k
  hb_draw_funcs_set_line_to_func (funcs, (hb_draw_line_to_func_t) _line_to, nullptr, nullptr);
147
27.7k
  hb_draw_funcs_set_quadratic_to_func (funcs, (hb_draw_quadratic_to_func_t) _quadratic_to, nullptr, nullptr);
148
27.7k
  hb_draw_funcs_set_cubic_to_func (funcs, (hb_draw_cubic_to_func_t) _cubic_to, nullptr, nullptr);
149
27.7k
  hb_draw_funcs_set_close_path_func (funcs, (hb_draw_close_path_func_t) _close_path, nullptr, nullptr);
150
27.7k
  volatile unsigned counter = !glyph_count;
151
27.7k
  hb_set_t *set = hb_set_create ();
152
229k
  for (unsigned gid = 0; gid < glyph_count; ++gid)
153
201k
  {
154
201k
    hb_font_draw_glyph (font, gid, funcs, &draw_data);
155
156
    /* Glyph extents also may practices the similar path, call it now that is related */
157
201k
    hb_glyph_extents_t extents;
158
201k
    if (hb_font_get_glyph_extents (font, gid, &extents))
159
107k
      counter += !!extents.width + !!extents.height + !!extents.x_bearing + !!extents.y_bearing;
160
161
201k
    if (!counter) counter += 1;
162
163
    /* other misc calls */
164
201k
    misc_calls_for_gid (face, font, set, gid);
165
201k
  }
166
27.7k
  hb_set_destroy (set);
167
27.7k
  assert (counter);
168
27.7k
  hb_draw_funcs_destroy (funcs);
169
170
27.7k
  hb_font_destroy (font);
171
27.7k
  hb_face_destroy (face);
172
27.7k
  hb_blob_destroy (blob);
173
27.7k
  return 0;
174
27.7k
}