Re: [PATCH 6/7] syntax-check: fix violations and implement sc_prohibit_test_const_follows_var.
On Tuesday 22 November 2011, Eric Blake wrote: > touch =; test -f =; echo $? > This is problematic also with pdksh 5.2.14 on Debian: $ pdksh -c 'touch ./=; test -f =; echo $?' pdksh: test: =: missing second argument 2 and with /bin/sh on OpenBSD 4.6 as well: $ /bin/sh -c 'touch ./=; test -f =; echo $?' /bin/sh: test: =: missing second argument 2 Regards, Stefano
Re: [PATCH 6/7] syntax-check: fix violations and implement sc_prohibit_test_const_follows_var.
On 11/22/2011 02:02 AM, Stefano Lattarini wrote: >>> test a = "$b" >>> >>> is just as likely to trigger improper evaluation in buggy test(1) >>> implementations as: >>> >>> test "$b" = a >> >> :-o For real? On non-museum pieces? Okay, you've convinced me otherwise. It looks like even buggy versions of test(1) at least have the decency to recognize "non-op" "=" "arbitrary" as always being a string comparison, even if "arbitrary" looks like an operator (I tried "!", "=", "(", ")", "-a", and so on). It is only when the first argument looks like an operator that the parser gets confused on what the remaining two arguments should be. > And in fact the autconf manual says: > > Similarly, Posix says that both `test "string1" = "string2"' and > `test "string1" != "string2"' work for any pairs of strings, but > in practice this is not true for troublesome strings that look > like operators or parentheses, or that begin with `-'. > > (Text that should be probably be expandend to show some examples, > *and* to report the exact names and versions of the affected > shells). Yes, the autoconf manual could be improved, based on the results of this thread. > >> I tested a bunch of /bin/sh, bash, ksh and zsh versions that I have >> easy access to, and for all of them, the only way to upset test with >> leading hypens the first argument. >> > I couldn't do this either (for leading hypens, that is); but see the > slighlty more elaborated issues presented above. I can demonstrate a problem with leading hyphen, on Solaris 10 at least: $ touch =; /bin/sh -c 'test -f ='; echo $? /bin/sh: test: argument expected 1 >> >> I'll postpone pushing this patch until we get to the bottom of the >> issue though. I withdraw my objection to the libtool patch. It might not be a common idiom to list the constant first, but who knows? maybe you've started a new trend. -- Eric Blake ebl...@redhat.com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature
Re: [PATCH 6/7] syntax-check: fix violations and implement sc_prohibit_test_const_follows_var.
[adding bug-autoconf in CC] On Tuesday 22 November 2011, Gary V wrote: > Hi Eric, > > On 22 Nov 2011, at 03:07, Eric Blake wrote: > > > On 11/21/2011 07:47 AM, Gary V. Vaughan wrote: > >> To safely use a non-literal first argument to `test', you must > >> always prepend a literal non-`-' character, but often the second > >> operand is a constant that doesn't begin with a `-' already, so > >> always use `test a = "$b"' instead of noisy `test "X$b" = Xa'. > > > > Not true. > > > > test a = "$b" > > > > is just as likely to trigger improper evaluation in buggy test(1) > > implementations as: > > > > test "$b" = a > > :-o For real? On non-museum pieces? > On Solaris 10 I see this: $ /bin/sh -c 'b="("; test "$b" = a'; echo status = $? /bin/sh: test: argument expected status = 1 $ /bin/sh -c 'b="!"; test "$b" = a'; echo status = $? /bin/sh: test: argument expected status = 1 And on NetBSD 5.1 I see this: $ /bin/sh -c 'b="("; test "$b" = a'; echo status = $? test: closing paren expected status = 2 $ /bin/sh -c 'b="!"; test "$b" = a'; echo status = $? test: a: unexpected operator status = 2 And in fact the autconf manual says: Similarly, Posix says that both `test "string1" = "string2"' and `test "string1" != "string2"' work for any pairs of strings, but in practice this is not true for troublesome strings that look like operators or parentheses, or that begin with `-'. (Text that should be probably be expandend to show some examples, *and* to report the exact names and versions of the affected shells). > I tested a bunch of /bin/sh, bash, ksh and zsh versions that I have > easy access to, and for all of them, the only way to upset test with > leading hypens the first argument. > I couldn't do this either (for leading hypens, that is); but see the slighlty more elaborated issues presented above. > > If you cannot guarantee the contents of "$b", then you MUST prefix both > > sides of the comparison with x or X. Conversely, if you CAN guarantee > > the contents of "$b" (for example, if you did b=$?, then you KNOW that b > > is a numeric tring with no problematic characters), then you might as > > well use the more idiomatic comparison of variable to constant. > > I don't suppose you can point me at a shell that chokes or fails on: > >test a != -b || echo bug > > ? Or at least some reliable documentation that shows we're not dealing > with outdated dogma here? > > I'll postpone pushing this patch until we get to the bottom of the > issue though. > > Cheers, > -- > Gary V. Vaughan (gary AT gnu DOT org) > Regards, Stefano
Re: [PATCH 6/7] syntax-check: fix violations and implement sc_prohibit_test_const_follows_var.
Hi Stefano, On 22 Nov 2011, at 03:13, Stefano Lattarini wrote: > Hi Gary. Few more random nits... Thanks ;) > On Monday 21 November 2011, Gary V wrote: >> To safely use a non-literal first argument to `test', you must >> always prepend a literal non-`-' character, but often the second >> operand is a constant that doesn't begin with a `-' already, so >> always use `test a = "$b"' instead of noisy `test "X$b" = Xa'. >> > This seems "back-bending" to me, and slightly unclear to read. Also, > it goes against the (unofficial) conventions of autoconf, which is > to use either `test "x$b" = xa' or `test "x$b" = Xa'. I was unable to find any shells that choke on: test a != -b || echo bug Where it's easy to upset test with: test -b != a > Also ... > >> # Bootstrap this package from checked-out sources. >> # Written by Gary V. Vaughan, 2010 >> @@ -1760,7 +1760,7 @@ func_ifcontains () >> ;; >> esac >> >> -test "$_G_status" -eq 0 || exit $_G_status >> +test 0 -eq $_G_status || exit $_G_status >> } > ... changes like this seems overly paranoid, in case $_G_status is > expected (as I surmise it is) to be a non-negative integer. And > if this assumption stps to hold dur to a bug in your code, you are > going to be bitten by much worse problem anyway: Well, in addition to saving a few characters of typing, and being consistent with other uses of test after this patch, it also prevents the syntax-check from triggering. I certainly wouldn't expect any difference in behaviour either way, even on buggy shells/test implementations. > # $shell is either Solaris 1 0or AT&T ksh, Solaris 10 XPG4 sh, or > # zsh 4.3.12. > $ $shell -c 'exit t; echo foo'; echo status = $? > status = 0 Cheers, -- Gary V. Vaughan (gary AT gnu DOT org)
Re: [PATCH 6/7] syntax-check: fix violations and implement sc_prohibit_test_const_follows_var.
Hi Eric, On 22 Nov 2011, at 03:07, Eric Blake wrote: > On 11/21/2011 07:47 AM, Gary V. Vaughan wrote: >> To safely use a non-literal first argument to `test', you must >> always prepend a literal non-`-' character, but often the second >> operand is a constant that doesn't begin with a `-' already, so >> always use `test a = "$b"' instead of noisy `test "X$b" = Xa'. > > Not true. > > test a = "$b" > > is just as likely to trigger improper evaluation in buggy test(1) > implementations as: > > test "$b" = a :-o For real? On non-museum pieces? I tested a bunch of /bin/sh, bash, ksh and zsh versions that I have easy access to, and for all of them, the only way to upset test with leading hyphens is in the first argument. > If you cannot guarantee the contents of "$b", then you MUST prefix both > sides of the comparison with x or X. Conversely, if you CAN guarantee > the contents of "$b" (for example, if you did b=$?, then you KNOW that b > is a numeric tring with no problematic characters), then you might as > well use the more idiomatic comparison of variable to constant. I don't suppose you can point me at a shell that chokes or fails on: test a != -b || echo bug ? Or at least some reliable documentation that shows we're not dealing with outdated dogma here? I'll postpone pushing this patch until we get to the bottom of the issue though. Cheers, -- Gary V. Vaughan (gary AT gnu DOT org)
Re: [PATCH 6/7] syntax-check: fix violations and implement sc_prohibit_test_const_follows_var.
Hi Gary. Few more random nits... On Monday 21 November 2011, Gary V wrote: > To safely use a non-literal first argument to `test', you must > always prepend a literal non-`-' character, but often the second > operand is a constant that doesn't begin with a `-' already, so > always use `test a = "$b"' instead of noisy `test "X$b" = Xa'. > This seems "back-bending" to me, and slightly unclear to read. Also, it goes against the (unofficial) conventions of autoconf, which is to use either `test "x$b" = xa' or `test "x$b" = Xa'. Also ... > # Bootstrap this package from checked-out sources. > # Written by Gary V. Vaughan, 2010 > @@ -1760,7 +1760,7 @@ func_ifcontains () >;; > esac > > -test "$_G_status" -eq 0 || exit $_G_status > +test 0 -eq $_G_status || exit $_G_status > } ... changes like this seems overly paranoid, in case $_G_status is expected (as I surmise it is) to be a non-negative integer. And if this assumption stps to hold dur to a bug in your code, you are going to be bitten by much worse problem anyway: # $shell is either Solaris 1 0or AT&T ksh, Solaris 10 XPG4 sh, or # zsh 4.3.12. $ $shell -c 'exit t; echo foo'; echo status = $? status = 0 Regards, Stefano
Re: [PATCH 6/7] syntax-check: fix violations and implement sc_prohibit_test_const_follows_var.
On 11/21/2011 07:47 AM, Gary V. Vaughan wrote: > To safely use a non-literal first argument to `test', you must > always prepend a literal non-`-' character, but often the second > operand is a constant that doesn't begin with a `-' already, so > always use `test a = "$b"' instead of noisy `test "X$b" = Xa'. Not true. test a = "$b" is just as likely to trigger improper evaluation in buggy test(1) implementations as: test "$b" = a If you cannot guarantee the contents of "$b", then you MUST prefix both sides of the comparison with x or X. Conversely, if you CAN guarantee the contents of "$b" (for example, if you did b=$?, then you KNOW that b is a numeric tring with no problematic characters), then you might as well use the more idiomatic comparison of variable to constant. -- Eric Blake ebl...@redhat.com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature