* include/freetype/internal/ftmemory.h, src/base/ftbitmap.c,
src/base/ftmac.c, src/base/ftrfork.c, src/lzw/ftzopen.c, src/raster/ftrend1.c, src/sfnt/ttpost.c, src/truetype/ttgxvar.c, src/type42/t42parse.c, src/winfonts/winfnt.c: hardening the code against out-of-bounds conditions when allocating arrays. This is for the cases where FT_NEW_ARRAY and FT_RENEW_ARRAY are not used already. Introducing the new FT_ALLOC_MULT and FT_REALLOC_MULT macros.
This commit is contained in:
parent
264f307e66
commit
9ca782569c
11
ChangeLog
11
ChangeLog
@ -1,5 +1,15 @@
|
||||
2006-05-02 David Turner <david@freetype.org>
|
||||
|
||||
* include/freetype/internal/ftmemory.h, src/base/ftbitmap.c,
|
||||
src/base/ftmac.c, src/base/ftrfork.c, src/lzw/ftzopen.c,
|
||||
src/raster/ftrend1.c, src/sfnt/ttpost.c, src/truetype/ttgxvar.c,
|
||||
src/type42/t42parse.c, src/winfonts/winfnt.c: hardening the code
|
||||
against out-of-bounds conditions when allocating arrays. This is
|
||||
for the cases where FT_NEW_ARRAY and FT_RENEW_ARRAY are not used
|
||||
already. Introducing the new FT_ALLOC_MULT and FT_REALLOC_MULT
|
||||
macros.
|
||||
|
||||
|
||||
* include/freetype/fterrdef.h, include/freetype/config/ftconfig.h,
|
||||
include/freetype/internal/ftmemory.h, src/base/ftdbgmem.c,
|
||||
src/base/ftutil.c: udpating the memory management functions and
|
||||
@ -25,6 +35,7 @@
|
||||
is defined, and FT_STRICT_ALIASING has disappeared, the corresponding
|
||||
code being now the default.
|
||||
|
||||
|
||||
2006-04-30 suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp>
|
||||
|
||||
Fix bug in Mac_Read_POST_Resource() to parse PFB font with MacOS
|
||||
|
@ -134,6 +134,19 @@ FT_BASE( long ) _ft_debug_lineno;
|
||||
#define FT_MEM_QRENEW_ARRAY(ptr,cur,new) \
|
||||
FT_DEBUG_INNER( (ptr) = ft_mem_qrealloc( memory, sizeof(*(ptr)), (cur), (new), (ptr), &error ) )
|
||||
|
||||
#define FT_MEM_ALLOC_MULT(ptr,count,item_size) \
|
||||
FT_DEBUG_INNER( (ptr) = ft_mem_realloc( memory, (item_size), 0, (count), NULL, &error ) )
|
||||
|
||||
#define FT_MEM_REALLOC_MULT(ptr,oldcnt,newcnt,itmsz) \
|
||||
FT_DEBUG_INNER( (ptr) = ft_mem_realloc( memory, (itmsz), (oldcnt), (newcnt), (ptr), &error ) )
|
||||
|
||||
#define FT_MEM_QALLOC_MULT(ptr,count,item_size) \
|
||||
FT_DEBUG_INNER( (ptr) = ft_mem_qrealloc( memory, (item_size), 0, (count), NULL, &error ) )
|
||||
|
||||
#define FT_MEM_QREALLOC_MULT(ptr,oldcnt,newcnt,itmsz) \
|
||||
FT_DEBUG_INNER( (ptr) = ft_mem_qrealloc( memory, (itmsz), (oldcnt), (newcnt), (ptr), &error ) )
|
||||
|
||||
|
||||
#define FT_MEM_SET_ERROR( cond ) ( (cond), error != 0 )
|
||||
|
||||
|
||||
@ -198,12 +211,24 @@ FT_BASE( long ) _ft_debug_lineno;
|
||||
#define FT_REALLOC(ptr,cursz,newsz) \
|
||||
FT_MEM_SET_ERROR( FT_MEM_REALLOC(ptr,cursz,newsz) )
|
||||
|
||||
#define FT_ALLOC_MULT(ptr,count,item_size) \
|
||||
FT_MEM_SET_ERROR( FT_MEM_ALLOC_MULT(ptr,count,item_size) )
|
||||
|
||||
#define FT_REALLOC_MULT(ptr,oldcnt,newcnt,itmsz) \
|
||||
FT_MEM_SET_ERROR( FT_MEM_REALLOC_MULT(ptr,oldcnt,newcnt,itmsz) )
|
||||
|
||||
#define FT_QALLOC(ptr,size) \
|
||||
FT_MEM_SET_ERROR( FT_MEM_QALLOC(ptr,size) )
|
||||
|
||||
#define FT_QREALLOC(ptr,cursz,newsz) \
|
||||
FT_MEM_SET_ERROR( FT_MEM_QREALLOC(ptr,cursz,newsz) )
|
||||
|
||||
#define FT_QALLOC_MULT(ptr,count,item_size) \
|
||||
FT_MEM_SET_ERROR( FT_MEM_QALLOC_MULT(ptr,count,item_size) )
|
||||
|
||||
#define FT_QREALLOC_MULT(ptr,oldcnt,newcnt,itmsz) \
|
||||
FT_MEM_SET_ERROR( FT_MEM_QREALLOC_MULT(ptr,oldcnt,newcnt,itmsz) )
|
||||
|
||||
#define FT_FREE(ptr) FT_MEM_FREE( ptr )
|
||||
|
||||
#define FT_NEW(ptr) \
|
||||
|
@ -165,7 +165,7 @@
|
||||
|
||||
new_pitch = ( bitmap->width + xpixels + ppb - 1 ) / ppb;
|
||||
|
||||
if ( FT_ALLOC( buffer, new_pitch * ( bitmap->rows + ypixels ) ) )
|
||||
if ( FT_QALLOC_MULT( buffer, new_pitch, bitmap->rows + ypixels ) )
|
||||
return error;
|
||||
|
||||
if ( bitmap->pitch > 0 )
|
||||
|
@ -808,6 +808,7 @@
|
||||
short res_id;
|
||||
unsigned char *buffer, *p, *size_p = NULL;
|
||||
FT_ULong total_size = 0;
|
||||
FT_ULong old_total_size = 0;
|
||||
FT_ULong post_size, pfb_chunk_size;
|
||||
Handle post_data;
|
||||
char code, last_code;
|
||||
@ -838,6 +839,15 @@
|
||||
|
||||
total_size += GetHandleSize( post_data ) - 2;
|
||||
last_code = code;
|
||||
|
||||
/* detect integer overflows */
|
||||
if ( total_size < old_total_size )
|
||||
{
|
||||
error = FT_Err_Array_Too_Large;
|
||||
goto Error;
|
||||
}
|
||||
|
||||
old_total_size = total_size;
|
||||
}
|
||||
|
||||
if ( FT_ALLOC( buffer, (FT_Long)total_size ) )
|
||||
|
@ -179,7 +179,7 @@
|
||||
if ( error )
|
||||
return error;
|
||||
|
||||
if ( FT_ALLOC( offsets_internal, *count * sizeof( FT_Long ) ) )
|
||||
if ( FT_NEW_ARRAY( offsets_internal, *count ) )
|
||||
return error;
|
||||
|
||||
for ( j = 0; j < *count; ++j )
|
||||
@ -426,20 +426,25 @@
|
||||
FT_Error error;
|
||||
char* newpath;
|
||||
FT_Memory memory;
|
||||
FT_Long base_file_len = ft_strlen( base_file_name );
|
||||
|
||||
FT_UNUSED( stream );
|
||||
|
||||
|
||||
memory = library->memory;
|
||||
|
||||
if ( FT_ALLOC( newpath,
|
||||
ft_strlen( base_file_name ) + ft_strlen( "/rsrc" ) + 1 ) )
|
||||
if ( base_file_len > FT_INT_MAX )
|
||||
return FT_Err_Array_Too_Large;
|
||||
|
||||
if ( FT_ALLOC( newpath, base_file_len + 6 ) )
|
||||
return error;
|
||||
|
||||
ft_strcpy( newpath, base_file_name );
|
||||
ft_strcat( newpath, "/rsrc" );
|
||||
FT_MEM_COPY( newpath, base_file_name, base_file_len );
|
||||
FT_MEM_COPY( newpath + base_file_len, "/rsrc", 6 );
|
||||
|
||||
*result_file_name = newpath;
|
||||
*result_offset = 0;
|
||||
*result_offset = 0;
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
|
@ -127,10 +127,8 @@
|
||||
* to write it literally.
|
||||
*
|
||||
*/
|
||||
if ( FT_REALLOC(
|
||||
state->prefix,
|
||||
old_size * (sizeof ( FT_UShort ) + sizeof ( FT_Byte ) ),
|
||||
new_size * (sizeof ( FT_UShort ) + sizeof ( FT_Byte ) ) ) )
|
||||
if ( FT_REALLOC_MULT( state->prefix, old_size, new_size,
|
||||
sizeof(FT_UShort)+sizeof(FT_Byte) ) )
|
||||
return -1;
|
||||
|
||||
/* now adjust `suffix' and move the data accordingly */
|
||||
|
@ -161,13 +161,13 @@
|
||||
if ( !( mode & FT_RENDER_MODE_MONO ) )
|
||||
{
|
||||
/* we pad to 32 bits, only for backwards compatibility with FT 1.x */
|
||||
pitch = FT_PAD_CEIL( width, 4 );
|
||||
pitch = FT_PAD_CEIL( width, 4 );
|
||||
bitmap->pixel_mode = FT_PIXEL_MODE_GRAY;
|
||||
bitmap->num_grays = 256;
|
||||
}
|
||||
else
|
||||
{
|
||||
pitch = ( ( width + 15 ) >> 4 ) << 1;
|
||||
pitch = ( ( width + 15 ) >> 4 ) << 1;
|
||||
bitmap->pixel_mode = FT_PIXEL_MODE_MONO;
|
||||
}
|
||||
|
||||
@ -175,7 +175,7 @@
|
||||
bitmap->rows = height;
|
||||
bitmap->pitch = pitch;
|
||||
|
||||
if ( FT_ALLOC( bitmap->buffer, (FT_ULong)pitch * height ) )
|
||||
if ( FT_ALLOC_MULT( bitmap->buffer, pitch, height ) )
|
||||
goto Exit;
|
||||
|
||||
slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
|
||||
|
@ -292,7 +292,7 @@
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if ( FT_ALLOC( offset_table, num_glyphs ) ||
|
||||
if ( FT_NEW_ARRAY( offset_table, num_glyphs ) ||
|
||||
FT_STREAM_READ( offset_table, num_glyphs ) )
|
||||
goto Fail;
|
||||
|
||||
|
@ -684,15 +684,17 @@
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if ( FT_ALLOC( face->blend, sizeof ( GX_BlendRec ) ) )
|
||||
if ( FT_NEW( face->blend ) )
|
||||
goto Exit;
|
||||
|
||||
/* XXX: TODO - check for overflows */
|
||||
face->blend->mmvar_len =
|
||||
sizeof ( FT_MM_Var ) +
|
||||
fvar_head.axisCount * sizeof ( FT_Var_Axis ) +
|
||||
fvar_head.instanceCount * sizeof ( FT_Var_Named_Style ) +
|
||||
fvar_head.instanceCount * fvar_head.axisCount * sizeof ( FT_Fixed ) +
|
||||
5 * fvar_head.axisCount;
|
||||
|
||||
if ( FT_ALLOC( mmvar, face->blend->mmvar_len ) )
|
||||
goto Exit;
|
||||
face->blend->mmvar = mmvar;
|
||||
@ -1253,7 +1255,7 @@
|
||||
for ( j = 0; j < point_count; ++j )
|
||||
{
|
||||
int pindex = localpoints[j];
|
||||
|
||||
|
||||
face->cvt[pindex] = (FT_Short)( face->cvt[pindex] +
|
||||
FT_MulFix( deltas[j], apply ) );
|
||||
}
|
||||
|
@ -623,6 +623,7 @@
|
||||
status = OTHER_TABLES;
|
||||
face->ttf_size = ttf_size;
|
||||
|
||||
/* there are no more than 256 tables, so no size check here */
|
||||
if ( FT_REALLOC( face->ttf_data, 12 + 16 * num_tables,
|
||||
ttf_size + 1 ) )
|
||||
goto Fail;
|
||||
@ -1071,7 +1072,7 @@
|
||||
if ( !name )
|
||||
continue;
|
||||
|
||||
if ( cur[0] == name[0] &&
|
||||
if ( cur[0] == name[0] &&
|
||||
len == (FT_PtrDist)ft_strlen( (const char *)name ) &&
|
||||
ft_memcmp( cur, name, len ) == 0 )
|
||||
{
|
||||
|
@ -531,7 +531,7 @@
|
||||
|
||||
/* reserve one slot for the .notdef glyph at index 0 */
|
||||
root->num_glyphs = font->header.last_char -
|
||||
font->header.first_char + 1 + 1;
|
||||
font->header.first_char + 1 + 1;
|
||||
|
||||
/* Some broken fonts don't delimit the face name with a final */
|
||||
/* NULL byte -- the frame is erroneously one byte too small. */
|
||||
@ -540,14 +540,18 @@
|
||||
family_size = font->header.file_size - font->header.face_name_offset;
|
||||
if ( FT_ALLOC( font->family_name, family_size + 1 ) )
|
||||
goto Fail;
|
||||
|
||||
FT_MEM_COPY( font->family_name,
|
||||
font->fnt_frame + font->header.face_name_offset,
|
||||
family_size );
|
||||
|
||||
font->family_name[family_size] = '\0';
|
||||
|
||||
if ( FT_REALLOC( font->family_name,
|
||||
family_size,
|
||||
ft_strlen( font->family_name ) + 1 ) )
|
||||
goto Fail;
|
||||
|
||||
root->family_name = font->family_name;
|
||||
root->style_name = (char *)"Regular";
|
||||
|
||||
@ -693,7 +697,7 @@
|
||||
|
||||
/* note: since glyphs are stored in columns and not in rows we */
|
||||
/* can't use ft_glyphslot_set_bitmap */
|
||||
if ( FT_ALLOC( bitmap->buffer, pitch * bitmap->rows ) )
|
||||
if ( FT_ALLOC_MULT( bitmap->buffer, pitch, bitmap->rows ) )
|
||||
goto Exit;
|
||||
|
||||
column = (FT_Byte*)bitmap->buffer;
|
||||
|
Loading…
Reference in New Issue
Block a user