From c2ee40181288ee486b179098e62da3494b49ee65 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Thu, 26 Dec 2019 07:03:35 -0800 Subject: [PATCH] Fixed opening workspace paths containing '/../' or '/./' --- BeefySysLib/platform/win/Platform.cpp | 52 ++++++++++++++++++++---- IDE/src/FileEditData.bf | 1 + IDE/src/IDEApp.bf | 3 ++ IDE/src/ui/MemoryPanel.bf | 1 + IDE/src/util/Curl.bf | 1 + IDEHelper/Compiler/BfModuleTypeUtils.cpp | 2 +- 6 files changed, 50 insertions(+), 10 deletions(-) diff --git a/BeefySysLib/platform/win/Platform.cpp b/BeefySysLib/platform/win/Platform.cpp index 2238d677..924ed19f 100644 --- a/BeefySysLib/platform/win/Platform.cpp +++ b/BeefySysLib/platform/win/Platform.cpp @@ -3150,18 +3150,52 @@ BFP_EXPORT void BFP_CALLTYPE BfpFile_GetActualPath(const char* inPathC, char* ou { String inPath = inPathC; String outPath; + + // Check for '/../' backtracking - handle those first + { + int i = 0; + int32 lastComponentStart = -1; + String subName; + + while (i < inPath.mLength) + { + // skip until path separator + while ((i < inPath.mLength) && (inPath[i] != DIR_SEP_CHAR) && (inPath[i] != DIR_SEP_CHAR_ALT)) + ++i; + + if (lastComponentStart != -1) + { + if ((i - lastComponentStart == 2) && (inPath[lastComponentStart] == '.') && (inPath[lastComponentStart + 1] == '.')) + { + // Backtrack + while ((lastComponentStart > 0) && + ((inPath[lastComponentStart - 1] == DIR_SEP_CHAR) || (inPath[lastComponentStart - 1] == DIR_SEP_CHAR_ALT))) + lastComponentStart--; + while ((lastComponentStart > 0) && (inPath[lastComponentStart - 1] != DIR_SEP_CHAR) && (inPath[lastComponentStart - 1] != DIR_SEP_CHAR_ALT)) + lastComponentStart--; + inPath.Remove(lastComponentStart, i - lastComponentStart + 1); + i = lastComponentStart; + continue; + } + else if ((i - lastComponentStart == 1) && (inPath[lastComponentStart] == '.')) + { + inPath.Remove(lastComponentStart, i - lastComponentStart + 1); + i = lastComponentStart; + continue; + } + } - // This is quite involved, but the meat is SHGetFileInfo - //const wchar8_t kSeparator = L'\\'; - // copy input string because we'll be temporary modifying it in place - //size_t length = wcslen(path); - //wchar8_t buffer[MAX_PATH]; - //memcpy( buffer, path, (length+1) * sizeof(path[0]) ); + ++i; + // Ignore multiple slashes in a row + while ((i < inPath.mLength) && ((inPath[i] == DIR_SEP_CHAR) || (inPath[i] == DIR_SEP_CHAR_ALT))) + ++i; + + lastComponentStart = i; + } + } int32 i = 0; - - //UTF16String result; - + // for network paths (\\server\share\RestOfPath), getting the display // name mangles it into unusable form (e.g. "\\server\share" turns // into "share on server (server)"). So detect this case and just skip diff --git a/IDE/src/FileEditData.bf b/IDE/src/FileEditData.bf index f9c84c30..c2a4041b 100644 --- a/IDE/src/FileEditData.bf +++ b/IDE/src/FileEditData.bf @@ -7,6 +7,7 @@ using System.Security.Cryptography; namespace IDE { + [AllowDuplicates] public enum LineEndingKind { Lf, // \n diff --git a/IDE/src/IDEApp.bf b/IDE/src/IDEApp.bf index 67ac2600..d7622a1d 100644 --- a/IDE/src/IDEApp.bf +++ b/IDE/src/IDEApp.bf @@ -804,6 +804,9 @@ namespace IDE #if !CLI if (mDeferredOpenFileName != null) { + String prevFilePath = scope .(mDeferredOpenFileName); + mDeferredOpenFileName.Clear(); + Path.GetActualPathName(prevFilePath, mDeferredOpenFileName); OpenWorkspace(mDeferredOpenFileName); DeleteAndNullify!(mDeferredOpenFileName); return; diff --git a/IDE/src/ui/MemoryPanel.bf b/IDE/src/ui/MemoryPanel.bf index 21464bbd..c534d7b5 100644 --- a/IDE/src/ui/MemoryPanel.bf +++ b/IDE/src/ui/MemoryPanel.bf @@ -36,6 +36,7 @@ namespace IDE.ui public class MemoryRepListView : DarkListView { + [AllowDuplicates] public enum RepType { // integer types (dual signed/unsigned reps) diff --git a/IDE/src/util/Curl.bf b/IDE/src/util/Curl.bf index 292ff5ff..22a04a96 100644 --- a/IDE/src/util/Curl.bf +++ b/IDE/src/util/Curl.bf @@ -14,6 +14,7 @@ namespace CURL const int32 cOptionFunction = 20000; const int32 cOptionOffT = 30000; + [AllowDuplicates] public enum Option { /* This is the FILE * or void * the regular output should be written to. */ diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 00600c48..6f7119dc 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -2992,7 +2992,7 @@ bool BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy } else if ((typeInstance->mCustomAttributes == NULL) || (typeInstance->mCustomAttributes->Get(mCompiler->mAllowDuplicatesAttributeTypeDef) == NULL)) { - auto error = Warn(0, StrFormat("Enum value '%lld' for field '%s' is not unique", foreignConst->mInt64, fieldDef->mName.c_str()), fieldDef->GetRefNode(), true); + auto error = Warn(0, StrFormat("Enum value '%lld' for field '%s' is not unique. Considering adding [AllowDuplicates] to the type declaration.", foreignConst->mInt64, fieldDef->mName.c_str()), fieldDef->GetRefNode(), true); if (error != NULL) mCompiler->mPassInstance->MoreInfo(StrFormat("This value was previously used for field '%s'", (*fieldDefPtr)->mName.c_str()), (*fieldDefPtr)->GetRefNode()); }