[ft-devel] endless loops in bytecode
Folks, do you have any ideas how to discover endless loops in bytecode that don't change the nesting level? This would be very helpful for broken or malicious fonts that can make bytecode interpretation very slow. There are three instructions which can cause such loops. JMPR (jump relative) JROT (jump relative on true) JROF (jump relative on false) All three opcodes allow negative offsets; it's not documented in the specification, but the MS interpreter disallows jumps to other functions, and so does FreeType. Here's the simplest possible endless loop. PUSHW[1] -3 JMPR The PUSHW instruction pushes one word onto the stack (value -3), which is the offset JMPR is using to jump back to the PUSHW position. Currently, FreeType aborts bytecode interpretation after executing one million instructions (this can be changed at compile time) – this limit holds per glyph. I wonder whether there are any suggestions how to catch those three sneaky instructions earlier. My only idea up to date is to count JMPR, JROT, and JROF separately, using a threshold of, say, 1. Those instructions are very rare in normal bytecode, and having so much jumps within a single function is extremely unlikely. Werner ___ Freetype-devel mailing list Freetype-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/freetype-devel
Re: [ft-devel] endless loops in bytecode
We had initially ignored jump instructions while designing our font analysis code. They do occur sometimes though. I'd go with a blacklisting approach on a per-font level (maybe per glyph?) Once someone trips the timeout they get no more hints. pat On Sep 10, 2016 13:39, "Werner LEMBERG" wrote: > > Folks, > > > do you have any ideas how to discover endless loops in bytecode that > don't change the nesting level? This would be very helpful for broken > or malicious fonts that can make bytecode interpretation very slow. > > There are three instructions which can cause such loops. > > JMPR (jump relative) > JROT (jump relative on true) > JROF (jump relative on false) > > All three opcodes allow negative offsets; it's not documented in the > specification, but the MS interpreter disallows jumps to other > functions, and so does FreeType. Here's the simplest possible endless > loop. > > PUSHW[1] > -3 > JMPR > > The PUSHW instruction pushes one word onto the stack (value -3), which > is the offset JMPR is using to jump back to the PUSHW position. > > Currently, FreeType aborts bytecode interpretation after executing one > million instructions (this can be changed at compile time) – this > limit holds per glyph. I wonder whether there are any suggestions how > to catch those three sneaky instructions earlier. > > My only idea up to date is to count JMPR, JROT, and JROF separately, > using a threshold of, say, 1. Those instructions are very rare in > normal bytecode, and having so much jumps within a single function is > extremely unlikely. > > > Werner > ___ > Freetype-devel mailing list > Freetype-devel@nongnu.org > https://lists.nongnu.org/mailman/listinfo/freetype-devel > ___ Freetype-devel mailing list Freetype-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/freetype-devel
Re: [ft-devel] endless loops in bytecode
> PUSHW[1] >-3 > JMPR > > The PUSHW instruction pushes one word onto the stack (value -3), which > is the offset JMPR is using to jump back Did you see jumps back in the real world? Can you just ignore jumps back? ___ Freetype-devel mailing list Freetype-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/freetype-devel
Re: [ft-devel] endless loops in bytecode
> We had initially ignored jump instructions while designing our font > analysis code. Yes, I've seen that. Is this fixed meanwhile? > I'd go with a blacklisting approach on a per-font level (maybe per > glyph?) Once someone trips the timeout they get no more hints. This is a possible solution, yes. Thanks for the idea. Werner ___ Freetype-devel mailing list Freetype-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/freetype-devel
Re: [ft-devel] endless loops in bytecode
>> PUSHW[1] >>-3 >> JMPR >> >> The PUSHW instruction pushes one word onto the stack (value -3), >> which is the offset JMPR is using to jump back > > Did you see jumps back in the real world? I can't remember whether I've seen JMPR in a font, but JROT and JROF definitely happen (e.g., in my ttfautohint's bytecode :-) – you need them for loops where LOOPCALL doesn't provide a good solution. Werner ___ Freetype-devel mailing list Freetype-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/freetype-devel
Re: [ft-devel] endless loops in bytecode
Have also seen a few (not many) on some fonts in my corpus. On Sep 10, 2016 16:28, "Alexei Podtelezhnikov" wrote: > > > PUSHW[1] > >-3 > > JMPR > > > > The PUSHW instruction pushes one word onto the stack (value -3), which > > is the offset JMPR is using to jump back > > Did you see jumps back in the real world? Can you just ignore jumps back? > > ___ > Freetype-devel mailing list > Freetype-devel@nongnu.org > https://lists.nongnu.org/mailman/listinfo/freetype-devel > ___ Freetype-devel mailing list Freetype-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/freetype-devel