/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 | } |