Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions src/core/ndarray.c
Original file line number Diff line number Diff line change
Expand Up @@ -1375,7 +1375,7 @@ void *asdf_ndarray_data_alloc_temp(asdf_file_t *file, asdf_ndarray_t *ndarray) {
if (UNLIKELY(!file || !ndarray))
return NULL;

asdf_ndarray_internal_t *internal = calloc(1, sizeof(asdf_ndarray_internal_t));
asdf_ndarray_internal_t *internal = asdf_ndarray_internal(ndarray, true);

if (UNLIKELY(!internal)) {
ASDF_ERROR_OOM(file);
Expand All @@ -1386,13 +1386,11 @@ void *asdf_ndarray_data_alloc_temp(asdf_file_t *file, asdf_ndarray_t *ndarray) {
void *data = calloc(1, (size_t)nbytes);

if (UNLIKELY(!data)) {
free(internal);
ASDF_ERROR_OOM(file);
return NULL;
}

internal->data = data;
ndarray->internal = internal;
asdf_file_write_cleanup_add(file, ndarray_write_data_cleanup, internal);
return data;
}
Expand Down
58 changes: 57 additions & 1 deletion tests/test-ndarray.c
Original file line number Diff line number Diff line change
Expand Up @@ -899,6 +899,61 @@ MU_TEST(ndarray_array_storage_override) {
}


/* Regression test for the bug where asdf_ndarray_data_alloc_temp leaked the
* asdf_ndarray_internal_t created by a prior asdf_ndarray_storage_set call
* (and silently dropped the array_storage setting). */
MU_TEST(ndarray_data_alloc_temp_storage_set_ordering) {
uint64_t shape[1] = {4};
asdf_ndarray_t nd = {
.datatype = {.type = ASDF_DATATYPE_UINT8, .size = 1},
.byteorder = ASDF_BYTEORDER_LITTLE,
.ndim = 1,
.shape = shape,
};

asdf_file_t *file = asdf_open(NULL);
assert_not_null(file);

/* Call storage_set BEFORE data_alloc_temp -- the natural authoring order.
* Prior to the fix, data_alloc_temp would leak the internal created here
* and discard the array_storage setting. */
asdf_ndarray_storage_set(&nd, ASDF_ARRAY_STORAGE_INLINE);
uint8_t *data = asdf_ndarray_data_alloc_temp(file, &nd);
assert_not_null(data);
for (int idx = 0; idx < 4; idx++)
data[idx] = (uint8_t)(idx + 1);

assert_int(asdf_ndarray_storage(&nd), ==, ASDF_ARRAY_STORAGE_INLINE);

const char *out_path = get_temp_file_path(fixture->tempfile_prefix, ".asdf");
asdf_value_t *val = asdf_value_of_ndarray(file, &nd);
assert_not_null(val);
assert_int(asdf_set_value(file, "arr", val), ==, ASDF_VALUE_OK);
assert_int(asdf_write_to(file, out_path), ==, 0);
asdf_close(file);

file = asdf_open(out_path, "r");
assert_not_null(file);
assert_size(asdf_block_count(file), ==, 0);

asdf_ndarray_t *nd_in = NULL;
assert_int(asdf_get_ndarray(file, "arr", &nd_in), ==, ASDF_VALUE_OK);
assert_not_null(nd_in);
assert_int(asdf_ndarray_storage(nd_in), ==, ASDF_ARRAY_STORAGE_INLINE);

size_t size = 0;
const void *raw = asdf_ndarray_data_raw(nd_in, &size);
assert_not_null(raw);
assert_size(size, ==, 4);
for (int idx = 0; idx < 4; idx++)
assert_int(((const uint8_t *)raw)[idx], ==, idx + 1);

asdf_ndarray_destroy(nd_in);
asdf_close(file);
return MUNIT_OK;
}


MU_TEST_SUITE(
ndarray,
MU_RUN_TEST(ndarray_read_1d_tile_contiguous),
Expand All @@ -912,7 +967,8 @@ MU_TEST_SUITE(
MU_RUN_TEST(ndarray_write_inline_data),
MU_RUN_TEST(ndarray_inline_warning_thresh),
MU_RUN_TEST(ndarray_array_storage_override, ndarray_array_storage_params),
MU_RUN_TEST(heap_use_after_free_issue_63)
MU_RUN_TEST(heap_use_after_free_issue_63),
MU_RUN_TEST(ndarray_data_alloc_temp_storage_set_ordering)
);


Expand Down
2 changes: 1 addition & 1 deletion tests/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ static void clean_stale_pgid_files(void) {


#define TEST_SERIAL_LEN 6
#define TEST_SERIAL_FMT "%6d"
#define TEST_SERIAL_FMT "%06d"
#define TEST_SERIAL_MAX 1000000


Expand Down
Loading