Updates H5Sset_extent_none() to set H5S_NULL

The API call used to set the internal H5S_NO_CLASS value which
produced errors when such a dataspace was passed to many other API
calls.

Fixes HDFFV-11027
This commit is contained in:
Dana Robinson 2020-07-27 17:32:01 -07:00
parent 74e09473c8
commit 91f5320ff0
3 changed files with 98 additions and 4 deletions

View File

@ -951,6 +951,21 @@ Bug Fixes since HDF5-1.10.3 release
(DER - 2019/12/09, HDFFV-10945)
- H5Sset_extent_none() sets the dataspace class to H5S_NO_CLASS which
causes asserts/errors when passed to other dataspace API calls.
H5S_NO_CLASS is an internal class value that should not have been
exposed via a public API call.
In debug builds of the library, this can cause asserts to trip. In
non-debug builds, it will produce normal library errors.
The new library behavior is for H5Sset_extent_none() to convert
the dataspace into one of type H5S_NULL, which is better handled
by the library and easier for developers to reason about.
(DER - 2020/07/27, HDFFV-11027)
Java Library:
----------------

View File

@ -437,6 +437,9 @@ H5S__extent_release(H5S_extent_t *extent)
extent->max = H5FL_ARR_FREE(hsize_t, extent->max);
} /* end if */
extent->rank = 0;
extent->nelem = 0;
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5S__extent_release() */
@ -1832,7 +1835,7 @@ done:
RETURNS
Non-negative on success/Negative on failure
DESCRIPTION
This function resets the type of a dataspace back to "none" with no
This function resets the type of a dataspace to H5S_NULL with no
extent information stored for the dataspace.
--------------------------------------------------------------------------*/
herr_t
@ -1852,7 +1855,7 @@ H5Sset_extent_none(hid_t space_id)
if(H5S__extent_release(&space->extent) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTDELETE, FAIL, "can't release previous dataspace")
space->extent.type = H5S_NO_CLASS;
space->extent.type = H5S_NULL;
done:
FUNC_LEAVE_API(ret_value)

View File

@ -15442,14 +15442,14 @@ test_hyper_io_1d(void)
/* Get the dataset's dataspace */
sid = H5Dget_space(did);
CHECK(sid, H5I_INVALID_HID, "H5Pcreate");
CHECK(sid, H5I_INVALID_HID, "H5Dget_space");
ret = H5Sselect_hyperslab(sid, H5S_SELECT_SET, offset, stride, count, block);
CHECK(ret, FAIL, "H5Sselect_hyperslab");
/* Set up contiguous memory dataspace for the selected elements */
dimsm[0] = count[0];
mid = H5Screate_simple(RANK, dimsm, NULL);
CHECK(mid, H5I_INVALID_HID, "H5Screate");
CHECK(mid, H5I_INVALID_HID, "H5Screate_simple");
/* Read all the selected 10th elements in the dataset into "rdata" */
ret = H5Dread(did, H5T_NATIVE_INT, mid, sid, H5P_DEFAULT, rdata);
@ -15473,6 +15473,77 @@ test_hyper_io_1d(void)
} /* test_hyper_io_1d() */
/****************************************************************
**
** test_get_extent_no_class:
** Test to verify the behavior of dataspace code when passed
** a dataspace modified by H5Sset_extent_none().
**
****************************************************************/
static void
test_h5s_set_extent_none(void)
{
hid_t sid = H5I_INVALID_HID;
hid_t dst_sid = H5I_INVALID_HID;
hid_t null_sid = H5I_INVALID_HID;
int rank = 1;
hsize_t current_dims = 123;
H5S_class_t cls;
int out_rank;
hsize_t out_dims;
hsize_t out_maxdims;
hssize_t out_points;
htri_t equal;
herr_t ret;
/* Specific values here don't matter as we're just going to reset */
sid = H5Screate_simple(rank, &current_dims, NULL);
CHECK(sid, H5I_INVALID_HID, "H5Screate_simple");
/* Dataspace class will be H5S_NULL after this.
* In versions prior to 1.10.7 / 1.12.1 this would produce a
* dataspace with the internal H5S_NO_SPACE class.
*/
ret = H5Sset_extent_none(sid);
CHECK(ret, FAIL, "H5Sset_extent_none");
cls = H5Sget_simple_extent_type(sid);
VERIFY(cls, H5S_NULL, "H5Sget_simple_extent_type");
/* Extent getters should generate normal results and not segfault.
*/
out_rank = H5Sget_simple_extent_dims(sid, &out_dims, &out_maxdims);
VERIFY(out_rank, 0, "H5Sget_simple_extent_dims");
out_rank = H5Sget_simple_extent_ndims(sid);
VERIFY(out_rank, 0, "H5Sget_simple_extent_ndims");
out_points = H5Sget_simple_extent_npoints(sid);
VERIFY(out_points, 0, "H5Sget_simple_extent_npoints");
/* Check that copying the new (non-)extent works.
*/
dst_sid = H5Screate_simple(rank, &current_dims, NULL);
CHECK(dst_sid, H5I_INVALID_HID, "H5Screate_simple");
ret = H5Sextent_copy(dst_sid, sid);
CHECK(ret, FAIL, "H5Sextent_copy");
/* Check that H5Sset_extent_none() produces the same extent as
* H5Screate(H5S_NULL).
*/
null_sid = H5Screate(H5S_NULL);
CHECK(null_sid, H5I_INVALID_HID, "H5Screate");
equal = H5Sextent_equal(sid, null_sid);
VERIFY(equal, TRUE, "H5Sextent_equal");
/* Close */
ret = H5Sclose(sid);
CHECK(ret, FAIL, "H5Sclose");
ret = H5Sclose(dst_sid);
CHECK(ret, FAIL, "H5Sclose");
ret = H5Sclose(null_sid);
CHECK(ret, FAIL, "H5Sclose");
} /* test_get_extent_no_class() */
/****************************************************************
**
@ -15660,6 +15731,11 @@ test_select(void)
/* Test reading of 1-d disjoint file space to 1-d single block memory space */
test_hyper_io_1d();
/* Test H5Sset_extent_none() functionality after we updated it to set
* the class to H5S_NULL instead of H5S_NO_CLASS.
*/
test_h5s_set_extent_none();
} /* test_select() */