blob: 9a524c25db34d868deecf095e3d43dd7409359c2 [file] [edit]
#include "hb-fuzzer.hh"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "hb-subset.h"
extern "C" int LLVMFuzzerTestOneInput (const uint8_t *data, size_t size)
{
alloc_state = _fuzzing_alloc_state (data, size);
hb_blob_t *blob = hb_blob_create ((const char *) data, size,
HB_MEMORY_MODE_READONLY, nullptr, nullptr);
hb_face_t *face = hb_face_create (blob, 0);
hb_subset_depend_t *depend = hb_subset_depend_from_face_or_fail (face);
if (depend)
{
// Iterate through dependency data and exercise full API
unsigned int num_glyphs = hb_face_get_glyph_count (face);
hb_set_t *temp_set = hb_set_create ();
for (unsigned int gid = 0; gid < num_glyphs && gid < 100; gid++)
{
// Iterate through up to 10 entries per glyph
unsigned int total = hb_subset_depend_lookup_glyph (depend, gid, 0, nullptr, nullptr);
unsigned int limit = total < 10u ? total : 10u;
for (unsigned int index = 0; index < limit; index++)
{
hb_subset_depend_entry_t entry;
unsigned int count = 1;
hb_subset_depend_lookup_glyph (depend, gid, index, &count, &entry);
// Access basic edge data
(void) entry.table_tag;
(void) entry.dependent;
(void) entry.layout_tag;
(void) entry.flags;
// If this edge has a ligature set, retrieve and check it
if (entry.ligature_set_index != HB_CODEPOINT_INVALID)
{
if (hb_subset_depend_lookup_set (depend, entry.ligature_set_index, temp_set))
{
unsigned pop = hb_set_get_population (temp_set);
// Ligature sets should be non-empty
if (pop == 0)
fprintf (stderr, "Warning: Empty ligature set at index %u\n", entry.ligature_set_index);
}
}
// If this edge has a context set, retrieve and check it
if (entry.context_set_index != HB_CODEPOINT_INVALID)
{
if (hb_subset_depend_lookup_set (depend, entry.context_set_index, temp_set))
{
unsigned pop = hb_set_get_population (temp_set);
// Context sets should be non-empty
if (pop == 0)
fprintf (stderr, "Warning: Empty context set at index %u\n", entry.context_set_index);
// Check for nested context sets (indirect references with 0x80000000 bit)
hb_codepoint_t elem = HB_SET_VALUE_INVALID;
while (hb_set_next (temp_set, &elem))
{
if (elem >= 0x80000000)
{
// Indirect reference - retrieve the nested set
hb_codepoint_t nested_idx = elem & 0x7FFFFFFF;
hb_set_t *nested_set = hb_set_create ();
if (hb_subset_depend_lookup_set (depend, nested_idx, nested_set))
{
unsigned nested_pop = hb_set_get_population (nested_set);
// Nested sets should also be non-empty
if (nested_pop == 0)
fprintf (stderr, "Warning: Empty nested context set at index %u\n", nested_idx);
}
hb_set_destroy (nested_set);
}
}
}
}
}
}
hb_set_destroy (temp_set);
hb_subset_depend_destroy (depend);
}
hb_face_destroy (face);
hb_blob_destroy (blob);
return 0;
}