diff --git a/ChangeLog b/ChangeLog index f39195811..b6cc3b644 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2017-04-03 Werner Lemberg + + [truetype] Avoid reexecution of `fpgm' and `prep' in case of error. + + Reported as + + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=981 + + * include/freetype/fterrdef.h (FT_Err_DEF_In_Glyf_Bytecode): New + error code. + + * src/truetype/ttinterp.c (Ins_FDEF, Ins_IDEF): Prohibit execution + of these two opcodes in `glyf' bytecode. + (TT_RunIns): Don't enforce reexecution of `fpgm' and `prep' bytecode + in case of error since function tables can no longer be modified + (due to the changes in `Ins_FDEF' and `Ins_IDEF'). This change can + enormously speed up handling of broken fonts. + 2017-04-02 Alexei Podtelezhnikov [autofit] Disable metrics adjustment for `FT_LOAD_TARGET_LCD'. diff --git a/include/freetype/fterrdef.h b/include/freetype/fterrdef.h index 232dccdc6..cabbac827 100644 --- a/include/freetype/fterrdef.h +++ b/include/freetype/fterrdef.h @@ -231,6 +231,8 @@ "invalid PostScript (post) table format" ) FT_ERRORDEF_( Invalid_Post_Table, 0x9B, "invalid PostScript (post) table" ) + FT_ERRORDEF_( DEF_In_Glyf_Bytecode, 0x9C, + "found FDEF or IDEF opcode in glyf bytecode" ) /* CFF, CID, and Type 1 errors */ diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c index 000c30b23..fed377d97 100644 --- a/src/truetype/ttinterp.c +++ b/src/truetype/ttinterp.c @@ -3564,6 +3564,13 @@ #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ + /* FDEF is only allowed in `prep' or `fpgm' */ + if ( exc->curRange == tt_coderange_glyph ) + { + exc->error = FT_THROW( DEF_In_Glyf_Bytecode ); + return; + } + /* some font programs are broken enough to redefine functions! */ /* We will then parse the current table. */ @@ -3990,6 +3997,13 @@ TT_DefRecord* limit; + /* we enable IDEF only in `prep' or `fpgm' */ + if ( exc->curRange == tt_coderange_glyph ) + { + exc->error = FT_THROW( DEF_In_Glyf_Bytecode ); + return; + } + /* First of all, look for the same function in our table */ def = exc->IDefs; @@ -8408,17 +8422,8 @@ exc->error = FT_THROW( Code_Overflow ); LErrorLabel_: - /* If any errors have occurred, function tables may be broken. */ - /* Force a re-execution of `prep' and `fpgm' tables if no */ - /* bytecode debugger is run. */ - if ( exc->error && - !exc->instruction_trap && - exc->curRange == tt_coderange_glyph ) - { + if ( exc->error && !exc->instruction_trap ) FT_TRACE1(( " The interpreter returned error 0x%x\n", exc->error )); - exc->size->bytecode_ready = -1; - exc->size->cvt_ready = -1; - } return exc->error; }