summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2004-08-08 22:12:21 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2004-08-08 22:12:21 (GMT)
commitf9e414bc751c50eee75bc7ec77690843c68c6f9a (patch)
tree7bc2e5f04da1cc1121b3bb580140e875de2fec9e /src
parent5a7fcfa213dbd65e8745d842b229ad777deace94 (diff)
downloadhdf5-f9e414bc751c50eee75bc7ec77690843c68c6f9a.zip
hdf5-f9e414bc751c50eee75bc7ec77690843c68c6f9a.tar.gz
hdf5-f9e414bc751c50eee75bc7ec77690843c68c6f9a.tar.bz2
[svn-r9054] 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.c66
-rw-r--r--src/H5Tconv.c6
2 files changed, 45 insertions, 27 deletions
diff --git a/src/H5T.c b/src/H5T.c
index dcbad77..3bcd0f0 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -2304,35 +2304,47 @@ 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(); /*ignore all shutdown errors*/
+ }
+ H5T_close(path->src);
+ H5T_close(path->dst);
+ H5FL_FREE(H5T_path_t,path);
+ H5E_clear(); /*ignore all shutdown errors*/
+ } /* end else */
}
done:
diff --git a/src/H5Tconv.c b/src/H5Tconv.c
index fd7693a..2bce779 100644
--- a/src/H5Tconv.c
+++ b/src/H5Tconv.c
@@ -1363,6 +1363,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