summaryrefslogtreecommitdiff
path: root/Src/Zle/computil.c
diff options
context:
space:
mode:
authorBarton E. Schaefer <schaefer@zsh.org>2017-03-08 21:26:55 -0800
committerBarton E. Schaefer <schaefer@zsh.org>2017-03-08 21:26:55 -0800
commit071017965f469c88b10467205f30ea3e609e56dc (patch)
treea6472c26ba37ff83be987c782eef231d989d2607 /Src/Zle/computil.c
parent67d882479b61165c5d58bd72430d6009f4a7f25f (diff)
downloadzsh-071017965f469c88b10467205f30ea3e609e56dc.tar.gz
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.c19
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;
}