/src/harfbuzz/test/fuzzing/hb-vector-fuzzer.cc
Line | Count | Source |
1 | | #include "hb-shape-input.hh" |
2 | | |
3 | | #include <hb-vector.h> |
4 | | |
5 | | static void |
6 | | exercise_format (const _fuzzing_shape_input_t *input, |
7 | | hb_vector_format_t format, |
8 | | unsigned precision, |
9 | | volatile unsigned *counter) |
10 | 27.9k | { |
11 | 27.9k | hb_vector_draw_t *draw = hb_vector_draw_create_or_fail (format); |
12 | 27.9k | hb_vector_paint_t *paint = hb_vector_paint_create_or_fail (format); |
13 | 27.9k | if (!draw || !paint) |
14 | 2.34k | { |
15 | 2.34k | hb_vector_draw_destroy (draw); |
16 | 2.34k | hb_vector_paint_destroy (paint); |
17 | 2.34k | return; |
18 | 2.34k | } |
19 | 25.6k | hb_vector_paint_set_foreground (paint, HB_COLOR (0, 0, 0, 255)); |
20 | | |
21 | 25.6k | hb_vector_draw_set_precision (draw, precision); |
22 | 25.6k | hb_vector_paint_set_precision (paint, precision); |
23 | | |
24 | 25.6k | unsigned glyph_count = hb_face_get_glyph_count (input->face); |
25 | 25.6k | unsigned limit = glyph_count > 16 ? 16 : glyph_count; |
26 | | |
27 | 25.6k | if (limit) |
28 | 21.7k | { |
29 | 21.7k | unsigned gid = input->text.empty () ? 0 : input->text[0] % limit; |
30 | 21.7k | float x = (float) ((gid % 4) * 40); |
31 | 21.7k | float y = (float) ((gid / 4) * 40); |
32 | 21.7k | hb_vector_draw_set_transform (draw, 1.f, 0.f, 0.f, 1.f, x, y); |
33 | 21.7k | hb_vector_draw_glyph (draw, input->font, gid, HB_VECTOR_EXTENTS_MODE_EXPAND); |
34 | 21.7k | hb_vector_paint_set_transform (paint, 1.f, 0.f, 0.f, 1.f, x, y); |
35 | 21.7k | hb_vector_paint_glyph (paint, input->font, gid, HB_VECTOR_EXTENTS_MODE_EXPAND); |
36 | | |
37 | 21.7k | hb_blob_t *draw_blob = hb_vector_draw_render (draw); |
38 | 21.7k | if (draw_blob) |
39 | 6.53k | { |
40 | 6.53k | unsigned length = 0; |
41 | 6.53k | const char *blob_data = hb_blob_get_data (draw_blob, &length); |
42 | 6.53k | *counter += length; |
43 | 6.53k | if (blob_data && length) |
44 | 6.53k | *counter += (unsigned char) blob_data[0]; |
45 | 6.53k | hb_vector_draw_recycle_blob (draw, draw_blob); |
46 | 6.53k | } |
47 | | |
48 | 21.7k | hb_blob_t *paint_blob = hb_vector_paint_render (paint); |
49 | 21.7k | if (paint_blob) |
50 | 5.62k | { |
51 | 5.62k | unsigned length = 0; |
52 | 5.62k | const char *blob_data = hb_blob_get_data (paint_blob, &length); |
53 | 5.62k | *counter += length; |
54 | 5.62k | if (blob_data && length) |
55 | 5.62k | *counter += (unsigned char) blob_data[0]; |
56 | 5.62k | hb_vector_paint_recycle_blob (paint, paint_blob); |
57 | 5.62k | } |
58 | 21.7k | } |
59 | | |
60 | 25.6k | hb_vector_draw_destroy (draw); |
61 | 25.6k | hb_vector_paint_destroy (paint); |
62 | 25.6k | } |
63 | | |
64 | | extern "C" int LLVMFuzzerTestOneInput (const uint8_t *data, size_t size) |
65 | 14.2k | { |
66 | 14.2k | alloc_state = _fuzzing_alloc_state (data, size); |
67 | | |
68 | 14.2k | _fuzzing_shape_input_t input; |
69 | 14.2k | if (_fuzzing_prepare_shape_input (data, size, 30, 30, &input) == HB_FUZZING_SHAPE_INPUT_MALFORMED) |
70 | 306 | return 0; |
71 | | |
72 | 13.9k | unsigned precision = size ? data[size - 1] % 5 : 0; |
73 | | |
74 | 13.9k | unsigned glyph_count = hb_face_get_glyph_count (input.face); |
75 | 13.9k | volatile unsigned counter = !glyph_count; |
76 | | |
77 | | /* Exercise both output formats. Each has its own serializer, path |
78 | | * encoder, gradient machinery, and (for PDF) indexed-PNG SMask + |
79 | | * Type 6 Coons-patch encoder. */ |
80 | 13.9k | exercise_format (&input, HB_VECTOR_FORMAT_SVG, precision, &counter); |
81 | 13.9k | exercise_format (&input, HB_VECTOR_FORMAT_PDF, precision, &counter); |
82 | | |
83 | 13.9k | return counter ? 0 : 0; |
84 | 14.2k | } |