From 815911ae2aac36e581fb7bc2a24024859f6d2771 Mon Sep 17 00:00:00 2001 From: David Turner Date: Sat, 16 Jun 2007 17:07:20 +0000 Subject: [PATCH] * src/truetype/ttgload.c (TT_Load_Simple_Glyph): check the well-formedness of the contours array when loading a glyph * src/truetype/ttinterp.c (Ins_IP): check argument ranges to reject bogus operations properly --- ChangeLog | 6 ++++++ src/truetype/ttgload.c | 14 ++++++++++++-- src/truetype/ttinterp.c | 18 ++++++++++++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2ae269979..61e3968ec 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,12 @@ * src/smooth/ftgrays.c (gray_hline): prevent integer overflows when rendering *very* large outlines + * src/truetype/ttgload.c (TT_Load_Simple_Glyph): check the well-formedness + of the contours array when loading a glyph + + * src/truetype/ttinterp.c (Ins_IP): check argument ranges to reject + bogus operations properly + 2006-06-16 Dmitry Timoshkov diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c index 8947055cc..90e438504 100644 --- a/src/truetype/ttgload.c +++ b/src/truetype/ttgload.c @@ -250,7 +250,7 @@ FT_Byte c, count; FT_Vector *vec, *vec_limit; FT_Pos x; - FT_Short *cont, *cont_limit; + FT_Short *cont, *cont_limit, prev_cont; FT_Int xy_size = 0; @@ -267,8 +267,18 @@ if ( n_contours >= 0xFFF || p + (n_contours + 1) * 2 > limit ) goto Invalid_Outline; - for ( ; cont < cont_limit; cont++ ) + cont[0] = prev_cont = FT_NEXT_USHORT( p ); + for ( cont++; cont < cont_limit; cont++ ) + { cont[0] = FT_NEXT_USHORT( p ); + if (cont[0] > prev_cont) + { + /* unordered contours, this is invalid */ + error = FT_Err_Invalid_Table; + goto Fail; + } + prev_cont = cont[0]; + } n_points = 0; if ( n_contours > 0 ) diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c index 31adb50b7..080337c2b 100644 --- a/src/truetype/ttinterp.c +++ b/src/truetype/ttinterp.c @@ -620,6 +620,9 @@ exec->pts.n_points = 0; exec->pts.n_contours = 0; + exec->zp1 = exec->pts; + exec->zp2 = exec->pts; + exec->zp0 = exec->pts; exec->instruction_trap = FALSE; @@ -6148,6 +6151,13 @@ */ twilight = CUR.GS.gep0 == 0 || CUR.GS.gep1 == 0 || CUR.GS.gep2 == 0; + if ( BOUNDS(CUR.GS.rp1, CUR.zp0.n_points) ) + { + if ( CUR.pedantic_hinting ) + CUR.error = TT_Err_Invalid_Reference; + return; + } + if ( twilight ) orus_base = &CUR.zp0.org[CUR.GS.rp1]; else @@ -6251,6 +6261,7 @@ FT_Vector* orgs; /* original and current coordinate */ FT_Vector* curs; /* arrays */ FT_Vector* orus; + FT_UInt max_points; } IUP_WorkerRec, *IUP_Worker; @@ -6291,6 +6302,10 @@ if ( p1 > p2 ) return; + if ( BOUNDS(ref1, worker->max_points) || + BOUNDS(ref2, worker->max_points) ) + return; + orus1 = worker->orus[ref1].x; orus2 = worker->orus[ref2].x; @@ -6389,6 +6404,9 @@ FT_UNUSED_ARG; + /* ignore empty outlines */ + if ( CUR.pts.n_contours == 0 ) + return; if ( CUR.opcode & 1 ) {