[aat] Sanitize ContextualSubtable

pull/702/head
Behdad Esfahbod 7 years ago
parent 9b82aa19d8
commit 17f01aff91
  1. 23
      src/hb-aat-layout-common-private.hh
  2. 34
      src/hb-aat-layout-morx-table.hh

@ -512,11 +512,17 @@ struct Entry
inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
{ {
TRACE_SANITIZE (this); 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: 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. */ HBUINT16 flags; /* Table specific. */
T data; /* Optional offsets to per-glyph tables. */ T data; /* Optional offsets to per-glyph tables. */
public: public:
@ -550,7 +556,12 @@ struct StateTable
{ return (this+classTable).get_class (glyph_id, num_glyphs); } { return (this+classTable).get_class (glyph_id, num_glyphs); }
inline const Entry<Extra> *get_entry (unsigned int state, unsigned int klass) const inline const Entry<Extra> *get_entries () const
{
return (this+entryTable).arrayZ;
}
inline const Entry<Extra> *get_entryZ (unsigned int state, unsigned int klass) const
{ {
if (unlikely (klass >= nClasses)) return nullptr; if (unlikely (klass >= nClasses)) return nullptr;
@ -562,7 +573,8 @@ struct StateTable
return &entries[entry]; 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); TRACE_SANITIZE (this);
if (unlikely (!c->check_struct (this))) return_trace (false); 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); return_trace (true);
} }

@ -79,7 +79,7 @@ struct RearrangementSubtable
unsigned int klass = i < count ? unsigned int klass = i < count ?
machine.get_class (info[i].codepoint, num_glyphs) : machine.get_class (info[i].codepoint, num_glyphs) :
0 /* End of text */; 0 /* End of text */;
const Entry<void> *entry = machine.get_entry (state, klass); const Entry<void> *entry = machine.get_entryZ (state, klass);
if (unlikely (!entry)) if (unlikely (!entry))
break; break;
@ -155,8 +155,8 @@ struct RearrangementSubtable
} }
} }
if (false/* XXX */ && flags & DontAdvance) if (false/* TODO */ && flags & DontAdvance)
i--; /* XXX Detect infinite loop. */ i--; /* TODO Detect infinite loop. */
state = entry->newState; state = entry->newState;
} }
@ -224,7 +224,7 @@ struct ContextualSubtable
unsigned int klass = i < count ? unsigned int klass = i < count ?
machine.get_class (info[i].codepoint, num_glyphs) : machine.get_class (info[i].codepoint, num_glyphs) :
0 /* End of text */; 0 /* End of text */;
const Entry<EntryData> *entry = machine.get_entry (state, klass); const Entry<EntryData> *entry = machine.get_entryZ (state, klass);
if (unlikely (!entry)) if (unlikely (!entry))
break; break;
@ -238,7 +238,7 @@ struct ContextualSubtable
if (entry->data.markIndex != 0xFFFF) if (entry->data.markIndex != 0xFFFF)
{ {
const Lookup<GlyphID> &lookup = subs[entry->data.markIndex]; // XXX bounds const Lookup<GlyphID> &lookup = subs[entry->data.markIndex];
const GlyphID *replacement = lookup.get_value (info[mark].codepoint, num_glyphs); const GlyphID *replacement = lookup.get_value (info[mark].codepoint, num_glyphs);
if (replacement) if (replacement)
{ {
@ -249,7 +249,7 @@ struct ContextualSubtable
} }
if (entry->data.currentIndex != 0xFFFF) if (entry->data.currentIndex != 0xFFFF)
{ {
const Lookup<GlyphID> &lookup = subs[entry->data.currentIndex]; // XXX bounds const Lookup<GlyphID> &lookup = subs[entry->data.currentIndex];
const GlyphID *replacement = lookup.get_value (info[i].codepoint, num_glyphs); const GlyphID *replacement = lookup.get_value (info[i].codepoint, num_glyphs);
if (replacement) if (replacement)
{ {
@ -259,8 +259,8 @@ struct ContextualSubtable
} }
} }
if (false/* XXX */ && flags & DontAdvance) if (false/* TODO */ && flags & DontAdvance)
i--; /* XXX Detect infinite loop. */ i--; /* TODO Detect infinite loop. */
state = entry->newState; state = entry->newState;
} }
@ -271,8 +271,22 @@ struct ContextualSubtable
inline bool sanitize (hb_sanitize_context_t *c) const inline bool sanitize (hb_sanitize_context_t *c) const
{ {
TRACE_SANITIZE (this); 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<EntryData> *entries = machine.get_entries ();
for (unsigned int i = 0; i < num_entries; i++)
{
const EntryData &data = entries[i].data;
num_lookups = MAX<unsigned int> (num_lookups, 1 + data.markIndex);
num_lookups = MAX<unsigned int> (num_lookups, 1 + data.currentIndex);
}
return_trace (substitutionTables.sanitize (c, this, num_lookups));
} }
protected: protected:

Loading…
Cancel
Save