Skip to content

Commit eefcf8c

Browse files
committed
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 <egmont@gmail.com>
1 parent 76b6712 commit eefcf8c

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
@@ -1438,8 +1438,15 @@ create_cd_command (const char *s)
14381438
{
14391439
n = str_cget_next_char_safe (su);
14401440

1441-
if (str_isalnum (su))
1441+
// tcsh doesn't support defining strings with UTF-8 characters broken down into individual
1442+
// bytes each escaped in octal, such as $'\303\251' instead of 'é'. So copy all valid
1443+
// multibyte UTF-8 characters as-is, without escaping; they aren't special shell characters
1444+
// in any shell and don't need protection.
1445+
// Also don't escape frequent safe filename characters like '/', '.' and such.
1446+
if ((unsigned char) su[0] >= 0x80 || g_ascii_isalnum (su[0])
1447+
|| strchr ("/.-_", su[0]) != NULL)
14421448
{
1449+
// It's a safe character that we copy as-is.
14431450
if (line_length + (n - su) > max_length)
14441451
{
14451452
// wrap to next physical line
@@ -1453,6 +1460,8 @@ create_cd_command (const char *s)
14531460
line_length += (n - su);
14541461
}
14551462
else
1463+
// It's a special shell character, or maybe an invalid UTF-8 segment.
1464+
// Escape each byte separately.
14561465
for (size_t c = 0; c < (size_t) (n - su); c++)
14571466
{
14581467
if (line_length + escaped_char_len > max_length)

0 commit comments

Comments
 (0)