Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure sufficient stack size for Lua values #4482

Merged
merged 4 commits into from Jul 19, 2022

Conversation

BMagnu
Copy link
Member

@BMagnu BMagnu commented Jul 9, 2022

Fixes #4287.
Until now, when we pushed values to the Lua stack from C, we never checked that the stack allocated by the lua interpreter had space available, let alone reserve new space.
This PR now adds checks on each push to the stack. While this might slightly degrade performance, it is a necessary check.
To avoid unnecessary checks, there is infrastructure in place to pre-reserve multiple stack spaces and pass the information about guaranteed sufficient stack pre-allocation to the value push, enabling omission of the check in these instances.

@BMagnu BMagnu added fix A fix for bugs, not-a-bugs, and/or regressions. scripting A feature or issue related to LUA scripting labels Jul 9, 2022
@BMagnu BMagnu added this to the Release 22.2 milestone Jul 9, 2022
@BMagnu BMagnu requested a review from asarium as a code owner July 9, 2022 23:54
@Goober5000 Goober5000 added this to In Progress in Bug Triage via automation Jul 10, 2022
Copy link
Contributor

@Goober5000 Goober5000 left a comment

Choose a reason for hiding this comment

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

Looks ok, I guess, but I defer to @asarium.

Edit: He says he won't be able to look at this until Monday.

@@ -101,7 +101,7 @@ class UniqueLuaReference {
* @brief Pushes the referenced value onto the stack.
* @param thread A specific thread state to push the value to. nullptr for the default state of this reference
*/
void pushValue(lua_State* thread) const;
void pushValue(lua_State* thread, bool guaranteeStack = false) const;
Copy link
Member

Choose a reason for hiding this comment

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

Adding a "random" boolean variable to this call would, in my opinion, make this API confusing to use. Furthermore, since you do the relevant call before the Lua function anyway, I do not think adding this parameter (and also to LuaValue) is necessary.

Copy link
Member Author

@BMagnu BMagnu Jul 18, 2022

Choose a reason for hiding this comment

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

While I make this call in this instance, it is necessary to do this for every case this function is called. Which is from quite a lot of places. You have to compromise at some point, either by asking the coder to always manually ensure the stack size before each call of pushValue (both for this and value), or eat the performance penalty of doing the allocation / check more than once if you push many values, or have the option to pass this as the API parameter.
Since I would really not want to have to rely on the programmer to always remember manually ensuring the stack size, it's basically a question of "do we want to waste performance in a low level function" vs "do we want one more parameter in the low level function".
IMO, with this case we should pick performance over pretty API.

Copy link
Member

Choose a reason for hiding this comment

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

Ok, I can understand that reasoning.
One thing I noticed though is that the current name suggests that a true value will trigger the lua_checkstack call but that is not the case. Maybe a parameter name like checkStack would be more appropriate here.

Copy link
Member Author

Choose a reason for hiding this comment

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

ok, clarified variable name and added documentation

code/scripting/lua/LuaReference.cpp Show resolved Hide resolved
@@ -101,7 +101,7 @@ class UniqueLuaReference {
* @brief Pushes the referenced value onto the stack.
* @param thread A specific thread state to push the value to. nullptr for the default state of this reference
*/
void pushValue(lua_State* thread) const;
void pushValue(lua_State* thread, bool guaranteeStack = false) const;
Copy link
Member

Choose a reason for hiding this comment

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

Ok, I can understand that reasoning.
One thing I noticed though is that the current name suggests that a true value will trigger the lua_checkstack call but that is not the case. Maybe a parameter name like checkStack would be more appropriate here.

@BMagnu BMagnu enabled auto-merge (squash) July 19, 2022 09:57
@BMagnu BMagnu merged commit 2b2333f into scp-fs2open:master Jul 19, 2022
Bug Triage automation moved this from In Progress to Closed Jul 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
fix A fix for bugs, not-a-bugs, and/or regressions. scripting A feature or issue related to LUA scripting
Projects
Development

Successfully merging this pull request may close these issues.

Lua SEXPs with large numbers of arguments cause heap corruption
3 participants