NetBSD Problem Report #50827
From www@NetBSD.org Thu Feb 18 07:31:16 2016
Return-Path: <www@NetBSD.org>
Received: from mail.netbsd.org (mail.NetBSD.org [199.233.217.200])
(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
(Client CN "mail.netbsd.org", Issuer "Postmaster NetBSD.org" (verified OK))
by mollari.NetBSD.org (Postfix) with ESMTPS id 690D57ACB8
for <gnats-bugs@gnats.NetBSD.org>; Thu, 18 Feb 2016 07:31:16 +0000 (UTC)
Message-Id: <20160218073115.38AAF7ACC5@mollari.NetBSD.org>
Date: Thu, 18 Feb 2016 07:31:15 +0000 (UTC)
From: rhansen@rhansen.org
Reply-To: rhansen@rhansen.org
To: gnats-bugs@NetBSD.org
Subject: sh -c ': "${x=$((1))}"' gives bogus syntax error
X-Send-Pr-Version: www-1.0
>Number: 50827
>Category: bin
>Synopsis: sh -c ': "${x=$((1))}"' gives bogus syntax error
>Confidential: no
>Severity: critical
>Priority: medium
>Responsible: bin-bug-people
>State: closed
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Feb 18 07:35:00 +0000 2016
>Closed-Date: Tue Feb 23 13:04:50 +0000 2016
>Last-Modified: Tue Feb 23 13:04:50 +0000 2016
>Originator: Richard Hansen
>Release: 7.0
>Organization:
>Environment:
NetBSD foo.example.com 7.0 NetBSD 7.0 (GENERIC.201509250726Z) amd64
>Description:
/bin/sh incorrectly reports a syntax error ("Missing '}'") with the following line:
: "${x=$((1))}"
The following work as expected:
: ${x=$((1))}
: ${x="$((1))"}
: "${x="$((1))"}
>How-To-Repeat:
$ sh -c ': "${x=$((1))}"'
sh: Syntax error: Missing '}'
>Fix:
>Release-Note:
>Audit-Trail:
From: Richard Hansen <rhansen@rhansen.org>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: bin/50827: sh -c ': "${x=$((1))}"' gives bogus syntax error
Date: Thu, 18 Feb 2016 02:59:08 -0500
Apologies -- the last example:
> : "${x="$((1))"}
should have been:
: "${x="$((1))"}"
(I forgot the second close double quote)
From: Robert Elz <kre@munnari.OZ.AU>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: bin/50827: sh -c ': "${x=$((1))}"' gives bogus syntax error
Date: Fri, 19 Feb 2016 16:31:13 +0700
Date: Thu, 18 Feb 2016 07:35:00 +0000 (UTC)
From: rhansen@rhansen.org
Message-ID: <20160218073500.BFF977ACD0@mollari.NetBSD.org>
| /bin/sh incorrectly reports a syntax error ("Missing '}'") with the following line:
|
| : "${x=$((1))}"
It also mishandles ...
sh -c ': ${x="$(("1"))"}'
sh: Syntax error: Missing '))'
and similar cases.
I believe the following patch might fix both of those problems (the 4
lines deleted fix rhansen's problem, the extra manipulation of varnest
and associated code fixes the $(( )) case.)
These bugs have been there a long time, so once verified, the fix should
be pulled up to the netbsd 6 & netbsd 7 series (all variants.)
kre
--- parser.c.old 2014-08-30 06:38:31.000000000 +0700
+++ parser.c 2016-02-19 16:18:50.000000000 +0700
@@ -1106,13 +1106,11 @@
--parenlevel;
} else {
if (pgetc() == ')') {
+ if (varnest > 0) /*always*/
+ varnest--;
if (--arinest == 0) {
USTPUTC(CTLENDARI, out);
syntax = prevsyntax;
- if (syntax == DQSYNTAX)
- SETDBLQUOTE();
- else
- CLRDBLQUOTE();
} else
USTPUTC(')', out);
} else {
@@ -1562,6 +1560,13 @@
*/
USTPUTC('(', out);
}
+
+ varnest++;
+ if (varnest >= maxnest) {
+ dblquotep = ckrealloc(dblquotep, maxnest / 8);
+ dblquotep[(maxnest / 32) - 1] = 0;
+ maxnest += 32;
+ }
goto parsearith_return;
}
From: "Christos Zoulas" <christos@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/50827 CVS commit: src/tests/bin/sh
Date: Fri, 19 Feb 2016 08:48:28 -0500
Module Name: src
Committed By: christos
Date: Fri Feb 19 13:48:28 UTC 2016
Modified Files:
src/tests/bin/sh: t_expand.sh t_varquote.sh
Log Message:
Add a test for PR/50827
To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/tests/bin/sh/t_expand.sh \
src/tests/bin/sh/t_varquote.sh
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: "Christos Zoulas" <christos@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/50827 CVS commit: src/bin/sh
Date: Fri, 19 Feb 2016 08:50:37 -0500
Module Name: src
Committed By: christos
Date: Fri Feb 19 13:50:37 UTC 2016
Modified Files:
src/bin/sh: parser.c
Log Message:
PR/50827: Richard Hansen: Fix default variable assignment with arithmetic,
from kre.
To generate a diff of this commit:
cvs rdiff -u -r1.93 -r1.94 src/bin/sh/parser.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
State-Changed-From-To: open->feedback
State-Changed-By: wiz@NetBSD.org
State-Changed-When: Fri, 19 Feb 2016 14:01:59 +0000
State-Changed-Why:
christos committed a fix, does it work for you?
From: Robert Elz <kre@munnari.OZ.AU>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: bin/50827 (sh -c ': "${x=$((1))}"' gives bogus syntax error)
Date: Fri, 19 Feb 2016 21:49:24 +0700
Date: Fri, 19 Feb 2016 14:02:00 +0000 (UTC)
From: wiz@NetBSD.org
Message-ID: <20160219140200.3F64A7ACAF@mollari.NetBSD.org>
| christos committed a fix, does it work for you?
I know this was not directed at me, so don't take this as an answer,
but it still fails on even more bizarre usages...
./sh -c 'echo ${x:-$(( ${y:-"$((4))"} ))}'
sh: Syntax error: Unterminated quoted string
this fails if the quotes are inside the outer $(( )), but not inside the
inner $(( )) .. doesn't matter if the entire ${y...} is quoted or just
as shown, it fails the same way. But works if it is just the "4" quoted.
And to go even further into the absurd ...
./sh -c 'echo ${x:-"$(( "${y:-$(( ${z:-$(( 9 ))} ))}" ))"}'
sh: Syntax error: Missing '))'
sh is better now than it was, but this stuff ought to be fixed as well.
Without quoting, that works (believe it or not.)
I am looking into it, but maybe the PR can remain open for now.
kre
From: christos@zoulas.com (Christos Zoulas)
To: gnats-bugs@NetBSD.org, gnats-admin@netbsd.org, netbsd-bugs@netbsd.org,
rhansen@rhansen.org
Cc:
Subject: Re: bin/50827 (sh -c ': "${x=$((1))}"' gives bogus syntax error)
Date: Fri, 19 Feb 2016 09:57:32 -0500
On Feb 19, 2:50pm, kre@munnari.OZ.AU (Robert Elz) wrote:
-- Subject: Re: bin/50827 (sh -c ': "${x=$((1))}"' gives bogus syntax error)
| The following reply was made to PR bin/50827; it has been noted by GNATS.
|
| From: Robert Elz <kre@munnari.OZ.AU>
| To: gnats-bugs@NetBSD.org
| Cc:
| Subject: Re: bin/50827 (sh -c ': "${x=$((1))}"' gives bogus syntax error)
| Date: Fri, 19 Feb 2016 21:49:24 +0700
|
| Date: Fri, 19 Feb 2016 14:02:00 +0000 (UTC)
| From: wiz@NetBSD.org
| Message-ID: <20160219140200.3F64A7ACAF@mollari.NetBSD.org>
|
| | christos committed a fix, does it work for you?
|
| I know this was not directed at me, so don't take this as an answer,
| but it still fails on even more bizarre usages...
|
| ./sh -c 'echo ${x:-$(( ${y:-"$((4))"} ))}'
| sh: Syntax error: Unterminated quoted string
|
| this fails if the quotes are inside the outer $(( )), but not inside the
| inner $(( )) .. doesn't matter if the entire ${y...} is quoted or just
| as shown, it fails the same way. But works if it is just the "4" quoted.
|
| And to go even further into the absurd ...
|
| ./sh -c 'echo ${x:-"$(( "${y:-$(( ${z:-$(( 9 ))} ))}" ))"}'
| sh: Syntax error: Missing '))'
|
| sh is better now than it was, but this stuff ought to be fixed as well.
| Without quoting, that works (believe it or not.)
|
| I am looking into it, but maybe the PR can remain open for now.
If you are looking into quoting, please look at: bin/43469. Also it might
be worthwhile to compare ours with FreeBSD's sh and switch to their code
if it is better.
christos
From: Robert Elz <kre@munnari.OZ.AU>
To: christos@zoulas.com (Christos Zoulas)
Cc: gnats-bugs@NetBSD.org, gnats-admin@netbsd.org, netbsd-bugs@netbsd.org,
rhansen@rhansen.org
Subject: Re: bin/50827 (sh -c ': "${x=$((1))}"' gives bogus syntax error)
Date: Fri, 19 Feb 2016 22:43:47 +0700
Date: Fri, 19 Feb 2016 09:57:32 -0500
From: christos@zoulas.com (Christos Zoulas)
Message-ID: <20160219145732.1539C17FDAF@rebar.astron.com>
| If you are looking into quoting, please look at: bin/43469.
Will do.
| Also it might be worthwhile to compare ours with FreeBSD's sh
I will look.
| and switch to their code if it is better.
I can offer an opinion (and it is not just a wholesale replacement) offer
some patches perhaps, but the actual switch (if it were to happen) would
need to be done by someone else...
kre
From: Richard Hansen <rhansen@rhansen.org>
To: gnats-bugs@NetBSD.org, gnats-admin@netbsd.org, netbsd-bugs@netbsd.org
Cc:
Subject: Re: bin/50827: sh -c ': "${x=$((1))}"' gives bogus syntax error
Date: Fri, 19 Feb 2016 22:45:04 -0500
On 2016-02-19 04:35, Robert Elz wrote:
> It also mishandles ...
>
> sh -c ': ${x="$(("1"))"}'
> sh: Syntax error: Missing '))'
From http://austingroupbugs.net/view.php?id=985#c2885 (which will become
POSIX standard once approved):
The expression shall be expanded as if it were a word in
double-quotes, except that the treatment of a double-quote inside
the expression is unspecified and the result of parameter expansion
of the '@' special parameter is unspecified.
So the NetBSD shell is OK as-is in this regard, though it doesn't hurt
to change the shell to treat "$(("1"))" like "$((1))" because POSIX says
(will say) "unspecified".
From: Richard Hansen <rhansen@rhansen.org>
To: gnats-bugs@NetBSD.org, gnats-admin@netbsd.org, netbsd-bugs@netbsd.org,
wiz@NetBSD.org
Cc:
Subject: Re: bin/50827 (sh -c ': "${x=$((1))}"' gives bogus syntax error)
Date: Sat, 20 Feb 2016 02:45:30 -0500
On 2016-02-19 09:02, wiz@NetBSD.org wrote:
> christos committed a fix, does it work for you?
Yes, it works for me. I did not test for any regressions.
Thank you!
State-Changed-From-To: feedback->analyzed
State-Changed-By: wiz@NetBSD.org
State-Changed-When: Sat, 20 Feb 2016 10:06:26 +0000
State-Changed-Why:
Original problem fixed; keep this PR open for a bit if kre wants to provide more fixes.
From: Robert Elz <kre@munnari.OZ.AU>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: bin/50827 (sh -c ': "${x=$((1))}"' gives bogus syntax error)
Date: Sun, 21 Feb 2016 00:22:31 +0700
Date: Sat, 20 Feb 2016 10:06:26 +0000 (UTC)
From: wiz@NetBSD.org
Message-ID: <20160220100626.B4EE07ACCD@mollari.NetBSD.org>
| Original problem fixed; keep this PR open for a bit if kre wants
| to provide more fixes.
An update ... I have a version that works for all I have tested so far
(but that is not yet a lot). It does include the initial subject of
this PR, and the horrid example I found last, and even the example from
PR 43469 that Christos asked me to look at (though that was really a different
problem.)
But I have yet to run (and then add to) the atf tests - and perhaps fix
anything I have broken along the way. Tomorrow sometime I hope.
kre
From: Christos Zoulas <christos@zoulas.com>
To: gnats-bugs@NetBSD.org
Cc: gnats-admin@netbsd.org, netbsd-bugs@netbsd.org, rhansen@rhansen.org
Subject: Re: bin/50827 (sh -c ': "${x=$((1))}"' gives bogus syntax error)
Date: Sat, 20 Feb 2016 12:33:30 -0500
> wow the 43469 one was giving me trouble for a while!
christos
From: Robert Elz <kre@munnari.OZ.AU>
To: Christos Zoulas <christos@zoulas.com>
Cc: gnats-bugs@NetBSD.org, gnats-admin@netbsd.org, netbsd-bugs@netbsd.org,
rhansen@rhansen.org
Subject: Re: bin/50827 (sh -c ': "${x=$((1))}"' gives bogus syntax error)
Date: Sun, 21 Feb 2016 08:19:00 +0700
Date: Sat, 20 Feb 2016 12:33:30 -0500
From: Christos Zoulas <christos@zoulas.com>
Message-ID: <61B42472-7C43-4B93-8185-D902A81727B5@zoulas.com>
| > wow the 43469 one was giving me trouble for a while!
Don't jump for joy just yet. The two expressions in the PR both work
(produce the same, correct, result) but there is potential for much
other breakage I have not yet tested, plus more variants of the expr
in question tha also need to work, also yet untested.
So some progress, but too early to open the champaign...
While here I'll ask another question ... the code in sh is sprinkled
with "volatile" all over the place (particularly in the area I have
been looking.) I gather this is to appease gcc wrt setjmp/longmp
(the FreeBSD code has a comment - or maybe commit log entry - simply
refusing to go that route...) Does anyone mind if I strip out most
of that, and add "just the right" volatile vars, so the trap longjmp
stuff works (at least in the token reading functions) - or should work,
modulo whatever nonsense gcc gets up to, and remove it from all the
rest? (If I do that I'll make it a separate patch.) All that (unnecessary)
volatile nonsense has to be slowing shell execution, and with my fixes,
it will be even worse. Until I remove it so I can measure the effect, I
don't know how much difference it really makes, but ... And of course,
nothing will happen there until the substantive changes are all fully
tested (and corrected if needed.)
kre
From: christos@zoulas.com (Christos Zoulas)
To: Robert Elz <kre@munnari.OZ.AU>
Cc: gnats-bugs@NetBSD.org, gnats-admin@netbsd.org, netbsd-bugs@netbsd.org,
rhansen@rhansen.org
Subject: Re: bin/50827 (sh -c ': "${x=$((1))}"' gives bogus syntax error)
Date: Sat, 20 Feb 2016 20:22:11 -0500
On Feb 21, 8:19am, kre@munnari.OZ.AU (Robert Elz) wrote:
-- Subject: Re: bin/50827 (sh -c ': "${x=$((1))}"' gives bogus syntax error)
| Don't jump for joy just yet. The two expressions in the PR both work
| (produce the same, correct, result) but there is potential for much
| other breakage I have not yet tested, plus more variants of the expr
| in question tha also need to work, also yet untested.
| So some progress, but too early to open the champaign...
Ok, I will put it back in the fridge.
| While here I'll ask another question ... the code in sh is sprinkled
| with "volatile" all over the place (particularly in the area I have
| been looking.) I gather this is to appease gcc wrt setjmp/longmp
| (the FreeBSD code has a comment - or maybe commit log entry - simply
| refusing to go that route...) Does anyone mind if I strip out most
| of that, and add "just the right" volatile vars, so the trap longjmp
| stuff works (at least in the token reading functions) - or should work,
| modulo whatever nonsense gcc gets up to, and remove it from all the
| rest? (If I do that I'll make it a separate patch.) All that (unnecessary)
| volatile nonsense has to be slowing shell execution, and with my fixes,
| it will be even worse. Until I remove it so I can measure the effect, I
| don't know how much difference it really makes, but ... And of course,
| nothing will happen there until the substantive changes are all fully
| tested (and corrected if needed.)
I think that most of the volatile was because gcc wanted it... I don't
mind the cleanup, go for it. But expect transient breakage amongst different
ports. Also our shell does vfork() which is a nother volatile creator, I
don't think that FreeBSD supports that.
christos
From: Robert Elz <kre@munnari.OZ.AU>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: bin/50827: sh -c ': "${x=$((1))}"' gives bogus syntax error
Date: Sun, 21 Feb 2016 15:45:39 +0700
Date: Sat, 20 Feb 2016 03:50:01 +0000 (UTC)
From: Richard Hansen <rhansen@rhansen.org>
Message-ID: <20160220035001.44F947ACAF@mollari.NetBSD.org>
| So the NetBSD shell is OK as-is in this regard, though it doesn't hurt
| to change the shell to treat "$(("1"))" like "$((1))" because POSIX says
| (will say) "unspecified".
Yes, something in one of ether the NetBSD or FreeBSD sources or commit
logs says something like (paraphrasing)...
We don't have to do this, but people write code this way
[quoted strings inside $(( ))] and expect it to work, so
we might as well make it work.
From what I can tell, so far, in my as yet un-committed (not submitted)
code, all of this stuff is now working fine. I am still running
tests (and working on the sh atf tests in general.)
kre
State-Changed-From-To: analyzed->closed
State-Changed-By: christos@NetBSD.org
State-Changed-When: Tue, 23 Feb 2016 08:04:50 -0500
State-Changed-Why:
fixed
>Unformatted:
(Contact us)
$NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2014
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.