[AAT] Handle transition errors during machine operation
authorBehdad Esfahbod <behdad@behdad.org>
Thu, 24 Jan 2019 17:01:07 +0000 (18:01 +0100)
committerBehdad Esfahbod <behdad@behdad.org>
Thu, 24 Jan 2019 17:01:07 +0000 (18:01 +0100)
Before we used to give up.  Now, just ignore error and continue processing.

Fixes https://github.com/harfbuzz/harfbuzz/issues/1531

src/hb-aat-layout-common.hh
src/hb-aat-layout-kerx-table.hh
src/hb-aat-layout-morx-table.hh

index 516a722..27ade28 100644 (file)
@@ -777,8 +777,7 @@ struct StateTableDriver
          buffer->unsafe_to_break (buffer->idx, buffer->idx + 2);
       }
 
-      if (unlikely (!c->transition (this, entry)))
-       ;//break; Ignore error.
+      c->transition (this, entry);
 
       state = machine.new_state (entry.newState);
       DEBUG_MSG (APPLY, nullptr, "s%d", state);
index 0630fba..a64c807 100644 (file)
@@ -232,7 +232,7 @@ struct KerxSubTableFormat1
     {
       return Format1EntryT::performAction (entry);
     }
-    bool transition (StateTableDriver<Types, EntryData> *driver,
+    void transition (StateTableDriver<Types, EntryData> *driver,
                     const Entry<EntryData> &entry)
     {
       hb_buffer_t *buffer = driver->buffer;
@@ -259,7 +259,7 @@ struct KerxSubTableFormat1
        if (!c->sanitizer.check_array (actions, depth, tuple_count))
        {
          depth = 0;
-         return false;
+         return;
        }
 
        hb_mask_t kern_mask = c->plan->kern_mask;
@@ -334,8 +334,6 @@ struct KerxSubTableFormat1
          }
        }
       }
-
-      return true;
     }
 
     private:
@@ -502,7 +500,7 @@ struct KerxSubTableFormat4
     {
       return entry.data.ankrActionIndex != 0xFFFF;
     }
-    bool transition (StateTableDriver<Types, EntryData> *driver,
+    void transition (StateTableDriver<Types, EntryData> *driver,
                     const Entry<EntryData> &entry)
     {
       hb_buffer_t *buffer = driver->buffer;
@@ -516,8 +514,7 @@ struct KerxSubTableFormat4
          {
            /* indexed into glyph outline. */
            const HBUINT16 *data = &ankrData[entry.data.ankrActionIndex];
-           if (!c->sanitizer.check_array (data, 2))
-             return false;
+           if (!c->sanitizer.check_array (data, 2)) return;
            HB_UNUSED unsigned int markControlPoint = *data++;
            HB_UNUSED unsigned int currControlPoint = *data++;
            hb_position_t markX = 0;
@@ -532,7 +529,7 @@ struct KerxSubTableFormat4
                                                              currControlPoint,
                                                              HB_DIRECTION_LTR /*XXX*/,
                                                              &currX, &currY))
-             return true; /* True, such that the machine continues. */
+             return;
 
            o.x_offset = markX - currX;
            o.y_offset = markY - currY;
@@ -543,8 +540,7 @@ struct KerxSubTableFormat4
          {
           /* Indexed into 'ankr' table. */
            const HBUINT16 *data = &ankrData[entry.data.ankrActionIndex];
-           if (!c->sanitizer.check_array (data, 2))
-             return false;
+           if (!c->sanitizer.check_array (data, 2)) return;
            unsigned int markAnchorPoint = *data++;
            unsigned int currAnchorPoint = *data++;
            const Anchor &markAnchor = c->ankr_table->get_anchor (c->buffer->info[mark].codepoint,
@@ -562,8 +558,7 @@ struct KerxSubTableFormat4
          case 2: /* Control Point Coordinate Actions. */
          {
            const FWORD *data = (const FWORD *) &ankrData[entry.data.ankrActionIndex];
-           if (!c->sanitizer.check_array (data, 4))
-             return false;
+           if (!c->sanitizer.check_array (data, 4)) return;
            int markX = *data++;
            int markY = *data++;
            int currX = *data++;
@@ -584,8 +579,6 @@ struct KerxSubTableFormat4
        mark_set = true;
        mark = buffer->idx;
       }
-
-      return true;
     }
 
     private:
index 564a618..8fc6c5d 100644 (file)
@@ -78,7 +78,7 @@ struct RearrangementSubtable
     {
       return (entry.flags & Verb) && start < end;
     }
-    bool transition (StateTableDriver<Types, EntryData> *driver,
+    void transition (StateTableDriver<Types, EntryData> *driver,
                     const Entry<EntryData> &entry)
     {
       hb_buffer_t *buffer = driver->buffer;
@@ -152,8 +152,6 @@ struct RearrangementSubtable
          }
        }
       }
-
-      return true;
     }
 
     public:
@@ -232,7 +230,7 @@ struct ContextualSubtable
 
       return entry.data.markIndex != 0xFFFF || entry.data.currentIndex != 0xFFFF;
     }
-    bool transition (StateTableDriver<Types, EntryData> *driver,
+    void transition (StateTableDriver<Types, EntryData> *driver,
                     const Entry<EntryData> &entry)
     {
       hb_buffer_t *buffer = driver->buffer;
@@ -240,7 +238,7 @@ struct ContextualSubtable
       /* Looks like CoreText applies neither mark nor current substitution for
        * end-of-text if mark was not explicitly set. */
       if (buffer->idx == buffer->len && !mark_set)
-        return true;
+        return;
 
       const GlyphID *replacement;
 
@@ -297,8 +295,6 @@ struct ContextualSubtable
        mark_set = true;
        mark = buffer->idx;
       }
-
-      return true;
     }
 
     public:
@@ -457,7 +453,7 @@ struct LigatureSubtable
     {
       return LigatureEntryT::performAction (entry);
     }
-    bool transition (StateTableDriver<Types, EntryData> *driver,
+    void transition (StateTableDriver<Types, EntryData> *driver,
                     const Entry<EntryData> &entry)
     {
       hb_buffer_t *buffer = driver->buffer;
@@ -466,7 +462,7 @@ struct LigatureSubtable
       if (entry.flags & LigatureEntryT::SetComponent)
       {
         if (unlikely (match_length >= ARRAY_LENGTH (match_positions)))
-         return false;
+         match_length = 0; /* TODO Use a ring buffer instead. */
 
        /* Never mark same index twice, in case DontAdvance was used... */
        if (match_length && match_positions[match_length - 1] == buffer->out_len)
@@ -482,10 +478,10 @@ struct LigatureSubtable
        unsigned int end = buffer->out_len;
 
        if (unlikely (!match_length))
-         return true;
+         return;
 
        if (buffer->idx >= buffer->len)
-         return false; // TODO Work on previous instead?
+         return; // TODO Work on previous instead?
 
        unsigned int cursor = match_length;
 
@@ -508,7 +504,7 @@ struct LigatureSubtable
          DEBUG_MSG (APPLY, nullptr, "Moving to stack position %u", cursor - 1);
          buffer->move_to (match_positions[--cursor]);
 
-         if (unlikely (!actionData->sanitize (&c->sanitizer))) return false;
+         if (unlikely (!actionData->sanitize (&c->sanitizer))) break;
          action = *actionData;
 
          uint32_t uoffset = action & LigActionOffset;
@@ -518,7 +514,7 @@ struct LigatureSubtable
          unsigned int component_idx = buffer->cur().codepoint + offset;
          component_idx = Types::wordOffsetToIndex (component_idx, table, component.arrayZ);
          const HBUINT16 &componentData = component[component_idx];
-         if (unlikely (!componentData.sanitize (&c->sanitizer))) return false;
+         if (unlikely (!componentData.sanitize (&c->sanitizer))) break;
          ligature_idx += componentData;
 
          DEBUG_MSG (APPLY, nullptr, "Action store %u last %u",
@@ -528,7 +524,7 @@ struct LigatureSubtable
          {
            ligature_idx = Types::offsetToIndex (ligature_idx, table, ligature.arrayZ);
            const GlyphID &ligatureData = ligature[ligature_idx];
-           if (unlikely (!ligatureData.sanitize (&c->sanitizer))) return false;
+           if (unlikely (!ligatureData.sanitize (&c->sanitizer))) break;
            hb_codepoint_t lig = ligatureData;
 
            DEBUG_MSG (APPLY, nullptr, "Produced ligature %u", lig);
@@ -552,8 +548,6 @@ struct LigatureSubtable
        while (!(action & LigActionLast));
        buffer->move_to (end);
       }
-
-      return true;
     }
 
     public:
@@ -723,7 +717,7 @@ struct InsertionSubtable
       return (entry.flags & (CurrentInsertCount | MarkedInsertCount)) &&
             (entry.data.currentInsertIndex != 0xFFFF ||entry.data.markedInsertIndex != 0xFFFF);
     }
-    bool transition (StateTableDriver<Types, EntryData> *driver,
+    void transition (StateTableDriver<Types, EntryData> *driver,
                     const Entry<EntryData> &entry)
     {
       hb_buffer_t *buffer = driver->buffer;
@@ -736,7 +730,7 @@ struct InsertionSubtable
        unsigned int count = (flags & MarkedInsertCount);
        unsigned int start = entry.data.markedInsertIndex;
        const GlyphID *glyphs = &insertionAction[start];
-       if (unlikely (!c->sanitizer.check_array (glyphs, count))) return false;
+       if (unlikely (!c->sanitizer.check_array (glyphs, count))) count = 0;
 
        bool before = flags & MarkedInsertBefore;
 
@@ -764,7 +758,7 @@ struct InsertionSubtable
        unsigned int count = (flags & CurrentInsertCount) >> 5;
        unsigned int start = entry.data.currentInsertIndex;
        const GlyphID *glyphs = &insertionAction[start];
-       if (unlikely (!c->sanitizer.check_array (glyphs, count))) return false;
+       if (unlikely (!c->sanitizer.check_array (glyphs, count))) count = 0;
 
        bool before = flags & CurrentInsertBefore;
 
@@ -795,8 +789,6 @@ struct InsertionSubtable
         */
        buffer->move_to ((flags & DontAdvance) ? end : end + count);
       }
-
-      return true;
     }
 
     public: