ref: 815911ae2aac36e581fb7bc2a24024859f6d2771
parent: 6c2ab0977cd6d443fe845f88c9846bda2944622a
author: David Turner <[email protected]>
date: Sat Jun 16 13:07:20 EDT 2007
* 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
--- 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 <[email protected]>
--- 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 )
--- 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 )
{