NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

bin/52090: /bin/sh does not expand $* (or $@) when unquoted correctly

>Number:         52090
>Category:       bin
>Synopsis:       /bin/sh does not expand $* (or $@) when unquoted correctly
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Mar 19 03:30:00 +0000 2017
>Originator:     Robert Elz
>Release:        NetBSD 7.99.65 (irrelevant, applies to all versions)
System: NetBSD 7.99.43 NetBSD 7.99.43 (VBOX64-1.2-20161202) #21: Sat Dec 3 00:43:51 ICT 2016 amd64
Architecture: x86_64
Machine: amd64
	The rules for expanding an unquoted $* (or $@) are that they
	produce 1 word for each set positional parameter.

	From Posix sh standard, section 2.5.2

74866    *	Expands to the positional parameters, starting from one,
		initially producing one field for
74867   	each positional parameter that is set.

	(the margin numbers are the line numbers from the current version,
	I wrapped the first line for this e-mail)

	There are, of course, more details, but those aren't relevant here.

	After those fields are produced, word splitting is (usually)
	performed, on each of them in turn, possibly generating more

[aside: "field' is the term used for what we would thing of as a word,
or perhaps an arg, but is more precisely defined, and those other terms
are used with different meanings.]

	What the NetBSD sh does is produce a single field, with the
	positional parameters separated by IFS[0] (the first char of $IFS)

	When word splitting is done, the field is split at each IFS[0]
	character (and other IFS characters if they occur) so each
	inserted IFS in the single field produced causes a new field
	to appear in the final output.

	It appears as if everything is just fine implementing it this
	way (and it more or less is) -- except when IFS=''

	Then the way the sh currently does it is simply to run all the
	positional parameters together into a single string.  Since there
	are no chars in IFS, when word splitting is attempted nothing
	happens.  The result is a single field, where there should be
	more one for each positional parameter.

	An easy way to see this is

		set a b c d		; # $# is 4, and $1 .. $4 are set
		IFS=			; no chars in IFS
		set $*			; set the args to whatever $* expands to
		echo $#			; should produce 4

	On NetBSD the final echo writes "1" rather than "4" as it should.
	There were 4 positional parameters, therefore $* should produce 4
	fields, each of which should be set back into the positional params
	1 .. 4.   Instead the NetBSD sh produces a single param "abcd"

	Note that if $* were quoted ("$*") what we do now is correct, even
	if it doesn't happen internally in quite the way envisaged.

	Not yet...

Home | Main Index | Thread Index | Old Index