Skip to content

Commit 2ae16ca

Browse files
egmontkobgithub-actions[bot]
authored andcommitted
Ticket #4480: Don't escape safe shell chars and multibyte UTF-8
Don't escape safe shell characters commonly used in paths, such as '/', '.', '-' and '_'. Don't escape multibyte UTF-8 characters. Escaping each byte separately in string assignments doesn't work in tcsh. The previous commit introduces a regression here: tcsh cannot enter directories whose name is valid UTF-8 but contains non-alphanumeric UTF-8 characters. It used to work because printf would glue them together correctly, but we no longer use printf and command substitution because that breaks newlines. Signed-off-by: Egmont Koblinger <[email protected]>
1 parent 057e5ab commit 2ae16ca

File tree

1 file changed

+10
-1
lines changed

1 file changed

+10
-1
lines changed

src/subshell/common.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1406,8 +1406,15 @@ create_cd_command (const char *s)
14061406
{
14071407
n = str_cget_next_char_safe (su);
14081408

1409-
if (str_isalnum (su))
1409+
// tcsh doesn't support defining strings with UTF-8 characters broken down into individual
1410+
// bytes each escaped in octal, such as $'\303\251' instead of 'é'. So copy all valid
1411+
// multibyte UTF-8 characters as-is, without escaping; they aren't special shell characters
1412+
// in any shell and don't need protection.
1413+
// Also don't escape frequent safe filename characters like '/', '.' and such.
1414+
if ((unsigned char) su[0] >= 0x80 || g_ascii_isalnum (su[0])
1415+
|| strchr ("/.-_", su[0]) != NULL)
14101416
{
1417+
// It's a safe character that we copy as-is.
14111418
if (line_length + (n - su) > max_length)
14121419
{
14131420
// wrap to next physical line
@@ -1421,6 +1428,8 @@ create_cd_command (const char *s)
14211428
line_length += (n - su);
14221429
}
14231430
else
1431+
// It's a special shell character, or maybe an invalid UTF-8 segment.
1432+
// Escape each byte separately.
14241433
for (size_t c = 0; c < (size_t) (n - su); c++)
14251434
{
14261435
if (line_length + escaped_char_len > max_length)

0 commit comments

Comments
 (0)