From 071017965f469c88b10467205f30ea3e609e56dc Mon Sep 17 00:00:00 2001 From: "Barton E. Schaefer" Date: Wed, 8 Mar 2017 21:26:55 -0800 Subject: 40763: count wide characters and Cmatcher pointers more sanely in cfp_matcher_pats(), and count characters in pattern_match() the same way to stay in sync Might not fix wide-char matching in completion matcher-lists but should avoid wild pointer crash --- Src/Zle/compmatch.c | 57 +++++------------------------------------------------ Src/Zle/computil.c | 19 ++++++++++++------ 2 files changed, 18 insertions(+), 58 deletions(-) (limited to 'Src/Zle') diff --git a/Src/Zle/compmatch.c b/Src/Zle/compmatch.c index aedf463fc..1cdbb8a48 100644 --- a/Src/Zle/compmatch.c +++ b/Src/Zle/compmatch.c @@ -1548,27 +1548,11 @@ pattern_match(Cpattern p, char *s, Cpattern wp, char *ws) { convchar_t c, wc; convchar_t ind, wind; - int len = 0, wlen, mt, wmt; -#ifdef MULTIBYTE_SUPPORT - mbstate_t lstate, wstate; - - memset(&lstate, 0, sizeof(lstate)); - memset(&wstate, 0, sizeof(wstate)); -#endif + int len = 0, wlen = 0, mt, wmt; while (p && wp && *s && *ws) { /* First test the word character */ -#ifdef MULTIBYTE_SUPPORT - wlen = mb_metacharlenconv_r(ws, &wc, &wstate); -#else - if (*ws == Meta) { - wc = STOUC(ws[1]) ^ 32; - wlen = 2; - } else { - wc = STOUC(*ws); - wlen = 1; - } -#endif + wc = unmeta_one(ws, &wlen); wind = pattern_match1(wp, wc, &wmt); if (!wind) return 0; @@ -1576,18 +1560,7 @@ pattern_match(Cpattern p, char *s, Cpattern wp, char *ws) /* * Now the line character. */ -#ifdef MULTIBYTE_SUPPORT - len = mb_metacharlenconv_r(s, &c, &lstate); -#else - /* We have the character itself. */ - if (*s == Meta) { - c = STOUC(s[1]) ^ 32; - len = 2; - } else { - c = STOUC(*s); - len = 1; - } -#endif + c = unmeta_one(s, &len); /* * If either is "?", they match each other; no further tests. * Apply this even if the character wasn't convertable; @@ -1627,17 +1600,7 @@ pattern_match(Cpattern p, char *s, Cpattern wp, char *ws) } while (p && *s) { -#ifdef MULTIBYTE_SUPPORT - len = mb_metacharlenconv_r(s, &c, &lstate); -#else - if (*s == Meta) { - c = STOUC(s[1]) ^ 32; - len = 2; - } else { - c = STOUC(*s); - len = 1; - } -#endif + c = unmeta_one(s, &len); if (!pattern_match1(p, c, &mt)) return 0; p = p->next; @@ -1645,17 +1608,7 @@ pattern_match(Cpattern p, char *s, Cpattern wp, char *ws) } while (wp && *ws) { -#ifdef MULTIBYTE_SUPPORT - wlen = mb_metacharlenconv_r(ws, &wc, &wstate); -#else - if (*ws == Meta) { - wc = STOUC(ws[1]) ^ 32; - wlen = 2; - } else { - wc = STOUC(*ws); - wlen = 1; - } -#endif + wc = unmeta_one(ws, &wlen); if (!pattern_match1(wp, wc, &wmt)) return 0; wp = wp->next; diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c index 325da6ddb..e704f9ffa 100644 --- a/Src/Zle/computil.c +++ b/Src/Zle/computil.c @@ -4465,17 +4465,24 @@ cfp_matcher_pats(char *matcher, char *add) if (m && m != pcm_err) { char *tmp; int al = strlen(add), zl = ztrlen(add), tl, cl; - VARARR(Cmatcher, ms, zl); + VARARR(Cmatcher, ms, zl); /* One Cmatcher per character */ Cmatcher *mp; Cpattern stopp; int stopl = 0; + /* zl >= (number of wide characters) is guaranteed */ memset(ms, 0, zl * sizeof(Cmatcher)); for (; m && *add; m = m->next) { stopp = NULL; if (!(m->flags & (CMF_LEFT|CMF_RIGHT))) { if (m->llen == 1 && m->wlen == 1) { + /* + * In this loop and similar loops below we step + * through tmp one (possibly wide) character at a + * time. pattern_match() compares only the first + * character using unmeta_one() so keep in step. + */ for (tmp = add, tl = al, mp = ms; tl; ) { if (pattern_match(m->line, tmp, NULL, NULL)) { if (*mp) { @@ -4485,10 +4492,10 @@ cfp_matcher_pats(char *matcher, char *add) } else *mp = m; } - cl = (*tmp == Meta) ? 2 : 1; + (void) unmeta_one(tmp, &cl); tl -= cl; tmp += cl; - mp += cl; + mp++; } } else { stopp = m->line; @@ -4505,10 +4512,10 @@ cfp_matcher_pats(char *matcher, char *add) } else *mp = m; } - cl = (*tmp == Meta) ? 2 : 1; + (void) unmeta_one(tmp, &cl); tl -= cl; tmp += cl; - mp += cl; + mp++; } } else if (m->llen) { stopp = m->line; @@ -4531,7 +4538,7 @@ cfp_matcher_pats(char *matcher, char *add) al = tmp - add; break; } - cl = (*tmp == Meta) ? 2 : 1; + (void) unmeta_one(tmp, &cl); tl -= cl; tmp += cl; } -- cgit 1.4.1