diff options
author | Peter Stephenson <p.w.stephenson@ntlworld.com> | 2015-01-18 22:38:57 +0000 |
---|---|---|
committer | Peter Stephenson <p.w.stephenson@ntlworld.com> | 2015-01-18 22:38:57 +0000 |
commit | c6c9f5daf2e196e6ab7346dfbf5f5166a1d87f0c (patch) | |
tree | de064fa6ba629549d42868b7016dd3c28bfb0e34 /Src/lex.c | |
parent | 6856ab39e32e0cba96fcdae004878938125890ac (diff) | |
download | zsh-c6c9f5daf2e196e6ab7346dfbf5f5166a1d87f0c.tar.gz zsh-c6c9f5daf2e196e6ab7346dfbf5f5166a1d87f0c.tar.xz zsh-c6c9f5daf2e196e6ab7346dfbf5f5166a1d87f0c.zip |
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.
Diffstat (limited to 'Src/lex.c')
-rw-r--r-- | Src/lex.c | 30 |
1 files changed, 21 insertions, 9 deletions
diff --git a/Src/lex.c b/Src/lex.c index e4dfdfaca..433c27fbb 100644 --- a/Src/lex.c +++ b/Src/lex.c @@ -1503,17 +1503,27 @@ dquote_parse(char endchar, int sub) 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 -parsestr(char *s) +parsestr(char **s) { int err; if ((err = parsestrnoerr(s))) { - untokenize(s); + untokenize(*s); if (err > 32 && err < 127) zerr("parse error near `%c'", err); else @@ -1524,18 +1534,20 @@ parsestr(char *s) /**/ mod_export int -parsestrnoerr(char *s) +parsestrnoerr(char **s) { - int l = strlen(s), err; + int l = strlen(*s), err; zcontext_save(); - untokenize(s); - inpush(dupstring(s), 0, NULL); + untokenize(*s); + inpush(dupstring(*s), 0, NULL); strinbeg(0); lexbuf.len = 0; - lexbuf.ptr = tokstr = s; + lexbuf.ptr = tokstr = *s; lexbuf.siz = l + 1; err = dquote_parse('\0', 1); + if (tokstr) + *s = tokstr; *lexbuf.ptr = '\0'; strinend(); inpop(); |