* 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
diff --git a/ChangeLog b/ChangeLog
index 2ae2699..61e3968 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 <dmitry@codeweavers.com>
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
index 8947055..90e4385 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 31adb50..080337c 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 )
{