Commit cbd5d1c4 authored by Dan McGee's avatar Dan McGee Committed by Tollef Fog Heen

Enable PCRE JIT-compiled regular expressions

Implemented more or less as described in the pcrejit(3) manpage, and
adds some compatibility defines for use with older pre-8.20 libraries
that do not have this functionality.

Fixes: #1080
parent 4dccc4fb
...@@ -36,9 +36,14 @@ ...@@ -36,9 +36,14 @@
struct vre { struct vre {
unsigned magic; unsigned magic;
#define VRE_MAGIC 0xe83097dc #define VRE_MAGIC 0xe83097dc
pcre *re; pcre *re;
pcre_extra *re_extra;
}; };
#ifndef PCRE_STUDY_JIT_COMPILE
#define PCRE_STUDY_JIT_COMPILE 0
#endif
/* /*
* We don't want to spread or even expose the majority of PCRE options * We don't want to spread or even expose the majority of PCRE options
* so we establish our own options and implement hard linkage to PCRE * so we establish our own options and implement hard linkage to PCRE
...@@ -62,6 +67,20 @@ VRE_compile(const char *pattern, int options, ...@@ -62,6 +67,20 @@ VRE_compile(const char *pattern, int options,
VRE_free(&v); VRE_free(&v);
return (NULL); return (NULL);
} }
v->re_extra = pcre_study(v->re, PCRE_STUDY_JIT_COMPILE, errptr);
if (v->re_extra == NULL) {
if (*errptr != NULL) {
VRE_free(&v);
return (NULL);
}
/* allocate our own, pcre_study can return NULL without it
* being an error */
v->re_extra = calloc(1, sizeof(pcre_extra));
if (v->re_extra == NULL) {
VRE_free(&v);
return (NULL);
}
}
return (v); return (v);
} }
...@@ -72,22 +91,23 @@ VRE_exec(const vre_t *code, const char *subject, int length, ...@@ -72,22 +91,23 @@ VRE_exec(const vre_t *code, const char *subject, int length,
{ {
CHECK_OBJ_NOTNULL(code, VRE_MAGIC); CHECK_OBJ_NOTNULL(code, VRE_MAGIC);
int ov[30]; int ov[30];
pcre_extra extra;
if (ovector == NULL) { if (ovector == NULL) {
ovector = ov; ovector = ov;
ovecsize = sizeof(ov)/sizeof(ov[0]); ovecsize = sizeof(ov)/sizeof(ov[0]);
} }
memset(&extra, 0, sizeof extra);
if (lim != NULL) { if (lim != NULL) {
extra.match_limit = lim->match; code->re_extra->match_limit = lim->match;
extra.flags |= PCRE_EXTRA_MATCH_LIMIT; code->re_extra->flags |= PCRE_EXTRA_MATCH_LIMIT;
extra.match_limit_recursion = lim->match_recursion; code->re_extra->match_limit_recursion = lim->match_recursion;
extra.flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION; code->re_extra->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION;
} else {
code->re_extra->flags &= ~PCRE_EXTRA_MATCH_LIMIT;
code->re_extra->flags &= ~PCRE_EXTRA_MATCH_LIMIT_RECURSION;
} }
return (pcre_exec(code->re, &extra, subject, length, return (pcre_exec(code->re, code->re_extra, subject, length,
startoffset, options, ovector, ovecsize)); startoffset, options, ovector, ovecsize));
} }
...@@ -98,6 +118,11 @@ VRE_free(vre_t **vv) ...@@ -98,6 +118,11 @@ VRE_free(vre_t **vv)
*vv = NULL; *vv = NULL;
CHECK_OBJ(v, VRE_MAGIC); CHECK_OBJ(v, VRE_MAGIC);
#ifdef PCRE_CONFIG_JIT
pcre_free_study(v->re_extra);
#else
free(v->re_extra);
#endif
pcre_free(v->re); pcre_free(v->re);
FREE_OBJ(v); FREE_OBJ(v);
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment