1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-09-23 17:01:05 +02:00

34322: bug with interface to parsestr() etc.

Was showing up in places like ${(e)...} where command substitution
could reallocate the token string, but actually there was never any
guarantee that the lexer wouldn't do that, so this was always
a bit iffy.
This commit is contained in:
Peter Stephenson 2015-01-18 22:38:57 +00:00
parent 6856ab39e3
commit c6c9f5daf2
11 changed files with 59 additions and 26 deletions

View file

@ -1,5 +1,11 @@
2015-01-18 Peter Stephenson <p.w.stephenson@ntlworld.com> 2015-01-18 Peter Stephenson <p.w.stephenson@ntlworld.com>
* 34322: Src/Zle/compctl.c, Src/Zle/compresult.c, Src/exec.c,
Src/init.c, Src/lex.c, Src/params.c, Src/prompt.c, Src/subst.c,
Src/utils.c, Test/D04parameter.ztst: update interface to
parsestr()/parsestrnoerr() to ensure correct token string
is passed back.
* 34320: Src/hist.c, Src/lex.c: alias expansion in history of * 34320: Src/hist.c, Src/lex.c: alias expansion in history of
command substitution. command substitution.

View file

@ -3853,7 +3853,7 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd)
yaptr = get_user_var(uv); yaptr = get_user_var(uv);
if ((tt = cc->explain)) { if ((tt = cc->explain)) {
tt = dupstring(tt); tt = dupstring(tt);
if ((cc->mask & CC_EXPANDEXPL) && !parsestr(tt)) { if ((cc->mask & CC_EXPANDEXPL) && !parsestr(&tt)) {
singsub(&tt); singsub(&tt);
untokenize(tt); untokenize(tt);
} }
@ -3873,7 +3873,7 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd)
} }
} else if ((tt = cc->explain)) { } else if ((tt = cc->explain)) {
tt = dupstring(tt); tt = dupstring(tt);
if ((cc->mask & CC_EXPANDEXPL) && !parsestr(tt)) { if ((cc->mask & CC_EXPANDEXPL) && !parsestr(&tt)) {
singsub(&tt); singsub(&tt);
untokenize(tt); untokenize(tt);
} }

View file

@ -1090,7 +1090,8 @@ do_single(Cmatch m)
} }
if (tryit) { if (tryit) {
noerrs = 1; noerrs = 1;
parsestr(p); p = dupstring(p);
parsestr(&p);
singsub(&p); singsub(&p);
errflag &= ~ERRFLAG_ERROR; errflag &= ~ERRFLAG_ERROR;
noerrs = ne; noerrs = ne;

View file

@ -3772,19 +3772,20 @@ gethere(char **strp, int typ)
*bptr++ = '\n'; *bptr++ = '\n';
} }
*t = '\0'; *t = '\0';
s = buf;
buf = dupstring(buf);
zfree(s, bsiz);
if (!qt) { if (!qt) {
int ef = errflag; int ef = errflag;
parsestr(buf); parsestr(&buf);
if (!errflag) { if (!errflag) {
/* Retain any user interrupt error */ /* Retain any user interrupt error */
errflag = ef | (errflag & ERRFLAG_INT); errflag = ef | (errflag & ERRFLAG_INT);
} }
} }
s = dupstring(buf); return buf;
zfree(buf, bsiz);
return s;
} }
/* open here string fd */ /* open here string fd */

View file

@ -1197,11 +1197,14 @@ run_init_scripts(void)
if (islogin) if (islogin)
sourcehome(".profile"); sourcehome(".profile");
noerrs = 2; noerrs = 2;
if (s && !parsestr(s)) { if (s) {
s = dupstring(s);
if (!parsestr(&s)) {
singsub(&s); singsub(&s);
noerrs = 0; noerrs = 0;
source(s); source(s);
} }
}
noerrs = 0; noerrs = 0;
} else } else
source("/etc/suid_profile"); source("/etc/suid_profile");

View file

@ -1503,17 +1503,27 @@ dquote_parse(char endchar, int sub)
return err; return err;
} }
/* Tokenize a string given in s. Parsing is done as in double * /*
* quotes. This is usually called before singsub(). */ * Tokenize a string given in s. Parsing is done as in double
* quotes. This is usually called before singsub().
*
* parsestr() is noisier, reporting an error if the parse failed.
*
* On entry, *s must point to a string allocated from the stack of
* exactly the right length, i.e. strlen(*s) + 1, as the string
* is used as the lexical token string whose memory management
* demands this. Usually the input string will therefore be
* the result of an immediately preceding dupstring().
*/
/**/ /**/
mod_export int mod_export int
parsestr(char *s) parsestr(char **s)
{ {
int err; int err;
if ((err = parsestrnoerr(s))) { if ((err = parsestrnoerr(s))) {
untokenize(s); untokenize(*s);
if (err > 32 && err < 127) if (err > 32 && err < 127)
zerr("parse error near `%c'", err); zerr("parse error near `%c'", err);
else else
@ -1524,18 +1534,20 @@ parsestr(char *s)
/**/ /**/
mod_export int mod_export int
parsestrnoerr(char *s) parsestrnoerr(char **s)
{ {
int l = strlen(s), err; int l = strlen(*s), err;
zcontext_save(); zcontext_save();
untokenize(s); untokenize(*s);
inpush(dupstring(s), 0, NULL); inpush(dupstring(*s), 0, NULL);
strinbeg(0); strinbeg(0);
lexbuf.len = 0; lexbuf.len = 0;
lexbuf.ptr = tokstr = s; lexbuf.ptr = tokstr = *s;
lexbuf.siz = l + 1; lexbuf.siz = l + 1;
err = dquote_parse('\0', 1); err = dquote_parse('\0', 1);
if (tokstr)
*s = tokstr;
*lexbuf.ptr = '\0'; *lexbuf.ptr = '\0';
strinend(); strinend();
inpop(); inpop();

View file

@ -1260,7 +1260,8 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w,
if (ishash && (keymatch || !rev)) if (ishash && (keymatch || !rev))
remnulargs(s); remnulargs(s);
if (needtok) { if (needtok) {
if (parsestr(s)) s = dupstring(s);
if (parsestr(&s))
return 0; return 0;
singsub(&s); singsub(&s);
} else if (rev) } else if (rev)

View file

@ -183,7 +183,7 @@ promptexpand(char *s, int ns, char *rs, char *Rs, unsigned int *txtchangep)
int oldval = lastval; int oldval = lastval;
s = dupstring(s); s = dupstring(s);
if (!parsestr(s)) if (!parsestr(&s))
singsub(&s); singsub(&s);
/* /*
* We don't need the special Nularg hack here and we're * We don't need the special Nularg hack here and we're

View file

@ -1306,7 +1306,7 @@ get_intarg(char **s, int *delmatchp)
p = dupstring(*s + arglen); p = dupstring(*s + arglen);
*s = t + arglen; *s = t + arglen;
*t = sav; *t = sav;
if (parsestr(p)) if (parsestr(&p))
return -1; return -1;
singsub(&p); singsub(&p);
if (errflag) if (errflag)
@ -1329,7 +1329,8 @@ subst_parse_str(char **sp, int single, int err)
*sp = s = dupstring(*sp); *sp = s = dupstring(*sp);
if (!(err ? parsestr(s) : parsestrnoerr(s))) { if (!(err ? parsestr(&s) : parsestrnoerr(&s))) {
*sp = s;
if (!single) { if (!single) {
int qt = 0; int qt = 0;
@ -1439,7 +1440,8 @@ check_colon_subscript(char *str, char **endp)
} }
sav = **endp; sav = **endp;
**endp = '\0'; **endp = '\0';
if (parsestr(str = dupstring(str))) str = dupstring(str);
if (parsestr(&str))
return NULL; return NULL;
singsub(&str); singsub(&str);
remnulargs(str); remnulargs(str);

View file

@ -1515,7 +1515,7 @@ checkmailpath(char **s)
setunderscore(*s); setunderscore(*s);
u = dupstring(u); u = dupstring(u);
if (! parsestr(u)) { if (!parsestr(&u)) {
singsub(&u); singsub(&u);
zputs(u, shout); zputs(u, shout);
fputc('\n', shout); fputc('\n', shout);

View file

@ -1663,3 +1663,10 @@
0:SHLVL appears sensible when about to exit shell 0:SHLVL appears sensible when about to exit shell
>2 >2
>2 >2
# The following tests the return behaviour of parsestr/parsestrnoerr
alias param-test-alias='print $'\''\x45xpanded in substitution'\'
param='$(param-test-alias)'
print ${(e)param}
0:Alias expansion in command substitution in parameter evaluation
>Expanded in substitution