summaryrefslogtreecommitdiff
path: root/src/truetype/ttgload.c
diff options
context:
space:
mode:
authorWerner Lemberg <wl@gnu.org>2018-08-26 11:59:02 +0200
committerWerner Lemberg <wl@gnu.org>2018-08-26 12:01:14 +0200
commit6e339b8d8e5641f0f2d5240f992336393a983107 (patch)
tree69a73b952d5f1b8d1623de4262a9f22a53fe79f9 /src/truetype/ttgload.c
parentb287c80b6a7d669a3c31aed7aeb6f8900e75a068 (diff)
downloadfreetype2-6e339b8d8e5641f0f2d5240f992336393a983107.tar.gz
[truetype] Avoid nested frames.
Triggered by https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10054 * src/truetype/ttgload.c (load_truetype_glyph): Don't use variable `opened_frame' to trace whether a frame must be closed at the end of function: This fails because `TT_Vary_Apply_Glyph_Deltas' (which gets called for space glyphs) uses a frame by itself. Instead, close the frame after loading the header, then use another frame for the remaining part of the glyph later on. Also avoid calling `tt_get_metrics' twice under some circumstances.
Diffstat (limited to 'src/truetype/ttgload.c')
-rw-r--r--src/truetype/ttgload.c62
1 files changed, 30 insertions, 32 deletions
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
index d76758465..b59e978cf 100644
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -1534,12 +1534,11 @@
FT_UInt recurse_count,
FT_Bool header_only )
{
- FT_Error error = FT_Err_Ok;
+ FT_Error error = FT_Err_Ok;
FT_Fixed x_scale, y_scale;
FT_ULong offset;
- TT_Face face = loader->face;
- FT_GlyphLoader gloader = loader->gloader;
- FT_Bool opened_frame = 0;
+ TT_Face face = loader->face;
+ FT_GlyphLoader gloader = loader->gloader;
#ifdef FT_CONFIG_OPTION_INCREMENTAL
FT_StreamRec inc_stream;
@@ -1572,15 +1571,15 @@
loader->glyph_index = glyph_index;
- if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
+ if ( loader->load_flags & FT_LOAD_NO_SCALE )
{
- x_scale = loader->size->metrics->x_scale;
- y_scale = loader->size->metrics->y_scale;
+ x_scale = 0x10000L;
+ y_scale = 0x10000L;
}
else
{
- x_scale = 0x10000L;
- y_scale = 0x10000L;
+ x_scale = loader->size->metrics->x_scale;
+ y_scale = loader->size->metrics->y_scale;
}
/* Set `offset' to the start of the glyph relative to the start of */
@@ -1639,38 +1638,36 @@
if ( error )
goto Exit;
- opened_frame = 1;
-
/* read glyph header first */
error = face->read_glyph_header( loader );
- if ( error )
- goto Exit;
- /* the metrics must be computed after loading the glyph header */
- /* since we need the glyph's `yMax' value in case the vertical */
- /* metrics must be emulated */
- error = tt_get_metrics( loader, glyph_index );
- if ( error )
- goto Exit;
+ face->forget_glyph_frame( loader );
- if ( header_only )
+ if ( error )
goto Exit;
}
+ /* a space glyph */
if ( loader->byte_len == 0 || loader->n_contours == 0 )
{
loader->bbox.xMin = 0;
loader->bbox.xMax = 0;
loader->bbox.yMin = 0;
loader->bbox.yMax = 0;
+ }
- error = tt_get_metrics( loader, glyph_index );
- if ( error )
- goto Exit;
+ /* the metrics must be computed after loading the glyph header */
+ /* since we need the glyph's `yMax' value in case the vertical */
+ /* metrics must be emulated */
+ error = tt_get_metrics( loader, glyph_index );
+ if ( error )
+ goto Exit;
- if ( header_only )
- goto Exit;
+ if ( header_only )
+ goto Exit;
+ if ( loader->byte_len == 0 || loader->n_contours == 0 )
+ {
/* must initialize points before (possibly) overriding */
/* glyph metrics from the incremental interface */
tt_loader_set_pp( loader );
@@ -1726,7 +1723,6 @@
loader->pp4.x = points[3].x;
loader->pp4.y = points[3].y;
-
/* recalculate linear horizontal and vertical advances */
/* if we don't have HVAR and VVAR, respectively */
if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
@@ -1767,6 +1763,14 @@
/***********************************************************************/
/***********************************************************************/
+ /* we now open a frame again, right after the glyph header */
+ /* (which consists of 10 bytes) */
+ error = face->access_glyph_frame( loader, glyph_index,
+ face->glyf_offset + offset + 10,
+ (FT_UInt)loader->byte_len - 10 );
+ if ( error )
+ goto Exit;
+
/* if it is a simple glyph, load it */
if ( loader->n_contours > 0 )
@@ -1777,7 +1781,6 @@
/* all data have been read */
face->forget_glyph_frame( loader );
- opened_frame = 0;
error = TT_Process_Simple_Glyph( loader );
if ( error )
@@ -1812,7 +1815,6 @@
* pointers with a width of at least 32 bits.
*/
-
/* clear the nodes filled by sibling chains */
node = ft_list_get_node_at( &loader->composites, recurse_count );
for ( node2 = node; node2; node2 = node2->next )
@@ -1852,7 +1854,6 @@
/* all data we need are read */
face->forget_glyph_frame( loader );
- opened_frame = 0;
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
@@ -2107,9 +2108,6 @@
Exit:
- if ( opened_frame )
- face->forget_glyph_frame( loader );
-
#ifdef FT_CONFIG_OPTION_INCREMENTAL
if ( glyph_data_loaded )