Skip to content

Commit 50be009

Browse files
authored
Merge pull request #8641 from diffblue/shell-quote-fix
fix shell quoting
2 parents 3c915eb + 9b0a0c3 commit 50be009

File tree

2 files changed

+41
-22
lines changed

2 files changed

+41
-22
lines changed

src/util/run.cpp

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,17 @@ Date: August 2012
2727
// clang-format on
2828
#else
2929

30-
#include <cstring>
31-
#include <cerrno>
32-
#include <cstdio>
33-
#include <cstdlib>
34-
35-
#include <fcntl.h>
36-
#include <signal.h>
37-
#include <sys/stat.h>
38-
#include <sys/wait.h>
39-
#include <unistd.h>
30+
# include <sys/stat.h>
31+
# include <sys/wait.h>
32+
33+
# include <cctype>
34+
# include <cerrno>
35+
# include <cstdio>
36+
# include <cstdlib>
37+
# include <cstring>
38+
# include <fcntl.h>
39+
# include <signal.h>
40+
# include <unistd.h>
4041

4142
#endif
4243

@@ -486,18 +487,18 @@ std::string shell_quote(const std::string &src)
486487

487488
// first check if quoting is needed at all
488489

489-
if(src.find(' ')==std::string::npos &&
490-
src.find('"')==std::string::npos &&
491-
src.find('*')==std::string::npos &&
492-
src.find('$')==std::string::npos &&
493-
src.find('\\')==std::string::npos &&
494-
src.find('?')==std::string::npos &&
495-
src.find('&')==std::string::npos &&
496-
src.find('|')==std::string::npos &&
497-
src.find('>')==std::string::npos &&
498-
src.find('<')==std::string::npos &&
499-
src.find('^')==std::string::npos &&
500-
src.find('\'')==std::string::npos)
490+
bool quotes_needed = false;
491+
492+
if(src.empty())
493+
quotes_needed = true;
494+
else
495+
{
496+
for(auto &ch : src)
497+
if(!isalnum(ch) && ch != '_' && ch != '.' && ch != '/' && ch != '-')
498+
quotes_needed = true;
499+
}
500+
501+
if(!quotes_needed)
501502
{
502503
// seems fine -- return as is
503504
return src;

unit/util/run.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,24 @@ Author: Michael Tautschnig
1313

1414
#include <fstream>
1515

16+
SCENARIO("shell_quote() escaping", "[core][util][run]")
17+
{
18+
#ifdef _WIN32
19+
REQUIRE(shell_quote("foo.bar") == "foo.bar");
20+
REQUIRE(shell_quote("foo&bar") == "\"foo&bar\"");
21+
REQUIRE(shell_quote("foo(bar)") == "\"foo(bar)\"");
22+
REQUIRE(shell_quote("foo\"bar") == "\"foo\"\"bar\"");
23+
#else
24+
REQUIRE(shell_quote("foo.bar") == "foo.bar");
25+
REQUIRE(shell_quote("foo/bar") == "foo/bar");
26+
REQUIRE(shell_quote("--foo") == "--foo");
27+
REQUIRE(shell_quote("") == "''");
28+
REQUIRE(shell_quote("foo\nbar") == "'foo\nbar'");
29+
REQUIRE(shell_quote("foo(bar)") == "'foo(bar)'");
30+
REQUIRE(shell_quote("foo'bar") == "'foo'\\'''bar'");
31+
#endif
32+
}
33+
1634
SCENARIO("run() error reporting", "[core][util][run]")
1735
{
1836
GIVEN("A command invoking a non-existent executable")

0 commit comments

Comments
 (0)