From b976940243bf1f174bd6abb85955789ef2631d24 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 24 Jan 2019 18:01:07 +0100 Subject: [PATCH] [AAT] Handle transition errors during machine operation 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 | 3 +-- src/hb-aat-layout-kerx-table.hh | 21 +++++++-------------- src/hb-aat-layout-morx-table.hh | 34 +++++++++++++--------------------- 3 files changed, 21 insertions(+), 37 deletions(-) diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh index 516a722..27ade28 100644 --- a/src/hb-aat-layout-common.hh +++ b/src/hb-aat-layout-common.hh @@ -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); diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index 0630fba..a64c807 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -232,7 +232,7 @@ struct KerxSubTableFormat1 { return Format1EntryT::performAction (entry); } - bool transition (StateTableDriver *driver, + void transition (StateTableDriver *driver, const Entry &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 *driver, + void transition (StateTableDriver *driver, const Entry &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: diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index 564a618..8fc6c5d 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -78,7 +78,7 @@ struct RearrangementSubtable { return (entry.flags & Verb) && start < end; } - bool transition (StateTableDriver *driver, + void transition (StateTableDriver *driver, const Entry &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 *driver, + void transition (StateTableDriver *driver, const Entry &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 *driver, + void transition (StateTableDriver *driver, const Entry &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 *driver, + void transition (StateTableDriver *driver, const Entry &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: -- 2.7.4