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