Browse Source

Bug fix: Incorrect escaping of values in single-quoted patterns in custom commands + Unifying escaping of shell command arguments

Source commit: 9a8ae65931380050e988b295b0ddd818c11a08a4
Martin Prikryl 3 years ago
parent
commit
b5f0f2cdb8

+ 29 - 12
source/core/Common.cpp

@@ -290,27 +290,38 @@ UnicodeString RemoveSuffix(const UnicodeString & Str, const UnicodeString & Suff
   return Result;
 }
 //---------------------------------------------------------------------------
-UnicodeString DelimitStr(UnicodeString Str, UnicodeString Chars)
+UnicodeString DelimitStr(const UnicodeString & Str, wchar_t Quote)
 {
-  for (int i = 1; i <= Str.Length(); i++)
+  UnicodeString SpecialChars;
+  if (Quote != L'\'')
   {
-    if (Str.IsDelimiter(Chars, i))
+    SpecialChars = L"$\\";
+    if (Quote == L'"')
     {
-      Str.Insert(L"\\", i);
+      SpecialChars += L"`\"";
+    }
+  }
+  UnicodeString Result(Str);
+  for (int i = 1; i <= Result.Length(); i++)
+  {
+    if (Result.IsDelimiter(SpecialChars, i))
+    {
+      Result.Insert(L"\\", i);
       i++;
     }
   }
-  return Str;
+  if (Result.IsDelimiter(L"-", 1))
+  {
+    Result.Insert(L"./", 1);
+  }
+  return Result;
 }
 //---------------------------------------------------------------------------
-UnicodeString ShellDelimitStr(UnicodeString Str, wchar_t Quote)
+UnicodeString ShellQuoteStr(const UnicodeString & Str)
 {
-  UnicodeString Chars = L"$\\";
-  if (Quote == L'"')
-  {
-    Chars += L"`\"";
-  }
-  return DelimitStr(Str, Chars);
+  wchar_t Quote = L'"';
+  UnicodeString QuoteStr(Quote);
+  return QuoteStr + DelimitStr(Str, Quote) + QuoteStr;
 }
 //---------------------------------------------------------------------------
 UnicodeString ExceptionLogString(Exception *E)
@@ -2976,6 +2987,12 @@ void __fastcall AddToList(UnicodeString & List, const UnicodeString & Value, con
   }
 }
 //---------------------------------------------------------------------------
+void AddToShellFileListCommandLine(UnicodeString & List, const UnicodeString & Value)
+{
+  UnicodeString Arg = ShellQuoteStr(Value);
+  AddToList(List, Arg, L" ");
+}
+//---------------------------------------------------------------------------
 bool __fastcall IsWinVista()
 {
   // Vista is 6.0

+ 3 - 2
source/core/Common.h

@@ -56,8 +56,8 @@ UnicodeString CopyToChars(const UnicodeString & Str, int & From, UnicodeString C
   wchar_t * Delimiter = NULL, bool DoubleDelimiterEscapes = false);
 UnicodeString CopyToChar(const UnicodeString & Str, wchar_t Ch, bool Trim);
 UnicodeString RemoveSuffix(const UnicodeString & Str, const UnicodeString & Suffix, bool RemoveNumbersAfterSuffix = false);
-UnicodeString DelimitStr(UnicodeString Str, UnicodeString Chars);
-UnicodeString ShellDelimitStr(UnicodeString Str, wchar_t Quote);
+UnicodeString DelimitStr(const UnicodeString & Str, wchar_t Quote = L'"');
+UnicodeString ShellQuoteStr(const UnicodeString & Str);
 UnicodeString ExceptionLogString(Exception *E);
 UnicodeString __fastcall MainInstructions(const UnicodeString & S);
 bool __fastcall HasParagraphs(const UnicodeString & S);
@@ -137,6 +137,7 @@ bool __fastcall CutToken(UnicodeString & Str, UnicodeString & Token,
 bool __fastcall CutTokenEx(UnicodeString & Str, UnicodeString & Token,
   UnicodeString * RawToken = NULL, UnicodeString * Separator = NULL);
 void __fastcall AddToList(UnicodeString & List, const UnicodeString & Value, const UnicodeString & Delimiter);
+void AddToShellFileListCommandLine(UnicodeString & List, const UnicodeString & Value);
 bool __fastcall IsWinVista();
 bool __fastcall IsWin7();
 bool __fastcall IsWin8();

+ 1 - 1
source/core/FileMasks.cpp

@@ -1038,7 +1038,7 @@ UnicodeString __fastcall TCustomCommand::Complete(const UnicodeString & Command,
 //---------------------------------------------------------------------------
 void __fastcall TCustomCommand::DelimitReplacement(UnicodeString & Replacement, wchar_t Quote)
 {
-  Replacement = ShellDelimitStr(Replacement, Quote);
+  Replacement = DelimitStr(Replacement, Quote);
 }
 //---------------------------------------------------------------------------
 void __fastcall TCustomCommand::Validate(const UnicodeString & Command)

+ 1 - 11
source/core/ScpFileSystem.cpp

@@ -476,16 +476,6 @@ bool __fastcall TSCPFileSystem::IsCapable(int Capability) const
   }
 }
 //---------------------------------------------------------------------------
-UnicodeString __fastcall TSCPFileSystem::DelimitStr(UnicodeString Str)
-{
-  if (!Str.IsEmpty())
-  {
-    Str = ::DelimitStr(Str, L"\\`$\"");
-    if (Str[1] == L'-') Str = L"./"+Str;
-  }
-  return Str;
-}
-//---------------------------------------------------------------------------
 void __fastcall TSCPFileSystem::EnsureLocation()
 {
   if (!FCachedDirectoryChange.IsEmpty())
@@ -961,7 +951,7 @@ void __fastcall TSCPFileSystem::ChangeDirectory(const UnicodeString Directory)
   if (!Directory.IsEmpty() &&
       ((Directory[1] != L'~') || (Directory.SubString(1, 2) == L"~ ")))
   {
-    ToDir = L"\"" + DelimitStr(Directory) + L"\"";
+    ToDir = ShellQuoteStr(Directory);
   }
   else
   {

+ 0 - 1
source/core/ScpFileSystem.h

@@ -110,7 +110,6 @@ private:
   void __fastcall ClearAlias(UnicodeString Alias);
   void __fastcall CustomReadFile(const UnicodeString FileName,
     TRemoteFile *& File, TRemoteFile * ALinkedByFile);
-  static UnicodeString __fastcall DelimitStr(UnicodeString Str);
   void __fastcall DetectReturnVar();
   bool __fastcall IsLastLine(UnicodeString & Line);
   static bool __fastcall IsTotalListingLine(const UnicodeString Line);

+ 1 - 6
source/core/Terminal.cpp

@@ -4222,12 +4222,7 @@ void __fastcall TTerminal::CustomCommandOnFiles(UnicodeString Command,
 
       if (!Dir || FLAGSET(Params, ccApplyToDirectories))
       {
-        if (!FileList.IsEmpty())
-        {
-          FileList += L" ";
-        }
-
-        FileList += L"\"" + ShellDelimitStr(Files->Strings[i], L'"') + L"\"";
+        AddToShellFileListCommandLine(FileList, Files->Strings[i]);
       }
     }