<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Mon, Jul 30, 2018 at 6:21 PM, Richard Wordingham <span dir="ltr"><<a href="mailto:richard.wordingham@ntlworld.com" target="_blank">richard.wordingham@ntlworld.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On Mon, 30 Jul 2018 17:04:42 -0700<br>
Behdad Esfahbod <<a href="mailto:behdad@behdad.org">behdad@behdad.org</a>> wrote:<br>
<br>
> On Thu, Jul 26, 2018 at 12:06 AM, Richard Wordingham <<br>
> <a href="mailto:richard.wordingham@ntlworld.com">richard.wordingham@ntlworld.<wbr>com</a>> wrote:  <br>
> <br>
> > On Tue, 24 Jul 2018 16:31:50 +0000 (UTC)<br>
> > <a href="mailto:behdad@kemper.freedesktop.org">behdad@kemper.freedesktop.org</a> (Behdad Esfahbod) wrote:<br>
> ><br>
> > The following change bothers me:<br>
> >  <br>
> > >  src/hb-ot-layout-common-<wbr>private.hh |    7 +++++++<br>
> > >  src/hb-ot-layout.cc                |    5 ++++-<br>
> > >  2 files changed, 11 insertions(+), 1 deletion(-)<br>
> > ><br>
> > > New commits:<br>
> > > commit 85646fdadb2f102333485e07425361<wbr>795b4e0412<br>
> > > Author: Garret Rieger <<a href="mailto:grieger@google.com">grieger@google.com</a>><br>
> > > Date:   Mon Jul 23 15:37:18 2018 -0700<br>
> > ><br>
> > >     [subset] Limit the iterations of the closure algorithm.<br>
> > >     Prevents O(n^2) run times.<br>
> > ><br>
> > > diff --git a/src/hb-ot-layout-common-<wbr>private.hh<br>
> > > b/src/hb-ot-layout-common-<wbr>private.hh index 21caf9e9..7ff0dbeb<br>
> > > 100644 --- a/src/hb-ot-layout-common-<wbr>private.hh<br>
> > > +++ b/src/hb-ot-layout-common-<wbr>private.hh<br>
> > > @@ -41,6 +41,13 @@<br>
> > >  #ifndef HB_MAX_CONTEXT_LENGTH<br>
> > >  #define HB_MAX_CONTEXT_LENGTH        64<br>
> > >  #endif<br>
> > > +#ifndef HB_CLOSURE_MAX_STAGES<br>
> > > +/*<br>
> > > + * The maximum number of times a lookup can be applied during<br>
> > > shaping.<br>
> > > + * Used to limit the number of iterations of the closure<br>
> > > algorithm.<br>
> > > + */<br>
> > > +#define HB_CLOSURE_MAX_STAGES        8<br>
> > > +#endif  <br>
> ><br>
> > I presume that this is intended to prevent a denial of service<br>
> > attack, <br>
> <br>
> Correct.<br>
> <br>
> <br>
> > at the cost of trashing a subset font.<br>
> >  <br>
> <br>
> Not really.<br>
> <br>
> <br>
> > In non-malicious use, how is the victim supposed to detect that and<br>
> > then how he needs to change HarfBuzz or his font?  Does he have to<br>
> > read all the text using the subset font simply to detect a<br>
> > problem?  How does one test that a font does not hit this limit?  <br>
> <br>
> <br>
> It's impossible to hit that limit...  Ok, it would be impossible if we<br>
> increase it to 32.  I'll do that.<br>
<br>
</div></div>That'll probably work, but I'm now intrigued.  Why have a limit that<br>
will never be hit?  Are you just catering for HarfBuzz's logic simply<br>
going badly wrong in very unusual circumstances?<br></blockquote><div><br></div><div>Yes, simply as defense against malicious fonts and how the subsetter's glyph-closure routine can be tricked to collect (way) more glyphs than shaper can actually reach.<br></div><div><br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
The further points is just nit-picking and can be safely ignored.<br>
<span class=""><br>
> >   Does one have to<br>
> > iterate over the power set of the supported characters for each<br>
> > script?  That's O(2^n) - impossible to do!<br>
> ><br>
> > The description of HB_CLOSURE_MAX_STAGES is completely wrong.  I was<br>
> > initially alarmed because I have lookups that are invoked in more<br>
> > than 8 places in substitution subtables.  A more accurate, but<br>
> > still not perfect, definition, would be 'the maximum number of<br>
> > times lookup can change a bit of text'.<br>
> >  <br>
> <br>
> Nope.  Stage is a technical term in HarfBuzz GSUB processing.<br>
> <br>
> According to OpenType spec, lookups are processed in increasing order<br>
> of their indices.  This implies that each lookup is processed one.<br>
> But then the script shaping specs say some features are applied<br>
> separately.  Each of those separated list of features/lookups applied<br>
> are called one stage.  The total number of stages in any shaper is<br>
> the total number of times a lookup can be applied in theory.<br>
<br>
</span>That applies to lookups that are always formally unconditionally<br>
applied. It doesn't apply to lookups invoked in response to context or<br>
chaincontext lookups.<br>
<span class="im HOEnZb"><br>
> Note<br>
> that this does NOT limit recursion through Context and ChainContext<br>
> lookups.<br>
<br>
</span><div class="HOEnZb"><div class="h5">Richard.<br>
______________________________<wbr>_________________<br>
HarfBuzz mailing list<br>
<a href="mailto:HarfBuzz@lists.freedesktop.org">HarfBuzz@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/harfbuzz" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/harfbuzz</a><br>
</div></div></blockquote></div><br><br clear="all"><br>-- <br><div class="gmail_signature" data-smartmail="gmail_signature">behdad<br><a href="http://behdad.org/" target="_blank">http://behdad.org/</a></div>
</div></div>