From d137d5579908ae29a4fecdc2e31a9987fc0c6c1c Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 11 Apr 2024 08:53:17 -0600 Subject: [PATCH] [aat] Add (unused) SubtableGlyphCoverage --- src/hb-aat-layout-common.hh | 32 ++++++++++++++++++++++++++++++++ src/hb-aat-layout-kerx-table.hh | 10 ++++++++++ src/hb-aat-layout-morx-table.hh | 11 +++++++++-- 3 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh index 1fb547079..1d379a78b 100644 --- a/src/hb-aat-layout-common.hh +++ b/src/hb-aat-layout-common.hh @@ -703,6 +703,38 @@ struct ClassTable DEFINE_SIZE_ARRAY (4, classArray); }; +struct SubtableGlyphCoverage +{ + bool sanitize (hb_sanitize_context_t *c, unsigned subtable_count) const + { + TRACE_SANITIZE (this); + + if (unlikely (!subtableOffsets.sanitize (c, subtable_count))) + return_trace (false); + + unsigned bytes = (c->get_num_glyphs () + CHAR_BIT - 1) / CHAR_BIT; + for (unsigned i = 0; i < subtable_count; i++) + { + uint32_t offset = subtableOffsets[i]; + if (offset == 0 || offset == 0xFFFFFFFF) + continue; + if (unlikely (!c->check_range (this, offset) || + !c->check_range (this, offset + bytes))) + return_trace (false); + } + + return_trace (true); + } + protected: + UnsizedArrayOf subtableOffsets; /* Array of offsets from the beginning of the + * subtable glyph coverage table to the glyph + * coverage bitfield for a given subtable; there + * is one offset for each subtable in the chain */ + /* UnsizedArrayOf coverageBitfields; *//* The individual coverage bitfields. */ + public: + DEFINE_SIZE_ARRAY (0, subtableOffsets); +}; + struct ObsoleteTypes { static constexpr bool extended = false; diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index 0de54e0a0..72480e072 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -977,6 +977,16 @@ struct KerxTable st = &StructAfter (*st); } + unsigned majorVersion = thiz()->version; + if (sizeof (thiz()->version) == 4) + majorVersion = majorVersion >> 16; + if (majorVersion >= 3) + { + const SubtableGlyphCoverage *coverage = (const SubtableGlyphCoverage *) st; + if (!coverage->sanitize (c, count)) + return_trace (false); + } + return_trace (true); } }; diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index 843655132..d86b09820 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -1100,7 +1100,7 @@ struct Chain unsigned int get_size () const { return length; } - bool sanitize (hb_sanitize_context_t *c, unsigned int version HB_UNUSED) const + bool sanitize (hb_sanitize_context_t *c, unsigned int version) const { TRACE_SANITIZE (this); if (!(length.sanitize (c) && @@ -1122,6 +1122,13 @@ struct Chain subtable = &StructAfter> (*subtable); } + if (version >= 3) + { + const SubtableGlyphCoverage *coverage = (const SubtableGlyphCoverage *) subtable; + if (!coverage->sanitize (c, count)) + return_trace (false); + } + return_trace (true); } @@ -1133,7 +1140,7 @@ struct Chain UnsizedArrayOf featureZ; /* Features. */ /*ChainSubtable firstSubtable;*//* Subtables. */ -/*subtableGlyphCoverageArray*/ /* Only if version >= 3. We don't use. */ +/*SubtableGlyphCoverage coverages*//* Only if version >= 3. */ public: DEFINE_SIZE_MIN (8 + 2 * sizeof (HBUINT));