bounds checked arrays

This commit is contained in:
2025-12-13 16:47:40 +01:00
parent 289f4bb371
commit 8485ad25e4
3 changed files with 90 additions and 0 deletions
+8
View File
@@ -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
View File
@@ -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);
+67
View File
@@ -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);
}
}