* 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
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 )