diff --git a/Source/Engine/Core/Types/Variant.h b/Source/Engine/Core/Types/Variant.h index 0c8f06f15..df8c4aeea 100644 --- a/Source/Engine/Core/Types/Variant.h +++ b/Source/Engine/Core/Types/Variant.h @@ -270,8 +270,8 @@ public: explicit operator float() const; explicit operator double() const; explicit operator void*() const; - explicit operator StringView() const; - explicit operator StringAnsiView() const; + explicit operator StringView() const; // Returned StringView, if not empty, is guaranteed to point to a null terminated buffer. + explicit operator StringAnsiView() const; // Returned StringView, if not empty, is guaranteed to point to a null terminated buffer. explicit operator ScriptingObject*() const; explicit operator struct _MonoObject*() const; explicit operator Asset*() const; diff --git a/Source/Engine/Platform/Windows/WindowsClipboard.cpp b/Source/Engine/Platform/Windows/WindowsClipboard.cpp index baba81e8f..056d187c6 100644 --- a/Source/Engine/Platform/Windows/WindowsClipboard.cpp +++ b/Source/Engine/Platform/Windows/WindowsClipboard.cpp @@ -23,9 +23,12 @@ void WindowsClipboard::Clear() void WindowsClipboard::SetText(const StringView& text) { - const int32 size = (text.Length() + 1) * sizeof(Char); - const HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, size); - Platform::MemoryCopy(GlobalLock(hMem), String(text).GetText(), size); + const int32 sizeWithoutNull = text.Length() * sizeof(Char); + const HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, sizeWithoutNull + sizeof(Char)); + + Char* pMem = static_cast(GlobalLock(hMem)); + Platform::MemoryCopy(pMem, text.GetNonTerminatedText(), sizeWithoutNull); + Platform::MemorySet(pMem + text.Length(), sizeof(Char), 0); GlobalUnlock(hMem); OpenClipboard(nullptr); diff --git a/Source/Engine/Platform/Windows/WindowsPlatform.cpp b/Source/Engine/Platform/Windows/WindowsPlatform.cpp index 6849c0ac8..ccd514c11 100644 --- a/Source/Engine/Platform/Windows/WindowsPlatform.cpp +++ b/Source/Engine/Platform/Windows/WindowsPlatform.cpp @@ -1111,7 +1111,7 @@ int32 WindowsPlatform::RunProcess(const StringView& cmdLine, const StringView& w // Create the process PROCESS_INFORMATION procInfo; - if (!CreateProcessW(nullptr, const_cast(String(cmdLine).GetText()), nullptr, nullptr, TRUE, dwCreationFlags, (LPVOID)environmentStr, String(workingDir).GetText(), &startupInfoEx.StartupInfo, &procInfo)) + if (!CreateProcessW(nullptr, const_cast(String(cmdLine).GetText()), nullptr, nullptr, TRUE, dwCreationFlags, (LPVOID)environmentStr, workingDir.HasChars() ? workingDir.Get() : nullptr, &startupInfoEx.StartupInfo, &procInfo)) { LOG(Warning, "Cannot start process '{0}'. Error code: 0x{1:x}", cmdLine, static_cast(GetLastError())); goto ERROR_EXIT; diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs index a071e161c..553cab3aa 100644 --- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs +++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs @@ -166,7 +166,7 @@ namespace Flax.Build.Bindings if (typeInfo.Type == "String") return $"(StringView){value}"; if (typeInfo.IsPtr && typeInfo.IsConst && typeInfo.Type == "Char") - return $"((StringView){value}).GetNonTerminatedText()"; // This is a bug, as we need a null-terminated strig here. Any idea how to fix it? + return $"((StringView){value}).GetNonTerminatedText()"; // (StringView)Variant, if not empty, is guaranteed to point to a null-terminated buffer. if (typeInfo.Type == "AssetReference" || typeInfo.Type == "WeakAssetReference") return $"ScriptingObject::Cast<{typeInfo.GenericArgs[0].Type}>((Asset*){value})"; if (typeInfo.Type == "ScriptingObjectReference" || typeInfo.Type == "SoftObjectReference")