[cff] Commit vstore data and regions on allocation.
The vstore->regionCount and vstore->dataCount were read directly from the data. However, vstore->varRegionList and vstore->varData would still contain uninitialized entries with uninitialized pointers in the event of an error, leading to issues when attempting to clean up. Reportd as https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=40104 * src/cff/cffload.c (cff_vstore_load): Read the region and data counts into locals and update the vstore counts immediately after each entry becomes free-able.
This commit is contained in:
parent
fde91ab8f1
commit
b5e003f1f2
|
@ -1138,6 +1138,8 @@
|
||||||
{
|
{
|
||||||
FT_UInt vsOffset;
|
FT_UInt vsOffset;
|
||||||
FT_UInt format;
|
FT_UInt format;
|
||||||
|
FT_UInt dataCount;
|
||||||
|
FT_UInt regionCount;
|
||||||
FT_ULong regionListOffset;
|
FT_ULong regionListOffset;
|
||||||
|
|
||||||
|
|
||||||
|
@ -1161,15 +1163,15 @@
|
||||||
|
|
||||||
/* read top level fields */
|
/* read top level fields */
|
||||||
if ( FT_READ_ULONG( regionListOffset ) ||
|
if ( FT_READ_ULONG( regionListOffset ) ||
|
||||||
FT_READ_USHORT( vstore->dataCount ) )
|
FT_READ_USHORT( dataCount ) )
|
||||||
goto Exit;
|
goto Exit;
|
||||||
|
|
||||||
/* make temporary copy of item variation data offsets; */
|
/* make temporary copy of item variation data offsets; */
|
||||||
/* we'll parse region list first, then come back */
|
/* we'll parse region list first, then come back */
|
||||||
if ( FT_QNEW_ARRAY( dataOffsetArray, vstore->dataCount ) )
|
if ( FT_QNEW_ARRAY( dataOffsetArray, dataCount ) )
|
||||||
goto Exit;
|
goto Exit;
|
||||||
|
|
||||||
for ( i = 0; i < vstore->dataCount; i++ )
|
for ( i = 0; i < dataCount; i++ )
|
||||||
{
|
{
|
||||||
if ( FT_READ_ULONG( dataOffsetArray[i] ) )
|
if ( FT_READ_ULONG( dataOffsetArray[i] ) )
|
||||||
goto Exit;
|
goto Exit;
|
||||||
|
@ -1178,13 +1180,14 @@
|
||||||
/* parse regionList and axisLists */
|
/* parse regionList and axisLists */
|
||||||
if ( FT_STREAM_SEEK( vsOffset + regionListOffset ) ||
|
if ( FT_STREAM_SEEK( vsOffset + regionListOffset ) ||
|
||||||
FT_READ_USHORT( vstore->axisCount ) ||
|
FT_READ_USHORT( vstore->axisCount ) ||
|
||||||
FT_READ_USHORT( vstore->regionCount ) )
|
FT_READ_USHORT( regionCount ) )
|
||||||
goto Exit;
|
goto Exit;
|
||||||
|
|
||||||
if ( FT_QNEW_ARRAY( vstore->varRegionList, vstore->regionCount ) )
|
vstore->regionCount = 0;
|
||||||
|
if ( FT_QNEW_ARRAY( vstore->varRegionList, regionCount ) )
|
||||||
goto Exit;
|
goto Exit;
|
||||||
|
|
||||||
for ( i = 0; i < vstore->regionCount; i++ )
|
for ( i = 0; i < regionCount; i++ )
|
||||||
{
|
{
|
||||||
CFF_VarRegion* region = &vstore->varRegionList[i];
|
CFF_VarRegion* region = &vstore->varRegionList[i];
|
||||||
|
|
||||||
|
@ -1192,6 +1195,9 @@
|
||||||
if ( FT_QNEW_ARRAY( region->axisList, vstore->axisCount ) )
|
if ( FT_QNEW_ARRAY( region->axisList, vstore->axisCount ) )
|
||||||
goto Exit;
|
goto Exit;
|
||||||
|
|
||||||
|
/* keep track of how many axisList to deallocate on error */
|
||||||
|
vstore->regionCount++;
|
||||||
|
|
||||||
for ( j = 0; j < vstore->axisCount; j++ )
|
for ( j = 0; j < vstore->axisCount; j++ )
|
||||||
{
|
{
|
||||||
CFF_AxisCoords* axis = ®ion->axisList[j];
|
CFF_AxisCoords* axis = ®ion->axisList[j];
|
||||||
|
@ -1211,10 +1217,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
/* use dataOffsetArray now to parse varData items */
|
/* use dataOffsetArray now to parse varData items */
|
||||||
if ( FT_QNEW_ARRAY( vstore->varData, vstore->dataCount ) )
|
vstore->dataCount = 0;
|
||||||
|
if ( FT_QNEW_ARRAY( vstore->varData, dataCount ) )
|
||||||
goto Exit;
|
goto Exit;
|
||||||
|
|
||||||
for ( i = 0; i < vstore->dataCount; i++ )
|
for ( i = 0; i < dataCount; i++ )
|
||||||
{
|
{
|
||||||
CFF_VarData* data = &vstore->varData[i];
|
CFF_VarData* data = &vstore->varData[i];
|
||||||
|
|
||||||
|
@ -1236,6 +1243,9 @@
|
||||||
if ( FT_QNEW_ARRAY( data->regionIndices, data->regionIdxCount ) )
|
if ( FT_QNEW_ARRAY( data->regionIndices, data->regionIdxCount ) )
|
||||||
goto Exit;
|
goto Exit;
|
||||||
|
|
||||||
|
/* keep track of how many regionIndices to deallocate on error */
|
||||||
|
vstore->dataCount++;
|
||||||
|
|
||||||
for ( j = 0; j < data->regionIdxCount; j++ )
|
for ( j = 0; j < data->regionIdxCount; j++ )
|
||||||
{
|
{
|
||||||
if ( FT_READ_USHORT( data->regionIndices[j] ) )
|
if ( FT_READ_USHORT( data->regionIndices[j] ) )
|
||||||
|
|
Loading…
Reference in New Issue