diff options
author | Ben Wagner <bungeman@chromium.org> | 2021-10-20 11:45:15 -0400 |
---|---|---|
committer | Alexei Podtelezhnikov <apodtele@gmail.com> | 2021-10-20 11:45:15 -0400 |
commit | fde91ab8f19d1f789720afc67e0414a0244490d3 (patch) | |
tree | 9cec095e74336a43967fd8171d20f8fc473649f6 | |
parent | 6d12e3a0caf7e6c730972cadfdee758b2908ba9c (diff) | |
download | freetype2-fde91ab8f19d1f789720afc67e0414a0244490d3.tar.gz |
[sfnt] Delay setting gasp ranges and count until computed.
Previously, the gasp.numRanges was set and gasp.gaspRanges was
allocated and assigned before a possible early exit if the frame could
not be entered. It is also possible that the gaspRanges allocation
could fail but the numRanges still be set to non-zero. In such cases
an error would be returned, but the face would have a gasp in an
inconsistent state which may still be accessed.
Reported as
https://bugs.chromium.org/p/chromium/issues/detail?id=1261450
* src/sfnt/ttload.c (tt_face_load_gasp): Delay setting gasp.numRanges
and gasp.gaspRanges until after the ranges are initialized.
-rw-r--r-- | src/sfnt/ttload.c | 26 |
1 files changed, 14 insertions, 12 deletions
diff --git a/src/sfnt/ttload.c b/src/sfnt/ttload.c index e83e3ff2d..eb4607b7e 100644 --- a/src/sfnt/ttload.c +++ b/src/sfnt/ttload.c @@ -1434,7 +1434,7 @@ FT_Memory memory = stream->memory; FT_UInt j,num_ranges; - TT_GaspRange gaspranges = NULL; + TT_GaspRange gasp_ranges = NULL; /* the gasp table is optional */ @@ -1445,8 +1445,8 @@ if ( FT_FRAME_ENTER( 4L ) ) goto Exit; - face->gasp.version = FT_GET_USHORT(); - face->gasp.numRanges = FT_GET_USHORT(); + face->gasp.version = FT_GET_USHORT(); + num_ranges = FT_GET_USHORT(); FT_FRAME_EXIT(); @@ -1458,29 +1458,31 @@ goto Exit; } - num_ranges = face->gasp.numRanges; FT_TRACE3(( "numRanges: %u\n", num_ranges )); - if ( FT_QNEW_ARRAY( face->gasp.gaspRanges, num_ranges ) || - FT_FRAME_ENTER( num_ranges * 4L ) ) + if ( FT_QNEW_ARRAY( gasp_ranges, num_ranges ) || + FT_FRAME_ENTER( num_ranges * 4L ) ) goto Exit; - gaspranges = face->gasp.gaspRanges; - for ( j = 0; j < num_ranges; j++ ) { - gaspranges[j].maxPPEM = FT_GET_USHORT(); - gaspranges[j].gaspFlag = FT_GET_USHORT(); + gasp_ranges[j].maxPPEM = FT_GET_USHORT(); + gasp_ranges[j].gaspFlag = FT_GET_USHORT(); FT_TRACE3(( "gaspRange %d: rangeMaxPPEM %5d, rangeGaspBehavior 0x%x\n", j, - gaspranges[j].maxPPEM, - gaspranges[j].gaspFlag )); + gasp_ranges[j].maxPPEM, + gasp_ranges[j].gaspFlag )); } + face->gasp.gaspRanges = gasp_ranges; + gasp_ranges = NULL; + face->gasp.numRanges = num_ranges; + FT_FRAME_EXIT(); Exit: + FT_FREE( gasp_ranges ); return error; } |