[subset] Limit the iterations of the closure algorithm.

Prevents O(n^2) run times.
pull/1108/head
Garret Rieger 7 years ago
parent 94759d4cf8
commit 85646fdadb
  1. 7
      src/hb-ot-layout-common-private.hh
  2. 5
      src/hb-ot-layout.cc

@ -41,6 +41,13 @@
#ifndef HB_MAX_CONTEXT_LENGTH #ifndef HB_MAX_CONTEXT_LENGTH
#define HB_MAX_CONTEXT_LENGTH 64 #define HB_MAX_CONTEXT_LENGTH 64
#endif #endif
#ifndef HB_CLOSURE_MAX_STAGES
/*
* The maximum number of times a lookup can be applied during shaping.
* Used to limit the number of iterations of the closure algorithm.
*/
#define HB_CLOSURE_MAX_STAGES 8
#endif
namespace OT { namespace OT {

@ -971,6 +971,7 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face,
OT::hb_closure_context_t c (face, glyphs, &done_lookups); OT::hb_closure_context_t c (face, glyphs, &done_lookups);
const OT::GSUB& gsub = _get_gsub (face); const OT::GSUB& gsub = _get_gsub (face);
unsigned int iteration_count = 0;
unsigned int glyphs_length; unsigned int glyphs_length;
do do
{ {
@ -985,7 +986,9 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face,
for (unsigned int i = 0; i < gsub.get_lookup_count (); i++) for (unsigned int i = 0; i < gsub.get_lookup_count (); i++)
gsub.get_lookup (i).closure (&c, i); gsub.get_lookup (i).closure (&c, i);
} }
} while (glyphs_length != glyphs->get_population ()); iteration_count++;
} while (iteration_count <= HB_CLOSURE_MAX_STAGES
&& glyphs_length != glyphs->get_population ());
} }
/* /*

Loading…
Cancel
Save