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/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 new file mode 100644 index 000000000..81d77f8c7 --- /dev/null +++ b/test/structures/globals.lua @@ -0,0 +1,32 @@ +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