[truetype] Simplify memory management.

Instead of using `Update_Max`, switch to regular FreeType memory
allocation macros, stop pre-allocating the glyph instruction arrays.

* src/truetype/ttgload.c (TT_Load_Simple_Glyph,
TT_Process_Composite_Glyph): Switch to regular memory allocation.
* src/truetype/ttinterp.c (Update_Max): Removed.
(TT_Load_Context): Reallocate stack and free old instructions.
(Modify_CVT_Check, Ins_WS): Switch to regular memory allocation.
* src/truetype/ttinterp.h (Update_Max): Removed.
This commit is contained in:
Alexei Podtelezhnikov 2023-02-26 08:07:08 -05:00
parent b2a9490623
commit de94e2cbfb
3 changed files with 68 additions and 152 deletions

View File

@ -437,7 +437,8 @@
if ( IS_HINTED( load->load_flags ) )
{
FT_ULong tmp;
TT_ExecContext exec = load->exec;
FT_Memory memory = exec->memory;
/* check instructions size */
@ -449,24 +450,19 @@
}
/* we don't trust `maxSizeOfInstructions' in the `maxp' table */
/* and thus update the bytecode array size by ourselves */
tmp = load->exec->glyphSize;
error = Update_Max( load->exec->memory,
&tmp,
sizeof ( FT_Byte ),
(void*)&load->exec->glyphIns,
n_ins );
load->exec->glyphSize = (FT_UInt)tmp;
if ( error )
return error;
load->glyph->control_len = n_ins;
load->glyph->control_data = load->exec->glyphIns;
/* and thus allocate the bytecode array size by ourselves */
if ( n_ins )
FT_MEM_COPY( load->exec->glyphIns, p, (FT_Long)n_ins );
{
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;
}
}
#endif /* TT_USE_BYTECODE_INTERPRETER */
@ -1331,12 +1327,12 @@
FT_UInt start_contour )
{
FT_Error error;
FT_Outline* outline;
FT_Outline* outline = &loader->gloader->base.outline;
FT_Stream stream = loader->stream;
FT_UShort n_ins;
FT_UInt i;
outline = &loader->gloader->base.outline;
/* make room for phantom points */
error = FT_GLYPHLOADER_CHECK_POINTS( loader->gloader,
outline->n_points + 4,
@ -1351,53 +1347,40 @@
#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_Stream stream = loader->stream;
FT_UShort n_ins, max_ins;
FT_ULong tmp;
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;
/* 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 ) )
if ( FT_QNEW_ARRAY( exec->glyphIns, n_ins ) ||
FT_STREAM_READ( exec->glyphIns, n_ins ) )
return error;
FT_TRACE5(( " Instructions size = %hu\n", n_ins ));
exec->glyphSize = n_ins;
/* check it */
max_ins = loader->face->max_profile.maxSizeOfInstructions;
if ( n_ins > max_ins )
{
/* 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 );
}
tmp = loader->exec->glyphSize;
error = Update_Max( loader->exec->memory,
&tmp,
sizeof ( FT_Byte ),
(void*)&loader->exec->glyphIns,
n_ins );
loader->exec->glyphSize = (FT_UShort)tmp;
if ( error )
return error;
}
else if ( n_ins == 0 )
return FT_Err_Ok;
if ( FT_STREAM_READ( loader->exec->glyphIns, n_ins ) )
return error;
loader->glyph->control_data = loader->exec->glyphIns;
loader->glyph->control_len = n_ins;
loader->glyph->control_data = exec->glyphIns;
}
#endif

View File

@ -275,57 +275,6 @@
}
/**************************************************************************
*
* @Function:
* Update_Max
*
* @Description:
* Checks the size of a buffer and reallocates it if necessary.
*
* @Input:
* memory ::
* A handle to the parent memory object.
*
* multiplier ::
* The size in bytes of each element in the buffer.
*
* new_max ::
* The new capacity (size) of the buffer.
*
* @InOut:
* size ::
* The address of the buffer's current size expressed
* in elements.
*
* buff ::
* The address of the buffer base pointer.
*
* @Return:
* FreeType error code. 0 means success.
*/
FT_LOCAL_DEF( FT_Error )
Update_Max( FT_Memory memory,
FT_ULong* size,
FT_ULong multiplier,
void* _pbuff,
FT_ULong new_max )
{
FT_Error error;
void** pbuff = (void**)_pbuff;
if ( *size < new_max )
{
if ( FT_QREALLOC( *pbuff, *size * multiplier, new_max * multiplier ) )
return error;
*size = new_max;
}
return FT_Err_Ok;
}
/**************************************************************************
*
* @Function:
@ -359,9 +308,9 @@
TT_Size size )
{
FT_Int i;
FT_ULong tmp;
TT_MaxProfile* maxp;
FT_Error error;
FT_Memory memory = exec->memory;
exec->face = face;
@ -406,25 +355,15 @@
/* XXX: We reserve a little more elements on the stack to deal safely */
/* with broken fonts like arialbs, courbs, timesbs, etc. */
tmp = (FT_ULong)exec->stackSize;
error = Update_Max( exec->memory,
&tmp,
sizeof ( FT_F26Dot6 ),
(void*)&exec->stack,
maxp->maxStackElements + 32 );
exec->stackSize = (FT_Long)tmp;
if ( error )
if ( FT_QRENEW_ARRAY( exec->stack,
exec->stackSize,
maxp->maxStackElements + 32 ) )
return error;
exec->stackSize = maxp->maxStackElements + 32;
tmp = (FT_ULong)exec->glyphSize;
error = Update_Max( exec->memory,
&tmp,
sizeof ( FT_Byte ),
(void*)&exec->glyphIns,
maxp->maxSizeOfInstructions );
exec->glyphSize = (FT_UInt)tmp;
if ( error )
return error;
/* free previous glyph code range */
FT_FREE( exec->glyphIns );
exec->glyphSize = 0;
exec->pts.n_points = 0;
exec->pts.n_contours = 0;
@ -1530,14 +1469,16 @@
if ( exc->iniRange == tt_coderange_glyph &&
exc->cvt != exc->glyfCvt )
{
exc->error = Update_Max( exc->memory,
&exc->glyfCvtSize,
sizeof ( FT_Long ),
(void*)&exc->glyfCvt,
exc->cvtSize );
if ( exc->error )
FT_Memory memory = exc->memory;
FT_Error error;
FT_MEM_QRENEW_ARRAY( exc->glyfCvt, exc->glyfCvtSize, exc->cvtSize );
exc->error = error;
if ( error )
return;
exc->glyfCvtSize = exc->cvtSize;
FT_ARRAY_COPY( exc->glyfCvt, exc->cvt, exc->glyfCvtSize );
exc->cvt = exc->glyfCvt;
}
@ -3117,18 +3058,18 @@
if ( exc->iniRange == tt_coderange_glyph &&
exc->storage != exc->glyfStorage )
{
FT_ULong tmp = (FT_ULong)exc->glyfStoreSize;
FT_Memory memory = exc->memory;
FT_Error error;
exc->error = Update_Max( exc->memory,
&tmp,
sizeof ( FT_Long ),
(void*)&exc->glyfStorage,
exc->storeSize );
exc->glyfStoreSize = (FT_UShort)tmp;
if ( exc->error )
FT_MEM_QRENEW_ARRAY( exc->glyfStorage,
exc->glyfStoreSize,
exc->storeSize );
exc->error = error;
if ( error )
return;
exc->glyfStoreSize = exc->storeSize;
FT_ARRAY_COPY( exc->glyfStorage, exc->storage, exc->glyfStoreSize );
exc->storage = exc->glyfStorage;
}

View File

@ -460,14 +460,6 @@ FT_BEGIN_HEADER
FT_LOCAL( void )
TT_Clear_CodeRange( TT_ExecContext exec,
FT_Int range );
FT_LOCAL( FT_Error )
Update_Max( FT_Memory memory,
FT_ULong* size,
FT_ULong multiplier,
void* _pbuff,
FT_ULong new_max );
#endif /* TT_USE_BYTECODE_INTERPRETER */