[cache] Fix Savannah bug #31923, patch drafted by Harsha.

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
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
nodes. This change depends previous change:
38b272ffbb

* src/cache/ftccache.h (FTC_CACHE_LOOKUP_CMP): Rescan the
top node if the cached nodes are changed.
* src/cache/ftccache.c (FTC_Cache_Lookup): Ditto.
This commit is contained in:
suzuki toshiya 2011-01-09 23:09:36 +09:00
parent 38b272ffbb
commit 5e7ad208e3
3 changed files with 64 additions and 0 deletions

View File

@ -1,3 +1,20 @@
2010-01-09 suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp>
[cache] Fix Savannah bug #31923, patch drafted by Harsha.
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
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
nodes. This change depends previous change:
38b272ffbbdaae276d636aec4ef84af407d16181
* src/cache/ftccache.h (FTC_CACHE_LOOKUP_CMP): Rescan the
top node if the cached nodes are changed.
* src/cache/ftccache.c (FTC_Cache_Lookup): Ditto.
2010-01-09 suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp>
[cache] Notice if a cache query induced the node list change.

23
src/cache/ftccache.c vendored
View File

@ -498,7 +498,11 @@
if ( cache == NULL || anode == NULL )
return FTC_Err_Invalid_Argument;
/* 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. */
/* NOTE: _nodcomp() may change the linked list to reduce memory. */
for (;;)
{
node = *pnode;
@ -512,6 +516,25 @@
pnode = &node->link;
}
if ( list_changed )
{
/* Update bucket by modified linked list */
bucket = pnode = FTC_NODE__TOP_FOR_HASH( cache, hash );
/* Update pnode by modified linked list */
while ( *pnode != node )
{
if ( *pnode == NULL )
{
FT_ERROR(("oops!!! node missing"));
goto NewNode;
}
else
pnode = &((*pnode)->link);
}
}
/* Reorder the list to move the found node to the `top' */
if ( node != *bucket )
{
*pnode = node->link;

24
src/cache/ftccache.h vendored
View File

@ -224,8 +224,12 @@ FT_BEGIN_HEADER
\
error = FTC_Err_Ok; \
node = NULL; \
\
/* 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. */ \
/* NOTE: _nodcomp() may change the linked list to reduce memory. */ \
for (;;) \
{ \
_node = *_pnode; \
@ -239,6 +243,25 @@ FT_BEGIN_HEADER
_pnode = &_node->link; \
} \
\
if ( _list_changed ) \
{ \
/* Update _bucket by possibly modified linked list */ \
_bucket = _pnode = FTC_NODE__TOP_FOR_HASH( _cache, _hash ); \
\
/* Update _pnode by possibly modified linked list */ \
while ( *_pnode != _node ) \
{ \
if ( *_pnode == NULL ) \
{ \
FT_ERROR(("oops!!! node missing")); \
goto _NewNode; \
} \
else \
_pnode = &((*_pnode)->link); \
} \
} \
\
/* Reorder the list to move the found node to the `top' */ \
if ( _node != *_bucket ) \
{ \
*_pnode = _node->link; \
@ -246,6 +269,7 @@ FT_BEGIN_HEADER
*_bucket = _node; \
} \
\
/* Update MRU list */ \
{ \
FTC_Manager _manager = _cache->manager; \
void* _nl = &_manager->nodes_list; \