forked from minhngoc25a/freetype2
[woff2] Improve memory and error handling.
Free up memory after use, and improve error handling. * src/sfnt/sfwoff2.c: Implement changes.
This commit is contained in:
parent
befd05c060
commit
af7d2967d5
|
@ -1333,6 +1333,7 @@
|
||||||
FT_Int nn = 0;
|
FT_Int nn = 0;
|
||||||
FT_UShort num_hmetrics;
|
FT_UShort num_hmetrics;
|
||||||
FT_ULong font_checksum = info->header_checksum;
|
FT_ULong font_checksum = info->header_checksum;
|
||||||
|
FT_Bool is_glyf_xform = FALSE;
|
||||||
|
|
||||||
FT_ULong table_entry_offset = 12;
|
FT_ULong table_entry_offset = 12;
|
||||||
WOFF2_Table head_table;
|
WOFF2_Table head_table;
|
||||||
|
@ -1370,7 +1371,8 @@
|
||||||
if ( FT_NEW( stream ) )
|
if ( FT_NEW( stream ) )
|
||||||
return FT_THROW( Invalid_Table );
|
return FT_THROW( Invalid_Table );
|
||||||
FT_Stream_OpenMemory( stream, transformed_buf, transformed_buf_size );
|
FT_Stream_OpenMemory( stream, transformed_buf, transformed_buf_size );
|
||||||
stream->close = stream_close;
|
stream->memory = memory;
|
||||||
|
stream->close = stream_close;
|
||||||
|
|
||||||
FT_ASSERT( FT_STREAM_POS() == 0 );
|
FT_ASSERT( FT_STREAM_POS() == 0 );
|
||||||
|
|
||||||
|
@ -1432,6 +1434,7 @@
|
||||||
|
|
||||||
if( table.Tag == TTAG_glyf )
|
if( table.Tag == TTAG_glyf )
|
||||||
{
|
{
|
||||||
|
is_glyf_xform = TRUE;
|
||||||
table.dst_offset = dest_offset;
|
table.dst_offset = dest_offset;
|
||||||
|
|
||||||
if( reconstruct_glyf( stream, &table, &checksum,
|
if( reconstruct_glyf( stream, &table, &checksum,
|
||||||
|
@ -1447,6 +1450,12 @@
|
||||||
}
|
}
|
||||||
else if( table.Tag == TTAG_hmtx )
|
else if( table.Tag == TTAG_hmtx )
|
||||||
{
|
{
|
||||||
|
if( !is_glyf_xform )
|
||||||
|
{
|
||||||
|
FT_ERROR(( "hmtx is transformed but glyf is not.\n" ));
|
||||||
|
error = FT_THROW( Unimplemented_Feature );
|
||||||
|
goto Fail;
|
||||||
|
}
|
||||||
table.dst_offset = dest_offset;
|
table.dst_offset = dest_offset;
|
||||||
if( reconstruct_hmtx( stream, table.src_length, info->num_glyphs,
|
if( reconstruct_hmtx( stream, table.src_length, info->num_glyphs,
|
||||||
info->num_hmetrics, info->x_mins, &checksum,
|
info->num_hmetrics, info->x_mins, &checksum,
|
||||||
|
@ -1501,7 +1510,11 @@
|
||||||
|
|
||||||
/* Set pointer of sfnt stream to its correct value. */
|
/* Set pointer of sfnt stream to its correct value. */
|
||||||
*sfnt_bytes = sfnt;
|
*sfnt_bytes = sfnt;
|
||||||
|
|
||||||
FT_FREE( table_entry );
|
FT_FREE( table_entry );
|
||||||
|
FT_Stream_Close( stream );
|
||||||
|
FT_FREE( stream );
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
Fail:
|
Fail:
|
||||||
|
@ -1509,10 +1522,10 @@
|
||||||
error = FT_THROW( Invalid_Table );
|
error = FT_THROW( Invalid_Table );
|
||||||
|
|
||||||
FT_FREE( table_entry );
|
FT_FREE( table_entry );
|
||||||
|
FT_Stream_Close( stream );
|
||||||
|
FT_FREE( stream );
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
/* TODO free the uncompressed stream after everything is done. */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1673,14 +1686,16 @@
|
||||||
if( table->Tag == TTAG_loca && table->TransformLength )
|
if( table->Tag == TTAG_loca && table->TransformLength )
|
||||||
{
|
{
|
||||||
FT_ERROR(( "woff_font_open: Invalid loca `transformLength'.\n" ));
|
FT_ERROR(( "woff_font_open: Invalid loca `transformLength'.\n" ));
|
||||||
return FT_THROW( Invalid_Table );
|
error = FT_THROW( Invalid_Table );
|
||||||
|
goto Exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( src_offset + table->TransformLength < src_offset )
|
if ( src_offset + table->TransformLength < src_offset )
|
||||||
{
|
{
|
||||||
FT_ERROR(( "woff_font_open: invalid WOFF2 table directory.\n" ));
|
FT_ERROR(( "woff_font_open: invalid WOFF2 table directory.\n" ));
|
||||||
return FT_THROW( Invalid_Table );
|
error = FT_THROW( Invalid_Table );
|
||||||
|
goto Exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
table->src_offset = src_offset;
|
table->src_offset = src_offset;
|
||||||
|
@ -1708,7 +1723,11 @@
|
||||||
woff2.uncompressed_size = last_table->src_offset
|
woff2.uncompressed_size = last_table->src_offset
|
||||||
+ last_table->src_length;
|
+ last_table->src_length;
|
||||||
if( woff2.uncompressed_size < last_table->src_offset )
|
if( woff2.uncompressed_size < last_table->src_offset )
|
||||||
return FT_THROW( Invalid_Table );
|
{
|
||||||
|
error = FT_THROW( Invalid_Table );
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
|
||||||
/* DEBUG - Remove later. */
|
/* DEBUG - Remove later. */
|
||||||
FT_TRACE2(( "Uncompressed size: %ld\n", woff2.uncompressed_size ));
|
FT_TRACE2(( "Uncompressed size: %ld\n", woff2.uncompressed_size ));
|
||||||
|
|
||||||
|
@ -1724,7 +1743,10 @@
|
||||||
FT_TRACE2(( "Header version: %lx\n", woff2.header_version ));
|
FT_TRACE2(( "Header version: %lx\n", woff2.header_version ));
|
||||||
if( woff2.header_version != 0x00010000 &&
|
if( woff2.header_version != 0x00010000 &&
|
||||||
woff2.header_version != 0x00020000 )
|
woff2.header_version != 0x00020000 )
|
||||||
return FT_THROW( Invalid_Table );
|
{
|
||||||
|
error = FT_THROW( Invalid_Table );
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
|
||||||
if( READ_255USHORT( woff2.num_fonts ) )
|
if( READ_255USHORT( woff2.num_fonts ) )
|
||||||
goto Exit;
|
goto Exit;
|
||||||
|
@ -1779,10 +1801,10 @@
|
||||||
{
|
{
|
||||||
if( glyf_index > loca_index ||
|
if( glyf_index > loca_index ||
|
||||||
loca_index - glyf_index != 1 )
|
loca_index - glyf_index != 1 )
|
||||||
return FT_THROW( Invalid_Table );
|
{
|
||||||
/* DEBUG - Remove later */
|
error = FT_THROW( Invalid_Table );
|
||||||
else
|
goto Exit;
|
||||||
FT_TRACE2(( "glyf and loca indices are valid.\n" ));
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Collection directory reading complete. */
|
/* Collection directory reading complete. */
|
||||||
|
@ -1795,24 +1817,36 @@
|
||||||
|
|
||||||
/* Few more checks before we start reading the tables. */
|
/* Few more checks before we start reading the tables. */
|
||||||
if( file_offset > woff2.length )
|
if( file_offset > woff2.length )
|
||||||
return FT_THROW( Invalid_Table );
|
{
|
||||||
|
error = FT_THROW( Invalid_Table );
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
|
||||||
if ( woff2.metaOffset )
|
if ( woff2.metaOffset )
|
||||||
{
|
{
|
||||||
if ( file_offset != woff2.metaOffset )
|
if ( file_offset != woff2.metaOffset )
|
||||||
return FT_THROW( Invalid_Table );
|
{
|
||||||
|
error = FT_THROW( Invalid_Table );
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
file_offset = ROUND4(woff2.metaOffset + woff2.metaLength);
|
file_offset = ROUND4(woff2.metaOffset + woff2.metaLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( woff2.privOffset )
|
if( woff2.privOffset )
|
||||||
{
|
{
|
||||||
if( file_offset != woff2.privOffset )
|
if( file_offset != woff2.privOffset )
|
||||||
return FT_THROW( Invalid_Table );
|
{
|
||||||
|
error = FT_THROW( Invalid_Table );
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
file_offset = ROUND4(woff2.privOffset + woff2.privLength);
|
file_offset = ROUND4(woff2.privOffset + woff2.privLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( file_offset != ( ROUND4( woff2.length ) ) )
|
if( file_offset != ( ROUND4( woff2.length ) ) )
|
||||||
return FT_THROW( Invalid_Table );
|
{
|
||||||
|
error = FT_THROW( Invalid_Table );
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
|
||||||
/* Only retain tables of the requested face in a TTC. */
|
/* Only retain tables of the requested face in a TTC. */
|
||||||
/* TODO Check whether it is OK for rest of the code to be unaware of the
|
/* TODO Check whether it is OK for rest of the code to be unaware of the
|
||||||
|
@ -1919,13 +1953,15 @@
|
||||||
error = woff2_uncompress( uncompressed_buf, woff2.uncompressed_size,
|
error = woff2_uncompress( uncompressed_buf, woff2.uncompressed_size,
|
||||||
stream->cursor, woff2.totalCompressedSize );
|
stream->cursor, woff2.totalCompressedSize );
|
||||||
if( error )
|
if( error )
|
||||||
goto Exit;
|
goto Exit;
|
||||||
|
|
||||||
FT_FRAME_EXIT();
|
FT_FRAME_EXIT();
|
||||||
|
|
||||||
reconstruct_font( uncompressed_buf, woff2.uncompressed_size,
|
error = reconstruct_font( uncompressed_buf, woff2.uncompressed_size,
|
||||||
indices, &woff2, &info, &sfnt, &sfnt_size,
|
indices, &woff2, &info, &sfnt, &sfnt_size,
|
||||||
memory );
|
memory );
|
||||||
|
if( error )
|
||||||
|
goto Exit;
|
||||||
|
|
||||||
/* Resize `sfnt' to actual size of sfnt stream. */
|
/* Resize `sfnt' to actual size of sfnt stream. */
|
||||||
if ( woff2.actual_sfnt_size < sfnt_size )
|
if ( woff2.actual_sfnt_size < sfnt_size )
|
||||||
|
@ -1953,7 +1989,7 @@
|
||||||
|
|
||||||
face->root.face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM;
|
face->root.face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM;
|
||||||
|
|
||||||
/* Set face_index to 0. */
|
/* Set face_index to 0. */
|
||||||
*face_instance_index = 0;
|
*face_instance_index = 0;
|
||||||
|
|
||||||
/* error = FT_THROW( Unimplemented_Feature ); */
|
/* error = FT_THROW( Unimplemented_Feature ); */
|
||||||
|
@ -1964,13 +2000,15 @@
|
||||||
Exit:
|
Exit:
|
||||||
FT_FREE( tables );
|
FT_FREE( tables );
|
||||||
FT_FREE( indices );
|
FT_FREE( indices );
|
||||||
FT_FREE( uncompressed_buf );
|
|
||||||
|
|
||||||
if( error )
|
if( error )
|
||||||
{
|
{
|
||||||
FT_FREE( sfnt );
|
FT_FREE( sfnt );
|
||||||
FT_Stream_Close( sfnt_stream );
|
if ( sfnt_stream )
|
||||||
FT_FREE( sfnt_stream );
|
{
|
||||||
|
FT_Stream_Close( sfnt_stream );
|
||||||
|
FT_FREE( sfnt_stream );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
|
|
Loading…
Reference in New Issue