diff -urN harfbuzz-1.7.5.old/src/hb-ot-layout-gsubgpos-private.hh harfbuzz-1.7.5/src/hb-ot-layout-gsubgpos-private.hh --- harfbuzz-1.7.5.old/src/hb-ot-layout-gsubgpos-private.hh 2018-01-27 07:43:07.000000000 +0530 +++ harfbuzz-1.7.5/src/hb-ot-layout-gsubgpos-private.hh 2023-09-25 12:18:00.277228938 +0530 @@ -368,7 +368,15 @@ inline bool prev (void) { assert (num_items > 0); - while (idx >= num_items) + unsigned stop = num_items - 1; + + /* When looking back, limit how far we search; this function is mostly + * used for looking back for base glyphs when attaching marks. If we + * don't limit, we can get O(n^2) behavior where n is the number of + * consecutive marks. */ + stop = (unsigned) ((int) stop >= (int) idx - HB_MAX_CONTEXT_LENGTH ? stop : (int) idx - HB_MAX_CONTEXT_LENGTH); + + while (idx > stop) { idx--; const hb_glyph_info_t &info = c->buffer->out_info[idx];