[aat] Sanitize ContextualSubtable

This commit is contained in:
Behdad Esfahbod 2018-01-11 18:54:49 +01:00
parent 9b82aa19d8
commit 17f01aff91
2 changed files with 43 additions and 14 deletions

View File

@ -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<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;
@ -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);
}

View File

@ -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<void> *entry = machine.get_entry (state, klass);
const Entry<void> *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<EntryData> *entry = machine.get_entry (state, klass);
const Entry<EntryData> *entry = machine.get_entryZ (state, klass);
if (unlikely (!entry))
break;
@ -238,7 +238,7 @@ struct ContextualSubtable
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);
if (replacement)
{
@ -249,7 +249,7 @@ struct ContextualSubtable
}
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);
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<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: