From: Junio C Hamano Date: Fri, 24 Mar 2017 20:07:35 +0000 (-0700) Subject: Merge branch 'js/regexec-buf' X-Git-Tag: v2.13.0-rc0~80 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/0efeb5ca12f070ca3a8cec48761af863e9a7f6fe?ds=inline;hp=-c Merge branch 'js/regexec-buf' Fix for potential segv introduced in v2.11.0 and later (also v2.10.2). * js/regexec-buf: pickaxe: fix segfault with '-S<...> --pickaxe-regex' --- 0efeb5ca12f070ca3a8cec48761af863e9a7f6fe diff --combined diffcore-pickaxe.c index 9795ca1c15,e627140b85..341529b5a8 --- a/diffcore-pickaxe.c +++ b/diffcore-pickaxe.c @@@ -7,8 -7,6 +7,8 @@@ #include "diffcore.h" #include "xdiff-interface.h" #include "kwset.h" +#include "commit.h" +#include "quote.h" typedef int (*pickaxe_fn)(mmfile_t *one, mmfile_t *two, struct diff_options *o, @@@ -81,12 -79,15 +81,15 @@@ static unsigned int contains(mmfile_t * regmatch_t regmatch; int flags = 0; - while (*data && + while (sz && *data && !regexec_buf(regexp, data, sz, 1, ®match, flags)) { flags |= REG_NOTBOL; data += regmatch.rm_eo; - if (*data && regmatch.rm_so == regmatch.rm_eo) + sz -= regmatch.rm_eo; + if (sz && *data && regmatch.rm_so == regmatch.rm_eo) { data++; + sz--; + } cnt++; } @@@ -198,18 -199,6 +201,18 @@@ static void pickaxe(struct diff_queue_s *q = outq; } +static void regcomp_or_die(regex_t *regex, const char *needle, int cflags) +{ + int err = regcomp(regex, needle, cflags); + if (err) { + /* The POSIX.2 people are surely sick */ + char errbuf[1024]; + regerror(err, regex, errbuf, 1024); + regfree(regex); + die("invalid regex: %s", errbuf); + } +} + void diffcore_pickaxe(struct diff_options *o) { const char *needle = o->pickaxe; @@@ -218,19 -207,18 +221,19 @@@ kwset_t kws = NULL; if (opts & (DIFF_PICKAXE_REGEX | DIFF_PICKAXE_KIND_G)) { - int err; int cflags = REG_EXTENDED | REG_NEWLINE; if (DIFF_OPT_TST(o, PICKAXE_IGNORE_CASE)) cflags |= REG_ICASE; - err = regcomp(®ex, needle, cflags); - if (err) { - /* The POSIX.2 people are surely sick */ - char errbuf[1024]; - regerror(err, ®ex, errbuf, 1024); - regfree(®ex); - die("invalid regex: %s", errbuf); - } + regcomp_or_die(®ex, needle, cflags); + regexp = ®ex; + } else if (DIFF_OPT_TST(o, PICKAXE_IGNORE_CASE) && + has_non_ascii(needle)) { + struct strbuf sb = STRBUF_INIT; + int cflags = REG_NEWLINE | REG_ICASE; + + basic_regex_quote_buf(&sb, needle); + regcomp_or_die(®ex, sb.buf, cflags); + strbuf_release(&sb); regexp = ®ex; } else { kws = kwsalloc(DIFF_OPT_TST(o, PICKAXE_IGNORE_CASE)