Subject: ash expansion of "$*" does not match manpage
To: None <gnats-bugs@NetBSD.ORG>
From: VaX#n8 <vax@linkdead.paranoia.com>
List: current-users
Date: 07/21/1996 13:49:08
>Submitter-Id: net
>Originator: VaX#n8
>Organization: Rampant Paranoia
>Confidential:
no
>Synopsis:
ash expansion of "$*" does not match manpage
>Severity:
non-critical
>Priority:
low
>Category:
sh/ash
>Class:
sw-bug
>Release: <NetBSD-current source date>
19906
>Environment:
System: NetBSD linkdead.paranoia.com 1.2_BETA NetBSD 1.2_BETA (LINKDEAD) #0: Sat Jul 20 02:34:14 CDT 1996 bashroot@linkdead.paranoia.com:/usr/src/sys/arch/i386/compile/LINKDEAD i386
>Description:
Due to expand.c:775
sep = '\0';
goto allargs;
}
/* fall through */
case '*':
sep = ' '; XXX here XXX
allargs:
for (ap = shellparam.p ; (p = *ap++) != NULL ; ) {
STRTODEST(p);
if (*ap)
STPUTC(sep, expdest);
It does not match the manpage sh.1:716-733
which says (formatted version included here, lines 813-830):
* Expands to the positional parameters, starting from
one. When the expansion occurs within a double-
quoted string it expands to a single field with the
value of each parameter separated by the first
^^^^^
character of the IFS variable, or by a <space> if
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^
IFS is unset.
^^^^^^^^^^^^
@ Expands to the positional parameters, starting from
one. When the expansion occurs within double-
quotes, each positional parameter expands as a sep-
arate argument. If there are no positional parame-
ters, the expansion of @ generates zero arguments,
even when @ is double-quoted. What this basically
means, for example, is if $1 is ``abc'' and $2 is
``def ghi'', then "$@" expands to the two argu-
ments:
"abc" "def ghi"
>How-To-Repeat:
/bin/sh <<EOM
set -- 1 2 3 4
IFS=".$IFS"
echo "$*"
exit
>Fix:
## Here's my fix results:
Script started on Sun Jul 21 13:31:39 1996
bash$ ./obj/sh
$ IFS=".$IFS"
$ echo $*
$ set -- 1 2 3 4
$ echo "$*"
1.2.3.4
$ echo $*
1 2 3 4
$ echo "$@"
1 2 3 4
$ eval echo $@
1 2 3 4
$ eval "echo $@"
1 2 3 4
$ eval "echo '$@'"
1 2 3 4
$ eval echo $*
1 2 3 4
$ eval echo "$*"
1.2.3.4
$ eval "echo $*"
1.2.3.4
$ eval "echo '$*'"
1.2.3.4
$ /usr/bin/true && echo "$*"
1.2.3.4
$ if /usr/bin/true; then echo "$@"; fi
1 2 3 4
$ if /usr/bin/true; then echo "$*"; fi
1.2.3.4
$ exit
bash$ exit
Script done on Sun Jul 21 13:34:55 1996
## And now the patch:
--- expand.c~ Wed Feb 14 06:13:38 1996
+++ expand.c Sun Jul 21 13:22:55 1996
@@ -772,7 +772,8 @@
}
/* fall through */
case '*':
- sep = ' ';
+ sep = ((p=bltinlookup("IFS", 1)) == NULL || p[0] == '\0')
+ ? ' ' : p[0];
allargs:
for (ap = shellparam.p ; (p = *ap++) != NULL ; ) {
STRTODEST(p);