GetQuotedString() uses correct windows cmdline notation

- escaping of backslash and quotes
- fixes gh-312 for new cmdline parser algorithm (gh-307, gh-310)

Signed-off-by: Sergey G. Brester <info@sebres.de>
Reviewed-by: Tino Reichardt <milky-7zip@mcmilk.de>
This commit is contained in:
sebres
2023-04-06 20:00:56 +02:00
committed by Tino Reichardt
parent 19e97e4c68
commit eef99c5416
2 changed files with 38 additions and 3 deletions

View File

@@ -408,7 +408,8 @@ static UString GetQuotedReducedString(const UString &s)
UString s2 = s; UString s2 = s;
ReduceString(s2); ReduceString(s2);
s2.Replace(L"&", L"&&"); s2.Replace(L"&", L"&&");
return GetQuotedString(s2); s2.InsertAtFront(L'"'); s2 += L'"'; // quote without GetQuotedString (because it escapes now)
return s2;
} }
static void MyFormatNew_ReducedName(UString &s, const UString &name) static void MyFormatNew_ReducedName(UString &s, const UString &name)

View File

@@ -1806,10 +1806,44 @@ FString us2fs(const wchar_t *s)
// ---------------------------------------- // ----------------------------------------
UString GetQuotedString(const UString &s) UString GetQuotedString(const UString &src)
{ {
UString s2 ('\"'); UString s2 ('\"');
s2 += s; unsigned bcount = 0;
wchar_t c; const wchar_t *f = src.Ptr(), *s = f, *b = f;
// add string considering backslashes before quote (escape them):
while (1)
{
c = *s++;
switch (c)
{
case L'\\':
// a backslash - save the position and count them up to quote-char or regular char
if (!bcount) b = s-1;
bcount++;
break;
case L'\0':
// end of string (it is always quoted, so need to escape backslashes too):
case L'"':
// add part before backslash (and unescaped backslashes if some are there):
s2.AddFrom(f, (unsigned)(s - f - 1));
f = s;
if (bcount) {
// escape backslashes before quote (same count of BS again):
s2.AddFrom(b, (unsigned)(s - b - 1));
}
// done if end of string
if (c == L'\0') goto done;
// escape this quote char:
s2 += L"\\\"";
break;
default:
// a regular character, reset backslash counter
bcount = 0;
}
}
s2.AddFrom(f, (unsigned)(s - f - 1));
done:
s2 += '\"'; s2 += '\"';
return s2; return s2;
} }