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