pcre2_malloc, pcre2_free, NULL);
#endif
-#ifdef USE_LIBPCRE1
- pcre_malloc = malloc;
- pcre_free = free;
-#endif
-
*opt = grep_defaults;
opt->repo = repo;
break;
case GREP_PATTERN_TYPE_PCRE:
-#ifdef USE_LIBPCRE2
opt->pcre2 = 1;
-#else
- /*
- * It's important that pcre1 always be assigned to
- * even when there's no USE_LIBPCRE* defined. We still
- * call the PCRE stub function, it just dies with
- * "cannot use Perl-compatible regexes[...]".
- */
- opt->pcre1 = 1;
-#endif
break;
}
}
return 1;
}
-#ifdef USE_LIBPCRE1
-static void compile_pcre1_regexp(struct grep_pat *p, const struct grep_opt *opt)
-{
- const char *error;
- int erroffset;
- int options = PCRE_MULTILINE;
- int study_options = 0;
-
- if (opt->ignore_case) {
- if (!opt->ignore_locale && has_non_ascii(p->pattern))
- p->pcre1_tables = pcre_maketables();
- options |= PCRE_CASELESS;
- }
- if (!opt->ignore_locale && is_utf8_locale() && has_non_ascii(p->pattern))
- options |= PCRE_UTF8;
-
- p->pcre1_regexp = pcre_compile(p->pattern, options, &error, &erroffset,
- p->pcre1_tables);
- if (!p->pcre1_regexp)
- compile_regexp_failed(p, error);
-
-#if defined(PCRE_CONFIG_JIT) && !defined(NO_LIBPCRE1_JIT)
- pcre_config(PCRE_CONFIG_JIT, &p->pcre1_jit_on);
-
- if (p->pcre1_jit_on)
- study_options = PCRE_STUDY_JIT_COMPILE;
-#endif
-
- p->pcre1_extra_info = pcre_study(p->pcre1_regexp, study_options, &error);
- if (!p->pcre1_extra_info && error)
- die("%s", error);
-}
-
-static int pcre1match(struct grep_pat *p, const char *line, const char *eol,
- regmatch_t *match, int eflags)
-{
- int ovector[30], ret, flags = PCRE_NO_UTF8_CHECK;
-
- if (eflags & REG_NOTBOL)
- flags |= PCRE_NOTBOL;
-
- ret = pcre_exec(p->pcre1_regexp, p->pcre1_extra_info, line,
- eol - line, 0, flags, ovector,
- ARRAY_SIZE(ovector));
-
- if (ret < 0 && ret != PCRE_ERROR_NOMATCH)
- die("pcre_exec failed with error code %d", ret);
- if (ret > 0) {
- ret = 0;
- match->rm_so = ovector[0];
- match->rm_eo = ovector[1];
- }
-
- return ret;
-}
-
-static void free_pcre1_regexp(struct grep_pat *p)
-{
- pcre_free(p->pcre1_regexp);
-#ifdef PCRE_CONFIG_JIT
- if (p->pcre1_jit_on)
- pcre_free_study(p->pcre1_extra_info);
- else
-#endif
- pcre_free(p->pcre1_extra_info);
- pcre_free((void *)p->pcre1_tables);
-}
-#else /* !USE_LIBPCRE1 */
-static void compile_pcre1_regexp(struct grep_pat *p, const struct grep_opt *opt)
-{
- die("cannot use Perl-compatible regexes when not compiled with USE_LIBPCRE");
-}
-
-static int pcre1match(struct grep_pat *p, const char *line, const char *eol,
- regmatch_t *match, int eflags)
-{
- return 1;
-}
-
-static void free_pcre1_regexp(struct grep_pat *p)
-{
-}
-#endif /* !USE_LIBPCRE1 */
-
#ifdef USE_LIBPCRE2
static void compile_pcre2_pattern(struct grep_pat *p, const struct grep_opt *opt)
{
}
if (!opt->ignore_locale && is_utf8_locale() && has_non_ascii(p->pattern) &&
!(!opt->ignore_case && (p->fixed || p->is_fixed)))
- options |= PCRE2_UTF;
+ options |= (PCRE2_UTF | PCRE2_MATCH_INVALID_UTF);
+
+ /* Work around https://bugs.exim.org/show_bug.cgi?id=2642 fixed in 10.36 */
+ if (PCRE2_MATCH_INVALID_UTF && options & (PCRE2_UTF | PCRE2_CASELESS)) {
+ struct strbuf buf;
+ int len;
+ int err;
+
+ if ((len = pcre2_config(PCRE2_CONFIG_VERSION, NULL)) < 0)
+ BUG("pcre2_config(..., NULL) failed: %d", len);
+ strbuf_init(&buf, len + 1);
+ if ((err = pcre2_config(PCRE2_CONFIG_VERSION, buf.buf)) < 0)
+ BUG("pcre2_config(..., buf.buf) failed: %d", err);
+ if (versioncmp(buf.buf, "10.36") < 0)
+ options |= PCRE2_NO_START_OPTIMIZE;
+ strbuf_release(&buf);
+ }
p->pcre2_pattern = pcre2_compile((PCRE2_SPTR)p->pattern,
p->patternlen, options, &error, &erroffset,
#else /* !USE_LIBPCRE2 */
static void compile_pcre2_pattern(struct grep_pat *p, const struct grep_opt *opt)
{
- /*
- * Unreachable until USE_LIBPCRE2 becomes synonymous with
- * USE_LIBPCRE. See the sibling comment in
- * grep_set_pattern_type_option().
- */
die("cannot use Perl-compatible regexes when not compiled with USE_LIBPCRE");
}
return;
}
- if (opt->pcre1) {
- compile_pcre1_regexp(p, opt);
- return;
- }
-
if (p->ignore_case)
regflags |= REG_ICASE;
if (opt->extended_regexp_option)
case GREP_PATTERN: /* atom */
case GREP_PATTERN_HEAD:
case GREP_PATTERN_BODY:
- if (p->pcre1_regexp)
- free_pcre1_regexp(p);
- else if (p->pcre2_pattern)
+ if (p->pcre2_pattern)
free_pcre2_pattern(p);
else
regfree(&p->regexp);
{
int hit;
- if (p->pcre1_regexp)
- hit = !pcre1match(p, line, eol, match, eflags);
- else if (p->pcre2_pattern)
+ if (p->pcre2_pattern)
hit = !pcre2match(p, line, eol, match, eflags);
else
hit = !regexec_buf(&p->regexp, line, eol - line, 1, match,