From 6bd08196351eef39c6728ea1e9b67b14be56306d Mon Sep 17 00:00:00 2001 From: lethosor Date: Fri, 11 Aug 2023 02:31:54 -0400 Subject: [PATCH 1/2] Fix crash in df.global:_field() when global address is unknown and add a test --- library/LuaTypes.cpp | 3 +++ test/structures/globals.lua | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 test/structures/globals.lua diff --git a/library/LuaTypes.cpp b/library/LuaTypes.cpp index ef69958e0..ddc166abc 100644 --- a/library/LuaTypes.cpp +++ b/library/LuaTypes.cpp @@ -664,6 +664,9 @@ static int meta_global_field_reference(lua_State *state) auto field = (struct_field_info*)find_field(state, 2, "reference"); if (!field) field_error(state, 2, "builtin property or method", "reference"); + void *ptr = *(void**)field->offset; + if (!ptr) + field_error(state, 2, "global address not known", "reference"); field_reference(state, field, *(void**)field->offset); return 1; } diff --git a/test/structures/globals.lua b/test/structures/globals.lua new file mode 100644 index 000000000..6b278af96 --- /dev/null +++ b/test/structures/globals.lua @@ -0,0 +1,33 @@ +config.mode = 'title' +config.target = 'core' + +local function with_temp_global_address(name, addr, callback, ...) + dfhack.call_with_finalizer(2, true, + dfhack.internal.setAddress, name, dfhack.internal.getAddress(name), + function(...) + dfhack.internal.setAddress(name, addr) + callback(...) + end, ...) +end + +function test.unknown_global_address() + expect.ne(dfhack.internal.getAddress('army_next_id'), 0) + local old_id = df.global.army_next_id + + with_temp_global_address('army_next_id', 0, function() + expect.error_match('Cannot read field global.army_next_id: global address not known.', function() + local _ = df.global.army_next_id + end) + + expect.error_match('Cannot write field global.army_next_id: global address not known.', function() + df.global.army_next_id = old_id + end) + + expect.error_match('Cannot reference field global.army_next_id: global address not known.', function() + local _ = df.global:_field('army_next_id') + end) + end) + + expect.gt(dfhack.internal.getAddress('army_next_id'), 0) + expect.eq(df.global.army_next_id, old_id) +end From 9aee332fbda8f17866bda63b2c5f88711451117a Mon Sep 17 00:00:00 2001 From: lethosor Date: Fri, 11 Aug 2023 12:52:28 -0400 Subject: [PATCH 2/2] Widen and clarify structures test mode restrictions --- test/structures/find.lua | 2 +- test/structures/globals.lua | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/test/structures/find.lua b/test/structures/find.lua index e93b2cc7f..590df8971 100644 --- a/test/structures/find.lua +++ b/test/structures/find.lua @@ -1,4 +1,4 @@ -config.mode = 'title' +config.mode = 'title' -- not safe to run when a world is loaded config.target = 'core' local function clean_vec(vec) diff --git a/test/structures/globals.lua b/test/structures/globals.lua index 6b278af96..81d77f8c7 100644 --- a/test/structures/globals.lua +++ b/test/structures/globals.lua @@ -1,4 +1,3 @@ -config.mode = 'title' config.target = 'core' local function with_temp_global_address(name, addr, callback, ...)