diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2004-08-08 22:12:18 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2004-08-08 22:12:18 (GMT) |
commit | 6ae26dba82e56fd6e895ca116a51da070470ba5b (patch) | |
tree | e5a8e813a7a306ef13ff733b972b3cf49685af79 /src | |
parent | 51bdf6c34d5d36f9ab4b4b977865b356c75dc736 (diff) | |
download | hdf5-6ae26dba82e56fd6e895ca116a51da070470ba5b.zip hdf5-6ae26dba82e56fd6e895ca116a51da070470ba5b.tar.gz hdf5-6ae26dba82e56fd6e895ca116a51da070470ba5b.tar.bz2 |
[svn-r9053] Purpose:
Bug fix
Description:
Correct possible core dump when a datatype conversion function is
registered with the library after a compound datatype has been converted
(having it's type conversion information cached by the library). The compound
datatype must have been created by inserting the fields in non-increasing
offset order to see the bug.
Solution:
Re-sort the fields in the compound datatypes before recalculating the
cached information when performing the conversion on them.
Platforms tested:
FreeBSD 4.10 (sleipnir)
h5committested
Diffstat (limited to 'src')
-rw-r--r-- | src/H5T.c | 68 | ||||
-rw-r--r-- | src/H5Tconv.c | 6 |
2 files changed, 46 insertions, 28 deletions
@@ -2367,36 +2367,48 @@ H5T_unregister(H5T_pers_t pers, const char *name, H5T_t *src, H5T_t *dst, for (i=H5T_g.npaths-1; i>0; --i) { path = H5T_g.path[i]; assert(path); - if ((H5T_PERS_SOFT==pers && path->is_hard) || - (H5T_PERS_HARD==pers && !path->is_hard)) continue; - if (name && *name && HDstrcmp(name, path->name)) continue; - if (src && H5T_cmp(src, path->src)) continue; - if (dst && H5T_cmp(dst, path->dst)) continue; - if (func && func!=path->func) continue; - - /* Remove from table */ - HDmemmove(H5T_g.path+i, H5T_g.path+i+1, - (H5T_g.npaths-(i+1))*sizeof(H5T_path_t*)); - --H5T_g.npaths; - - /* Shut down path */ - H5T_print_stats(path, &nprint); - path->cdata.command = H5T_CONV_FREE; - if ((path->func)(FAIL, FAIL, &(path->cdata), 0, 0, 0, NULL, NULL, - dxpl_id)<0) { + + /* Not a match */ + if (((H5T_PERS_SOFT==pers && path->is_hard) || + (H5T_PERS_HARD==pers && !path->is_hard)) || + (name && *name && HDstrcmp(name, path->name)) || + (src && H5T_cmp(src, path->src)) || + (dst && H5T_cmp(dst, path->dst)) || + (func && func!=path->func)) { + /* + * Notify all other functions to recalculate private data since some + * functions might cache a list of conversion functions. For + * instance, the compound type converter caches a list of conversion + * functions for the members, so removing a function should cause + * the list to be recalculated to avoid the removed function. + */ + path->cdata.recalc = TRUE; + } /* end if */ + else { + /* Remove from table */ + HDmemmove(H5T_g.path+i, H5T_g.path+i+1, + (H5T_g.npaths-(i+1))*sizeof(H5T_path_t*)); + --H5T_g.npaths; + + /* Shut down path */ + H5T_print_stats(path, &nprint); + path->cdata.command = H5T_CONV_FREE; + if ((path->func)(FAIL, FAIL, &(path->cdata), 0, 0, 0, NULL, NULL, + dxpl_id)<0) { #ifdef H5T_DEBUG - if (H5DEBUG(T)) { - fprintf(H5DEBUG(T), "H5T: conversion function 0x%08lx failed " - "to free private data for %s (ignored)\n", - (unsigned long)(path->func), path->name); - } + if (H5DEBUG(T)) { + fprintf(H5DEBUG(T), "H5T: conversion function 0x%08lx failed " + "to free private data for %s (ignored)\n", + (unsigned long)(path->func), path->name); + } #endif - } - H5T_close(path->src); - H5T_close(path->dst); - H5FL_FREE(H5T_path_t,path); - H5E_clear(NULL); /*ignore all shutdown errors*/ - } + } + H5T_close(path->src); + H5T_close(path->dst); + H5FL_FREE(H5T_path_t,path); + H5E_clear(NULL); /*ignore all shutdown errors*/ + } /* end else */ + } /* end for */ done: FUNC_LEAVE_NOAPI(ret_value); diff --git a/src/H5Tconv.c b/src/H5Tconv.c index a419577..0a500b5 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -1534,6 +1534,12 @@ H5T_conv_struct_init (H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata, hid_t dxpl_id) } } } + else { + /* Restore sorted conditions for the datatypes */ + /* (Required for the src2dst array to be valid) */ + H5T_sort_value(src, NULL); + H5T_sort_value(dst, NULL); + } /* end else */ /* * (Re)build the cache of member conversion functions and pointers to |