From f62c77c35ce568a9ff87111dfc0b1e28ece60d0f Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Mon, 21 Oct 2024 12:37:55 +0200 Subject: [PATCH] Fix game deployment if output name contains invalid path characters #3004 --- .../Platform/Windows/WindowsPlatformTools.cpp | 5 ++-- Source/Editor/Utilities/EditorUtilities.cpp | 28 +++++++++++++++++-- Source/Editor/Utilities/EditorUtilities.h | 7 +++++ Source/Engine/Tools/ModelTool/ModelTool.cpp | 6 +--- 4 files changed, 37 insertions(+), 9 deletions(-) diff --git a/Source/Editor/Cooker/Platform/Windows/WindowsPlatformTools.cpp b/Source/Editor/Cooker/Platform/Windows/WindowsPlatformTools.cpp index 9d3280f4b..5259ca2df 100644 --- a/Source/Editor/Cooker/Platform/Windows/WindowsPlatformTools.cpp +++ b/Source/Editor/Cooker/Platform/Windows/WindowsPlatformTools.cpp @@ -511,11 +511,12 @@ bool WindowsPlatformTools::OnDeployBinaries(CookingData& data) // Rename app const String newName = EditorUtilities::GetOutputName(); - if (newName != StringUtils::GetFileNameWithoutExtension(files[0])) + const StringView oldName = StringUtils::GetFileNameWithoutExtension(files[0]); + if (newName != oldName) { if (FileSystem::MoveFile(data.NativeCodeOutputPath / newName + TEXT(".exe"), files[0], true)) { - data.Error(TEXT("Failed to change output executable name.")); + data.Error(String::Format(TEXT("Failed to change output executable name from '{}' to '{}'."), oldName, newName)); return true; } } diff --git a/Source/Editor/Utilities/EditorUtilities.cpp b/Source/Editor/Utilities/EditorUtilities.cpp index 0fc614af5..e3f521437 100644 --- a/Source/Editor/Utilities/EditorUtilities.cpp +++ b/Source/Editor/Utilities/EditorUtilities.cpp @@ -5,10 +5,11 @@ #include "Engine/Platform/File.h" #include "Engine/Platform/FileSystem.h" #include "Engine/Platform/CreateProcessSettings.h" -#include "Engine/Core/Log.h" #include "Engine/Graphics/Textures/TextureData.h" #include "Engine/Graphics/PixelFormatExtensions.h" #include "Engine/Tools/TextureTool/TextureTool.h" +#include "Engine/Core/Log.h" +#include "Engine/Core/Types/StringBuilder.h" #include "Engine/Core/Config/GameSettings.h" #include "Engine/Core/Config/BuildSettings.h" #include "Engine/Content/Content.h" @@ -28,6 +29,7 @@ String EditorUtilities::GetOutputName() outputName.Replace(TEXT("${COMPANY_NAME}"), *gameSettings->CompanyName, StringSearchCase::IgnoreCase); if (outputName.IsEmpty()) outputName = TEXT("FlaxGame"); + ValidatePathChars(outputName, 0); return outputName; } @@ -360,6 +362,28 @@ bool EditorUtilities::IsInvalidPathChar(Char c) return false; } +void EditorUtilities::ValidatePathChars(String& filename, char invalidCharReplacement) +{ + if (invalidCharReplacement == 0) + { + StringBuilder result; + for (int32 i = 0; i < filename.Length(); i++) + { + if (!IsInvalidPathChar(filename[i])) + result.Append(filename[i]); + } + filename = result.ToString(); + } + else + { + for (int32 i = 0; i < filename.Length(); i++) + { + if (IsInvalidPathChar(filename[i])) + filename[i] = invalidCharReplacement; + } + } +} + bool EditorUtilities::ReplaceInFiles(const String& folderPath, const Char* searchPattern, DirectorySearchOption searchOption, const String& findWhat, const String& replaceWith) { Array files; @@ -391,7 +415,7 @@ bool EditorUtilities::ReplaceInFile(const StringView& file, const Dictionarytrue if the given character cannot be used as a path because it is illegal character; otherwise, false. static bool IsInvalidPathChar(Char c); + /// + /// Validates path characters and replaces any incorrect ones. + /// + /// The input and output filename string to process. + /// The character to use for replacement for any invalid characters in the path. Use '0' to remove them. + static void ValidatePathChars(String& filename, char invalidCharReplacement = ' '); + /// /// Replaces the given text with other one in the files. /// diff --git a/Source/Engine/Tools/ModelTool/ModelTool.cpp b/Source/Engine/Tools/ModelTool/ModelTool.cpp index 408fcb887..91c2edc06 100644 --- a/Source/Engine/Tools/ModelTool/ModelTool.cpp +++ b/Source/Engine/Tools/ModelTool/ModelTool.cpp @@ -1080,11 +1080,7 @@ void TrySetupMaterialParameter(MaterialInstance* instance, Span par String GetAdditionalImportPath(const String& autoImportOutput, Array& importedFileNames, const String& name) { String filename = name; - for (int32 j = filename.Length() - 1; j >= 0; j--) - { - if (EditorUtilities::IsInvalidPathChar(filename[j])) - filename[j] = ' '; - } + EditorUtilities::ValidatePathChars(filename); if (importedFileNames.Contains(filename)) { int32 counter = 1;