* [EXPAND] Split unquoted $@/$* correctly when IFS is set but empty
@ 2014-10-08 7:26 Herbert Xu
2014-10-20 21:59 ` Stephane Chazelas
0 siblings, 1 reply; 2+ messages in thread
From: Herbert Xu @ 2014-10-08 7:26 UTC (permalink / raw)
To: dash
commit 3c06acdac0b1ba0e0acdda513a57ee6e31385dce
Author: Herbert Xu <herbert@gondor.apana.org.au>
Date: Wed Oct 8 15:24:23 2014 +0800
[EXPAND] Split unquoted $@/$* correctly when IFS is set but empty
Currently we do not field-split $@/$* when it isn't quoted and IFS
is set but empty. This is obviously wrong. This patch fixes this.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
diff --git a/ChangeLog b/ChangeLog
index b990628..dd2ee9d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2014-10-08 Herbert Xu <herbert@gondor.apana.org.au>
+
+ * Split unquoted $@/$* correctly when IFS is set but empty.
+
2014-10-07 Herbert Xu <herbert@gondor.apana.org.au>
* Use setvareq to set OPTIND initially.
diff --git a/src/expand.c b/src/expand.c
index 11fd7b7..51ba8a1 100644
--- a/src/expand.c
+++ b/src/expand.c
@@ -116,7 +116,7 @@ STATIC const char *subevalvar(char *, char *, int, int, int, int, int);
STATIC char *evalvar(char *, int);
STATIC size_t strtodest(const char *, const char *, int);
STATIC void memtodest(const char *, size_t, const char *, int);
-STATIC ssize_t varvalue(char *, int, int);
+STATIC ssize_t varvalue(char *, int, int, int *);
STATIC void expandmeta(struct strlist *, int);
#ifdef HAVE_GLOB
STATIC void addglob(const glob_t *);
@@ -722,6 +722,7 @@ evalvar(char *p, int flag)
ssize_t varlen;
int easy;
int quoted;
+ int nulonly;
varflags = *p++;
subtype = varflags & VSTYPE;
@@ -732,11 +733,12 @@ evalvar(char *p, int flag)
quoted = flag & EXP_QUOTED;
var = p;
easy = (!quoted || (*var == '@' && shellparam.nparam));
+ nulonly = easy;
startloc = expdest - (char *)stackblock();
p = strchr(p, '=') + 1;
again:
- varlen = varvalue(var, varflags, flag);
+ varlen = varvalue(var, varflags, flag, &nulonly);
if (varflags & VSNUL)
varlen--;
@@ -787,7 +789,7 @@ vsplus:
if (!easy)
goto end;
record:
- recordregion(startloc, expdest - (char *)stackblock(), quoted);
+ recordregion(startloc, expdest - (char *)stackblock(), nulonly);
goto end;
}
@@ -892,7 +894,7 @@ strtodest(p, syntax, quotes)
*/
STATIC ssize_t
-varvalue(char *name, int varflags, int flags)
+varvalue(char *name, int varflags, int flags, int *nulonly)
{
int num;
char *p;
@@ -907,7 +909,8 @@ varvalue(char *name, int varflags, int flags)
int quotes = (discard ? 0 : (flags & QUOTES_ESC)) | QUOTES_KEEPNUL;
ssize_t len = 0;
- sep = quoted ? ((flags & EXP_FULL) << CHAR_BIT) : 0;
+ sep = *nulonly ? (flags & EXP_FULL) << CHAR_BIT : 0;
+ *nulonly = 0;
syntax = quoted ? DQSYNTAX : BASESYNTAX;
switch (*name) {
@@ -938,15 +941,16 @@ numvar:
expdest = p;
break;
case '@':
- if (sep)
+ if (quoted)
goto param;
/* fall through */
case '*':
- sep = ifsset() ? ifsval()[0] : ' ';
+ sep |= ifsset() ? ifsval()[0] : ' ';
param:
if (!(ap = shellparam.p))
return -1;
sepc = sep;
+ *nulonly = !sepc;
while ((p = *ap++)) {
len += strtodest(p, syntax, quotes);
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [EXPAND] Split unquoted $@/$* correctly when IFS is set but empty
2014-10-08 7:26 [EXPAND] Split unquoted $@/$* correctly when IFS is set but empty Herbert Xu
@ 2014-10-20 21:59 ` Stephane Chazelas
0 siblings, 0 replies; 2+ messages in thread
From: Stephane Chazelas @ 2014-10-20 21:59 UTC (permalink / raw)
To: dash
2014-10-08 15:26:36 +0800, Herbert Xu:
> commit 3c06acdac0b1ba0e0acdda513a57ee6e31385dce
> Author: Herbert Xu <herbert@gondor.apana.org.au>
> Date: Wed Oct 8 15:24:23 2014 +0800
>
> [EXPAND] Split unquoted $@/$* correctly when IFS is set but empty
>
> Currently we do not field-split $@/$* when it isn't quoted and IFS
> is set but empty. This is obviously wrong. This patch fixes this.
[...]
Well, if IFS is empty, field splitting is disabled. There's
nothing in POSIX that clearly says that $@ and $* should expand
to the positional parameters *as separate arguments in list
contexts*. yash and the Bourne shell behave like dash. Only
shells with array support behave differently.
The whole $*/$@ expansion is rather unclear in the POSIX spec.
I've just raised the problem on the Austin group mailing list.
See also
http://thread.gmane.org/gmane.linux.debian.devel.general/197901
Cheers,
Stephane
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2014-10-20 22:10 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-10-08 7:26 [EXPAND] Split unquoted $@/$* correctly when IFS is set but empty Herbert Xu
2014-10-20 21:59 ` Stephane Chazelas
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).