diff options
author | Barton E. Schaefer <schaefer@zsh.org> | 2017-03-08 21:26:55 -0800 |
---|---|---|
committer | Barton E. Schaefer <schaefer@zsh.org> | 2017-03-08 21:26:55 -0800 |
commit | 071017965f469c88b10467205f30ea3e609e56dc (patch) | |
tree | a6472c26ba37ff83be987c782eef231d989d2607 /Src/Zle/computil.c | |
parent | 67d882479b61165c5d58bd72430d6009f4a7f25f (diff) | |
download | zsh-071017965f469c88b10467205f30ea3e609e56dc.tar.gz zsh-071017965f469c88b10467205f30ea3e609e56dc.tar.xz zsh-071017965f469c88b10467205f30ea3e609e56dc.zip |
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
Diffstat (limited to 'Src/Zle/computil.c')
-rw-r--r-- | Src/Zle/computil.c | 19 |
1 files changed, 13 insertions, 6 deletions
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; } |