Skip to content

Commit fb016a1

Browse files
msizanoen1bluca
authored andcommitted
escape: Ensure that output is always valid UTF-8
This ensures that shell string escape operations will not produce output with invalid UTF-8 from the input by escaping invalid UTF-8 data as if they were single byte characters. (cherry picked from commit 00f5715) (cherry picked from commit e906fd2) (cherry picked from commit e0a674f) (cherry picked from commit dfa043a)
1 parent 654e805 commit fb016a1

File tree

1 file changed

+18
-7
lines changed

1 file changed

+18
-7
lines changed

src/basic/escape.c

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -475,14 +475,20 @@ char* octescape(const char *s, size_t len) {
475475
static char* strcpy_backslash_escaped(char *t, const char *s, const char *bad) {
476476
assert(bad);
477477

478-
for (; *s; s++)
479-
if (char_is_cc(*s))
480-
t += cescape_char(*s, t);
481-
else {
478+
while (*s) {
479+
int l = utf8_encoded_valid_unichar(s, SIZE_MAX);
480+
481+
if (char_is_cc(*s) || l < 0)
482+
t += cescape_char(*(s++), t);
483+
else if (l == 1) {
482484
if (*s == '\\' || strchr(bad, *s))
483485
*(t++) = '\\';
484-
*(t++) = *s;
486+
*(t++) = *(s++);
487+
} else {
488+
t = mempcpy(t, s, l);
489+
s += l;
485490
}
491+
}
486492

487493
return t;
488494
}
@@ -511,11 +517,16 @@ char* shell_maybe_quote(const char *s, ShellEscapeFlags flags) {
511517
if (FLAGS_SET(flags, SHELL_ESCAPE_EMPTY) && isempty(s))
512518
return strdup("\"\""); /* We don't use $'' here in the POSIX mode. "" is fine too. */
513519

514-
for (p = s; *p; p++)
515-
if (char_is_cc(*p) ||
520+
for (p = s; *p; ) {
521+
int l = utf8_encoded_valid_unichar(p, SIZE_MAX);
522+
523+
if (char_is_cc(*p) || l < 0 ||
516524
strchr(WHITESPACE SHELL_NEED_QUOTES, *p))
517525
break;
518526

527+
p += l;
528+
}
529+
519530
if (!*p)
520531
return strdup(s);
521532

0 commit comments

Comments
 (0)