[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 ) ) if ( IS_HINTED( load->load_flags ) )
{ {
FT_ULong tmp; TT_ExecContext exec = load->exec;
FT_Memory memory = exec->memory;
/* check instructions size */ /* check instructions size */
@ -449,24 +450,19 @@
} }
/* we don't trust `maxSizeOfInstructions' in the `maxp' table */ /* we don't trust `maxSizeOfInstructions' in the `maxp' table */
/* and thus update the bytecode array size by ourselves */ /* and thus allocate 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;
if ( n_ins ) 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 */ #endif /* TT_USE_BYTECODE_INTERPRETER */
@ -1331,12 +1327,12 @@
FT_UInt start_contour ) FT_UInt start_contour )
{ {
FT_Error error; 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; FT_UInt i;
outline = &loader->gloader->base.outline;
/* make room for phantom points */ /* make room for phantom points */
error = FT_GLYPHLOADER_CHECK_POINTS( loader->gloader, error = FT_GLYPHLOADER_CHECK_POINTS( loader->gloader,
outline->n_points + 4, outline->n_points + 4,
@ -1351,53 +1347,40 @@
#ifdef TT_USE_BYTECODE_INTERPRETER #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_TRACE1(( "TT_Process_Composite_Glyph:"
FT_UShort n_ins, max_ins; " too many instructions (%hu) for glyph with length %u\n",
FT_ULong tmp; 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 */ if ( FT_QNEW_ARRAY( exec->glyphIns, n_ins ) ||
/* so we read them here */ FT_STREAM_READ( exec->glyphIns, n_ins ) )
if ( FT_STREAM_SEEK( loader->ins_pos ) ||
FT_READ_USHORT( n_ins ) )
return error; 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_len = n_ins;
loader->glyph->control_data = exec->glyphIns;
} }
#endif #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: * @Function:
@ -359,9 +308,9 @@
TT_Size size ) TT_Size size )
{ {
FT_Int i; FT_Int i;
FT_ULong tmp;
TT_MaxProfile* maxp; TT_MaxProfile* maxp;
FT_Error error; FT_Error error;
FT_Memory memory = exec->memory;
exec->face = face; exec->face = face;
@ -406,25 +355,15 @@
/* XXX: We reserve a little more elements on the stack to deal safely */ /* XXX: We reserve a little more elements on the stack to deal safely */
/* with broken fonts like arialbs, courbs, timesbs, etc. */ /* with broken fonts like arialbs, courbs, timesbs, etc. */
tmp = (FT_ULong)exec->stackSize; if ( FT_QRENEW_ARRAY( exec->stack,
error = Update_Max( exec->memory, exec->stackSize,
&tmp, maxp->maxStackElements + 32 ) )
sizeof ( FT_F26Dot6 ),
(void*)&exec->stack,
maxp->maxStackElements + 32 );
exec->stackSize = (FT_Long)tmp;
if ( error )
return error; return error;
exec->stackSize = maxp->maxStackElements + 32;
tmp = (FT_ULong)exec->glyphSize; /* free previous glyph code range */
error = Update_Max( exec->memory, FT_FREE( exec->glyphIns );
&tmp, exec->glyphSize = 0;
sizeof ( FT_Byte ),
(void*)&exec->glyphIns,
maxp->maxSizeOfInstructions );
exec->glyphSize = (FT_UInt)tmp;
if ( error )
return error;
exec->pts.n_points = 0; exec->pts.n_points = 0;
exec->pts.n_contours = 0; exec->pts.n_contours = 0;
@ -1530,14 +1469,16 @@
if ( exc->iniRange == tt_coderange_glyph && if ( exc->iniRange == tt_coderange_glyph &&
exc->cvt != exc->glyfCvt ) exc->cvt != exc->glyfCvt )
{ {
exc->error = Update_Max( exc->memory, FT_Memory memory = exc->memory;
&exc->glyfCvtSize, FT_Error error;
sizeof ( FT_Long ),
(void*)&exc->glyfCvt,
exc->cvtSize ); FT_MEM_QRENEW_ARRAY( exc->glyfCvt, exc->glyfCvtSize, exc->cvtSize );
if ( exc->error ) exc->error = error;
if ( error )
return; return;
exc->glyfCvtSize = exc->cvtSize;
FT_ARRAY_COPY( exc->glyfCvt, exc->cvt, exc->glyfCvtSize ); FT_ARRAY_COPY( exc->glyfCvt, exc->cvt, exc->glyfCvtSize );
exc->cvt = exc->glyfCvt; exc->cvt = exc->glyfCvt;
} }
@ -3117,18 +3058,18 @@
if ( exc->iniRange == tt_coderange_glyph && if ( exc->iniRange == tt_coderange_glyph &&
exc->storage != exc->glyfStorage ) 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, FT_MEM_QRENEW_ARRAY( exc->glyfStorage,
&tmp, exc->glyfStoreSize,
sizeof ( FT_Long ), exc->storeSize );
(void*)&exc->glyfStorage, exc->error = error;
exc->storeSize ); if ( error )
exc->glyfStoreSize = (FT_UShort)tmp;
if ( exc->error )
return; return;
exc->glyfStoreSize = exc->storeSize;
FT_ARRAY_COPY( exc->glyfStorage, exc->storage, exc->glyfStoreSize ); FT_ARRAY_COPY( exc->glyfStorage, exc->storage, exc->glyfStoreSize );
exc->storage = exc->glyfStorage; exc->storage = exc->glyfStorage;
} }

View File

@ -460,14 +460,6 @@ FT_BEGIN_HEADER
FT_LOCAL( void ) FT_LOCAL( void )
TT_Clear_CodeRange( TT_ExecContext exec, TT_Clear_CodeRange( TT_ExecContext exec,
FT_Int range ); 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 */ #endif /* TT_USE_BYTECODE_INTERPRETER */