From b2a187918757a0faaf0f564ec2b0766c09fa364c Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 23 Jun 2018 10:32:28 -0400 Subject: [PATCH] In Coverage iterator, bail out if table smells In particular, if CoverageFormat2 has unsorted ranges, bail out. Otherwise, 64k ranges of each 64k glyphs can DoS closure() method. We can do the same for CoverageFormat1, but that one does not expose the quadratic behavior, so, fine. --- src/hb-ot-layout-common-private.hh | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/hb-ot-layout-common-private.hh b/src/hb-ot-layout-common-private.hh index 763ea92f9..ff9c5650f 100644 --- a/src/hb-ot-layout-common-private.hh +++ b/src/hb-ot-layout-common-private.hh @@ -832,7 +832,12 @@ struct CoverageFormat2 c = &c_; coverage = 0; i = 0; - j = c->rangeRecord.len ? c_.rangeRecord[0].start : 0; + j = c->rangeRecord.len ? c->rangeRecord[0].start : 0; + if (unlikely (c->rangeRecord[0].start > c->rangeRecord[0].end)) + { + /* Broken table. Skip. */ + i = c->rangeRecord.len; + } } inline bool more (void) { return i < c->rangeRecord.len; } inline void next (void) @@ -842,7 +847,14 @@ struct CoverageFormat2 i++; if (more ()) { + hb_codepoint_t old = j; j = c->rangeRecord[i].start; + if (unlikely (j <= old)) + { + /* Broken table. Skip. Important to avoid DoS. */ + i = c->rangeRecord.len; + return; + } coverage = c->rangeRecord[i].value; } return; @@ -855,7 +867,8 @@ struct CoverageFormat2 private: const struct CoverageFormat2 *c; - unsigned int i, j, coverage; + unsigned int i, coverage; + hb_codepoint_t j; }; private: