Skip to content

Commit d7abc76

Browse files
Windows arg escape is handling internal quotes.
1 parent 0d5f117 commit d7abc76

File tree

1 file changed

+25
-14
lines changed

1 file changed

+25
-14
lines changed

src/windows/default_launcher.cpp

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,49 +29,59 @@ namespace windows
2929

3030
const auto has_space = ws.find(space) != basic_string_view<wchar_t>::npos;
3131
const auto quoted = (ws.front() == quote) && (ws.back() == quote);
32-
const auto needs_escape = has_space && !quoted ;
32+
const auto has_inner_quote = std::find(std::next(ws.begin()), std::prev(ws.end()), quote) != std::prev(ws.end());
33+
const auto needs_escape = (has_space && !quoted) || has_inner_quote;
3334

3435
if (!needs_escape)
3536
return ws.size();
36-
else
37-
return ws.size() + std::count(ws.begin(), ws.end(), quote) + 2u;
37+
else
38+
return ws.size() + std::count(ws.begin(), ws.end(), quote) + (quoted ? 2u : 0u);
3839
}
3940

4041

4142
std::size_t default_launcher::escape_argv_string(wchar_t * itr, std::size_t max_size,
4243
basic_string_view<wchar_t> ws)
4344
{
45+
constexpr static auto space = L' ';
46+
constexpr static auto quote = L'"';
47+
4448
const auto sz = escaped_argv_length(ws);
4549
if (sz > max_size)
4650
return 0u;
4751
if (ws.empty())
4852
{
49-
itr[0] = L'"';
50-
itr[1] = L'"';
53+
itr[0] = quote;
54+
itr[1] = quote;
5155
return 2u;
5256
}
5357

54-
const auto has_space = ws.find(L' ') != basic_string_view<wchar_t>::npos;
55-
const auto quoted = (ws.front() == L'"') && (ws.back() == L'"');
56-
const auto needs_escape = has_space && !quoted;
58+
59+
const auto has_space = ws.find(space) != basic_string_view<wchar_t>::npos;
60+
const auto quoted = (ws.front() == quote) && (ws.back() == quote);
61+
const auto has_inner_quote = std::find(std::next(ws.begin()), std::prev(ws.end()), quote) != std::prev(ws.end());
62+
const auto needs_escape = (has_space && !quoted) || has_inner_quotes;
5763

5864
if (!needs_escape)
5965
return std::copy(ws.begin(), ws.end(), itr) - itr;
6066

6167
if (sz < (2u + ws.size()))
6268
return 0u;
63-
69+
70+
71+
6472
const auto end = itr + sz;
6573
const auto begin = itr;
66-
*(itr ++) = L'"';
74+
if (!quoted)
75+
*(itr++) = quote;
76+
6777
for (auto wc : ws)
6878
{
69-
if (wc == L'"')
79+
if (wc == quote)
7080
*(itr++) = L'\\';
7181
*(itr++) = wc;
7282
}
73-
74-
*(itr ++) = L'"';
83+
if (!quoted)
84+
*(itr++) = quote;
7585
return itr - begin;
7686
}
7787

@@ -117,4 +127,5 @@ namespace windows
117127
}
118128
BOOST_PROCESS_V2_END_NAMESPACE
119129

120-
#endif
130+
#endif
131+

0 commit comments

Comments
 (0)