[truetype] Fix recent fallout in memory management. * src/truetype/ttgload.c (TT_Process_Composite_Glyph, TT_Load_Simple_Glyph): Clean up old instructions regardless of new ones, postpone setting `control_len` and `control_data` until... (TT_Load_Glyph): ... the exit from this function.
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 108 109 110 111 112 113 114 115 116 117
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
index 5419fa0..56e1c95 100644
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -422,10 +422,6 @@
if ( error )
goto Fail;
- /* reading the bytecode instructions */
- load->glyph->control_len = 0;
- load->glyph->control_data = NULL;
-
if ( p + 2 > limit )
goto Invalid_Outline;
@@ -449,21 +445,20 @@
goto Fail;
}
+ if ( exec->glyphSize )
+ FT_FREE( exec->glyphIns );
+ exec->glyphSize = 0;
+
/* we don't trust `maxSizeOfInstructions' in the `maxp' table */
/* and thus allocate the bytecode array size by ourselves */
if ( n_ins )
{
- if ( exec->glyphSize )
- FT_FREE( exec->glyphIns );
if ( FT_QNEW_ARRAY( exec->glyphIns, n_ins ) )
return error;
FT_MEM_COPY( exec->glyphIns, p, (FT_Long)n_ins );
exec->glyphSize = n_ins;
-
- load->glyph->control_len = n_ins;
- load->glyph->control_data = exec->glyphIns;
}
}
@@ -1347,27 +1342,6 @@
#ifdef TT_USE_BYTECODE_INTERPRETER
- /* TT_Load_Composite_Glyph only gives us the offset of instructions */
- /* so we read them here */
- if ( FT_STREAM_SEEK( loader->ins_pos ) ||
- FT_READ_USHORT( n_ins ) )
- return error;
-
- FT_TRACE5(( " Instructions size = %hu\n", n_ins ));
-
- if ( !n_ins )
- return FT_Err_Ok;
-
- /* don't trust `maxSizeOfInstructions'; */
- /* only do a rough safety check */
- if ( n_ins > loader->byte_len )
- {
- FT_TRACE1(( "TT_Process_Composite_Glyph:"
- " too many instructions (%hu) for glyph with length %u\n",
- n_ins, loader->byte_len ));
- return FT_THROW( Too_Many_Hints );
- }
-
{
TT_ExecContext exec = loader->exec;
FT_Memory memory = exec->memory;
@@ -1375,14 +1349,34 @@
if ( exec->glyphSize )
FT_FREE( exec->glyphIns );
+ exec->glyphSize = 0;
+
+ /* TT_Load_Composite_Glyph only gives us the offset of instructions */
+ /* so we read them here */
+ if ( FT_STREAM_SEEK( loader->ins_pos ) ||
+ FT_READ_USHORT( n_ins ) )
+ return error;
+
+ FT_TRACE5(( " Instructions size = %hu\n", n_ins ));
+
+ if ( !n_ins )
+ return FT_Err_Ok;
+
+ /* don't trust `maxSizeOfInstructions'; */
+ /* only do a rough safety check */
+ if ( n_ins > loader->byte_len )
+ {
+ FT_TRACE1(( "TT_Process_Composite_Glyph:"
+ " too many instructions (%hu) for glyph with length %u\n",
+ n_ins, loader->byte_len ));
+ return FT_THROW( Too_Many_Hints );
+ }
+
if ( FT_QNEW_ARRAY( exec->glyphIns, n_ins ) ||
FT_STREAM_READ( exec->glyphIns, n_ins ) )
return error;
exec->glyphSize = n_ins;
-
- loader->glyph->control_len = n_ins;
- loader->glyph->control_data = exec->glyphIns;
}
#endif
@@ -2940,6 +2934,9 @@
if ( IS_HINTED( load_flags ) )
{
+ glyph->control_data = loader.exec->glyphIns;
+ glyph->control_len = loader.exec->glyphSize;
+
if ( loader.exec->GS.scan_control )
{
/* convert scan conversion mode to FT_OUTLINE_XXX flags */