[aat] Sanitize ContextualSubtable
This commit is contained in:
parent
9b82aa19d8
commit
17f01aff91
|
@ -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…
Reference in New Issue