[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] read: non-raw-mode fixes
From: |
Grisha Levit |
Subject: |
[PATCH] read: non-raw-mode fixes |
Date: |
Wed, 26 Jul 2023 14:23:45 -0400 |
This patches addresses a few issues with `read' when not in raw mode.
If the last character read was an (unescaped) backslash, store it as
such instead of as a CTLESC. Avoids:
$ printf '\\' | { read; echo "${REPLY@Q}"; }
bash: DEBUG warning: dequote_string: string with bare CTLESC
$'\001'
If an escaped null byte is read, skip it as we do with an unescaped one,
instead of adding it to input_string. Avoids:
$ printf 'A\\\0B\nC\n' | while read; do echo "${REPLY@Q}"; done
'A'
'C'
$ printf '\\\0' | { read; echo "${REPLY@Q}"; }
bash: DEBUG warning: dequote_string: string with bare CTLESC
$'\001' # even after fix for first issue
If IFS contains \177 and the input consists of only backslash-newline
pairs and a sole \177, prevent the bare CTLNUL from being turned into an
empty string. Avoids:
$ printf '\\\n\177' | { IFS=$'\177' read; echo "${REPLY@Q}"; }
''
---
builtins/read.def | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/builtins/read.def b/builtins/read.def
index 5b2621fe..84878699 100644
--- a/builtins/read.def
+++ b/builtins/read.def
@@ -404,7 +404,7 @@ read_builtin (WORD_LIST *list)
input_string[0] = '\0';
pass_next = 0; /* Non-zero signifies last char was backslash. */
- saw_escape = 0; /* Non-zero signifies that we saw an escape char */
+ saw_escape = 0; /* Index+1 of when we last saw an escape char. */
/* More input and options validation */
if (nflag == 1 && nchars == 0)
@@ -751,11 +751,11 @@ read_builtin (WORD_LIST *list)
if (pass_next)
{
pass_next = 0;
- if (c == '\n')
+ if (c == '\n' || c == '\0')
{
if (skip_ctlesc == 0 && i > 0)
i--; /* back up over the CTLESC */
- if (interactive && input_is_tty && raw == 0)
+ if (interactive && input_is_tty && raw == 0 && c == '\n')
print_ps2 = 1;
}
else
@@ -769,8 +769,8 @@ read_builtin (WORD_LIST *list)
pass_next++;
if (skip_ctlesc == 0)
{
- saw_escape++;
input_string[i++] = CTLESC;
+ saw_escape=i;
}
continue;
}
@@ -783,8 +783,8 @@ read_builtin (WORD_LIST *list)
if ((skip_ctlesc == 0 && c == CTLESC) || (skip_ctlnul == 0 && c
== CTLNUL))
{
- saw_escape++;
input_string[i++] = CTLESC;
+ saw_escape=i;
}
add_char:
@@ -825,6 +825,12 @@ add_char:
if (nchars > 0 && nr >= nchars)
break;
}
+
+ if (i && saw_escape == i && input_string[i-1] == CTLESC)
+ input_string[i-1] = '\\'; /* Preserve trailing backslash */
+ else if (skip_ctlnul && i == 1 & saw_escape == 1 && input_string[0]
== CTLNUL)
+ saw_escape = 0; /* Avoid dequoting bare CTLNUL */
+
input_string[i] = '\0';
check_read_timeout ();
--
2.41.0
0001-read-non-raw-mode-fixes.patch
Description: Binary data
- [PATCH] read: non-raw-mode fixes,
Grisha Levit <=