hb-draw-fuzzer.cc 5.9 KB

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