src/hb-aat-layout-common-private.hh |   36 +++++++++++++++++++++++++++++-------
 1 file changed, 29 insertions(+), 7 deletions(-)

New commits:
commit f7600228a4b37e6f6b65394aceeeb14bf4133c23
Author: Behdad Esfahbod <beh...@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 */
 };
 
 
_______________________________________________
HarfBuzz mailing list
HarfBuzz@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/harfbuzz

Reply via email to