Fix _get_ligature_caret's oob read issue

AAT::Lookup has no other way to detect whether it is returned from
a real and sanitized font data or from a null pool, this checks if
the table has been recognized valid by sanitizer by checking
table's major version which is zero if returned from a null pool and
non-zero if is from a sanitized font data, it is expected the other
calls of the table (unlikely to have more calls however) also do a
similar version check before calling the lookups used on the table.
This commit is contained in:
Ebrahim Byagowi 2020-05-21 00:25:17 +04:30
parent 57886e2162
commit c68ab4b52b
4 changed files with 18 additions and 10 deletions

View File

@ -116,6 +116,8 @@ struct lcar
{ {
static constexpr hb_tag_t tableTag = HB_AAT_TAG_lcar; static constexpr hb_tag_t tableTag = HB_AAT_TAG_lcar;
bool has_data () const { return version.major; }
unsigned int get_lig_carets (hb_font_t *font, unsigned int get_lig_carets (hb_font_t *font,
hb_direction_t direction, hb_direction_t direction,
hb_codepoint_t glyph, hb_codepoint_t glyph,
@ -123,6 +125,13 @@ struct lcar
unsigned int *caret_count /* IN/OUT */, unsigned int *caret_count /* IN/OUT */,
hb_position_t *caret_array /* OUT */) const hb_position_t *caret_array /* OUT */) const
{ {
if (!has_data ())
{
if (caret_count)
*caret_count = 0;
return 0;
}
switch (format) switch (format)
{ {
case 0: return u.format0.get_lig_carets (font, direction, glyph, start_offset, case 0: return u.format0.get_lig_carets (font, direction, glyph, start_offset,

View File

@ -95,6 +95,8 @@ test_font (hb_font_t *font, hb_codepoint_t cp)
hb_ot_layout_has_substitution (face); hb_ot_layout_has_substitution (face);
hb_ot_layout_has_positioning (face); hb_ot_layout_has_positioning (face);
hb_ot_layout_get_ligature_carets (font, HB_DIRECTION_LTR, cp, 0, NULL, NULL);
hb_ot_math_has_data (face); hb_ot_math_has_data (face);
hb_ot_math_get_constant (font, HB_OT_MATH_CONSTANT_MATH_LEADING); hb_ot_math_get_constant (font, HB_OT_MATH_CONSTANT_MATH_LEADING);
hb_ot_math_get_glyph_italics_correction (font, cp); hb_ot_math_get_glyph_italics_correction (font, cp);

View File

@ -96,16 +96,12 @@ test_ot_layout_get_ligature_carets_ot_gsub (void)
hb_position_t caret_array[16]; hb_position_t caret_array[16];
{ {
/*
unsigned caret_count = 16; unsigned caret_count = 16;
g_assert_cmpuint (210, ==, hb_ot_layout_get_ligature_carets (font, HB_DIRECTION_LTR, g_assert_cmpuint (0, ==, hb_ot_layout_get_ligature_carets (font, HB_DIRECTION_LTR,
188, 0, &caret_count, 188, 0, &caret_count,
caret_array)); caret_array));
g_assert_cmpuint (3, ==, caret_count);
g_assert_cmpuint (2718, ==, caret_array[0]); g_assert_cmpuint (0, ==, caret_count);
g_assert_cmpuint (5438, ==, caret_array[1]);
g_assert_cmpuint (5438, ==, caret_array[1]);
*/
} }
{ {
@ -118,17 +114,15 @@ test_ot_layout_get_ligature_carets_ot_gsub (void)
g_assert_cmpuint (2718, ==, caret_array[0]); g_assert_cmpuint (2718, ==, caret_array[0]);
g_assert_cmpuint (5438, ==, caret_array[1]); g_assert_cmpuint (5438, ==, caret_array[1]);
g_assert_cmpuint (5438, ==, caret_array[1]); g_assert_cmpuint (5438, ==, caret_array[1]);
} }
{ {
/*
unsigned caret_count = 16; unsigned caret_count = 16;
g_assert_cmpuint (0, ==, hb_ot_layout_get_ligature_carets (font, HB_DIRECTION_LTR, g_assert_cmpuint (0, ==, hb_ot_layout_get_ligature_carets (font, HB_DIRECTION_LTR,
1021, 0, &caret_count, 1021, 0, &caret_count,
caret_array)); caret_array));
g_assert_cmpuint (0, ==, caret_count); g_assert_cmpuint (0, ==, caret_count);
*/
} }
{ {

View File

@ -121,6 +121,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
counter += !!extents.width + !!extents.height + !!extents.x_bearing + !!extents.y_bearing; counter += !!extents.width + !!extents.height + !!extents.x_bearing + !!extents.y_bearing;
if (!counter) counter += 1; if (!counter) counter += 1;
/* misc calls, TODO: test more of calls working with some specific gid */
hb_ot_layout_get_ligature_carets (font, HB_DIRECTION_LTR, gid, 0, nullptr, nullptr);
} }
assert (counter); assert (counter);
#ifdef HB_EXPERIMENTAL_API #ifdef HB_EXPERIMENTAL_API