From 901145b59f14b26b01b51cb38bf96b63ad9d1ff1 Mon Sep 17 00:00:00 2001 From: Test_User Date: Thu, 5 Sep 2024 01:55:15 -0400 Subject: Remove UB around function/non-function pointer casting (by stuff using this) --- hax_table.c | 40 ++++++++++++++++++++++++---------------- hax_table.h | 17 ++++++++++++----- 2 files changed, 36 insertions(+), 21 deletions(-) diff --git a/hax_table.c b/hax_table.c index 0b89a35..c2c82a3 100644 --- a/hax_table.c +++ b/hax_table.c @@ -102,7 +102,7 @@ static inline size_t search(struct table tbl, struct string name, char *exists) } } -int set_table_index(struct table *tbl, struct string name, void *ptr) { +int set_table_index(struct table *tbl, struct string name, union table_ptr ptr) { char exists; size_t index = search(*tbl, name, &exists); @@ -132,11 +132,10 @@ int set_table_index(struct table *tbl, struct string name, void *ptr) { return 0; } -void * get_table_index(struct table tbl, struct string name) { - char exists; - size_t index = search(tbl, name, &exists); - if (!exists) - return 0; +union table_ptr get_table_index(struct table tbl, struct string name, char *exists) { + size_t index = search(tbl, name, exists); + if (!*exists) + return (union table_ptr){0}; return tbl.array[index].ptr; } @@ -147,14 +146,13 @@ char has_table_index(struct table tbl, struct string name) { return exists; } -void * remove_table_index(struct table *tbl, struct string name) { - char exists; - size_t index = search(*tbl, name, &exists); +union table_ptr get_and_remove_table_index(struct table *tbl, struct string name, char *exists) { + size_t index = search(*tbl, name, exists); - if (!exists) - return 0; + if (!*exists) + return (union table_ptr){0}; - void *ptr = tbl->array[index].ptr; + union table_ptr ptr = tbl->array[index].ptr; free(tbl->array[index].name.data); memmove(&(tbl->array[index]), &(tbl->array[index+1]), (tbl->len - index - 1) * sizeof(*(tbl->array))); @@ -168,6 +166,12 @@ void * remove_table_index(struct table *tbl, struct string name) { return ptr; } +void remove_table_index(struct table *tbl, struct string name) { + char exists; + get_and_remove_table_index(tbl, name, &exists); + return; +} + void clear_table(struct table *tbl) { for (size_t i = 0; i < tbl->len; i++) free(tbl->array[i].name.data); @@ -181,10 +185,14 @@ size_t get_table_offset(struct table tbl, struct string name, char *exists) { } // TODO: Proper lookup -void * get_table_prefix(struct table tbl, struct string name) { - for (size_t i = 0; i < tbl.len; i++) - if (tbl.array[i].name.len <= name.len && memcmp(tbl.array[i].name.data, name.data, tbl.array[i].name.len) == 0) +union table_ptr get_table_prefix(struct table tbl, struct string name, char *exists) { + for (size_t i = 0; i < tbl.len; i++) { + if (tbl.array[i].name.len <= name.len && memcmp(tbl.array[i].name.data, name.data, tbl.array[i].name.len) == 0) { + *exists = 1; return tbl.array[i].ptr; + } + } - return 0; + *exists = 0; + return (union table_ptr){0}; } diff --git a/hax_table.h b/hax_table.h index 90cbbdb..5db58ee 100644 --- a/hax_table.h +++ b/hax_table.h @@ -30,9 +30,15 @@ #include "hax_string.h" +// because C and function pointers vs non-function pointers +union table_ptr { + void *data; + void (*function)(void); +}; + struct table_index { struct string name; - void *ptr; + union table_ptr ptr; }; struct table { @@ -40,12 +46,13 @@ struct table { size_t len; }; -extern int set_table_index(struct table *tbl, struct string name, void *ptr); -extern void * get_table_index(struct table tbl, struct string name); +extern int set_table_index(struct table *tbl, struct string name, union table_ptr ptr); +extern union table_ptr get_table_index(struct table tbl, struct string name, char *exists); extern char has_table_index(struct table tbl, struct string name); -extern void * remove_table_index(struct table *tbl, struct string name); // returns same as get_table_index +extern void remove_table_index(struct table *tbl, struct string name); +extern union table_ptr get_and_remove_table_index(struct table *tbl, struct string name, char *exists); // returns same as get_table_index extern void clear_table(struct table *tbl); extern size_t get_table_offset(struct table tbl, struct string name, char *exists); // Longest index that starts with -extern void * get_table_prefix(struct table tbl, struct string name); +extern union table_ptr get_table_prefix(struct table tbl, struct string name, char *exists); -- cgit v1.2.3