From 5ab41363172ca48071f7f04f0643683ccab739c3 Mon Sep 17 00:00:00 2001 From: David Turner Date: Sun, 18 Jul 2004 07:15:18 +0000 Subject: [PATCH] * include/freetype/cache/ftcglyph.h, src/cache/ftcglyph.c: fixed a dangling pointer bug that happened in very rare cases: i.e. when a new family object was destroyed by an out-of-memory condition during a glyph node initialization. The function FTC_Cache_Lookup would flush the cache and restart the lookup with a bad pointer. * src/cache/ftcmanag.c: fixed a cache flushing bug --- ChangeLog | 11 +++++++++++ include/freetype/cache/ftcglyph.h | 15 +++++++++++++++ include/freetype/config/ftoption.h | 2 +- src/cache/ftcglyph.c | 15 +++++++++++++-- src/cache/ftcmanag.c | 2 +- src/truetype/ttinterp.c | 6 +++--- 6 files changed, 44 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 627c51af6..f8ad3dcc0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2004-07-17 David Turner + + * include/freetype/cache/ftcglyph.h, src/cache/ftcglyph.c: + fixed a dangling pointer bug that happened in very rare cases: + i.e. when a new family object was destroyed by an out-of-memory + condition during a glyph node initialization. The function + FTC_Cache_Lookup would flush the cache and restart the lookup + with a bad pointer. + + * src/cache/ftcmanag.c: fixed a cache flushing bug + 2004-07-15 Werner Lemberg * docs/CHANGES: Updated. diff --git a/include/freetype/cache/ftcglyph.h b/include/freetype/cache/ftcglyph.h index be237f934..639ab94b6 100644 --- a/include/freetype/cache/ftcglyph.h +++ b/include/freetype/cache/ftcglyph.h @@ -255,6 +255,12 @@ FT_BEGIN_HEADER FTC_Node *anode ); + /* */ +#define FTC_FAMILY_FREE(family,cache) \ + FTC_MruList_Remove( &FTC_GCACHE((cache))->families, \ + (FTC_MruNode)(family) ) + + #ifdef FTC_INLINE #define FTC_GCACHE_LOOKUP_CMP( cache, famcmp, nodecmp, hash, \ @@ -270,7 +276,16 @@ FT_BEGIN_HEADER FTC_MRULIST_LOOKUP_CMP( &_gcache->families, _gquery, _fcompare, \ _gquery->family, error ); \ if ( !error ) \ + { \ + FTC_Family _gqfamily = _gquery->family; \ + \ + _gqfamily->num_nodes++; \ + \ FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error ); \ + \ + if ( --_gqfamily->num_nodes == 0 ) \ + FTC_FAMILY_FREE( _gqfamily, _gcache ); \ + } \ FT_END_STMNT /* */ diff --git a/include/freetype/config/ftoption.h b/include/freetype/config/ftoption.h index 028c6ea9c..b3a660bbf 100644 --- a/include/freetype/config/ftoption.h +++ b/include/freetype/config/ftoption.h @@ -436,7 +436,7 @@ FT_BEGIN_HEADER /* Do not #undef this macro here, since the build system might */ /* define it for certain configurations only. */ /* */ -/* #define TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ +#define TT_CONFIG_OPTION_BYTECODE_INTERPRETER /*************************************************************************/ diff --git a/src/cache/ftcglyph.c b/src/cache/ftcglyph.c index 1f3158e79..c5c9e700f 100644 --- a/src/cache/ftcglyph.c +++ b/src/cache/ftcglyph.c @@ -27,6 +27,7 @@ #include "ftcerror.h" + /* create a new chunk node, setting its cache index and ref count */ FT_EXPORT_DEF( void ) FTC_GNode_Init( FTC_GNode gnode, @@ -48,8 +49,7 @@ gnode->family = NULL; if ( family && --family->num_nodes <= 0 ) - FTC_MruList_Remove( &FTC_GCACHE( cache )->families, - (FTC_MruNode)family ); + FTC_FAMILY_FREE( family, cache ); } @@ -180,8 +180,19 @@ FTC_MRULIST_LOOKUP( &cache->families, query, query->family, error ); if ( !error ) + { + FTC_Family family = query->family; + + /* prevent the family from being destroyed too early when an out-of-memory + * condition occurs during glyph node initialization. + */ + family->num_nodes++; + error = FTC_Cache_Lookup( FTC_CACHE( cache ), hash, query, anode ); + if ( --family->num_nodes <= 0 ) + FTC_FAMILY_FREE( family, cache ); + } return error; } diff --git a/src/cache/ftcmanag.c b/src/cache/ftcmanag.c index 97d324c61..3935f7234 100644 --- a/src/cache/ftcmanag.c +++ b/src/cache/ftcmanag.c @@ -639,7 +639,7 @@ result++; } - if ( prev == manager->nodes_list ) + if ( node == first ) break; node = prev; diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c index 889ebbf4f..7446cdcc3 100644 --- a/src/truetype/ttinterp.c +++ b/src/truetype/ttinterp.c @@ -2474,7 +2474,7 @@ W = Vx * Vx + Vy * Vy; /* Now, we want that Sqrt( W ) = 0x4000 */ - /* Or 0x1000000 <= W < 0x1004000 */ + /* Or 0x10000000 <= W < 0x10004000 */ if ( Vx < 0 ) { @@ -2492,7 +2492,7 @@ else S2 = FALSE; - while ( W < 0x1000000L ) + while ( W < 0x10000000L ) { /* We need to increase W by a minimal amount */ if ( Vx < Vy ) @@ -2503,7 +2503,7 @@ W = Vx * Vx + Vy * Vy; } - while ( W >= 0x1004000L ) + while ( W >= 0x10004000L ) { /* We need to decrease W by a minimal amount */ if ( Vx < Vy )