libutil: add bashEscape, which escapes non-printing characters with $''
(cherry picked from commit ee91eec5cf)
Change-Id: I7e5c88ebe27c0a283982f8ac25f0fb0c6a6a6964
This commit is contained in:
+35
-2
@@ -129,8 +129,41 @@ std::string shellEscape(const std::string_view s)
|
||||
std::string r;
|
||||
r.reserve(s.size() + 2);
|
||||
r += "'";
|
||||
for (auto & i : s)
|
||||
if (i == '\'') r += "'\\''"; else r += i;
|
||||
for (auto & i : s) {
|
||||
if (i == '\'') {
|
||||
// End the single quote, add a single backslash-escaped single quote,
|
||||
// then start a single quote again.
|
||||
// i.e., `I didn't know` becomes `'I didn'\''t know'`.
|
||||
r += "'\\''";
|
||||
} else {
|
||||
r += i;
|
||||
}
|
||||
}
|
||||
|
||||
r += '\'';
|
||||
return r;
|
||||
}
|
||||
|
||||
std::string bashEscape(const std::string_view s)
|
||||
{
|
||||
std::string r;
|
||||
r.reserve(s.size() + 2);
|
||||
r += "'";
|
||||
for (auto & i : s) {
|
||||
if (!std::isprint(i)) {
|
||||
// Close the single quote, start an "ANSI-C Quote" ($'foo'), add `\xXX`,
|
||||
// close the ANSI-C Quote, and finally start a normal single quote again.
|
||||
r += fmt("'$'\\x%02x''", static_cast<unsigned int>(static_cast<unsigned char>(i)));
|
||||
} else if (i == '\'') {
|
||||
// End the single quote, add a single backslash-escaped single quote,
|
||||
// then start a single quote again.
|
||||
// i.e., `I didn't know` becomes `'I didn'\''t know'`.
|
||||
r += "'\\''";
|
||||
} else {
|
||||
r += i;
|
||||
}
|
||||
}
|
||||
|
||||
r += '\'';
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -191,6 +191,11 @@ std::string toLower(const std::string & s);
|
||||
*/
|
||||
std::string shellEscape(const std::string_view s);
|
||||
|
||||
/**
|
||||
* Same as shellEscape, but also escapes nonprinting characters using $'ANSI C quotes'.
|
||||
*/
|
||||
std::string bashEscape(const std::string_view s);
|
||||
|
||||
/**
|
||||
* Base64 encoding/decoding.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user