[HarfBuzz] harfbuzz: Branch 'master'
Behdad Esfahbod
behdad at kemper.freedesktop.org
Fri Jan 12 10:09:43 UTC 2018
src/hb-aat-layout-common-private.hh | 36 +++++++++++++++++++++++++++++-------
1 file changed, 29 insertions(+), 7 deletions(-)
New commits:
commit f7600228a4b37e6f6b65394aceeeb14bf4133c23
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Fri Jan 12 11:09:21 2018 +0100
[aat] Detect infinite-loops in state machine
diff --git a/src/hb-aat-layout-common-private.hh b/src/hb-aat-layout-common-private.hh
index 4ed2d3a1..37a84bef 100644
--- a/src/hb-aat-layout-common-private.hh
+++ b/src/hb-aat-layout-common-private.hh
@@ -614,15 +614,23 @@ struct StateTableDriver
machine (machine_),
buffer (buffer_),
num_glyphs (face_->get_num_glyphs ()),
- state (0),
- last_zero (0) {}
+ last_zero (0)
+ {
+ dont_advance_set.init ();
+ }
+
+ inline ~StateTableDriver (void)
+ {
+ dont_advance_set.finish ();
+ }
template <typename context_t>
inline void drive (context_t *c)
{
hb_glyph_info_t *info = buffer->info;
unsigned int count = buffer->len;
-
+ unsigned int state = 0;
+ bool last_was_dont_advance = false;
for (buffer->idx = 0; buffer->idx <= count; buffer->idx++)
{
if (!state)
@@ -637,8 +645,22 @@ struct StateTableDriver
c->transition (this, entry);
+
if (entry->flags & context_t::DontAdvance)
- buffer->idx--; /* TODO Detect infinite loop. */
+ {
+ if (!last_was_dont_advance)
+ dont_advance_set.clear ();
+
+ unsigned int key = info[buffer->idx].codepoint | (state << 16);
+ if (likely (!dont_advance_set.has (key)))
+ {
+ dont_advance_set.add (key);
+ buffer->idx--;
+ last_was_dont_advance = true;
+ }
+ }
+ else
+ last_was_dont_advance = false;
state = entry->newState;
}
@@ -649,11 +671,11 @@ struct StateTableDriver
public:
const StateTable<EntryData> &machine;
hb_buffer_t *buffer;
-
unsigned int num_glyphs;
-
- unsigned int state;
unsigned int last_zero;
+
+ private:
+ hb_set_t dont_advance_set; /* Infinite-loop detection */
};
More information about the HarfBuzz
mailing list