Skip to content

Commit b8a447a

Browse files
Reworked arg handling on windows (v2)
1 parent d7abc76 commit b8a447a

File tree

2 files changed

+25
-31
lines changed

2 files changed

+25
-31
lines changed

src/windows/default_launcher.cpp

Lines changed: 11 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -24,54 +24,34 @@ namespace windows
2424
if (ws.empty())
2525
return 2u; // just quotes
2626

27-
constexpr static auto space = L' ';
2827
constexpr static auto quote = L'"';
29-
30-
const auto has_space = ws.find(space) != basic_string_view<wchar_t>::npos;
31-
const auto quoted = (ws.front() == quote) && (ws.back() == quote);
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;
34-
35-
if (!needs_escape)
36-
return ws.size();
37-
else
38-
return ws.size() + std::count(ws.begin(), ws.end(), quote) + (quoted ? 2u : 0u);
28+
const auto needs_quotes = ws.find_first_of(L" \t") != std::basic_string_view<wchar_t>::npos;
29+
return ws.size() + std::count(ws.begin(), ws.end(), quote) + (needs_quotes ? 2u : 0u);
3930
}
4031

4132

4233
std::size_t default_launcher::escape_argv_string(wchar_t * itr, std::size_t max_size,
4334
basic_string_view<wchar_t> ws)
4435
{
45-
constexpr static auto space = L' ';
4636
constexpr static auto quote = L'"';
47-
48-
const auto sz = escaped_argv_length(ws);
37+
const auto needs_quotes = ws.find_first_of(L" \t") != basic_string_view<wchar_t>::npos;
38+
const auto need_escapes = std::count(ws.begin(), ws.end(), quote);
39+
40+
const auto sz = ws.size() + needed_escapes + (needs_quotes ? 2u : 0u);
41+
4942
if (sz > max_size)
5043
return 0u;
44+
5145
if (ws.empty())
5246
{
5347
itr[0] = quote;
5448
itr[1] = quote;
5549
return 2u;
5650
}
5751

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;
63-
64-
if (!needs_escape)
65-
return std::copy(ws.begin(), ws.end(), itr) - itr;
66-
67-
if (sz < (2u + ws.size()))
68-
return 0u;
69-
70-
71-
7252
const auto end = itr + sz;
7353
const auto begin = itr;
74-
if (!quoted)
54+
if (needs_quotes)
7555
*(itr++) = quote;
7656

7757
for (auto wc : ws)
@@ -80,7 +60,8 @@ namespace windows
8060
*(itr++) = L'\\';
8161
*(itr++) = wc;
8262
}
83-
if (!quoted)
63+
64+
if (needs_quotes)
8465
*(itr++) = quote;
8566
return itr - begin;
8667
}

test/v2/process.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ BOOST_AUTO_TEST_CASE(print_args_spec_out)
257257
asio::connect_pipe(rp, wp);
258258

259259

260-
bpv::process proc(ctx, pth, {"print-args", "&foo", "&", "|bar", "\"", "#foobar"}, bpv::process_stdio{/*in*/{},/*out*/wp, /*err*/ nullptr});
260+
bpv::process proc(ctx, pth, {"print-args", "&foo", "&", "", "\"\"", "\\\"", "|bar", "\"", "#foobar"}, bpv::process_stdio{/*in*/{},/*out*/wp, /*err*/ nullptr});
261261

262262
wp.close();
263263
asio::streambuf st;
@@ -288,6 +288,18 @@ BOOST_AUTO_TEST_CASE(print_args_spec_out)
288288
trim_end(line);
289289
BOOST_CHECK_EQUAL("&", line);
290290

291+
BOOST_CHECK(std::getline(is, line));
292+
trim_end(line);
293+
BOOST_CHECK_EQUAL("", line);
294+
295+
BOOST_CHECK(std::getline(is, line));
296+
trim_end(line);
297+
BOOST_CHECK_EQUAL("\"\"", line);
298+
299+
BOOST_CHECK(std::getline(is, line));
300+
trim_end(line);
301+
BOOST_CHECK_EQUAL("\\\"", line);
302+
291303
BOOST_CHECK(std::getline(is, line));
292304
trim_end(line);
293305
BOOST_CHECK_EQUAL("|bar", line);
@@ -296,6 +308,7 @@ BOOST_AUTO_TEST_CASE(print_args_spec_out)
296308
trim_end(line);
297309
BOOST_CHECK_EQUAL("\"", line);
298310

311+
299312
BOOST_CHECK(std::getline(is, line));
300313
trim_end(line);
301314
BOOST_CHECK_EQUAL("#foobar", line);

0 commit comments

Comments
 (0)