summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2008-11-02 17:36:26 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2008-11-02 17:36:26 +0000
commitd41c6098b4a23c247467180497169b0bb0ea74ad (patch)
tree29cbad0f4eb93eac6ff2adf98962ed8c05bb2450
parent6dbf2f2f4a97e2831094a73c662484ce990e7e41 (diff)
downloadzsh-d41c6098b4a23c247467180497169b0bb0ea74ad.tar.gz
zsh-d41c6098b4a23c247467180497169b0bb0ea74ad.zip
25989: fix crash in matching
-rw-r--r--ChangeLog5
-rw-r--r--Src/Zle/computil.c63
2 files changed, 32 insertions, 36 deletions
diff --git a/ChangeLog b/ChangeLog
index fbdb631ae..ed9cfb25e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2008-11-02 Peter Stephenson <p.w.stephenson@ntlworld.com>
+
+ * 25989: Src/Zle/computil.c: Slight improvement for multibyte
+ characters in matching to prevent crash.
+
2008-11-02 Clint Adams <clint@zsh.org>
* 25988: Completion/Darwin/Command/_fink,
diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c
index 056a611ac..264213ccf 100644
--- a/Src/Zle/computil.c
+++ b/Src/Zle/computil.c
@@ -4024,7 +4024,17 @@ cfp_matcher_range(Cmatcher *ms, char *add)
* management is difficult.
*/
for (;;) {
+ MB_METACHARINIT();
for (mp = ms; *add; ) {
+ convchar_t addc;
+ int addlen;
+
+ addlen = MB_METACHARLENCONV(add, &addc);
+#ifdef MULTIBYTE_SUPPORT
+ if (addc == WEOF)
+ addc = (wchar_t)(*p == Meta ? p[1] ^ 32 : *p);
+#endif
+
if (!(m = *mp)) {
/*
* No matcher, so just match the character
@@ -4034,13 +4044,10 @@ cfp_matcher_range(Cmatcher *ms, char *add)
* metacharacter?
*/
if (ret) {
- if (*add == Meta) {
- *p++ = Meta;
- *p++ = add[1];
- } else
- *p++ = *add;
+ memcpy(p, add, addlen);
+ p += addlen;
} else
- len += (*add == Meta) ? 2 : 1;
+ len += addlen;
} else if (m->flags & CMF_RIGHT) {
/*
* Right-anchored: match anything followed
@@ -4049,16 +4056,12 @@ cfp_matcher_range(Cmatcher *ms, char *add)
if (ret) {
*p++ = '*';
/* TODO: quote again? */
- if (*add == Meta) {
- *p++ = Meta;
- *p++ = add[1];
- } else
- *p++ = *add;
+ memcpy(p, add, addlen);
+ p += addlen;
} else
- len += (*add == Meta) ? 3 : 2;
+ len += addlen + 1;
} else {
/* The usual set of matcher possibilities. */
- int chr = (*add == Meta) ? add[1] ^ 32 : *add;
int ind;
if (m->line->tp == CPAT_EQUIV &&
m->word->tp == CPAT_EQUIV) {
@@ -4073,21 +4076,17 @@ cfp_matcher_range(Cmatcher *ms, char *add)
*/
if (ret) {
*p++ = '[';
- if (*add == Meta) {
- *p++ = Meta;
- *p++ = add[1];
- } else
- *p++ = *add;
+ memcpy(p, add, addlen);
+ p += addlen;
} else
- len += (*add == Meta) ? 3 : 2;
- if (PATMATCHRANGE(m->line->u.str, CONVCAST(chr),
- &ind, &mt)) {
+ len += addlen + 1;
+ if (PATMATCHRANGE(m->line->u.str, addc, &ind, &mt)) {
/*
* Find the equivalent match for ind in the
* word pattern.
*/
if ((ind = pattern_match_equivalence
- (m->word, ind, mt, CONVCAST(chr))) != -1) {
+ (m->word, ind, mt, addc)) != -1) {
if (ret) {
if (imeta(ind)) {
*p++ = Meta;
@@ -4159,7 +4158,7 @@ cfp_matcher_range(Cmatcher *ms, char *add)
* if *add is ] and ] is also the first
* character in the range.
*/
- addadd = !pattern_match1(m->word, CONVCAST(chr), &mt);
+ addadd = !pattern_match1(m->word, addc, &mt);
if (addadd && *add == ']') {
if (ret)
*p++ = *add;
@@ -4196,13 +4195,10 @@ cfp_matcher_range(Cmatcher *ms, char *add)
}
if (addadd && *add != ']') {
if (ret) {
- if (imeta(*add)) {
- *p++ = Meta;
- *p++ = *add ^ 32;
- } else
- *p++ = *add;
+ memcpy(p, add, addlen);
+ p += addlen;
} else
- len += imeta(*add) ? 2 : 1;
+ len += addlen;
}
if (ret)
*p++ = ']';
@@ -4219,13 +4215,8 @@ cfp_matcher_range(Cmatcher *ms, char *add)
}
}
}
- if (*add == Meta) {
- add += 2;
- mp += 2;
- } else {
- add++;
- mp++;
- }
+ add += addlen;
+ mp++;
}
if (ret) {
*p = '\0';