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

Bug in how ULuaState::FromFProperty() handles map properties #70

Open
hanoixan opened this issue Sep 23, 2024 · 0 comments
Open

Bug in how ULuaState::FromFProperty() handles map properties #70

hanoixan opened this issue Sep 23, 2024 · 0 comments

Comments

@hanoixan
Copy link

hanoixan commented Sep 23, 2024

Using: Windows 11, Unreal Engine 5.2, Visual Studio 2022, LuaMachine 20240424

In LuaState.cpp:2196, in the handler for FMapProperty properties, it iterates over all map pairs with this code:

			uint8* ArrayKeyPtr = Helper.GetKeyPtr(MapIndex);
			uint8* ArrayValuePtr = Helper.GetValuePtr(MapIndex);
			bool bArrayItemSuccess = false;
			NewLuaTable.SetField(
				FromProperty(ArrayKeyPtr, MapProperty->KeyProp, bArrayItemSuccess, 0).ToString(),
				FromProperty(ArrayValuePtr, MapProperty->ValueProp, bArrayItemSuccess, 0));

After investigating a crash, I determined that the map item pair's FProperty::Offset_Internal is being computed by both GetValuePtr() and the MapProperty->ValueProp being used in the second FromProperty() call. Because the ArrayValuePtr from the first offset is being used to compute the second FromProperty, it overshoots the value offset and causes a crash.

The best workaround I can see is the following:

			uint8* ArrayPairPtr = Helper.GetPairPtr(MapIndex);
			bool bArrayItemSuccess = false;
			NewLuaTable.SetField(
				FromProperty(ArrayPairPtr, MapProperty->KeyProp, bArrayItemSuccess, 0).ToString(),
				FromProperty(ArrayPairPtr, MapProperty->ValueProp, bArrayItemSuccess, 0));

This uses the pair's ptr as the base of the offset math, which works because the key offset is 0. It's not possible for me to create a fork and PR at this time, so I'm just inlining the simple code change here for your consideration.

To reproduce this, simply run something like this:

// declare

USTRUCT(BlueprintType)
struct WAVESCENEOBJECTS_API FMyLuaFunctionContext
{
	GENERATED_BODY()

	UPROPERTY()
	TMap<FString, FLuaValue> Config;
};

// and then try to turn a populated instance of this into an FLuaValue:

FLuaValue TestMapSerialization(ULuaState& LuaState, FString& Key, FLuaValue& Value)
{
	FMyLuaFunctionContext Context;
	Context.Config.Add(Key, Value);

	FLuaValue ReturnValue = LuaState.StructToLuaValue(Context); // Crash
	return ReturnValue;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant