Commit 5ab41363172ca48071f7f04f0643683ccab739c3

David Turner 2004-07-18T07:15:18

* 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

diff --git a/ChangeLog b/ChangeLog
index 627c51a..f8ad3dc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2004-07-17  David Turner  <david@freetype.org>
+
+        * 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  <wl@gnu.org>
 
 	* docs/CHANGES: Updated.
diff --git a/include/freetype/cache/ftcglyph.h b/include/freetype/cache/ftcglyph.h
index be237f9..639ab94 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 028c6ea..b3a660b 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 1f3158e..c5c9e70 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 97d324c..3935f72 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 889ebbf..7446cdc 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 )