提交 4d3aeb8c 编写于 作者: B Behdad Esfahbod

[GSUB/GPOS] Fix mark skip indexing issues

Mozilla bug 701637 and 714067 combined.

Patch from Jonathan Kew.
上级 e8eedf26
...@@ -629,21 +629,21 @@ struct PairPosFormat1 ...@@ -629,21 +629,21 @@ struct PairPosFormat1
inline bool apply (hb_apply_context_t *c) const inline bool apply (hb_apply_context_t *c) const
{ {
TRACE_APPLY (); TRACE_APPLY ();
unsigned int end = MIN (c->buffer->len, c->buffer->idx + c->context_length); unsigned int j = c->buffer->idx;
if (unlikely (c->buffer->idx + 2 > end)) unsigned int end = MIN (c->buffer->len, j + c->context_length);
if (unlikely (j >= end))
return false; return false;
unsigned int index = (this+coverage) (c->buffer->info[c->buffer->idx].codepoint); unsigned int index = (this+coverage) (c->buffer->info[j].codepoint);
if (likely (index == NOT_COVERED)) if (likely (index == NOT_COVERED))
return false; return false;
unsigned int j = c->buffer->idx + 1; do
while (_hb_ot_layout_skip_mark (c->face, &c->buffer->info[j], c->lookup_props, NULL))
{ {
j++;
if (unlikely (j == end)) if (unlikely (j == end))
return false; return false;
j++; } while (_hb_ot_layout_skip_mark (c->face, &c->buffer->info[j], c->lookup_props, NULL));
}
return (this+pairSet[index]).apply (c, &valueFormat1, j); return (this+pairSet[index]).apply (c, &valueFormat1, j);
} }
...@@ -691,21 +691,21 @@ struct PairPosFormat2 ...@@ -691,21 +691,21 @@ struct PairPosFormat2
inline bool apply (hb_apply_context_t *c) const inline bool apply (hb_apply_context_t *c) const
{ {
TRACE_APPLY (); TRACE_APPLY ();
unsigned int end = MIN (c->buffer->len, c->buffer->idx + c->context_length); unsigned int j = c->buffer->idx;
if (unlikely (c->buffer->idx + 2 > end)) unsigned int end = MIN (c->buffer->len, j + c->context_length);
if (unlikely (j >= end))
return false; return false;
unsigned int index = (this+coverage) (c->buffer->info[c->buffer->idx].codepoint); unsigned int index = (this+coverage) (c->buffer->info[j].codepoint);
if (likely (index == NOT_COVERED)) if (likely (index == NOT_COVERED))
return false; return false;
unsigned int j = c->buffer->idx + 1; do
while (_hb_ot_layout_skip_mark (c->face, &c->buffer->info[j], c->lookup_props, NULL))
{ {
j++;
if (unlikely (j == end)) if (unlikely (j == end))
return false; return false;
j++; } while (_hb_ot_layout_skip_mark (c->face, &c->buffer->info[j], c->lookup_props, NULL));
}
unsigned int len1 = valueFormat1.get_len (); unsigned int len1 = valueFormat1.get_len ();
unsigned int len2 = valueFormat2.get_len (); unsigned int len2 = valueFormat2.get_len ();
...@@ -846,21 +846,21 @@ struct CursivePosFormat1 ...@@ -846,21 +846,21 @@ struct CursivePosFormat1
if (c->property & HB_OT_LAYOUT_GLYPH_CLASS_MARK) if (c->property & HB_OT_LAYOUT_GLYPH_CLASS_MARK)
return false; return false;
unsigned int end = MIN (c->buffer->len, c->buffer->idx + c->context_length); unsigned int j = c->buffer->idx;
if (unlikely (c->buffer->idx + 2 > end)) unsigned int end = MIN (c->buffer->len, j + c->context_length);
if (unlikely (j >= end))
return false; return false;
const EntryExitRecord &this_record = entryExitRecord[(this+coverage) (c->buffer->info[c->buffer->idx].codepoint)]; const EntryExitRecord &this_record = entryExitRecord[(this+coverage) (c->buffer->info[j].codepoint)];
if (!this_record.exitAnchor) if (!this_record.exitAnchor)
return false; return false;
unsigned int j = c->buffer->idx + 1; do
while (_hb_ot_layout_skip_mark (c->face, &c->buffer->info[j], c->lookup_props, NULL))
{ {
j++;
if (unlikely (j == end)) if (unlikely (j == end))
return false; return false;
j++; } while (_hb_ot_layout_skip_mark (c->face, &c->buffer->info[j], c->lookup_props, NULL));
}
const EntryExitRecord &next_record = entryExitRecord[(this+coverage) (c->buffer->info[j].codepoint)]; const EntryExitRecord &next_record = entryExitRecord[(this+coverage) (c->buffer->info[j].codepoint)];
if (!next_record.entryAnchor) if (!next_record.entryAnchor)
......
...@@ -343,24 +343,25 @@ struct Ligature ...@@ -343,24 +343,25 @@ struct Ligature
inline bool apply (hb_apply_context_t *c) const inline bool apply (hb_apply_context_t *c) const
{ {
TRACE_APPLY (); TRACE_APPLY ();
unsigned int i, j; unsigned int i;
unsigned int j = c->buffer->idx;
unsigned int count = component.len; unsigned int count = component.len;
unsigned int end = MIN (c->buffer->len, c->buffer->idx + c->context_length); unsigned int end = MIN (c->buffer->len, j + c->context_length);
if (unlikely (count < 2 || c->buffer->idx + count > end)) if (unlikely (count < 2 || j >= end))
return false; return false;
bool first_was_mark = (c->property & HB_OT_LAYOUT_GLYPH_CLASS_MARK); bool first_was_mark = (c->property & HB_OT_LAYOUT_GLYPH_CLASS_MARK);
bool found_non_mark = false; bool found_non_mark = false;
for (i = 1, j = c->buffer->idx + 1; i < count; i++, j++) for (i = 1; i < count; i++)
{ {
unsigned int property; unsigned int property;
while (_hb_ot_layout_skip_mark (c->face, &c->buffer->info[j], c->lookup_props, &property)) do
{ {
if (unlikely (j + count - i == end))
return false;
j++; j++;
} if (unlikely (j == end))
return false;
} while (_hb_ot_layout_skip_mark (c->face, &c->buffer->info[j], c->lookup_props, &property));
found_non_mark |= !(property & HB_OT_LAYOUT_GLYPH_CLASS_MARK); found_non_mark |= !(property & HB_OT_LAYOUT_GLYPH_CLASS_MARK);
...@@ -376,9 +377,9 @@ struct Ligature ...@@ -376,9 +377,9 @@ struct Ligature
c->buffer->info[c->buffer->idx].lig_comp() = 0; c->buffer->info[c->buffer->idx].lig_comp() = 0;
c->buffer->info[c->buffer->idx].lig_id() = lig_id; c->buffer->info[c->buffer->idx].lig_id() = lig_id;
if (j == c->buffer->idx + i) /* No input glyphs skipped */ if (j < c->buffer->idx + count) /* No input glyphs skipped */
{ {
c->replace_glyphs_be16 (i, 1, (const uint16_t *) &ligGlyph); c->replace_glyphs_be16 (count, 1, (const uint16_t *) &ligGlyph);
} }
else else
{ {
......
...@@ -132,25 +132,26 @@ static inline bool match_input (hb_apply_context_t *c, ...@@ -132,25 +132,26 @@ static inline bool match_input (hb_apply_context_t *c,
const void *match_data, const void *match_data,
unsigned int *context_length_out) unsigned int *context_length_out)
{ {
unsigned int i, j; unsigned int i;
unsigned int end = MIN (c->buffer->len, c->buffer->idx + c->context_length); unsigned int j = c->buffer->idx;
if (unlikely (c->buffer->idx + count > end)) unsigned int end = MIN (c->buffer->len, j + c->context_length);
if (unlikely (j + count > end))
return false; return false;
for (i = 1, j = c->buffer->idx + 1; i < count; i++, j++) for (i = 1; i < count; i++)
{ {
while (_hb_ot_layout_skip_mark (c->face, &c->buffer->info[j], c->lookup_props, NULL)) do
{ {
if (unlikely (j + count - i == end))
return false;
j++; j++;
} if (unlikely (j >= end))
return false;
} while (_hb_ot_layout_skip_mark (c->face, &c->buffer->info[j], c->lookup_props, NULL));
if (likely (!match_func (c->buffer->info[j].codepoint, input[i - 1], match_data))) if (likely (!match_func (c->buffer->info[j].codepoint, input[i - 1], match_data)))
return false; return false;
} }
*context_length_out = j - c->buffer->idx; *context_length_out = j - c->buffer->idx + 1;
return true; return true;
} }
...@@ -161,17 +162,16 @@ static inline bool match_backtrack (hb_apply_context_t *c, ...@@ -161,17 +162,16 @@ static inline bool match_backtrack (hb_apply_context_t *c,
match_func_t match_func, match_func_t match_func,
const void *match_data) const void *match_data)
{ {
if (unlikely (c->buffer->backtrack_len () < count)) unsigned int j = c->buffer->backtrack_len ();
return false;
for (unsigned int i = 0, j = c->buffer->backtrack_len () - 1; i < count; i++, j--) for (unsigned int i = 0; i < count; i++)
{ {
while (_hb_ot_layout_skip_mark (c->face, &c->buffer->out_info[j], c->lookup_props, NULL)) do
{ {
if (unlikely (j + 1 == count - i)) if (unlikely (!j))
return false; return false;
j--; j--;
} } while (_hb_ot_layout_skip_mark (c->face, &c->buffer->out_info[j], c->lookup_props, NULL));
if (likely (!match_func (c->buffer->out_info[j].codepoint, backtrack[i], match_data))) if (likely (!match_func (c->buffer->out_info[j].codepoint, backtrack[i], match_data)))
return false; return false;
...@@ -187,19 +187,18 @@ static inline bool match_lookahead (hb_apply_context_t *c, ...@@ -187,19 +187,18 @@ static inline bool match_lookahead (hb_apply_context_t *c,
const void *match_data, const void *match_data,
unsigned int offset) unsigned int offset)
{ {
unsigned int i, j; unsigned int i;
unsigned int j = c->buffer->idx + offset - 1;
unsigned int end = MIN (c->buffer->len, c->buffer->idx + c->context_length); unsigned int end = MIN (c->buffer->len, c->buffer->idx + c->context_length);
if (unlikely (c->buffer->idx + offset + count > end))
return false;
for (i = 0, j = c->buffer->idx + offset; i < count; i++, j++) for (i = 0; i < count; i++)
{ {
while (_hb_ot_layout_skip_mark (c->face, &c->buffer->info[j], c->lookup_props, NULL)) do
{ {
if (unlikely (j + count - i == end))
return false;
j++; j++;
} if (unlikely (j >= end))
return false;
} while (_hb_ot_layout_skip_mark (c->face, &c->buffer->info[j], c->lookup_props, NULL));
if (likely (!match_func (c->buffer->info[j].codepoint, lookahead[i], match_data))) if (likely (!match_func (c->buffer->info[j].codepoint, lookahead[i], match_data)))
return false; return false;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册