diff --git a/ChangeLog b/ChangeLog index abf7c3858..a6dc57626 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2006-02-27 David Turner + + * src/base/ftutil.c: ft_mem_alloc and related functions now return an + error if a negative size is passed in parameters. + + * src/cache/ftccache.c: make ftc_node_destroy FT_BASE_DEF, it needs to + be exported for rogue clients + + * src/pshinter/pshglob.c: prevent problems with malformed fonts which + have an odd number of blue values (these are broken according to the + specs). + + * src/cff/cffload.c, src/type1/t1load.c: modify the loaders to force + even-ness of 'num_blue_values'. Also change the CFF loader so that + invalid entries in index files are ignored. + 2006-02-27 Chia-I Wu * src/base/ftobjs.c (FT_Set_Char_Size): Ahh.. forgot to check the case diff --git a/src/base/ftutil.c b/src/base/ftutil.c index 31d3a1c65..ddddd349b 100644 --- a/src/base/ftutil.c +++ b/src/base/ftutil.c @@ -66,6 +66,11 @@ else FT_MEM_ZERO( block, size ); } + else if ( size < 0 ) + { + /* may help catch/prevent nasty security issues */ + error = FT_Err_Invalid_Argument; + } *p_error = error; return block; @@ -87,6 +92,11 @@ if ( block == NULL ) error = FT_Err_Out_Of_Memory; } + else + { + /* may help catch/prevent security issues */ + error = FT_Err_Invalid_Argument; + } *p_error = error; return block; @@ -103,12 +113,16 @@ FT_Error error = FT_Err_Ok; - if ( size <= 0 ) + if ( size < 0 || current < 0 ) + { + error = FT_Err_Invalid_Argument; + } + else if ( size == 0 ) { ft_mem_free( memory, block ); block = NULL; } - else if ( current <= 0 ) + else if ( current == 0 ) { FT_ASSERT( block == NULL ); @@ -145,12 +159,16 @@ FT_Error error = FT_Err_Ok; - if ( size <= 0 ) + if ( size < 0 || current < 0 ) + { + error = FT_Err_Invalid_Argument; + } + else if ( size == 0 ) { ft_mem_free( memory, block ); block = NULL; } - else if ( current <= 0 ) + else if ( current == 0 ) { FT_ASSERT( block == NULL ); @@ -190,7 +208,9 @@ ft_mem_alloc( FT_Memory memory, FT_Long size, void* *P ) - { + { + FT_Error error = FT_Err_Ok; + FT_ASSERT( P != 0 ); if ( size > 0 ) @@ -207,13 +227,17 @@ FT_MEM_ZERO( *P, size ); } else + { *P = NULL; + if ( size < 0 ) + error = FT_Err_Invalid_Argument; + } FT_TRACE7(( "ft_mem_alloc:" )); FT_TRACE7(( " size = %ld, block = 0x%08p, ref = 0x%08p\n", size, *P, P )); - return FT_Err_Ok; + return error; } @@ -224,6 +248,8 @@ FT_Long size, void* *P ) { + FT_Error error = FT_Err_Ok; + FT_ASSERT( P != 0 ); if ( size > 0 ) @@ -239,13 +265,17 @@ } } else + { *P = NULL; + if ( size < 0 ) + error = FT_Err_Invalid_Argument; + } FT_TRACE7(( "ft_mem_qalloc:" )); FT_TRACE7(( " size = %ld, block = 0x%08p, ref = 0x%08p\n", size, *P, P )); - return FT_Err_Ok; + return error; } @@ -267,12 +297,15 @@ return ft_mem_alloc( memory, size, P ); /* if the new block if zero-sized, clear the current one */ - if ( size <= 0 ) + if ( size == 0 ) { ft_mem_free( memory, P ); return FT_Err_Ok; } + if ( size < 0 || current < 0 ) + return FT_Err_Invalid_Argument; + Q = memory->realloc( memory, current, size, *P ); if ( !Q ) goto Fail; @@ -309,12 +342,15 @@ return ft_mem_qalloc( memory, size, P ); /* if the new block if zero-sized, clear the current one */ - if ( size <= 0 ) + if ( size == 0 ) { ft_mem_free( memory, P ); return FT_Err_Ok; } + if ( size < 0 || current < 0 ) + return FT_Err_Invalid_Argument; + Q = memory->realloc( memory, current, size, *P ); if ( !Q ) goto Fail; diff --git a/src/cache/ftccache.c b/src/cache/ftccache.c index 22ec06cb8..fd756fad1 100644 --- a/src/cache/ftccache.c +++ b/src/cache/ftccache.c @@ -256,7 +256,8 @@ /* remove a node from the cache manager */ - FT_LOCAL_DEF( void ) + /* this function is FT_BASE since it may be called by old rogue clients */ + FT_BASE_DEF( void ) ftc_node_destroy( FTC_Node node, FTC_Manager manager ) { diff --git a/src/cff/cffload.c b/src/cff/cffload.c index 6d73e985d..e576c3c86 100644 --- a/src/cff/cffload.c +++ b/src/cff/cffload.c @@ -1235,7 +1235,7 @@ } /* access element */ - if ( off1 ) + if ( off1 && off2 > off1 ) { *pbyte_len = off2 - off1; @@ -2011,7 +2011,7 @@ if ( error ) goto Exit; - + /* if it is a CID font, we stop there */ if ( top->cid_registry != 0xFFFFU ) goto Exit; @@ -2040,6 +2040,9 @@ FT_FRAME_EXIT(); if ( error ) goto Exit; + + /* ensure that 'num_blue_values' is even */ + priv->num_blue_values &= ~1; } /* read the local subrs, if any */ diff --git a/src/pshinter/pshglob.c b/src/pshinter/pshglob.c index 21d45e92f..c02dc0b07 100644 --- a/src/pshinter/pshglob.c +++ b/src/pshinter/pshglob.c @@ -150,7 +150,7 @@ FT_UNUSED( target ); - for ( ; read_count > 0; read_count -= 2 ) + for ( ; read_count > 1; read_count -= 2 ) { FT_Int reference, delta; FT_UInt count; diff --git a/src/type1/t1load.c b/src/type1/t1load.c index 75c0e9523..66c89a6a7 100644 --- a/src/type1/t1load.c +++ b/src/type1/t1load.c @@ -1989,6 +1989,9 @@ keyword_flags ); if ( error ) goto Exit; + + /* ensure even-ness of 'num_blue_values' */ + priv->num_blue_values &= ~1; #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT