summaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
authorkre <kre@NetBSD.org>2022-08-19 12:17:18 +0000
committerkre <kre@NetBSD.org>2022-08-19 12:17:18 +0000
commitb422b2b83613a453f9048d413ad706f151146da9 (patch)
tree11d224dd18931ac64bb30dade31982efc21e6190 /bin
parenta1f000382706237d8e806c23c33c921182c9d479 (diff)
PR bin/56972 Fix escape ('\') handling in sh read builtin.
In 1.35 (March 2005) (the big read fixup), most escape handling and IFS processing in the read builtin was corrected. However 2 cases were missed, one is a word (something to be assigned to any variable but the last) in which every character is escaped (the code was relying on a non-escaped char to set the "in a word" status), and second trailing IFS whitespace at the end of the line was being deleted, even if the chars had been escaped (the escape chars are no longer present). See the PR for more details (including the case that detected the problem). After fixing this, I looked at the FreeBSD code (normally might do it before, but these fixes were trivial) to check their implementation. Their code does similar things to ours now does, but in a completely different way, their read builtin is more complex than ours needs to be (they handle more options). For anyone tempted to simply incorporate their code, note that it relies upon infrastructure changes elsewhere in the shell, so would not be a simple cut and drop in exercise. This needs pullups to -3 -4 -5 -6 -7 -8 and -9 (fortunately this is happening before -10 is branched, so will never be broken this way there).
Diffstat (limited to 'bin')
-rw-r--r--bin/sh/miscbltin.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/bin/sh/miscbltin.c b/bin/sh/miscbltin.c
index 6f81a186bda..9bb7cbadb9c 100644
--- a/bin/sh/miscbltin.c
+++ b/bin/sh/miscbltin.c
@@ -1,4 +1,4 @@
-/* $NetBSD: miscbltin.c,v 1.50 2022/04/16 14:26:26 kre Exp $ */
+/* $NetBSD: miscbltin.c,v 1.51 2022/08/19 12:17:18 kre Exp $ */
/*-
* Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)miscbltin.c 8.4 (Berkeley) 5/4/95";
#else
-__RCSID("$NetBSD: miscbltin.c,v 1.50 2022/04/16 14:26:26 kre Exp $");
+__RCSID("$NetBSD: miscbltin.c,v 1.51 2022/08/19 12:17:18 kre Exp $");
#endif
#endif /* not lint */
@@ -100,6 +100,7 @@ readcmd(int argc, char **argv)
int i;
int is_ifs;
int saveall = 0;
+ ptrdiff_t wordlen = 0;
rflag = 0;
prompt = NULL;
@@ -137,7 +138,7 @@ readcmd(int argc, char **argv)
break;
}
if (c != '\n')
- STPUTC(c, p);
+ goto wdch;
continue;
}
if (c == '\n')
@@ -164,12 +165,14 @@ readcmd(int argc, char **argv)
}
if (is_ifs == 0) {
+ wdch:;
/* append this character to the current variable */
startword = 0;
if (saveall)
/* Not just a spare terminator */
saveall++;
STPUTC(c, p);
+ wordlen = p - stackblock();
continue;
}
@@ -187,11 +190,12 @@ readcmd(int argc, char **argv)
setvar(*ap, stackblock(), 0);
ap++;
STARTSTACKSTR(p);
+ wordlen = 0;
}
STACKSTRNUL(p);
/* Remove trailing IFS chars */
- for (; stackblock() <= --p; *p = 0) {
+ for (; stackblock() + wordlen <= --p; *p = 0) {
if (!strchr(ifs, *p))
break;
if (strchr(" \t\n", *p))