Flagsify EscapeStyle and make ESCAPE_BACKSLASH_ONELINE implicit
I want to tweak behaviour further, and that'll be easier when "style" is converted to a bitfield. Some callers used ESCAPE_BACKSLASH_ONELINE, and others not. But the ones that didn't, simply didn't care, because the argument was assumed to be one-line anyway (e.g. a service name). In environment-generator, this could make a difference. But I think it's better to escape the newlines there too. So newlines are now always escaped, to simplify the code and the test matrix.
This commit is contained in:
+11
-20
@@ -494,7 +494,7 @@ char* shell_escape(const char *s, const char *bad) {
|
||||
return r;
|
||||
}
|
||||
|
||||
char* shell_maybe_quote(const char *s, EscapeStyle style) {
|
||||
char* shell_maybe_quote(const char *s, ShellEscapeFlags flags) {
|
||||
const char *p;
|
||||
char *r, *t;
|
||||
|
||||
@@ -513,36 +513,27 @@ char* shell_maybe_quote(const char *s, EscapeStyle style) {
|
||||
if (!*p)
|
||||
return strdup(s);
|
||||
|
||||
r = new(char, (style == ESCAPE_POSIX) + 1 + strlen(s)*2 + 1 + 1);
|
||||
r = new(char, FLAGS_SET(flags, SHELL_ESCAPE_POSIX) + 1 + strlen(s)*2 + 1 + 1);
|
||||
if (!r)
|
||||
return NULL;
|
||||
|
||||
t = r;
|
||||
switch (style) {
|
||||
case ESCAPE_BACKSLASH:
|
||||
case ESCAPE_BACKSLASH_ONELINE:
|
||||
*(t++) = '"';
|
||||
break;
|
||||
case ESCAPE_POSIX:
|
||||
if (FLAGS_SET(flags, SHELL_ESCAPE_POSIX)) {
|
||||
*(t++) = '$';
|
||||
*(t++) = '\'';
|
||||
break;
|
||||
default:
|
||||
assert_not_reached("Bad EscapeStyle");
|
||||
}
|
||||
} else
|
||||
*(t++) = '"';
|
||||
|
||||
t = mempcpy(t, s, p - s);
|
||||
|
||||
if (IN_SET(style, ESCAPE_BACKSLASH, ESCAPE_BACKSLASH_ONELINE))
|
||||
t = strcpy_backslash_escaped(t, p, SHELL_NEED_ESCAPE,
|
||||
style == ESCAPE_BACKSLASH_ONELINE);
|
||||
else
|
||||
t = strcpy_backslash_escaped(t, p, SHELL_NEED_ESCAPE_POSIX, true);
|
||||
t = strcpy_backslash_escaped(t, p,
|
||||
FLAGS_SET(flags, SHELL_ESCAPE_POSIX) ? SHELL_NEED_ESCAPE_POSIX : SHELL_NEED_ESCAPE,
|
||||
true);
|
||||
|
||||
if (IN_SET(style, ESCAPE_BACKSLASH, ESCAPE_BACKSLASH_ONELINE))
|
||||
*(t++) = '"';
|
||||
else
|
||||
if (FLAGS_SET(flags, SHELL_ESCAPE_POSIX))
|
||||
*(t++) = '\'';
|
||||
else
|
||||
*(t++) = '"';
|
||||
*t = 0;
|
||||
|
||||
return r;
|
||||
|
||||
+7
-10
@@ -33,15 +33,12 @@ typedef enum UnescapeFlags {
|
||||
UNESCAPE_ACCEPT_NUL = 1 << 1,
|
||||
} UnescapeFlags;
|
||||
|
||||
typedef enum EscapeStyle {
|
||||
ESCAPE_BACKSLASH = 1, /* Add shell quotes ("") so the shell will consider this a single
|
||||
argument, possibly multiline. Tabs and newlines are not escaped. */
|
||||
ESCAPE_BACKSLASH_ONELINE = 2, /* Similar to ESCAPE_BACKSLASH, but always produces a single-line
|
||||
string instead. Shell escape sequences are produced for tabs and
|
||||
newlines. */
|
||||
ESCAPE_POSIX = 3, /* Similar to ESCAPE_BACKSLASH_ONELINE, but uses POSIX shell escape
|
||||
* syntax (a string enclosed in $'') instead of plain quotes. */
|
||||
} EscapeStyle;
|
||||
typedef enum ShellEscapeFlags {
|
||||
/* The default is to add shell quotes ("") so the shell will consider this a single argument.
|
||||
* Tabs and newlines are escaped. */
|
||||
|
||||
SHELL_ESCAPE_POSIX = 1 << 1, /* Use POSIX shell escape syntax (a string enclosed in $'') instead of plain quotes. */
|
||||
} ShellEscapeFlags;
|
||||
|
||||
char* cescape(const char *s);
|
||||
char* cescape_length(const char *s, size_t n);
|
||||
@@ -64,4 +61,4 @@ char* octescape(const char *s, size_t len);
|
||||
char* escape_non_printable_full(const char *str, size_t console_width, bool eight_bit);
|
||||
|
||||
char* shell_escape(const char *s, const char *bad);
|
||||
char* shell_maybe_quote(const char *s, EscapeStyle style);
|
||||
char* shell_maybe_quote(const char *s, ShellEscapeFlags flags);
|
||||
|
||||
Reference in New Issue
Block a user