| #include "hb-shape-input.hh" | |
| #include <hb-vector.h> | |
| static void | |
| exercise_format (const _fuzzing_shape_input_t *input, | |
| hb_vector_format_t format, | |
| unsigned precision, | |
| volatile unsigned *counter) | |
| { | |
| hb_vector_draw_t *draw = hb_vector_draw_create_or_fail (format); | |
| hb_vector_paint_t *paint = hb_vector_paint_create_or_fail (format); | |
| if (!draw || !paint) | |
| { | |
| hb_vector_draw_destroy (draw); | |
| hb_vector_paint_destroy (paint); | |
| return; | |
| } | |
| hb_vector_paint_set_foreground (paint, HB_COLOR (0, 0, 0, 255)); | |
| hb_vector_draw_set_precision (draw, precision); | |
| hb_vector_paint_set_precision (paint, precision); | |
| unsigned glyph_count = hb_face_get_glyph_count (input->face); | |
| unsigned limit = glyph_count > 16 ? 16 : glyph_count; | |
| if (limit) | |
| { | |
| unsigned gid = input->text.empty () ? 0 : input->text[0] % limit; | |
| float x = (float) ((gid % 4) * 40); | |
| float y = (float) ((gid / 4) * 40); | |
| hb_vector_draw_set_transform (draw, 1.f, 0.f, 0.f, 1.f, x, y); | |
| hb_vector_draw_glyph (draw, input->font, gid, HB_VECTOR_EXTENTS_MODE_EXPAND); | |
| hb_vector_paint_set_transform (paint, 1.f, 0.f, 0.f, 1.f, x, y); | |
| hb_vector_paint_glyph (paint, input->font, gid, HB_VECTOR_EXTENTS_MODE_EXPAND); | |
| hb_blob_t *draw_blob = hb_vector_draw_render (draw); | |
| if (draw_blob) | |
| { | |
| unsigned length = 0; | |
| const char *blob_data = hb_blob_get_data (draw_blob, &length); | |
| *counter += length; | |
| if (blob_data && length) | |
| *counter += (unsigned char) blob_data[0]; | |
| hb_vector_draw_recycle_blob (draw, draw_blob); | |
| } | |
| hb_blob_t *paint_blob = hb_vector_paint_render (paint); | |
| if (paint_blob) | |
| { | |
| unsigned length = 0; | |
| const char *blob_data = hb_blob_get_data (paint_blob, &length); | |
| *counter += length; | |
| if (blob_data && length) | |
| *counter += (unsigned char) blob_data[0]; | |
| hb_vector_paint_recycle_blob (paint, paint_blob); | |
| } | |
| } | |
| hb_vector_draw_destroy (draw); | |
| hb_vector_paint_destroy (paint); | |
| } | |
| extern "C" int LLVMFuzzerTestOneInput (const uint8_t *data, size_t size) | |
| { | |
| alloc_state = _fuzzing_alloc_state (data, size); | |
| _fuzzing_shape_input_t input; | |
| if (_fuzzing_prepare_shape_input (data, size, 30, 30, &input) == HB_FUZZING_SHAPE_INPUT_MALFORMED) | |
| return 0; | |
| unsigned precision = size ? data[size - 1] % 5 : 0; | |
| unsigned glyph_count = hb_face_get_glyph_count (input.face); | |
| volatile unsigned counter = !glyph_count; | |
| /* Exercise both output formats. Each has its own serializer, path | |
| * encoder, gradient machinery, and (for PDF) indexed-PNG SMask + | |
| * Type 6 Coons-patch encoder. */ | |
| exercise_format (&input, HB_VECTOR_FORMAT_SVG, precision, &counter); | |
| exercise_format (&input, HB_VECTOR_FORMAT_PDF, precision, &counter); | |
| return counter ? 0 : 0; | |
| } |