Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 30 Aug 2015 17:24:23 +0000 (UTC)
From:      Jilles Tjoelker <jilles@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r287308 - in head/bin/sh: . tests/builtins
Message-ID:  <201508301724.t7UHON4k051299@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jilles
Date: Sun Aug 30 17:24:22 2015
New Revision: 287308
URL: https://svnweb.freebsd.org/changeset/base/287308

Log:
  sh: Fix read with escaped IFS characters at the end.
  
  Characters escaped with a backslash must be treated as if they were not in
  IFS. This includes stripping trailing IFS characters.

Added:
  head/bin/sh/tests/builtins/read9.0   (contents, props changed)
Modified:
  head/bin/sh/miscbltin.c
  head/bin/sh/tests/builtins/Makefile

Modified: head/bin/sh/miscbltin.c
==============================================================================
--- head/bin/sh/miscbltin.c	Sun Aug 30 16:10:12 2015	(r287307)
+++ head/bin/sh/miscbltin.c	Sun Aug 30 17:24:22 2015	(r287308)
@@ -100,6 +100,7 @@ readcmd(int argc __unused, char **argv _
 	int i;
 	int is_ifs;
 	int saveall = 0;
+	ptrdiff_t lastnonifs, lastnonifsws;
 	struct timeval tv;
 	char *tvptr;
 	fd_set ifds;
@@ -169,6 +170,7 @@ readcmd(int argc __unused, char **argv _
 	startword = 2;
 	backslash = 0;
 	STARTSTACKSTR(p);
+	lastnonifs = lastnonifsws = -1;
 	for (;;) {
 		nread = read(STDIN_FILENO, &c, 1);
 		if (nread == -1) {
@@ -193,6 +195,7 @@ readcmd(int argc __unused, char **argv _
 			backslash = 0;
 			if (c != '\n') {
 				startword = 0;
+				lastnonifs = lastnonifsws = p - stackblock();
 				USTPUTC(c, p);
 			}
 			continue;
@@ -218,8 +221,10 @@ readcmd(int argc __unused, char **argv _
 			if (is_ifs == 2 && startword == 1) {
 				/* Only one non-whitespace IFS per word */
 				startword = 2;
-				if (saveall)
+				if (saveall) {
+					lastnonifsws = p - stackblock();
 					USTPUTC(c, p);
+				}
 				continue;
 			}
 		}
@@ -230,6 +235,7 @@ readcmd(int argc __unused, char **argv _
 			if (saveall)
 				/* Not just a spare terminator */
 				saveall++;
+			lastnonifs = lastnonifsws = p - stackblock();
 			USTPUTC(c, p);
 			continue;
 		}
@@ -240,6 +246,8 @@ readcmd(int argc __unused, char **argv _
 		if (ap[1] == NULL) {
 			/* Last variable needs all IFS chars */
 			saveall++;
+			if (is_ifs == 2)
+				lastnonifsws = p - stackblock();
 			USTPUTC(c, p);
 			continue;
 		}
@@ -248,20 +256,17 @@ readcmd(int argc __unused, char **argv _
 		setvar(*ap, stackblock(), 0);
 		ap++;
 		STARTSTACKSTR(p);
+		lastnonifs = lastnonifsws = -1;
 	}
 	STACKSTRNUL(p);
 
-	/* Remove trailing IFS chars */
-	for (; stackblock() <= --p; *p = 0) {
-		if (!strchr(ifs, *p))
-			break;
-		if (strchr(" \t\n", *p))
-			/* Always remove whitespace */
-			continue;
-		if (saveall > 1)
-			/* Don't remove non-whitespace unless it was naked */
-			break;
-	}
+	/*
+	 * Remove trailing IFS chars: always remove whitespace, don't remove
+	 * non-whitespace unless it was naked
+	 */
+	if (saveall <= 1)
+		lastnonifsws = lastnonifs;
+	stackblock()[lastnonifsws + 1] = '\0';
 	setvar(*ap, stackblock(), 0);
 
 	/* Set any remaining args to "" */

Modified: head/bin/sh/tests/builtins/Makefile
==============================================================================
--- head/bin/sh/tests/builtins/Makefile	Sun Aug 30 16:10:12 2015	(r287307)
+++ head/bin/sh/tests/builtins/Makefile	Sun Aug 30 17:24:22 2015	(r287308)
@@ -123,6 +123,7 @@ FILES+=		read5.0
 FILES+=		read6.0
 FILES+=		read7.0
 FILES+=		read8.0
+FILES+=		read9.0
 FILES+=		return1.0
 FILES+=		return2.1
 FILES+=		return3.1

Added: head/bin/sh/tests/builtins/read9.0
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/bin/sh/tests/builtins/read9.0	Sun Aug 30 17:24:22 2015	(r287308)
@@ -0,0 +1,10 @@
+# $FreeBSD$
+
+empty=''
+read a b c <<EOF
+\ \ A B\ \ B C\ \ $empty
+EOF
+read d e <<EOF
+D\ $empty
+EOF
+[ "$a.$b.$c.$d.$e" = "  A.B  B.C  .D ." ]



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201508301724.t7UHON4k051299>