by _mental_ » Wed Mar 11, 2020 4:59 am
There is a potential size mismatch between C++ and ZScript structures.
It's caused by tail padding of native structures that isn't taken into account when calculating object sizes for scripting side.
So far,
FLineTraceData is certainly affected by this issue. It's native size is 120 bytes (Visual Studio, x64 target) while ZScript assumes 116 bytes only.
As the result,
this line overwrites four bytes that are not belonging to an instance of
FLineTraceData.
Spoiler: Samples
Spawning the following actor and restarting the game triggers heap corruption with VS x64 debug build.
Code: Select all
class LineTraceDataTest1 : Actor
{
FLineTraceData trace;
override void BeginPlay()
{
LineTrace(0, 0, 0, 0, 0, 0, 0, trace);
}
}
Spawning the following actor outputs
"expected: 1234567890, actual: 0"
Code: Select all
class LineTraceDataTest2 : Actor
{
FLineTraceData trace;
int num;
override void BeginPlay()
{
int std = 1234567890;
num = std;
LineTrace(0, 0, 0, 0, 0, 0, 0, trace);
console.printf("expected: %i, actual: %i", std, num);
}
}
It seems we have no way to declare relation between such
native and
scripting definitions.
There is a potential size mismatch between C++ and ZScript structures.
It's caused by tail padding of native structures that isn't taken into account when calculating object sizes for scripting side.
So far, [b]FLineTraceData[/b] is certainly affected by this issue. It's native size is 120 bytes (Visual Studio, x64 target) while ZScript assumes 116 bytes only.
As the result, [url=https://github.com/coelckers/gzdoom/blob/920b322d72bb69dfa29f1815eec4a69eb83609a5/src/playsim/p_map.cpp#L4815]this line[/url] overwrites four bytes that are not belonging to an instance of [b]FLineTraceData[/b].
[spoiler=Samples]Spawning the following actor and restarting the game triggers heap corruption with VS x64 debug build.
[code]class LineTraceDataTest1 : Actor
{
FLineTraceData trace;
override void BeginPlay()
{
LineTrace(0, 0, 0, 0, 0, 0, 0, trace);
}
}[/code]
Spawning the following actor outputs [i]"expected: 1234567890, actual: 0"[/i]
[code]class LineTraceDataTest2 : Actor
{
FLineTraceData trace;
int num;
override void BeginPlay()
{
int std = 1234567890;
num = std;
LineTrace(0, 0, 0, 0, 0, 0, 0, trace);
console.printf("expected: %i, actual: %i", std, num);
}
}[/code][/spoiler]
It seems we have no way to declare relation between such [url=https://github.com/coelckers/gzdoom/blob/7351a76404dc59b18681f4ac96249e39666b170e/src/playsim/p_linetracedata.h#L9]native[/url] and [url=https://github.com/coelckers/gzdoom/blob/9e5444f8ae48564ab6e1cc24f19ec561a0f7ea29/wadsrc/static/zscript/actors/actor.zs#L36]scripting[/url] definitions.