From 17f01aff910b3871d0a6c45fd4305304b7f68ab5 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 11 Jan 2018 18:54:49 +0100 Subject: [PATCH] [aat] Sanitize ContextualSubtable --- src/hb-aat-layout-common-private.hh | 23 +++++++++++++++---- src/hb-aat-layout-morx-table.hh | 34 ++++++++++++++++++++--------- 2 files changed, 43 insertions(+), 14 deletions(-) diff --git a/src/hb-aat-layout-common-private.hh b/src/hb-aat-layout-common-private.hh index 4d2285a81..fca74ea2c 100644 --- a/src/hb-aat-layout-common-private.hh +++ b/src/hb-aat-layout-common-private.hh @@ -512,11 +512,17 @@ struct Entry inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && data.sanitize (c)); + /* Note, we don't recurse-sanitize data because we don't access it. + * That said, in our DEFINE_SIZE_STATIC we access T::static_size, + * which ensures that data has a simple sanitize(). To be determined + * if I need to remove that as well. */ + return_trace (c->check_struct (this)); } public: - HBUINT16 newState; /* Byte offset from beginning of state table to the new state. */ + HBUINT16 newState; /* Byte offset from beginning of state table + * to the new state. Really?!?! Or just state + * number? The latter in morx for sure. */ HBUINT16 flags; /* Table specific. */ T data; /* Optional offsets to per-glyph tables. */ public: @@ -550,7 +556,12 @@ struct StateTable { return (this+classTable).get_class (glyph_id, num_glyphs); } - inline const Entry *get_entry (unsigned int state, unsigned int klass) const + inline const Entry *get_entries () const + { + return (this+entryTable).arrayZ; + } + + inline const Entry *get_entryZ (unsigned int state, unsigned int klass) const { if (unlikely (klass >= nClasses)) return nullptr; @@ -562,7 +573,8 @@ struct StateTable return &entries[entry]; } - inline bool sanitize (hb_sanitize_context_t *c) const + inline bool sanitize (hb_sanitize_context_t *c, + unsigned int *num_entries_out = nullptr) const { TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); @@ -600,6 +612,9 @@ struct StateTable } } + if (num_entries_out) + *num_entries_out = num_entries; + return_trace (true); } diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index 0433f1f48..50805eb82 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -79,7 +79,7 @@ struct RearrangementSubtable unsigned int klass = i < count ? machine.get_class (info[i].codepoint, num_glyphs) : 0 /* End of text */; - const Entry *entry = machine.get_entry (state, klass); + const Entry *entry = machine.get_entryZ (state, klass); if (unlikely (!entry)) break; @@ -155,8 +155,8 @@ struct RearrangementSubtable } } - if (false/* XXX */ && flags & DontAdvance) - i--; /* XXX Detect infinite loop. */ + if (false/* TODO */ && flags & DontAdvance) + i--; /* TODO Detect infinite loop. */ state = entry->newState; } @@ -224,7 +224,7 @@ struct ContextualSubtable unsigned int klass = i < count ? machine.get_class (info[i].codepoint, num_glyphs) : 0 /* End of text */; - const Entry *entry = machine.get_entry (state, klass); + const Entry *entry = machine.get_entryZ (state, klass); if (unlikely (!entry)) break; @@ -238,7 +238,7 @@ struct ContextualSubtable if (entry->data.markIndex != 0xFFFF) { - const Lookup &lookup = subs[entry->data.markIndex]; // XXX bounds + const Lookup &lookup = subs[entry->data.markIndex]; const GlyphID *replacement = lookup.get_value (info[mark].codepoint, num_glyphs); if (replacement) { @@ -249,7 +249,7 @@ struct ContextualSubtable } if (entry->data.currentIndex != 0xFFFF) { - const Lookup &lookup = subs[entry->data.currentIndex]; // XXX bounds + const Lookup &lookup = subs[entry->data.currentIndex]; const GlyphID *replacement = lookup.get_value (info[i].codepoint, num_glyphs); if (replacement) { @@ -259,8 +259,8 @@ struct ContextualSubtable } } - if (false/* XXX */ && flags & DontAdvance) - i--; /* XXX Detect infinite loop. */ + if (false/* TODO */ && flags & DontAdvance) + i--; /* TODO Detect infinite loop. */ state = entry->newState; } @@ -271,8 +271,22 @@ struct ContextualSubtable inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (machine.sanitize (c) && - substitutionTables.sanitize (c, this, 0U/*XXX count*/)); + + unsigned int num_entries; + if (unlikely (!machine.sanitize (c, &num_entries))) return false; + + unsigned int num_lookups = 0; + + const Entry *entries = machine.get_entries (); + for (unsigned int i = 0; i < num_entries; i++) + { + const EntryData &data = entries[i].data; + + num_lookups = MAX (num_lookups, 1 + data.markIndex); + num_lookups = MAX (num_lookups, 1 + data.currentIndex); + } + + return_trace (substitutionTables.sanitize (c, this, num_lookups)); } protected: