* src/truetype/ttgload.c: fixing the TrueType loader to handle invalid composites correctly by limiting the recursion depth
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
diff --git a/ChangeLog b/ChangeLog
index 8dadbf9..3811137 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,6 +4,9 @@
src/pshinter/pshalgo3.c: implemented the FT_RENDER_MODE_LIGHT hinting
mode in the auto and postscript hinters
+ * src/truetype/ttgload.c: fixing the TrueType loader to handle invalid
+ composites correctly by limiting the recursion depth
+
2003-01-08 David Turner <david@freetype.org>
* src/base/ftobjs.c (find_unicode_charmap): fixed the error code
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
index c5f2654..7f4e8f5 100644
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -58,6 +58,15 @@
#define UNSCALED_COMPONENT_OFFSET 0x1000
+/* Maximum recursion depth we allow for composite glyphs.
+ * The TrueType spec doesn't say anything about recursion,
+ * so it isn't clear that recursion is allowed at all. But
+ * we'll be generous.
+ */
+#define TT_MAX_COMPOSITE_RECURSE 5
+
+
+
/*************************************************************************/
/* */
/* <Function> */
@@ -747,7 +756,8 @@
/* */
static FT_Error
load_truetype_glyph( TT_Loader loader,
- FT_UInt glyph_index )
+ FT_UInt glyph_index,
+ FT_UInt recurse_count )
{
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
@@ -769,6 +779,11 @@
FT_Bool glyph_data_loaded = 0;
#endif
+ if ( recurse_count >= TT_MAX_COMPOSITE_RECURSE )
+ {
+ error = TT_Err_Invalid_Composite;
+ goto Exit;
+ }
/* check glyph index */
if ( glyph_index >= (FT_UInt)face->root.num_glyphs )
@@ -985,7 +1000,7 @@
/***********************************************************************/
/* otherwise, load a composite! */
- else
+ else if ( contours_count == -1 )
{
TT_GlyphSlot glyph = (TT_GlyphSlot)loader->glyph;
FT_UInt start_point;
@@ -1059,7 +1074,8 @@
num_base_points = gloader->base.outline.n_points;
- error = load_truetype_glyph( loader, subglyph->index );
+ error = load_truetype_glyph( loader, subglyph->index,
+ recurse_count+1 );
if ( error )
goto Fail;
@@ -1326,6 +1342,12 @@
}
/* end of composite loading */
}
+ else
+ {
+ /* invalid composite count ( negative but not -1 ) */
+ error = TT_Err_Invalid_Outline;
+ goto Fail;
+ }
/***********************************************************************/
/***********************************************************************/
@@ -1757,7 +1779,7 @@
glyph->format = FT_GLYPH_FORMAT_OUTLINE;
glyph->num_subglyphs = 0;
- error = load_truetype_glyph( &loader, glyph_index );
+ error = load_truetype_glyph( &loader, glyph_index, 0 );
if ( !error )
compute_glyph_metrics( &loader, glyph_index );