Fixed ACS scripts executing a function from another library that cause a division/modulus of zero from aborting the game #2910
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
A while ago, I discovered this issue from a Zandronum mod that caused Zandronum to crash, and only looked further into it recently. Currently in GZDoom, this issue causes a fatal error but no crash.
If an ACS script (let's pretend said script is defined in a library called "LIB1") executes a function that's defined in another library (let's also pretend this library is called "LIB2"), and that function causes a division/modulus of zero and forces the script to terminate, the game will abort because of this code:
The reason why this happens is because when a function from another library/module is executed,
DLevelScript::activeBehavior
is temporarily changed to that of the function. There are several or more p-codes that can change the script's state toSCRIPT_DivideBy0
orSCRIPT_ModulusBy0
, but they won't revertactiveBehavior
back tosavedActiveBehavior
, unlike when the script hits an unknown p-code. As a result,scriptptr
will be invalid when the code above executes.Adding this check just before the code snippet above fixes the error:
Here's a link to a minimal example WAD to test:
pukename test1
in the console executes an ACS script that terminates properly when encountering a division of zero.pukename test2
executes an ACS script that causes the game to abort instead without the fix.