Safely quote all variable expansions.

When expanding a variable set by a message from the kernel, safely
quote all arguments expanded when creating a command line for the
shell.

Reviewd by: Shawn Webb, Oliver Pinter, brd@
Sponsored by: Netflix
This commit is contained in:
imp 2018-06-27 23:44:37 +00:00
parent c8a4419e7c
commit 7a13e31898
2 changed files with 27 additions and 3 deletions

View File

@ -636,6 +636,30 @@ config::is_id_char(char ch) const
ch == '-')); ch == '-'));
} }
string
config::shell_quote(const string &s)
{
string buffer;
/*
* Enclose the string in $' ' with escapes for ' and / characters making
* it one argument and ensuring the shell won't be affected by its
* usual list of candidates.
*/
buffer.reserve(s.length() * 3 / 2);
buffer += '$';
buffer += '\'';
for (const char &c : s) {
if (c == '\'' || c == '\\') {
buffer += '\\';
}
buffer += c;
}
buffer += '\'';
return buffer;
}
void void
config::expand_one(const char *&src, string &dst) config::expand_one(const char *&src, string &dst)
{ {
@ -650,8 +674,7 @@ config::expand_one(const char *&src, string &dst)
} }
// $(foo) -> $(foo) // $(foo) -> $(foo)
// Not sure if I want to support this or not, so for now we just pass // This is the escape hatch for passing down shell subcommands
// it through.
if (*src == '(') { if (*src == '(') {
dst += '$'; dst += '$';
count = 1; count = 1;
@ -677,7 +700,7 @@ config::expand_one(const char *&src, string &dst)
do { do {
buffer += *src++; buffer += *src++;
} while (is_id_char(*src)); } while (is_id_char(*src));
dst.append(get_variable(buffer)); dst.append(shell_quote(get_variable(buffer)));
} }
const string const string

View File

@ -173,6 +173,7 @@ protected:
void parse_one_file(const char *fn); void parse_one_file(const char *fn);
void parse_files_in_dir(const char *dirname); void parse_files_in_dir(const char *dirname);
void expand_one(const char *&src, std::string &dst); void expand_one(const char *&src, std::string &dst);
std::string shell_quote(const std::string &s);
bool is_id_char(char) const; bool is_id_char(char) const;
bool chop_var(char *&buffer, char *&lhs, char *&rhs) const; bool chop_var(char *&buffer, char *&lhs, char *&rhs) const;
private: private: