NetBSD Problem Report #50960

From kre@munnari.OZ.AU  Sat Mar 12 20:52:24 2016
Return-Path: <kre@munnari.OZ.AU>
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 A6B5C7ABEE
	for <gnats-bugs@www.NetBSD.org>; Sat, 12 Mar 2016 20:52:24 +0000 (UTC)
Message-Id: <201603122051.u2CKpuF6022926@andromeda.noi.kre.to>
Date: Sun, 13 Mar 2016 03:51:56 +0700 (ICT)
From: kre@munnari.OZ.AU
To: gnats-bugs@www.NetBSD.org
Subject: /bin/sh generates incorrect value for && and || inside $(( ))
X-Send-Pr-Version: 3.95

>Number:         50960
>Category:       bin
>Synopsis:       /bin/sh generates incorrect value for && and || inside $(( ))
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people
>State:          closed
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Mar 12 20:55:00 +0000 2016
>Closed-Date:    Mon Apr 04 12:38:54 +0000 2016
>Last-Modified:  Mon Apr 04 12:38:54 +0000 2016
>Originator:     Robert Elz
>Release:        NetBSD 7.99.26 (all up to date of this PR)
>Organization:
>Environment:
System: NetBSD andromeda.noi.kre.to 7.99.26 NetBSD 7.99.26 (VBOX64-1.1-20160128) #43: Thu Jan 28 16:09:08 ICT 2016 kre@onyx.coe.psu.ac.th:/usr/obj/current/kernels/amd64/VBOX64 amd64
Architecture: x86_64
Machine: amd64
>Description:
	The logical && and || operators are supposed to generate a boolean
	value (which should be 0 for false and 1 for true, the same as
	is done in C).  Currently they generate 0 for false, ad non-zero
	for true (where the non-zero will be whichever of the operand
	values was decisive in determining the answer is not false, ie:
	the RHS for &&, or the LHS for ||).

	No other stell I have tested act like this, they all return 0 or 1
	in all cases.

	The ops are also  expected to do lazy evaluation, but inside the
	shell, this means very little (the shell calculates the results as
	a side effect of parsing the expression, so it all gets
	evaluated anyway).  While we have no operators with side-effects
	(no assignment operators - see PR bin/50958) this makes no
	difference at all.

	It will never happen (because of the rules of sh parsing and
	evaluation) that
		$(( 1 && $(some command that prints a number) ))
	will fail to execute the "some command..." part, that happens
	before the $(( )) expression parsing even starts,

>How-To-Repeat:
		bin/sh -c 'echo $(( 3 && 4 ))'
		4

		/bin/sh -c 'echo $(( 3 || 4 ))'
		3

	Other shells produce 1 in both cases.

	If the result is "false" the answer is 0, so most of the time this
	difference makes no difference, but it some expressions, it can.

>Fix:
	The fix is easy, and is implemented in my sources, however I will
	not submit a patch to change this in the master sources for /bin/sh
	in case there is something in the NetBSD tree which is depending
	upon this behaviour.

	We do not need to worry about externally sourced software, no-one
	else (I have tested anyway, which includes the FreeBSD shell,
	along with bash dash zsh pdksh and mksh) does what the NetBSD
	shell does, so nothing in the outside world will care.

	But there might be something buried in the NetBSD sources that
	does care, so I will leave this one pending a while to see if
	anyone knows of any case like that.

>Release-Note:

>Audit-Trail:
From: <Paul_Koning@Dell.com>
To: <gnats-bugs@NetBSD.org>
Cc: <gnats-admin@netbsd.org>, <netbsd-bugs@netbsd.org>
Subject: Re: bin/50960: /bin/sh generates incorrect value for && and ||
 inside $(( ))
Date: Sat, 12 Mar 2016 21:34:59 +0000

 > On Mar 12, 2016, at 3:55 PM, <kre@munnari.OZ.AU> <kre@munnari.OZ.AU> wrot=
 e:
 >=20
 >> ...
 > 	The logical && and || operators are supposed to generate a boolean
 > 	value (which should be 0 for false and 1 for true, the same as
 > 	is done in C).  Currently they generate 0 for false, ad non-zero
 > 	for true (where the non-zero will be whichever of the operand
 > 	values was decisive in determining the answer is not false, ie:
 > 	the RHS for &&, or the LHS for ||).

 Actually, 0 for true and non-zero for false, a very confusion shell rule.  =
 But yes, other shells don't do this.  Then again, it's analogous to what Py=
 thon does, for what little that's worth.

 	paul

From: Robert Elz <kre@munnari.OZ.AU>
To: Paul_Koning@Dell.com
Cc: gnats-bugs@NetBSD.org, netbsd-bugs@netbsd.org
Subject: Re: bin/50960: /bin/sh generates incorrect value for && and || inside $(( ))
Date: Sun, 13 Mar 2016 05:10:47 +0700

     Date:        Sat, 12 Mar 2016 21:34:59 +0000
     From:        <Paul_Koning@Dell.com>
     Message-ID:  <7E5297F8-347F-4850-8AB2-4C087F6CEE8A@dell.com>

   | Actually, 0 for true and non-zero for false,

 It actually isn't, not for expressions in $(( ))

 You're thinking of the && and || command line operators, and exit
 statuses from commands, where non-zero is false and 0 is true.

 At that level, the kind of evaluation that $(( )) is doing
 is correct, that is, if you were (for some obscure reason) to do

 	(exit 3) || (exit 4)

 The result would (correctly) be "4" (that's what $? would be set to),
 which is "false" if the value is ever used that way.

 Generating 0 or 1 (whichever is to be true and false) in that situation
 would be wrong.

 It is currently very unlikely that anyone is actually currently
 using || or && in arithmetic expressions, as there is no way to use
 the value in any sensible way.   That is, there is (currently) no
 testing operator (see PR bin/50958)

 If one were to attempt
 	$(( x + ( y && z ) ))
 then in C (which is the model for these expressions) you'd get (the value
 of) x, or x+1

 But in shell (currently) you get x or x + z (never x + y) which isn't
 a very useful outcome, I don't think.

 In any case, in these expressions it is definitely 0 for false and != 0 for
 true (on input, when generated, the value is 1).

 And that is what $(( 6 > 4 )) gives (1) (or $(( 6 < 4 )) --> 0 ) and all
 the similar relational operators as well.

 kre

From: "Christos Zoulas" <christos@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/50960 CVS commit: src/bin/sh
Date: Wed, 16 Mar 2016 11:43:38 -0400

 Module Name:	src
 Committed By:	christos
 Date:		Wed Mar 16 15:43:38 UTC 2016

 Modified Files:
 	src/bin/sh: arith.y

 Log Message:
 PR/50960:  The || and && operators in $(( )) should always have a 0 or 1
 result, never anything different. (from kre)


 To generate a diff of this commit:
 cvs rdiff -u -r1.23 -r1.24 src/bin/sh/arith.y

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

State-Changed-From-To: open->closed
State-Changed-By: wiz@NetBSD.org
State-Changed-When: Mon, 04 Apr 2016 12:38:54 +0000
State-Changed-Why:
Fixed, thanks!


>Unformatted:

NetBSD Home
NetBSD PR Database Search

(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.