diff --git a/ChangeLog b/ChangeLog index 56bbf9a39..79869402a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,7 +4,7 @@ When a node comparator changes the cached nodes during the search of a node matching with queried properties, the - pointers obtained before the functon should be updated to + pointers obtained before the function should be updated to prevent the dereference to freed or reallocated nodes. To minimize the rescan of the linked list, the update is executed when the comparator notifies the change of cached @@ -19,54 +19,56 @@ [cache] Notice if a cache query induced the node list change. - Some node comparators (comparing the cache node content and - the properties specified by the query) can flush the cache - node to prevent the cache inflation. The change may - invalidate the pointers to the node obtained before the node - comparison, so the change should be noticed to the caller. - The problem caused by the cache node changing is reported by - Harsha, see Savannah bug #31923. + Some node comparators (comparing the cache node contents and the + properties specified by the query) can flush the cache node to + prevent the cache inflation. The change may invalidate the pointers + to the node obtained before the node comparison, so it should be + noticed to the caller. The problem caused by the cache node + changing is reported by Harsha, see Savannah bug #31923. - * src/cache/ftccache.h (FTC_Node_CompareFunc): Add new - argument `FT_Bool* list_changed' to indicate the change of - the cached nodes to the caller. - (FTC_CACHE_LOOKUP_CMP): Watch the change of the cached nodes - by `_list_changed'. + * src/cache/ftccache.h (FTC_Node_CompareFunc): Add new argument + `FT_Bool* list_changed' to indicate the change of the cached nodes + to the caller. + (FTC_CACHE_LOOKUP_CMP): Watch the change of the cached nodes by + `_list_changed'. (FTC_CACHE_TRYLOOP_END): Take new macro argument `_list_changed' - and update it when FTC_Manager_FlushN() flushes any nodes. + and update it when `FTC_Manager_FlushN' flushes any nodes. - * src/cache/ftccback.h (ftc_snode_compare): Updated to fit - with new FTC_Node_CompareFunc type. (ftc_gnode_compare): Ditto. + * src/cache/ftccback.h (ftc_snode_compare): Updated to fit with new + FTC_Node_CompareFunc type. + (ftc_gnode_compare): Ditto. - * src/cache/ftcbasic.c: Include FT_INTERNAL_OBJECTS_H to - use TRUE/FALSE macros. (ftc_basic_gnode_compare_faceid): - New argument `FT_Bool* list_changed' to indicate the change - of the cache nodes, anyway, it is always FALSE. + * src/cache/ftcbasic.c: Include FT_INTERNAL_OBJECTS_H to use + TRUE/FALSE macros. + (ftc_basic_gnode_compare_faceid): New argument `FT_Bool* + list_changed' to indicate the change of the cache nodes (anyway, it + is always FALSE). - * src/cache/ftccmap.c: Include FT_INTERNAL_OBJECTS_H to - use TRUE/FALSE macros. (ftc_cmap_node_compare): - New argument `FT_Bool* list_changed' to indicate the change - of the cache nodes, anyway, it is always FALSE. + * src/cache/ftccmap.c: Include FT_INTERNAL_OBJECTS_H to use + TRUE/FALSE macros. + (ftc_cmap_node_compare): New argument `FT_Bool* list_changed' to + indicate the change of the cache nodes (anyway, it is always FALSE). (ftc_cmap_node_remove_faceid): Ditto. - * src/cache/ftccache.c (FTC_Cache_NewNode): Pass a NULL - pointer to FTC_CACHE_TRYLOOP_END(), because the result is - not needed. (FTC_Cache_Lookup): Watch the change of the cache - nodes by `list_changed'. (FTC_Cache_RemoveFaceID): Ditto. + * src/cache/ftccache.c (FTC_Cache_NewNode): Pass a NULL pointer to + `FTC_CACHE_TRYLOOP_END', because the result is not needed. + (FTC_Cache_Lookup): Watch the change of the cache nodes by + `list_changed'. + (FTC_Cache_RemoveFaceID): Ditto. - * src/cache/ftcglyph.c: Include FT_INTERNAL_OBJECTS_H to - use TRUE/FALSE macros. (ftc_gnode_compare): New argument - `FT_Bool* list_changed' to indicate the change of the cache - nodes, anyway, it is always FALSE. (FTC_GNode_Compare): - New argument `FT_Bool* list_changed' to be passed to - ftc_gnode_compare(). + * src/cache/ftcglyph.c: Include FT_INTERNAL_OBJECTS_H to use + TRUE/FALSE macros. + (ftc_gnode_compare): New argument `FT_Bool* list_changed' to + indicate the change of the cache nodes (anyway, it is always FALSE). + (FTC_GNode_Compare): New argument `FT_Bool* list_changed' to be + passed to `ftc_gnode_compare'. * src/cache/ftcglyph.h (FTC_GNode_Compare): Ditto. - * src/cache/ftcsbits.c (ftc_snode_compare): New argument - `FT_Bool* list_changed' to indicate the change of the cache - nodes, anyway. It is updated by FTC_CACHE_TRYLOOP(). - (FTC_SNode_Compare): New argument `FT_Bool* list_changed' - to be passed to ftc_snode_compare(). + * src/cache/ftcsbits.c (ftc_snode_compare): New argument `FT_Bool* + list_changed' to indicate the change of the cache nodes, anyway. It + is updated by `FTC_CACHE_TRYLOOP'. + (FTC_SNode_Compare): New argument `FT_Bool* list_changed' to be + passed to `ftc_snode_compare'. * src/cache/ftcsbits.h (FTC_SNode_Compare): Ditto. 2011-01-09 suzuki toshiya @@ -83,7 +85,7 @@ [cache] Deduplicate the code to get the top node by a hash. - There are several duplicated codes getting the top node + There are several duplicated code fragments getting the top node from a cache by a given hash, like: idx = hash & cache->mask; @@ -91,17 +93,16 @@ idx = hash & ( cache->mask * 2 + 1 ); pnode = cache->buckets + idx; - To deduplicate them, a cpp-macro to do same work - FTC_NODE__TOP_FOR_HASH( cache, hash ) is introduced. - For non-inlined config, non-ftc_get_top_node_for_hash() is - also introduced. + To remove duplication, a cpp-macro to do same work + `FTC_NODE__TOP_FOR_HASH' is introduced. For non-inlined + configuration, non-ftc_get_top_node_for_hash() is also introduced. * src/cache/ftccache.h (FTC_NODE__TOP_FOR_HASH): Declare and implement inlined version. - (FTC_CACHE_LOOKUP_CMP): Use FTC_NODE__TOP_FOR_HASH(). - * src/cache/ftccache.c (ftc_get_top_node_for_hash): Non- - inlined version. - (ftc_node_hash_unlink): Use FTC_NODE__TOP_FOR_HASH(). + (FTC_CACHE_LOOKUP_CMP): Use `FTC_NODE__TOP_FOR_HASH'. + * src/cache/ftccache.c (ftc_get_top_node_for_hash): Non-inlined + version. + (ftc_node_hash_unlink): Use `FTC_NODE__TOP_FOR_HASH'. (ftc_node_hash_link): Ditto. (FTC_Cache_Lookup): Ditto. @@ -109,25 +110,25 @@ [cache] inline-specific functions are conditionalized. - * src/cache/ftcglyph.c (FTC_GNode_Compare): Conditionalized - for inlined config. This function is a thin wrapper of - ftc_gnode_compare() for inlined FTC_CACHE_LOOKUP_CMP() - (see `nodecmp' argument). Under non-inlined config, - ftc_gnode_compare() is invoked by FTC_Cache_Lookup(), - via FTC_Cache->clazz.node_compare(). + * src/cache/ftcglyph.c (FTC_GNode_Compare): Conditionalized for + inlined configuration. This function is a thin wrapper of + `ftc_gnode_compare' for inlined `FTC_CACHE_LOOKUP_CMP' (see + `nodecmp' argument). Under non-inlined configuration, + `ftc_gnode_compare' is invoked by `FTC_Cache_Lookup', via + `FTC_Cache->clazz.node_compare'. * src/cache/ftcglyph.h (FTC_GNode_Compare): Ditto. - * src/cache/ftcsbits.c (FTC_SNode_Compare): Ditto, - for ftc_snode_compare(). + * src/cache/ftcsbits.c (FTC_SNode_Compare): Ditto, for + `ftc_snode_compare'. * src/cache/ftcsbits.h (FTC_SNode_Compare): Ditto. 2011-01-09 suzuki toshiya [cache] Correct a type mismatch under non-inlined config. - * src/cache/ftcglyph.h (FTC_GCACHE_LOOKUP_CMP): - FTC_GCache_Lookup() takes the node via a pointer `FTC_Node*', - differently from cpp-macro FTC_CACHE_LOOKUP_CMP(). + * src/cache/ftcglyph.h (FTC_GCACHE_LOOKUP_CMP): `FTC_GCache_Lookup' + takes the node via a pointer `FTC_Node*', differently from cpp-macro + `FTC_CACHE_LOOKUP_CMP'. 2011-01-06 suzuki toshiya @@ -433,7 +434,7 @@ On LLP64 platforms (e.g. Win64), FT_ULong (32-bit) variables are inappropriate to calculate hash values - from the memory address (64-bit). The hash variables + from the memory address (64-bit). The hash variables are extended from FT_ULong to FT_PtrDist and new hashing macro functions are introduced. The hash values on 16-bit memory platforms are changed, but @@ -443,7 +444,7 @@ * src/cache/ftccache.h (_FTC_FACE_ID_HASH): New hash function to replace FTC_FACE_ID_HASH() for portability. - * src/cache/ftcmanag.h (FTC_SCALER_HASH): Replace + * src/cache/ftcmanag.h (FTC_SCALER_HASH): Replace FTC_FACE_ID_HASH() by _FTC_FACE_ID_HASH(). * src/cache/ftccmap.c (FTC_CMAP_HASH): Ditto. @@ -467,7 +468,7 @@ * src/cache/ftccache.h (FTC_CACHE_LOOKUP_CMP): Ditto. Also the type of the internal variable `_idx' is changed to FT_PtrDist from FT_UFast for better pointer calculation. - + 2010-10-24 suzuki toshiya [cache] Hide internal macros incompatible with LLP64. @@ -530,7 +531,7 @@ * src/base/ftobjs.c (load_face_in_embedded_rfork): When FT_Stream_New() returns FT_Err_Cannot_Open_Stream, it means that the file is possible to be fopen()-ed but zero-sized. - Also there is a case that the resource fork is not zero-sized, + Also there is a case that the resource fork is not zero-sized, but no supported font exists in it. If a rule by Darwin VFS falls into such cases, there is no need to try other Darwin VFS rules anymore. Such cases are marked by vfs_rfork_has_no_font. @@ -544,7 +545,7 @@ a resource fork via ANSI C or POSIX interface. Current resource fork accessor tries all possible methods to support all kernels. But if a method could open a resource fork but no font is found, - there is no need to try other methods older than tested method. + there is no need to try other methods older than tested method. To determine whether the rule index is for Darwin VFS, a local function ftrfork.c::raccess_rule_by_darwin_vfs() is introduced. To use this function in ftobjs.c etc but it should be inlined, diff --git a/src/cache/ftcbasic.c b/src/cache/ftcbasic.c index 48cfab0fe..09d793ecf 100644 --- a/src/cache/ftcbasic.c +++ b/src/cache/ftcbasic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType basic cache interface (body). */ /* */ -/* Copyright 2003, 2004, 2005, 2006, 2007, 2009, 2010 by */ +/* Copyright 2003, 2004, 2005, 2006, 2007, 2009, 2010, 2011 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/cache/ftccache.c b/src/cache/ftccache.c index ad1c5c307..865fbb71a 100644 --- a/src/cache/ftccache.c +++ b/src/cache/ftccache.c @@ -4,7 +4,8 @@ /* */ /* The FreeType internal cache interface (body). */ /* */ -/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010 by */ +/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010, */ +/* 2011 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -32,7 +33,7 @@ #define FTC_HASH_MIN_LOAD 1 #define FTC_HASH_SUB_LOAD ( FTC_HASH_MAX_LOAD - FTC_HASH_MIN_LOAD ) -/* this one _must_ be a power of 2! */ + /* this one _must_ be a power of 2! */ #define FTC_HASH_INITIAL_SIZE 8 @@ -115,9 +116,9 @@ for (;;) { FTC_Node node, *pnode; - FT_UFast p = cache->p; - FT_UFast mask = cache->mask; - FT_UFast count = mask + p + 1; /* number of buckets */ + FT_UFast p = cache->p; + FT_UFast mask = cache->mask; + FT_UFast count = mask + p + 1; /* number of buckets */ /* do we need to shrink the buckets array? */ @@ -136,7 +137,8 @@ /* if we can't expand the array, leave immediately */ - if ( FT_RENEW_ARRAY( cache->buckets, (mask+1)*2, (mask+1)*4 ) ) + if ( FT_RENEW_ARRAY( cache->buckets, + ( mask + 1 ) * 2, ( mask + 1 ) * 4 ) ) break; } @@ -210,7 +212,9 @@ cache->slack -= FTC_HASH_MAX_LOAD; cache->p = p; } - else /* the hash table is balanced */ + + /* otherwise, the hash table is balanced */ + else break; } } @@ -418,8 +422,8 @@ FT_PtrDist hash, FTC_Node node ) { - node->hash = hash; - node->cache_index = (FT_UInt16) cache->index; + node->hash = hash; + node->cache_index = (FT_UInt16)cache->index; node->ref_count = 0; ftc_node_hash_link( node, cache ); @@ -489,7 +493,7 @@ FTC_Node* bucket; FTC_Node* pnode; FTC_Node node; - FT_Error error = FTC_Err_Ok; + FT_Error error = FTC_Err_Ok; FT_Bool list_changed = FALSE; FTC_Node_CompareFunc compare = cache->clazz.node_compare; @@ -509,7 +513,7 @@ if ( node == NULL ) goto NewNode; - if ( node->hash == hash && + if ( node->hash == hash && compare( node, query, cache, &list_changed ) ) break; @@ -526,7 +530,7 @@ { if ( *pnode == NULL ) { - FT_ERROR(("oops!!! node missing")); + FT_ERROR(( "FTC_Cache_Lookup: oops!!! node missing\n" )); goto NewNode; } else @@ -551,6 +555,7 @@ ftc_node_mru_up( node, manager ); } *anode = node; + return error; NewNode: @@ -585,7 +590,8 @@ if ( node == NULL ) break; - if ( cache->clazz.node_remove_faceid( node, face_id, cache, &list_changed ) ) + if ( cache->clazz.node_remove_faceid( node, face_id, + cache, &list_changed ) ) { *pnode = node->link; node->link = frees; diff --git a/src/cache/ftccache.h b/src/cache/ftccache.h index d696621e7..d60984f77 100644 --- a/src/cache/ftccache.h +++ b/src/cache/ftccache.h @@ -4,7 +4,8 @@ /* */ /* FreeType internal cache interface (specification). */ /* */ -/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010 by */ +/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010, */ +/* 2011 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,7 +25,7 @@ FT_BEGIN_HEADER -#define _FTC_FACE_ID_HASH( i ) \ +#define _FTC_FACE_ID_HASH( i ) \ ((FT_PtrDist)(( (FT_PtrDist)(i) >> 3 ) ^ ( (FT_PtrDist)(i) << 7 ))) /* handle to cache object */ @@ -73,16 +74,16 @@ FT_BEGIN_HEADER #define FTC_NODE__PREV( x ) FTC_NODE( (x)->mru.prev ) #ifdef FTC_INLINE -#define FTC_NODE__TOP_FOR_HASH( cache, hash ) \ - ( ( cache )->buckets + \ - ( ( ( ( hash ) & ( cache )->mask ) < ( cache )->p ) ? \ - ( ( hash ) & ( ( cache )->mask * 2 + 1 ) ) : \ - ( ( hash ) & ( cache )->mask ) ) ) +#define FTC_NODE__TOP_FOR_HASH( cache, hash ) \ + ( ( cache )->buckets + \ + ( ( ( ( hash ) & ( cache )->mask ) < ( cache )->p ) \ + ? ( ( hash ) & ( ( cache )->mask * 2 + 1 ) ) \ + : ( ( hash ) & ( cache )->mask ) ) ) #else FT_LOCAL( FTC_Node* ) ftc_get_top_node_for_hash( FTC_Cache cache, FT_PtrDist hash ); -#define FTC_NODE__TOP_FOR_HASH( cache, hash ) \ +#define FTC_NODE__TOP_FOR_HASH( cache, hash ) \ ftc_get_top_node_for_hash( ( cache ), ( hash ) ) #endif @@ -176,7 +177,7 @@ FT_BEGIN_HEADER FT_LOCAL( void ) FTC_Cache_Done( FTC_Cache cache ); - /* Call this function to lookup the cache. If no corresponding + /* Call this function to look up the cache. If no corresponding * node is found, a new one is automatically created. This function * is capable of flushing the cache adequately to make room for the * new cache object. @@ -198,7 +199,7 @@ FT_BEGIN_HEADER /* Remove all nodes that relate to a given face_id. This is useful * when un-installing fonts. Note that if a cache node relates to - * the face_id, but is locked (i.e., has `ref_count > 0'), the node + * the face_id but is locked (i.e., has `ref_count > 0'), the node * will _not_ be destroyed, but its internal face_id reference will * be modified. * @@ -228,7 +229,7 @@ FT_BEGIN_HEADER /* Go to the `top' node of the list sharing same masked hash */ \ _bucket = _pnode = FTC_NODE__TOP_FOR_HASH( _cache, _hash ); \ \ - /* Lookup a node with exactly same hash and queried properties. */ \ + /* Look up a node with identical hash and queried properties. */ \ /* NOTE: _nodcomp() may change the linked list to reduce memory. */ \ for (;;) \ { \ @@ -253,7 +254,7 @@ FT_BEGIN_HEADER { \ if ( *_pnode == NULL ) \ { \ - FT_ERROR(("oops!!! node missing")); \ + FT_ERROR(( "FTC_CACHE_LOOKUP_CMP: oops!!! node missing\n" )); \ goto _NewNode; \ } \ else \ @@ -304,7 +305,7 @@ FT_BEGIN_HEADER * loop to flush the cache repeatedly in case of memory overflows. * * It is used when creating a new cache node, or within a lookup - * that needs to allocate data (e.g., the sbit cache lookup). + * that needs to allocate data (e.g. the sbit cache lookup). * * Example: * diff --git a/src/cache/ftccback.h b/src/cache/ftccback.h index 4f5a32629..80ec9ce44 100644 --- a/src/cache/ftccback.h +++ b/src/cache/ftccback.h @@ -4,7 +4,7 @@ /* */ /* Callback functions of the caching sub-system (specification only). */ /* */ -/* Copyright 2004, 2005, 2006 by */ +/* Copyright 2004, 2005, 2006, 2011 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/cache/ftccmap.c b/src/cache/ftccmap.c index b0e85d1a9..b7bd2919d 100644 --- a/src/cache/ftccmap.c +++ b/src/cache/ftccmap.c @@ -5,7 +5,7 @@ /* FreeType CharMap cache (body) */ /* */ /* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, */ -/* 2010 by */ +/* 2010, 2011 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -224,6 +224,7 @@ FTC_FaceID face_id = (FTC_FaceID)ftcface_id; FT_UNUSED( cache ); + if ( list_changed ) *list_changed = FALSE; return FT_BOOL( node->face_id == face_id ); diff --git a/src/cache/ftcglyph.c b/src/cache/ftcglyph.c index ff041e89e..441e17723 100644 --- a/src/cache/ftcglyph.c +++ b/src/cache/ftcglyph.c @@ -4,7 +4,7 @@ /* */ /* FreeType Glyph Image (FT_Glyph) cache (body). */ /* */ -/* Copyright 2000-2001, 2003, 2004, 2006, 2009 by */ +/* Copyright 2000-2001, 2003, 2004, 2006, 2009, 2011 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -88,7 +88,8 @@ FTC_Cache cache, FT_Bool* list_changed ) { - return ftc_gnode_compare( FTC_NODE( gnode ), gquery, cache, list_changed ); + return ftc_gnode_compare( FTC_NODE( gnode ), gquery, + cache, list_changed ); } #endif diff --git a/src/cache/ftcglyph.h b/src/cache/ftcglyph.h index d15ca3cd8..5fed19cb8 100644 --- a/src/cache/ftcglyph.h +++ b/src/cache/ftcglyph.h @@ -4,7 +4,7 @@ /* */ /* FreeType abstract glyph cache (specification). */ /* */ -/* Copyright 2000-2001, 2003, 2004, 2006, 2007 by */ +/* Copyright 2000-2001, 2003, 2004, 2006, 2007, 2011 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/cache/ftcmanag.h b/src/cache/ftcmanag.h index 13f26bb10..d6c85162a 100644 --- a/src/cache/ftcmanag.h +++ b/src/cache/ftcmanag.h @@ -4,7 +4,7 @@ /* */ /* FreeType Cache Manager (specification). */ /* */ -/* Copyright 2000-2001, 2003, 2004, 2006 by */ +/* Copyright 2000-2001, 2003, 2004, 2006, 2010 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/cache/ftcsbits.c b/src/cache/ftcsbits.c index d4db99416..8bf8d607e 100644 --- a/src/cache/ftcsbits.c +++ b/src/cache/ftcsbits.c @@ -4,7 +4,7 @@ /* */ /* FreeType sbits manager (body). */ /* */ -/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2009, 2010 by */ +/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2009, 2010, 2011 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -412,7 +412,8 @@ FTC_Cache cache, FT_Bool* list_changed ) { - return ftc_snode_compare( FTC_NODE( snode ), gquery, cache, list_changed ); + return ftc_snode_compare( FTC_NODE( snode ), gquery, + cache, list_changed ); } #endif diff --git a/src/cache/ftcsbits.h b/src/cache/ftcsbits.h index 5548149f9..df55dca80 100644 --- a/src/cache/ftcsbits.h +++ b/src/cache/ftcsbits.h @@ -4,7 +4,7 @@ /* */ /* A small-bitmap cache (specification). */ /* */ -/* Copyright 2000-2001, 2002, 2003, 2006 by */ +/* Copyright 2000-2001, 2002, 2003, 2006, 2011 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */