[PATCH v2] shells: correctly count backslashes in read built-in

Ron Yorston rmy at pobox.com
Fri Aug 22 09:13:54 UTC 2025


When the read built-in's '-n' option is used to limit the number
of characters read, backslashes should only be counted if the '-r'
option is also suppiled.  This matches how bash behaves.

function                                             old     new   delta
shell_builtin_read                                  1360    1363      +3
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 3/0)                 Total: 3 bytes

v2: Add missing adjustment for backslash-escaped newline.

Signed-off-by: Ron Yorston <rmy at pobox.com>
---
 shell/ash_test/ash-read/read_n.right   | 2 ++
 shell/ash_test/ash-read/read_n.tests   | 2 ++
 shell/hush_test/hush-read/read_n.right | 2 ++
 shell/hush_test/hush-read/read_n.tests | 2 ++
 shell/shell_common.c                   | 3 ++-
 5 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/shell/ash_test/ash-read/read_n.right b/shell/ash_test/ash-read/read_n.right
index 1f81af0bc..bd29f8ca3 100644
--- a/shell/ash_test/ash-read/read_n.right
+++ b/shell/ash_test/ash-read/read_n.right
@@ -1,3 +1,5 @@
 test
 tes
 tes
+12
+\1
diff --git a/shell/ash_test/ash-read/read_n.tests b/shell/ash_test/ash-read/read_n.tests
index 12423ba6e..fde3d8954 100755
--- a/shell/ash_test/ash-read/read_n.tests
+++ b/shell/ash_test/ash-read/read_n.tests
@@ -1,3 +1,5 @@
 echo 'test' | (read reply; echo "$reply")
 echo 'test' | (read -n 3 reply; echo "$reply")
 echo 'test' | (read -n3 reply; echo "$reply")
+echo '\1\2' | (read -n 2 reply; echo "$reply")
+echo '\1\2' | (read -r -n 2 reply; echo "$reply")
diff --git a/shell/hush_test/hush-read/read_n.right b/shell/hush_test/hush-read/read_n.right
index 1f81af0bc..bd29f8ca3 100644
--- a/shell/hush_test/hush-read/read_n.right
+++ b/shell/hush_test/hush-read/read_n.right
@@ -1,3 +1,5 @@
 test
 tes
 tes
+12
+\1
diff --git a/shell/hush_test/hush-read/read_n.tests b/shell/hush_test/hush-read/read_n.tests
index 12423ba6e..fde3d8954 100755
--- a/shell/hush_test/hush-read/read_n.tests
+++ b/shell/hush_test/hush-read/read_n.tests
@@ -1,3 +1,5 @@
 echo 'test' | (read reply; echo "$reply")
 echo 'test' | (read -n 3 reply; echo "$reply")
 echo 'test' | (read -n3 reply; echo "$reply")
+echo '\1\2' | (read -n 2 reply; echo "$reply")
+echo '\1\2' | (read -r -n 2 reply; echo "$reply")
diff --git a/shell/shell_common.c b/shell/shell_common.c
index 754fef34b..c799fd8f3 100644
--- a/shell/shell_common.c
+++ b/shell/shell_common.c
@@ -239,6 +239,7 @@ shell_builtin_read(struct builtin_read_params *params)
 				backslash = 0;
 				if (c != '\n')
 					goto put;
+				++nchars;
 				continue;
 			}
 			if (c == '\\') {
@@ -279,7 +280,7 @@ shell_builtin_read(struct builtin_read_params *params)
 		}
  put:
 		bufpos++;
-	} while (--nchars);
+	} while (backslash || --nchars);
 
 	if (argv[0]) {
 		/* Remove trailing space $IFS chars */
-- 
2.50.1



More information about the busybox mailing list