From 9e3c413c918367cf44a1072ce727d487375b6b18 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Wed, 13 Jan 2021 00:22:52 +0100 Subject: [PATCH] Fix crash when using Byte, Int16 or UInt16 as VS parameters --- Source/Engine/Core/Types/Variant.cpp | 25 ++++++++++++++++++++++++- Source/Engine/Serialization/Stream.cpp | 18 +++++++++++++++--- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/Source/Engine/Core/Types/Variant.cpp b/Source/Engine/Core/Types/Variant.cpp index 62c791875..db71c2f77 100644 --- a/Source/Engine/Core/Types/Variant.cpp +++ b/Source/Engine/Core/Types/Variant.cpp @@ -2612,7 +2612,8 @@ Variant Variant::Lerp(const Variant& a, const Variant& b, float alpha) void Variant::AllocStructure() { - const ScriptingTypeHandle typeHandle = Scripting::FindScriptingType(StringAnsiView(Type.TypeName)); + const StringAnsiView typeName(Type.TypeName); + const ScriptingTypeHandle typeHandle = Scripting::FindScriptingType(typeName); if (typeHandle) { const ScriptingType& type = typeHandle.GetType(); @@ -2620,8 +2621,26 @@ void Variant::AllocStructure() AsBlob.Data = Allocator::Allocate(AsBlob.Length); type.Struct.Ctor(AsBlob.Data); } + else if (typeName == "System.Byte") + { + // Hack for byte + AsBlob.Length = 1; + AsBlob.Data = Allocator::Allocate(AsBlob.Length); + *((byte*)AsBlob.Data) = 0; + } + else if (typeName == "System.Int16" || typeName == "System.UInt16") + { + // Hack for 16bit int + AsBlob.Length = 2; + AsBlob.Data = Allocator::Allocate(AsBlob.Length); + *((int16*)AsBlob.Data) = 0; + } else { + if (typeName.Length() != 0) + { + LOG(Warning, "Missing scripting type \'{0}\'", String(typeName.Get())); + } AsBlob.Data = nullptr; AsBlob.Length = 0; } @@ -2637,6 +2656,10 @@ void Variant::CopyStructure(void* src) auto& type = typeHandle.GetType(); type.Struct.Copy(AsBlob.Data, src); } + else + { + Platform::MemoryCopy(AsBlob.Data, src, AsBlob.Length); + } } } diff --git a/Source/Engine/Serialization/Stream.cpp b/Source/Engine/Serialization/Stream.cpp index e10ae9fd6..2d3ef8b30 100644 --- a/Source/Engine/Serialization/Stream.cpp +++ b/Source/Engine/Serialization/Stream.cpp @@ -4,8 +4,9 @@ #include "WriteStream.h" #include "Engine/Core/Types/CommonValue.h" #include "Engine/Core/Types/Variant.h" -#include "Engine/Content/Asset.h" #include "Engine/Core/Collections/Dictionary.h" +#include "Engine/Content/Asset.h" +#include "Engine/Debug/DebugLog.h" #include "Engine/Scripting/ScriptingObject.h" #include "Engine/Scripting/ScriptingObjectReference.h" @@ -330,8 +331,19 @@ void ReadStream::ReadVariant(Variant* data) { int32 length; ReadInt32(&length); - ASSERT(data->AsBlob.Length == length); - ReadBytes(data->AsBlob.Data, length); + if (data->AsBlob.Length == length) + { + ReadBytes(data->AsBlob.Data, length); + } + else + { + LOG(Error, "Invalid Variant {2} data length {0}. Expected {1} bytes from stream.", data->AsBlob.Length, length, data->Type.ToString()); + + // Skip those bytes + void* ptr = Allocator::Allocate(length); + ReadBytes(ptr, length); + Allocator::Free(ptr); + } break; } case VariantType::Blob: