1*2d1272b8SAndroid Build Coastguard Worker #include "hb-fuzzer.hh"
2*2d1272b8SAndroid Build Coastguard Worker
3*2d1272b8SAndroid Build Coastguard Worker #include <stdlib.h>
4*2d1272b8SAndroid Build Coastguard Worker #include <stdio.h>
5*2d1272b8SAndroid Build Coastguard Worker #include <string.h>
6*2d1272b8SAndroid Build Coastguard Worker #include <assert.h>
7*2d1272b8SAndroid Build Coastguard Worker
8*2d1272b8SAndroid Build Coastguard Worker #include "hb-subset.h"
9*2d1272b8SAndroid Build Coastguard Worker
10*2d1272b8SAndroid Build Coastguard Worker static void
trySubset(hb_face_t * face,const hb_codepoint_t text[],int text_length,unsigned flag_bits,hb_subset_input_t * input)11*2d1272b8SAndroid Build Coastguard Worker trySubset (hb_face_t *face,
12*2d1272b8SAndroid Build Coastguard Worker const hb_codepoint_t text[],
13*2d1272b8SAndroid Build Coastguard Worker int text_length,
14*2d1272b8SAndroid Build Coastguard Worker unsigned flag_bits,
15*2d1272b8SAndroid Build Coastguard Worker hb_subset_input_t *input)
16*2d1272b8SAndroid Build Coastguard Worker {
17*2d1272b8SAndroid Build Coastguard Worker if (!input) return;
18*2d1272b8SAndroid Build Coastguard Worker
19*2d1272b8SAndroid Build Coastguard Worker hb_subset_input_set_flags (input, (hb_subset_flags_t) flag_bits);
20*2d1272b8SAndroid Build Coastguard Worker
21*2d1272b8SAndroid Build Coastguard Worker hb_set_t *codepoints = hb_subset_input_unicode_set (input);
22*2d1272b8SAndroid Build Coastguard Worker
23*2d1272b8SAndroid Build Coastguard Worker for (int i = 0; i < text_length; i++)
24*2d1272b8SAndroid Build Coastguard Worker hb_set_add (codepoints, text[i]);
25*2d1272b8SAndroid Build Coastguard Worker
26*2d1272b8SAndroid Build Coastguard Worker hb_face_t *result = hb_subset_or_fail (face, input);
27*2d1272b8SAndroid Build Coastguard Worker if (result)
28*2d1272b8SAndroid Build Coastguard Worker {
29*2d1272b8SAndroid Build Coastguard Worker hb_blob_t *blob = hb_face_reference_blob (result);
30*2d1272b8SAndroid Build Coastguard Worker unsigned int length;
31*2d1272b8SAndroid Build Coastguard Worker const char *data = hb_blob_get_data (blob, &length);
32*2d1272b8SAndroid Build Coastguard Worker
33*2d1272b8SAndroid Build Coastguard Worker // Something not optimizable just to access all the blob data
34*2d1272b8SAndroid Build Coastguard Worker unsigned int bytes_count = 0;
35*2d1272b8SAndroid Build Coastguard Worker for (unsigned int i = 0; i < length; ++i)
36*2d1272b8SAndroid Build Coastguard Worker if (data[i]) ++bytes_count;
37*2d1272b8SAndroid Build Coastguard Worker assert (bytes_count || !length);
38*2d1272b8SAndroid Build Coastguard Worker
39*2d1272b8SAndroid Build Coastguard Worker hb_blob_destroy (blob);
40*2d1272b8SAndroid Build Coastguard Worker }
41*2d1272b8SAndroid Build Coastguard Worker hb_face_destroy (result);
42*2d1272b8SAndroid Build Coastguard Worker
43*2d1272b8SAndroid Build Coastguard Worker hb_subset_input_destroy (input);
44*2d1272b8SAndroid Build Coastguard Worker }
45*2d1272b8SAndroid Build Coastguard Worker
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)46*2d1272b8SAndroid Build Coastguard Worker extern "C" int LLVMFuzzerTestOneInput (const uint8_t *data, size_t size)
47*2d1272b8SAndroid Build Coastguard Worker {
48*2d1272b8SAndroid Build Coastguard Worker alloc_state = _fuzzing_alloc_state (data, size);
49*2d1272b8SAndroid Build Coastguard Worker
50*2d1272b8SAndroid Build Coastguard Worker hb_blob_t *blob = hb_blob_create ((const char *) data, size,
51*2d1272b8SAndroid Build Coastguard Worker HB_MEMORY_MODE_READONLY, nullptr, nullptr);
52*2d1272b8SAndroid Build Coastguard Worker hb_face_t *face = hb_face_create (blob, 0);
53*2d1272b8SAndroid Build Coastguard Worker
54*2d1272b8SAndroid Build Coastguard Worker /* Just test this API here quickly. */
55*2d1272b8SAndroid Build Coastguard Worker hb_set_t *output = hb_set_create ();
56*2d1272b8SAndroid Build Coastguard Worker hb_face_collect_unicodes (face, output);
57*2d1272b8SAndroid Build Coastguard Worker hb_set_destroy (output);
58*2d1272b8SAndroid Build Coastguard Worker
59*2d1272b8SAndroid Build Coastguard Worker unsigned flags = HB_SUBSET_FLAGS_DEFAULT;
60*2d1272b8SAndroid Build Coastguard Worker const hb_codepoint_t text[] =
61*2d1272b8SAndroid Build Coastguard Worker {
62*2d1272b8SAndroid Build Coastguard Worker 'A', 'B', 'C', 'D', 'E', 'X', 'Y', 'Z', '1', '2',
63*2d1272b8SAndroid Build Coastguard Worker '3', '@', '_', '%', '&', ')', '*', '$', '!'
64*2d1272b8SAndroid Build Coastguard Worker };
65*2d1272b8SAndroid Build Coastguard Worker
66*2d1272b8SAndroid Build Coastguard Worker hb_subset_input_t *input = hb_subset_input_create_or_fail ();
67*2d1272b8SAndroid Build Coastguard Worker if (!input)
68*2d1272b8SAndroid Build Coastguard Worker {
69*2d1272b8SAndroid Build Coastguard Worker hb_face_destroy (face);
70*2d1272b8SAndroid Build Coastguard Worker hb_blob_destroy (blob);
71*2d1272b8SAndroid Build Coastguard Worker return 0;
72*2d1272b8SAndroid Build Coastguard Worker }
73*2d1272b8SAndroid Build Coastguard Worker trySubset (face, text, sizeof (text) / sizeof (hb_codepoint_t), flags, input);
74*2d1272b8SAndroid Build Coastguard Worker
75*2d1272b8SAndroid Build Coastguard Worker unsigned num_axes;
76*2d1272b8SAndroid Build Coastguard Worker hb_codepoint_t text_from_data[16];
77*2d1272b8SAndroid Build Coastguard Worker if (size > sizeof (text_from_data) + sizeof (flags) + sizeof(num_axes)) {
78*2d1272b8SAndroid Build Coastguard Worker hb_subset_input_t *input = hb_subset_input_create_or_fail ();
79*2d1272b8SAndroid Build Coastguard Worker if (!input)
80*2d1272b8SAndroid Build Coastguard Worker {
81*2d1272b8SAndroid Build Coastguard Worker hb_face_destroy (face);
82*2d1272b8SAndroid Build Coastguard Worker hb_blob_destroy (blob);
83*2d1272b8SAndroid Build Coastguard Worker return 0;
84*2d1272b8SAndroid Build Coastguard Worker }
85*2d1272b8SAndroid Build Coastguard Worker size -= sizeof (text_from_data);
86*2d1272b8SAndroid Build Coastguard Worker memcpy (text_from_data,
87*2d1272b8SAndroid Build Coastguard Worker data + size,
88*2d1272b8SAndroid Build Coastguard Worker sizeof (text_from_data));
89*2d1272b8SAndroid Build Coastguard Worker
90*2d1272b8SAndroid Build Coastguard Worker size -= sizeof (flags);
91*2d1272b8SAndroid Build Coastguard Worker memcpy (&flags,
92*2d1272b8SAndroid Build Coastguard Worker data + size,
93*2d1272b8SAndroid Build Coastguard Worker sizeof (flags));
94*2d1272b8SAndroid Build Coastguard Worker
95*2d1272b8SAndroid Build Coastguard Worker size -= sizeof (num_axes);
96*2d1272b8SAndroid Build Coastguard Worker memcpy (&num_axes,
97*2d1272b8SAndroid Build Coastguard Worker data + size,
98*2d1272b8SAndroid Build Coastguard Worker sizeof (num_axes));
99*2d1272b8SAndroid Build Coastguard Worker
100*2d1272b8SAndroid Build Coastguard Worker if (num_axes > 0 && num_axes < 8 && size > num_axes * (sizeof(hb_tag_t) + sizeof(int)))
101*2d1272b8SAndroid Build Coastguard Worker {
102*2d1272b8SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_axes; i++) {
103*2d1272b8SAndroid Build Coastguard Worker hb_tag_t tag;
104*2d1272b8SAndroid Build Coastguard Worker int value;
105*2d1272b8SAndroid Build Coastguard Worker size -= sizeof (tag);
106*2d1272b8SAndroid Build Coastguard Worker memcpy (&tag,
107*2d1272b8SAndroid Build Coastguard Worker data + size,
108*2d1272b8SAndroid Build Coastguard Worker sizeof (tag));
109*2d1272b8SAndroid Build Coastguard Worker size -= sizeof (value);
110*2d1272b8SAndroid Build Coastguard Worker memcpy (&value,
111*2d1272b8SAndroid Build Coastguard Worker data + size,
112*2d1272b8SAndroid Build Coastguard Worker sizeof (value));
113*2d1272b8SAndroid Build Coastguard Worker
114*2d1272b8SAndroid Build Coastguard Worker hb_subset_input_pin_axis_location(input,
115*2d1272b8SAndroid Build Coastguard Worker face,
116*2d1272b8SAndroid Build Coastguard Worker tag,
117*2d1272b8SAndroid Build Coastguard Worker (float) value);
118*2d1272b8SAndroid Build Coastguard Worker }
119*2d1272b8SAndroid Build Coastguard Worker }
120*2d1272b8SAndroid Build Coastguard Worker
121*2d1272b8SAndroid Build Coastguard Worker
122*2d1272b8SAndroid Build Coastguard Worker
123*2d1272b8SAndroid Build Coastguard Worker unsigned int text_size = sizeof (text_from_data) / sizeof (hb_codepoint_t);
124*2d1272b8SAndroid Build Coastguard Worker trySubset (face, text_from_data, text_size, flags, input);
125*2d1272b8SAndroid Build Coastguard Worker }
126*2d1272b8SAndroid Build Coastguard Worker
127*2d1272b8SAndroid Build Coastguard Worker hb_face_destroy (face);
128*2d1272b8SAndroid Build Coastguard Worker hb_blob_destroy (blob);
129*2d1272b8SAndroid Build Coastguard Worker
130*2d1272b8SAndroid Build Coastguard Worker return 0;
131*2d1272b8SAndroid Build Coastguard Worker }
132