Skip to content

Commit 3d102dc

Browse files
committed
Enable UBSan and fix sanitizer findings
1 parent 0cf34f3 commit 3d102dc

25 files changed

Lines changed: 177 additions & 51 deletions

CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ option(BTECH_SCALED_INFRARED "Scale infrared BTH with increasing heat" ON)
4343
option(BTECH_OVERSPEEDING "Allow mech overspeeding" OFF)
4444

4545
option(BTECH_ENABLE_ASAN "Build with AddressSanitizer instrumentation" ON)
46+
option(BTECH_ENABLE_UBSAN "Build with UndefinedBehaviorSanitizer instrumentation" ON)
4647
option(BTECH_ENABLE_CLANG_TIDY "Run clang-tidy during compilation" OFF)
4748

4849
if(BTECH_ENABLE_CLANG_TIDY)
@@ -171,6 +172,10 @@ if(BTECH_ENABLE_ASAN)
171172
target_compile_options(btmux_options INTERFACE -fsanitize=address)
172173
target_link_options(btmux_options INTERFACE -fsanitize=address)
173174
endif()
175+
if(BTECH_ENABLE_UBSAN)
176+
target_compile_options(btmux_options INTERFACE -fsanitize=undefined)
177+
target_link_options(btmux_options INTERFACE -fsanitize=undefined)
178+
endif()
174179

175180
set(BTECH_SOURCES
176181
${BTECH_SOURCE_DIR}/src/btech_context.c

src/btech/persistence/btech_persistence_sqlite.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -681,8 +681,10 @@ static int btech_special_resize_map(MAP *map, int width, int height) {
681681
static int btech_special_allocate_map_dynamic(MAP *map) {
682682
int index;
683683

684-
if (!map->first_free)
684+
if (!map->first_free) {
685+
map->dynamic_size = 0;
685686
return 0;
687+
}
686688
map->mechsOnMap = calloc(map->first_free, sizeof(*map->mechsOnMap));
687689
map->mechflags = calloc(map->first_free, sizeof(*map->mechflags));
688690
map->LOSinfo = calloc(map->first_free, sizeof(*map->LOSinfo));
@@ -692,8 +694,10 @@ static int btech_special_allocate_map_dynamic(MAP *map) {
692694
map->LOSinfo[index] = calloc(map->first_free, sizeof(*map->LOSinfo[index]));
693695
}
694696
if (map->mechsOnMap && map->mechflags && map->LOSinfo &&
695-
index == map->first_free)
697+
index == map->first_free) {
698+
map->dynamic_size = map->first_free;
696699
return 0;
700+
}
697701
if (map->LOSinfo)
698702
for (index = 0; index < map->first_free; index++)
699703
free(map->LOSinfo[index]);
@@ -703,6 +707,7 @@ static int btech_special_allocate_map_dynamic(MAP *map) {
703707
map->LOSinfo = NULL;
704708
map->mechflags = NULL;
705709
map->mechsOnMap = NULL;
710+
map->dynamic_size = 0;
706711
return -1;
707712
}
708713

src/btech/src/btech/autopilot_ai.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -911,7 +911,12 @@ static astar_node *auto_create_astar_node(short x, short y, short x_parent,
911911
*
912912
* Returns 1 if it found a path and 0 if it doesn't
913913
*/
914-
int astar_compare(int a, int b, void *arg) { return a - b; }
914+
static int astar_compare(void *left_key, void *right_key, void *arg) {
915+
const long left = (long)left_key;
916+
const long right = (long)right_key;
917+
918+
return (left > right) - (left < right);
919+
}
915920
void astar_release(void *key, void *data) { free(data); }
916921
int auto_astar_generate_path(AUTO *autopilot, MECH *mech, short end_x,
917922
short end_y) {
@@ -964,9 +969,9 @@ int auto_astar_generate_path(AUTO *autopilot, MECH *mech, short end_x,
964969
memset(open_list_bitfield, 0, sizeof(open_list_bitfield));
965970

966971
/* Setup the trees */
967-
open_list_by_score = red_black_tree_init((void *)astar_compare, NULL);
968-
open_list_by_xy = red_black_tree_init((void *)astar_compare, NULL);
969-
closed_list = red_black_tree_init((void *)astar_compare, NULL);
972+
open_list_by_score = red_black_tree_init(astar_compare, NULL);
973+
open_list_by_xy = red_black_tree_init(astar_compare, NULL);
974+
closed_list = red_black_tree_init(astar_compare, NULL);
970975

971976
/* Setup the path */
972977
/* Destroy any existing path first */

src/btech/src/btech/map.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -653,7 +653,9 @@ void newfreemap(DbRef key, void **data, int selector) {
653653
new->mapobj[i] = NULL;
654654
snprintf(new->mapname, MAP_NAME_SIZE, "%s", "Default Map");
655655
break;
656-
case SPECIAL_FREE:
656+
case SPECIAL_FREE: {
657+
const int allocated_slots = new->dynamic_size;
658+
657659
/* Seriously. We weren't clearing the map of mechas. Bad bad accounting!!!
658660
*/
659661
map_clearmechs(GOD, new, "");
@@ -664,8 +666,15 @@ void newfreemap(DbRef key, void **data, int selector) {
664666
free((char *)(new->map[i]));
665667
free((char *)(new->map));
666668
}
669+
if (new->LOSinfo)
670+
for (i = 0; i < allocated_slots; i++)
671+
free(new->LOSinfo[i]);
672+
free(new->LOSinfo);
673+
free(new->mechflags);
674+
free(new->mechsOnMap);
667675
break;
668676
}
677+
}
669678
}
670679

671680
int map_sizefun(void *data, int flag) {

src/btech/src/btech/map.dynamic.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ void eliminate_empties(MAP *map) {
7979
ReCreate(map->mechflags, char, count);
8080

8181
map->first_free = count;
82+
map->dynamic_size = count;
8283
econ_fix_stuff(map->xcode.context, GOD, map->mynum);
8384
}
8485

@@ -165,6 +166,7 @@ void add_mech_to_map(MAP *newmap, MECH *mech) {
165166
}
166167
for (i = 0; i < count; i++)
167168
newmap->LOSinfo[loop][i] = 0;
169+
newmap->dynamic_size = count;
168170
}
169171
mech->mapindex = newmap->mynum;
170172
mech->mapnumber = loop;

src/btech/src/btech/map.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ typedef struct map_data {
197197
char buildflag;
198198

199199
unsigned char first_free; /* First free on da map */
200+
int dynamic_size; /* Allocated occupancy/LOS matrix dimension. */
200201
DbRef *mechsOnMap; /* Mechs on the map */
201202
unsigned short **LOSinfo; /* Line of sight info */
202203

src/btech/src/btech/map.obj.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,13 @@ void del_mapobj(MAP *map, mapobj *mapob, int type, int zap) {
126126
tmap->onmap = 0;
127127
}
128128
}
129+
if (type == TYPE_BITS && mapob->datai != 0) {
130+
unsigned char **bits = (unsigned char **)mapob->datai;
131+
132+
for (int y = 0; y < map->map_height; y++)
133+
free(bits[y]);
134+
free(bits);
135+
}
129136
free(mapob);
130137
}
131138

src/btech/src/btech/mech.restrict.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "p.mech.build.h"
2020
#include "p.mech.c3.h"
2121
#include "p.mech.c3i.h"
22+
#include "p.mech.update.h"
2223
#include "p.mech.utils.h"
2324
#include "p.mechrep.h"
2425

@@ -255,6 +256,7 @@ void newfreemech(DbRef key, void **data, int selector) {
255256
FillDefaultCriticals(new, i);
256257
break;
257258
case SPECIAL_FREE:
259+
ClearAllStaggerDamage(new);
258260
if (new->mapindex != -1 &&
259261
(map = btech_context_get_map(new->xcode.context, new->mapindex)))
260262
remove_mech_from_map(map, new);

src/btech/src/debug.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,17 @@ void ShutDownMap(BtechContext *context, DbRef player, DbRef mapnumber) {
176176
remove_mech_from_map(map, mech);
177177
}
178178
}
179+
if (map->LOSinfo)
180+
for (j = 0; j < map->dynamic_size; j++)
181+
free(map->LOSinfo[j]);
182+
free(map->LOSinfo);
183+
free(map->mechflags);
184+
free(map->mechsOnMap);
185+
map->LOSinfo = nullptr;
186+
map->mechflags = nullptr;
187+
map->mechsOnMap = nullptr;
179188
map->first_free = 0;
189+
map->dynamic_size = 0;
180190
notify(btech_context_evaluation(context), player, "Map Cleared");
181191
return;
182192
}

src/mux/commands/command.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,41 @@ void init_cmdtab(CommandRegistry *registry) {
405405
registry->goto_command = hash_table_find("goto", &registry->commands);
406406
}
407407

408+
void command_aliases_destroy(HashTable *commands) {
409+
CMDENT **aliases = nullptr;
410+
size_t alias_count = 0;
411+
412+
if (commands == nullptr || commands->tree == nullptr)
413+
return;
414+
for (char *key = hash_table_first_key(commands); key != nullptr;
415+
key = hash_table_next_key(commands)) {
416+
CMDENT *command = hash_table_find(key, commands);
417+
bool built_in = false;
418+
419+
for (CMDENT *candidate = command_table; candidate->cmdname; candidate++) {
420+
if (command == candidate) {
421+
built_in = true;
422+
break;
423+
}
424+
}
425+
if (built_in || strcasecmp(key, command->cmdname))
426+
continue;
427+
CMDENT **grown = realloc(aliases, (alias_count + 1) * sizeof(*aliases));
428+
if (grown == nullptr)
429+
break;
430+
aliases = grown;
431+
aliases[alias_count++] = command;
432+
}
433+
for (size_t index = 0; index < alias_count; index++) {
434+
#pragma clang diagnostic push
435+
#pragma clang diagnostic ignored "-Wcast-qual"
436+
free((void *)aliases[index]->cmdname);
437+
#pragma clang diagnostic pop
438+
free(aliases[index]);
439+
}
440+
free(aliases);
441+
}
442+
408443
void set_prefix_cmds(CommandRegistry *registry) {
409444
/*
410445
* Load the command prefix table. Note - these commands can never *

0 commit comments

Comments
 (0)