From owner-svn-src-all@freebsd.org Sun Aug 30 17:24:24 2015 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 38CA99C5F4F; Sun, 30 Aug 2015 17:24:24 +0000 (UTC) (envelope-from jilles@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 241F41A46; Sun, 30 Aug 2015 17:24:24 +0000 (UTC) (envelope-from jilles@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.70]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id t7UHOOpX051302; Sun, 30 Aug 2015 17:24:24 GMT (envelope-from jilles@FreeBSD.org) Received: (from jilles@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id t7UHON4k051299; Sun, 30 Aug 2015 17:24:23 GMT (envelope-from jilles@FreeBSD.org) Message-Id: <201508301724.t7UHON4k051299@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: jilles set sender to jilles@FreeBSD.org using -f From: Jilles Tjoelker Date: Sun, 30 Aug 2015 17:24:23 +0000 (UTC) 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 X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 30 Aug 2015 17:24:24 -0000 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 <