From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 29058 invoked by alias); 17 Jun 2015 06:26:41 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: X-Seq: 35501 Received: (qmail 6917 invoked from network); 17 Jun 2015 06:26:39 -0000 X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_HI, RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL autolearn=ham autolearn_force=no version=3.4.0 X-Helo: d01dlp03.pok.ibm.com X-MailFrom: hanpt@linux.vnet.ibm.com X-RcptTo: zsh-workers@zsh.org Date: Wed, 17 Jun 2015 14:16:28 +0800 From: Han Pingtian To: zsh-workers@zsh.org Subject: [PATCH] don't let char class disturb end finding Message-ID: <20150617061628.GA27402@localhost.localdomain> Mail-Followup-To: zsh-workers@zsh.org MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 15061706-0033-0000-0000-000004E292FE Please review this patch. Thanks. This patch try to fix this problem: compadd -M '[[:lower:]123456]=...' will cause the end of class to be the ']' before 1 and will alloc range of memory less than enough for the cpattern. --- Src/Zle/complete.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/Src/Zle/complete.c b/Src/Zle/complete.c index ea5e41f..c3c6ac2 100644 --- a/Src/Zle/complete.c +++ b/Src/Zle/complete.c @@ -393,9 +393,12 @@ parse_pattern(char *name, char **sp, int *lp, char e, int *err) if (*s == '[' || *s == '{') { s = parse_class(n, s); - if (!*s) { + if (!s || !*s) { *err = 1; - zwarnnam(name, "unterminated character class"); + if (!s) + zwarnnam(name, "invalid character class"); + else + zwarnnam(name, "unterminated character class"); return NULL; } s++; @@ -439,7 +442,7 @@ parse_pattern(char *name, char **sp, int *lp, char e, int *err) static char * parse_class(Cpattern p, char *iptr) { - int endchar, firsttime = 1; + int endchar, firsttime = 1, rf = 0; char *optr, *nptr; if (*iptr++ == '[') { @@ -456,9 +459,24 @@ parse_class(Cpattern p, char *iptr) } /* find end of class. End character can appear literally first. */ - for (optr = iptr; optr == iptr || *optr != endchar; optr++) + for (optr = iptr; optr == iptr || *optr != endchar; optr++) { if (!*optr) return optr; + if (endchar == ']') { + if (!rf && *optr == '[' && optr[1] == ':') { + rf--; //range start likely + optr++; + } else if (rf < 0) { + if (*optr == ':' && optr[1] == ']') { + rf++; + optr++; + } + } + } + } + if (rf < 0) + return NULL; + /* * We can always fit the parsed class within the same length * because of the tokenization (including a null byte). @@ -479,6 +497,8 @@ parse_class(Cpattern p, char *iptr) iptr = nptr + 2; if (ch != PP_UNKWN) *optr++ = STOUC(Meta) + ch; + else + return NULL; } else { /* characters stay metafied */ char *ptr1 = iptr; -- 1.9.3