diff options
author | Jun-ichi Takimoto <takimoto-j@kba.biglobe.ne.jp> | 2021-04-06 23:05:03 +0900 |
---|---|---|
committer | Jun-ichi Takimoto <takimoto-j@kba.biglobe.ne.jp> | 2021-04-06 23:05:03 +0900 |
commit | 0f62e07c802e3fa58d1199f34fcf9772da70c264 (patch) | |
tree | a85aec1da2877c2c97439f5fac5b1b24692e1f94 /Src | |
parent | ccc7ff90a46d7b1bdcf61bae2dba20d68dca7654 (diff) | |
download | zsh-0f62e07c802e3fa58d1199f34fcf9772da70c264.tar.gz zsh-0f62e07c802e3fa58d1199f34fcf9772da70c264.tar.xz zsh-0f62e07c802e3fa58d1199f34fcf9772da70c264.zip |
48389: getkeystring() should not return ptr to local var
Now it returns NULL if called with GETKEY_SINGLE_CHAR and next character is not found. Caller must check the return value.
Diffstat (limited to 'Src')
-rw-r--r-- | Src/math.c | 7 | ||||
-rw-r--r-- | Src/utils.c | 33 |
2 files changed, 31 insertions, 9 deletions
diff --git a/Src/math.c b/Src/math.c index b57ba42d4..1d0d86639 100644 --- a/Src/math.c +++ b/Src/math.c @@ -840,13 +840,18 @@ zzlex(void) if (*ptr == '#') { if (*++ptr == '\\' || *ptr == '#') { int v; + char *optr = ptr; ptr++; if (!*ptr) { zerr("bad math expression: character missing after ##"); return EOI; } - ptr = getkeystring(ptr, NULL, GETKEYS_MATH, &v); + if(!(ptr = getkeystring(ptr, NULL, GETKEYS_MATH, &v))) { + zerr("bad math expression: bad character after ##"); + ptr = optr; + return EOI; + } yyval.u.l = v; return NUM; } diff --git a/Src/utils.c b/Src/utils.c index 1ac064a4e..5a9222919 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -6697,13 +6697,21 @@ ucs4toutf8(char *dest, unsigned int wval) * * The return value is unmetafied unless GETKEY_DOLLAR_QUOTE is * in use. + * + * If GETKEY_SINGLE_CHAR is set in how, a next character in the given + * string is parsed, and the character code for it is returned in misc. + * The return value of the function is a pointer to the byte in the + * given string from where the next parsing should start. If the next + * character can't be found then NULL is returned. + * CAUTION: Currently, GETKEY_SINGLE_CHAR can be used only via + * GETKEYS_MATH. Other use of it may cause trouble. */ /**/ mod_export char * getkeystring(char *s, int *len, int how, int *misc) { - char *buf, tmp[1]; + char *buf = NULL, tmp[1]; char *t, *tdest = NULL, *u = NULL, *sstart = s, *tbuf = NULL; char svchar = '\0'; int meta = 0, control = 0, ignoring = 0; @@ -6729,9 +6737,11 @@ getkeystring(char *s, int *len, int how, int *misc) DPUTS((how & (GETKEY_DOLLAR_QUOTE|GETKEY_SINGLE_CHAR)) == (GETKEY_DOLLAR_QUOTE|GETKEY_SINGLE_CHAR), "BUG: incompatible options in getkeystring"); + DPUTS((how & GETKEY_SINGLE_CHAR) && (how != GETKEYS_MATH), + "BUG: unsupported options in getkeystring"); if (how & GETKEY_SINGLE_CHAR) - t = buf = tmp; + t = tmp; else { /* Length including terminating NULL */ int maxlen = 1; @@ -7165,13 +7175,20 @@ getkeystring(char *s, int *len, int how, int *misc) */ DPUTS((how & (GETKEY_DOLLAR_QUOTE|GETKEY_UPDATE_OFFSET)) == GETKEY_DOLLAR_QUOTE, "BUG: unterminated $' substitution"); - *t = '\0'; - if (how & GETKEY_DOLLAR_QUOTE) - *tdest = '\0'; - if (how & GETKEY_SINGLE_CHAR) + + if (how & GETKEY_SINGLE_CHAR) { + /* couldn't find a character */ *misc = 0; - else - *len = ((how & GETKEY_DOLLAR_QUOTE) ? tdest : t) - buf; + return NULL; + } + if (how & GETKEY_DOLLAR_QUOTE) { + *tdest = '\0'; + *len = tdest - buf; + } + else { + *t = '\0'; + *len = t - buf; + } return buf; } |