Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions library/Core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -453,13 +453,13 @@ void get_commands(color_ostream &con, std::vector<std::string> &commands) {
con.printerr("Failed Lua call to helpdb.get_commands.\n");
}

Lua::GetVector(L, commands);
Lua::GetVector(L, commands, top + 1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This only works because the stack size increases by a net of 1 item (the return value from helpdb.get_commands()) between when top is initialized and when this line is reached. In between, there are several stack operations (helpdb is pushed and popped internally to PushModulePublic, and helpdb.get_commands is pushed by PushModulePublic and popped by SafeCall). In my experience, there is some risk that someone coming along later could change the intervening logic to push more things on the stack without popping them, which is legal since this function is using a StackUnwinder, but would break this index.

So I would suggest

Suggested change
Lua::GetVector(L, commands, top + 1);
Lua::GetVector(L, commands, -1);

which is equivalent to Lua::GetVector(L, commands, lua_gettop(L) - 1); and will always give you the top-most item on the stack, which is what you want here.

Copy link
Member

@lethosor lethosor Nov 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mentioned on Discord that -1 won't work because GetVector itself manipulates the stack before using the input index. The patch you posted would fix that.

@@ -449,11 +450,12 @@ void get_commands(color_ostream &con, std::vector<std::string> &commands) {
         return;
     }

-    if (!Lua::SafeCall(con, L, 0, 1)) {
+    if (!Lua::SafeCall(con, L, 0, 1) || !lua_istable(L, -1)) {
         con.printerr("Failed Lua call to helpdb.get_commands.\n");
+        return;
     }

-    Lua::GetVector(L, commands, top + 1);
+    Lua::GetVector(L, commands, -1);
 }

 static bool try_autocomplete(color_ostream &con, const std::string &first, std::string &completed)
diff --git a/library/LuaTools.cpp b/library/LuaTools.cpp
index 08b90bd61..fb4a593ff 100644
--- a/library/LuaTools.cpp
+++ b/library/LuaTools.cpp
@@ -122,6 +122,9 @@ void DFHack::Lua::Push(lua_State *state, const df::coord2d &pos)

 void DFHack::Lua::GetVector(lua_State *state, std::vector<std::string> &pvec, int idx)
 {
+    // Allow usage of relative indexes in arg
+    idx = lua_absindex(state, idx);
+
     luaL_checktype(state, idx, LUA_TTABLE);
     lua_pushnil(state);   // first key
     while (lua_next(state, idx) != 0)

}

static bool try_autocomplete(color_ostream &con, const std::string &first, std::string &completed)
{
std::vector<std::string> commands, possible;

get_commands(con, commands);
for (auto &command : commands)
if (command.substr(0, first.size()) == first)
possible.push_back(command);
Expand Down