mirror of
https://github.com/HDFGroup/hdf5.git
synced 2024-12-09 07:32:32 +08:00
Fix for HDFFV-10217 infinite loop in H5VM_power2up().
The function H5VM_power2up() returns the next power of 2 for n. When n exceeds 2^63, it overflows and becomes 0 causing the infinite looping. The fix ensures that the function checks for n >= 2^63 and returns 0.
This commit is contained in:
parent
45724d8082
commit
fc76c77852
@ -1019,11 +1019,16 @@ H5D__chunk_init(H5F_t *f, hid_t dxpl_id, const H5D_t *dset, hid_t dapl_id)
|
||||
unsigned u; /* Local index value */
|
||||
|
||||
for(u = 0; u < dset->shared->ndims; u++) {
|
||||
hsize_t scaled_power2up; /* Scaled value, rounded to next power of 2 */
|
||||
|
||||
/* Initial scaled dimension sizes */
|
||||
rdcc->scaled_dims[u] = dset->shared->curr_dims[u] / dset->shared->layout.u.chunk.dim[u];
|
||||
|
||||
if( !(scaled_power2up = H5VM_power2up(rdcc->scaled_dims[u])) )
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get the next power of 2")
|
||||
|
||||
/* Inital 'power2up' values for scaled dimensions */
|
||||
rdcc->scaled_power2up[u] = H5VM_power2up(rdcc->scaled_dims[u]);
|
||||
rdcc->scaled_power2up[u] = scaled_power2up;
|
||||
|
||||
/* Number of bits required to encode scaled dimension size */
|
||||
rdcc->scaled_encode_bits[u] = H5VM_log2_gen(rdcc->scaled_power2up[u]);
|
||||
|
@ -329,8 +329,11 @@ H5D__extend(H5D_t *dataset, const hsize_t *size, hid_t dxpl_id)
|
||||
dataset->shared->cache.chunk.scaled_dims[u] > dataset->shared->cache.chunk.nslots))
|
||||
update_chunks = TRUE;
|
||||
|
||||
if( !(scaled_power2up = H5VM_power2up(scaled)) )
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get the next power of 2")
|
||||
|
||||
/* Check if the number of bits required to encode the scaled size value changed */
|
||||
if(dataset->shared->cache.chunk.scaled_power2up[u] != (scaled_power2up = H5VM_power2up(scaled))) {
|
||||
if(dataset->shared->cache.chunk.scaled_power2up[u] != scaled_power2up) {
|
||||
/* Update the 'power2up' & 'encode_bits' values for the current dimension */
|
||||
dataset->shared->cache.chunk.scaled_power2up[u] = scaled_power2up;
|
||||
dataset->shared->cache.chunk.scaled_encode_bits[u] = H5VM_log2_gen(scaled_power2up);
|
||||
|
14
src/H5Dint.c
14
src/H5Dint.c
@ -745,8 +745,13 @@ H5D__cache_dataspace_info(const H5D_t *dset)
|
||||
dset->shared->ndims = (unsigned)sndims;
|
||||
|
||||
/* Compute the inital 'power2up' values */
|
||||
for(u = 0; u < dset->shared->ndims; u++)
|
||||
dset->shared->curr_power2up[u] = H5VM_power2up(dset->shared->curr_dims[u]);
|
||||
for(u = 0; u < dset->shared->ndims; u++) {
|
||||
hsize_t scaled_power2up; /* Scaled value, rounded to next power of 2 */
|
||||
|
||||
if( !(scaled_power2up = H5VM_power2up(dset->shared->curr_dims[u])) )
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get the next power of 2")
|
||||
dset->shared->curr_power2up[u] = scaled_power2up;
|
||||
}
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
@ -2809,8 +2814,11 @@ H5D__set_extent(H5D_t *dset, const hsize_t *size, hid_t dxpl_id)
|
||||
dset->shared->cache.chunk.scaled_dims[u] > dset->shared->cache.chunk.nslots))
|
||||
update_chunks = TRUE;
|
||||
|
||||
if( !(scaled_power2up = H5VM_power2up(scaled)) )
|
||||
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get the next power of 2")
|
||||
|
||||
/* Check if the number of bits required to encode the scaled size value changed */
|
||||
if(dset->shared->cache.chunk.scaled_power2up[u] != (scaled_power2up = H5VM_power2up(scaled))) {
|
||||
if(dset->shared->cache.chunk.scaled_power2up[u] != scaled_power2up) {
|
||||
/* Update the 'power2up' & 'encode_bits' values for the current dimension */
|
||||
dset->shared->cache.chunk.scaled_power2up[u] = scaled_power2up;
|
||||
dset->shared->cache.chunk.scaled_encode_bits[u] = H5VM_log2_gen(scaled_power2up);
|
||||
|
@ -460,7 +460,11 @@ H5VM_power2up(hsize_t n)
|
||||
{
|
||||
hsize_t ret_value = 1; /* Return value */
|
||||
|
||||
while(ret_value < n)
|
||||
/* Returns 0 when n exceeds 2^63 */
|
||||
if(n >= (hsize_t)1 << ((sizeof(hsize_t) * CHAR_BIT) - 1))
|
||||
ret_value = 0;
|
||||
|
||||
while(ret_value && ret_value < n)
|
||||
ret_value <<= 1;
|
||||
|
||||
return(ret_value);
|
||||
|
97
test/dsets.c
97
test/dsets.c
@ -51,14 +51,15 @@ const char *FILENAME[] = {
|
||||
"copy_dcpl_newfile",/* 13 */
|
||||
"partial_chunks", /* 14 */
|
||||
"layout_extend", /* 15 */
|
||||
"zero_chunk", /* 16 */
|
||||
"zero_chunk", /* 16 */
|
||||
"chunk_single", /* 17 */
|
||||
"swmr_non_latest", /* 18 */
|
||||
"earray_hdr_fd", /* 19 */
|
||||
"farray_hdr_fd", /* 20 */
|
||||
"bt2_hdr_fd", /* 21 */
|
||||
"storage_size", /* 22 */
|
||||
"storage_size", /* 22 */
|
||||
"dls_01_strings", /* 23 */
|
||||
"power2up", /* 24 */
|
||||
NULL
|
||||
};
|
||||
#define FILENAME_BUF_SIZE 1024
|
||||
@ -11343,6 +11344,97 @@ error:
|
||||
return -1;
|
||||
} /* end test_storage_size() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: test_power2up
|
||||
*
|
||||
* Purpose: Tests that the H5VM_power2up(n) function does not result in an
|
||||
* infinite loop when input n exceeds 2^63. (HDFFV-10217)
|
||||
* H5VM_power2up() is used to calculate the next power of 2 for
|
||||
* a dataset's scaled dimension sizes.
|
||||
*
|
||||
* Return: Success: 0
|
||||
* Failure: -1
|
||||
*
|
||||
* Programmer: Vailin Choi; June 2017
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
test_power2up(hid_t fapl)
|
||||
{
|
||||
char filename[FILENAME_BUF_SIZE];
|
||||
hid_t fid = -1; /* File ID */
|
||||
hid_t dcpl = -1; /* Dataset creation property list */
|
||||
hid_t sid = -1; /* Dataspace ID */
|
||||
hid_t did = -1; /* Dataset ID */
|
||||
hsize_t dims[2]; /* Dataset dimension sizes */
|
||||
hsize_t max_dims[2]; /* Maximum dimension sizes */
|
||||
hsize_t chunk_dims[2]; /* Chunk dimensions */
|
||||
hsize_t ext_dims[2]; /* Extended dimension sizes */
|
||||
herr_t status; /* Error status */
|
||||
|
||||
TESTING("the next power of 2");
|
||||
|
||||
h5_fixname(FILENAME[24], fapl, filename, sizeof filename);
|
||||
|
||||
/* Create file */
|
||||
if((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) FAIL_STACK_ERROR
|
||||
|
||||
/* Set dims[1] to ((2^63) -1) */
|
||||
dims[0] = 0;
|
||||
dims[1] = ((hsize_t)1 << ((sizeof(hsize_t) * CHAR_BIT) -1)) - 1;
|
||||
max_dims[0] = max_dims[1] = H5S_UNLIMITED;
|
||||
sid = H5Screate_simple(2, dims, max_dims);
|
||||
|
||||
/* Create dataset creation property list */
|
||||
if((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Set chunk size */
|
||||
chunk_dims[0] = chunk_dims[1] = 1;
|
||||
if(H5Pset_chunk(dcpl, 2, chunk_dims) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Create chunked dataset */
|
||||
if((did = H5Dcreate2(fid, "dset", H5T_NATIVE_INT64, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
ext_dims[0] = 1;
|
||||
ext_dims[1] = dims[1] + 5;
|
||||
|
||||
/* Extend to (2^63)+ */
|
||||
H5E_BEGIN_TRY {
|
||||
status = H5Dset_extent(did, ext_dims);
|
||||
} H5E_END_TRY;
|
||||
if(status >= 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Closing */
|
||||
if(H5Dclose(did) < 0)
|
||||
TEST_ERROR
|
||||
if(H5Sclose(sid) < 0)
|
||||
TEST_ERROR
|
||||
if(H5Pclose(dcpl) < 0)
|
||||
TEST_ERROR
|
||||
if(H5Fclose(fid) < 0)
|
||||
TEST_ERROR
|
||||
|
||||
PASSED();
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
H5E_BEGIN_TRY {
|
||||
H5Pclose(dcpl);
|
||||
H5Dclose(did);
|
||||
H5Sclose(sid);
|
||||
H5Pclose(dcpl);
|
||||
H5Fclose(fid);
|
||||
} H5E_END_TRY;
|
||||
return -1;
|
||||
} /* end test_power2up() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: test_scatter
|
||||
@ -12928,6 +13020,7 @@ main(void)
|
||||
nerrors += (test_large_chunk_shrink(my_fapl) < 0 ? 1 : 0);
|
||||
nerrors += (test_zero_dim_dset(my_fapl) < 0 ? 1 : 0);
|
||||
nerrors += (test_storage_size(my_fapl) < 0 ? 1 : 0);
|
||||
nerrors += (test_power2up(my_fapl) < 0 ? 1 : 0);
|
||||
|
||||
nerrors += (test_swmr_non_latest(envval, my_fapl) < 0 ? 1 : 0);
|
||||
nerrors += (test_earray_hdr_fd(envval, my_fapl) < 0 ? 1 : 0);
|
||||
|
Loading…
Reference in New Issue
Block a user