bounds checked arrays
This commit is contained in:
@@ -180,6 +180,14 @@ size_t arr_cap(void *this);
|
||||
|
||||
#define arr_pop(THIS) (arr_shrink(THIS, 1), THIS[arr_len(THIS)])
|
||||
|
||||
void dyn_array_bounds_check_func(void *this, size_t index, const char *file, int line);
|
||||
|
||||
#define arr_get(THIS, INDEX) \
|
||||
(dyn_array_bounds_check_func(THIS, INDEX, __FILE__, __LINE__), (THIS)[INDEX])
|
||||
|
||||
#define arr_set(THIS, INDEX, VALUE) \
|
||||
(dyn_array_bounds_check_func(THIS, INDEX, __FILE__, __LINE__), (THIS)[INDEX] = (VALUE))
|
||||
|
||||
#define STATIC_ASSERT(expr) ((void)sizeof(char[(expr) ? 1 : -1]))
|
||||
|
||||
bool dyn_array_contains_func(void *this, uint8_t *value);
|
||||
|
||||
+15
@@ -96,6 +96,21 @@ bool dyn_array_contains_cmp_func(void *this, uint8_t *value, dyn_array_eq_fn eq)
|
||||
return false;
|
||||
}
|
||||
|
||||
void dyn_array_bounds_check_func(void *this, size_t index, const char *file, int line) {
|
||||
size_t len = arr_len(this);
|
||||
if (index >= len) {
|
||||
fprintf(
|
||||
stderr,
|
||||
"%s:%d: array index %zu out of bounds (length is %zu)\n",
|
||||
file,
|
||||
line,
|
||||
index,
|
||||
len
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void dyn_array_insert_sorted_func(void **this_ptr, const void *value, dyn_array_cmp_fn cmp, const char *file, int line) {
|
||||
void *this = *this_ptr;
|
||||
dyn_array_header_t *header = PTR_FROM_FIELD_PTR(dyn_array_header_t, bytes, this);
|
||||
|
||||
@@ -293,3 +293,70 @@ Test(dynamic_arrays, contains_cmp_key_value_map) {
|
||||
}
|
||||
}
|
||||
|
||||
Test(dynamic_arrays, get_valid_indices) {
|
||||
with_borrow(alloc) {
|
||||
int *arr = make_arr(alloc, int);
|
||||
arr_append(arr, 10);
|
||||
arr_append(arr, 20);
|
||||
arr_append(arr, 30);
|
||||
arr_append(arr, 40);
|
||||
|
||||
cr_assert_eq(arr_get(arr, 0), 10);
|
||||
cr_assert_eq(arr_get(arr, 1), 20);
|
||||
cr_assert_eq(arr_get(arr, 2), 30);
|
||||
cr_assert_eq(arr_get(arr, 3), 40);
|
||||
}
|
||||
}
|
||||
|
||||
Test(dynamic_arrays, set_valid_indices) {
|
||||
with_borrow(alloc) {
|
||||
int *arr = make_arr(alloc, int);
|
||||
arr_append(arr, 10);
|
||||
arr_append(arr, 20);
|
||||
arr_append(arr, 30);
|
||||
|
||||
arr_set(arr, 0, 100);
|
||||
arr_set(arr, 1, 200);
|
||||
arr_set(arr, 2, 300);
|
||||
|
||||
cr_assert_eq(arr_get(arr, 0), 100);
|
||||
cr_assert_eq(arr_get(arr, 1), 200);
|
||||
cr_assert_eq(arr_get(arr, 2), 300);
|
||||
}
|
||||
}
|
||||
|
||||
Test(dynamic_arrays, get_out_of_bounds, .exit_code = 1) {
|
||||
with_borrow(alloc) {
|
||||
int *arr = make_arr(alloc, int);
|
||||
arr_append(arr, 10);
|
||||
arr_append(arr, 20);
|
||||
|
||||
(void)arr_get(arr, 2);
|
||||
}
|
||||
}
|
||||
|
||||
Test(dynamic_arrays, set_out_of_bounds, .exit_code = 1) {
|
||||
with_borrow(alloc) {
|
||||
int *arr = make_arr(alloc, int);
|
||||
arr_append(arr, 10);
|
||||
arr_append(arr, 20);
|
||||
|
||||
arr_set(arr, 2, 999);
|
||||
}
|
||||
}
|
||||
|
||||
Test(dynamic_arrays, get_empty_array, .exit_code = 1) {
|
||||
with_borrow(alloc) {
|
||||
int *arr = make_arr(alloc, int);
|
||||
(void)arr_get(arr, 0);
|
||||
}
|
||||
}
|
||||
|
||||
Test(dynamic_arrays, set_empty_array, .exit_code = 1) {
|
||||
with_borrow(alloc) {
|
||||
int *arr = make_arr(alloc, int);
|
||||
arr_set(arr, 0, 42);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user