Commit c378fa6f authored by Geoff Simmons's avatar Geoff Simmons

more reduction of code repetition

parent 2b7b320c
...@@ -57,6 +57,23 @@ ...@@ -57,6 +57,23 @@
#define INIT(ctx) (((ctx)->method & VCL_MET_INIT) != 0) #define INIT(ctx) (((ctx)->method & VCL_MET_INIT) != 0)
#define SET_OPT(lval, opt, PCRE2_OPT) \
do { if (opt) (lval) |= (PCRE2_OPT); } while(0)
#define SET_CTX_PARAM(ctx, param, type) do { \
if ((param) != 0) AZ(pcre2_set_##param((ctx), (type)(param))); \
} while(0)
#define CHECK_UINT32_RANGE(limit, vcl_name, caller, ret) \
do { \
if ((limit) < 0 || (limit) > UINT32_MAX) { \
VERR(ctx, #limit " (%lld) out of range in %s" \
caller " (must be >= 0 and <= %" PRIu32 ")", \
(long long)(limit), (vcl_name), UINT32_MAX); \
return ret; \
} \
} while(0)
struct vmod_pcre2_regex { struct vmod_pcre2_regex {
unsigned magic; unsigned magic;
#define VMOD_PCRE2_REGEX_MAGIC 0x3adb2a78 #define VMOD_PCRE2_REGEX_MAGIC 0x3adb2a78
...@@ -156,7 +173,7 @@ vmod_regex__init(VRT_CTX, struct vmod_pcre2_regex **regexp, ...@@ -156,7 +173,7 @@ vmod_regex__init(VRT_CTX, struct vmod_pcre2_regex **regexp,
VCL_BOOL alt_verbnames, VCL_BOOL caseless, VCL_BOOL alt_verbnames, VCL_BOOL caseless,
VCL_BOOL dollar_endonly, VCL_BOOL dotall, VCL_BOOL dupnames, VCL_BOOL dollar_endonly, VCL_BOOL dotall, VCL_BOOL dupnames,
VCL_BOOL extended, VCL_BOOL firstline, VCL_STRING locale, VCL_BOOL extended, VCL_BOOL firstline, VCL_STRING locale,
VCL_BOOL match_unset_backref, VCL_INT max_pattern_len, VCL_BOOL match_unset_backref, VCL_INT max_pattern_length,
VCL_BOOL multiline, VCL_BOOL never_backslash_c, VCL_BOOL multiline, VCL_BOOL never_backslash_c,
VCL_BOOL never_ucp, VCL_BOOL never_utf, VCL_ENUM newlines, VCL_BOOL never_ucp, VCL_BOOL never_utf, VCL_ENUM newlines,
VCL_BOOL no_auto_capture, VCL_BOOL no_auto_possess, VCL_BOOL no_auto_capture, VCL_BOOL no_auto_possess,
...@@ -190,70 +207,42 @@ vmod_regex__init(VRT_CTX, struct vmod_pcre2_regex **regexp, ...@@ -190,70 +207,42 @@ vmod_regex__init(VRT_CTX, struct vmod_pcre2_regex **regexp,
* to assume that max_pattern_len can never be too large. * to assume that max_pattern_len can never be too large.
*/ */
assert(sizeof(VCL_INT) <= sizeof(PCRE2_SIZE)); assert(sizeof(VCL_INT) <= sizeof(PCRE2_SIZE));
if (max_pattern_len < 0) { if (max_pattern_length < 0) {
VERR(ctx, "max_pattern_len (%lld) must be >= 0 in %s " VERR(ctx, "max_pattern_len (%lld) must be >= 0 in %s "
"constructor", (long long) max_pattern_len, vcl_name); "constructor", (long long)max_pattern_length, vcl_name);
return;
}
if (parens_nest_limit < 0 || parens_nest_limit > UINT32_MAX) {
VERR(ctx, "parens_nest_limit (%lld) out of range in %s "
"constructor (must be >= 0 and <= %" PRIu32 ")",
(long long)parens_nest_limit, vcl_name, UINT32_MAX);
return; return;
} }
CHECK_UINT32_RANGE(parens_nest_limit, vcl_name, " constructor",);
/* XXX check illegal combinations such as never_ucp && ucp ... ? */ /* XXX check illegal combinations such as never_ucp && ucp ... ? */
if (anchored) SET_OPT(options, anchored, PCRE2_ANCHORED);
options |= PCRE2_ANCHORED; SET_OPT(options, allow_empty_class, PCRE2_ALLOW_EMPTY_CLASS);
if (allow_empty_class) SET_OPT(options, alt_bsux, PCRE2_ALT_BSUX);
options |= PCRE2_ALLOW_EMPTY_CLASS; SET_OPT(options, alt_circumflex, PCRE2_ALT_CIRCUMFLEX);
if (alt_bsux) SET_OPT(options, alt_verbnames, PCRE2_ALT_VERBNAMES);
options |= PCRE2_ALT_BSUX; SET_OPT(options, caseless, PCRE2_CASELESS);
if (alt_circumflex) SET_OPT(options, dollar_endonly, PCRE2_DOLLAR_ENDONLY);
options |= PCRE2_ALT_CIRCUMFLEX; SET_OPT(options, dotall, PCRE2_DOTALL);
if (alt_verbnames) SET_OPT(options, dupnames, PCRE2_DUPNAMES);
options |= PCRE2_ALT_VERBNAMES; SET_OPT(options, extended, PCRE2_EXTENDED);
if (caseless) SET_OPT(options, firstline, PCRE2_FIRSTLINE);
options |= PCRE2_CASELESS; SET_OPT(options, match_unset_backref, PCRE2_MATCH_UNSET_BACKREF);
if (dollar_endonly) SET_OPT(options, multiline, PCRE2_MULTILINE);
options |= PCRE2_DOLLAR_ENDONLY; SET_OPT(options, never_backslash_c, PCRE2_NEVER_BACKSLASH_C);
if (dotall) SET_OPT(options, never_ucp, PCRE2_NEVER_UCP);
options |= PCRE2_DOTALL; SET_OPT(options, never_utf, PCRE2_NEVER_UTF);
if (dupnames) SET_OPT(options, no_auto_capture, PCRE2_NO_AUTO_CAPTURE);
options |= PCRE2_DUPNAMES; SET_OPT(options, no_auto_possess, PCRE2_NO_AUTO_POSSESS);
if (extended) SET_OPT(options, no_dotstar_anchor, PCRE2_NO_DOTSTAR_ANCHOR);
options |= PCRE2_EXTENDED; SET_OPT(options, no_start_optimize, PCRE2_NO_START_OPTIMIZE);
if (firstline) SET_OPT(options, no_utf_check, PCRE2_NO_UTF_CHECK);
options |= PCRE2_FIRSTLINE; SET_OPT(options, ucp, PCRE2_UCP);
if (match_unset_backref) SET_OPT(options, ungreedy, PCRE2_UNGREEDY);
options |= PCRE2_MATCH_UNSET_BACKREF; SET_OPT(options, use_offset_limit, PCRE2_USE_OFFSET_LIMIT);
if (multiline) SET_OPT(options, utf, PCRE2_UTF);
options |= PCRE2_MULTILINE;
if (never_backslash_c) SET_CTX_PARAM(ccontext, max_pattern_length, PCRE2_SIZE);
options |= PCRE2_NEVER_BACKSLASH_C; SET_CTX_PARAM(ccontext, parens_nest_limit, uint32_t);
if (never_ucp)
options |= PCRE2_NEVER_UCP;
if (never_utf)
options |= PCRE2_NEVER_UTF;
if (no_auto_capture)
options |= PCRE2_NO_AUTO_CAPTURE;
if (no_auto_possess)
options |= PCRE2_NO_AUTO_POSSESS;
if (no_dotstar_anchor)
options |= PCRE2_NO_DOTSTAR_ANCHOR;
if (no_start_optimize)
options |= PCRE2_NO_START_OPTIMIZE;
if (no_utf_check)
options |= PCRE2_NO_UTF_CHECK;
if (ucp)
options |= PCRE2_UCP;
if (ungreedy)
options |= PCRE2_UNGREEDY;
if (use_offset_limit)
options |= PCRE2_USE_OFFSET_LIMIT;
if (utf)
options |= PCRE2_UTF;
if (bsrs != NULL) { if (bsrs != NULL) {
if (strcmp("ANYCRLF", bsrs) == 0) if (strcmp("ANYCRLF", bsrs) == 0)
val = PCRE2_BSR_ANYCRLF; val = PCRE2_BSR_ANYCRLF;
...@@ -284,9 +273,6 @@ vmod_regex__init(VRT_CTX, struct vmod_pcre2_regex **regexp, ...@@ -284,9 +273,6 @@ vmod_regex__init(VRT_CTX, struct vmod_pcre2_regex **regexp,
AZ(pcre2_set_character_tables(ccontext, tables)); AZ(pcre2_set_character_tables(ccontext, tables));
AN(setlocale(LC_CTYPE, saved_lc)); AN(setlocale(LC_CTYPE, saved_lc));
} }
if (max_pattern_len != 0)
AZ(pcre2_set_max_pattern_length(ccontext,
(PCRE2_SIZE)max_pattern_len));
if (newlines != NULL) { if (newlines != NULL) {
if (strcmp("CR", newlines) == 0) if (strcmp("CR", newlines) == 0)
val = PCRE2_NEWLINE_CR; val = PCRE2_NEWLINE_CR;
...@@ -302,9 +288,6 @@ vmod_regex__init(VRT_CTX, struct vmod_pcre2_regex **regexp, ...@@ -302,9 +288,6 @@ vmod_regex__init(VRT_CTX, struct vmod_pcre2_regex **regexp,
WRONG("Illegal newline enum value"); WRONG("Illegal newline enum value");
AZ(pcre2_set_newline(ccontext, val)); AZ(pcre2_set_newline(ccontext, val));
} }
if (parens_nest_limit != 0)
AZ(pcre2_set_parens_nest_limit(ccontext,
(uint32_t)parens_nest_limit));
/* XXX set the length via parameter */ /* XXX set the length via parameter */
code = pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED, code = pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED,
...@@ -434,7 +417,7 @@ vmod_regex_match(VRT_CTX, struct vmod_pcre2_regex *regex, ...@@ -434,7 +417,7 @@ vmod_regex_match(VRT_CTX, struct vmod_pcre2_regex *regex,
else { else {
/* /*
* pcre2_general_context is declared as an incomplete * pcre2_general_context is declared as an incomplete
* type, so we can't check if it's full size is allocated. * type, so we can't check if its full size is allocated.
*/ */
WS_Assert_Allocated(ctx->ws, gctx_task->priv, 0); WS_Assert_Allocated(ctx->ws, gctx_task->priv, 0);
gctx = gctx_task->priv; gctx = gctx_task->priv;
...@@ -445,34 +428,21 @@ vmod_regex_match(VRT_CTX, struct vmod_pcre2_regex *regex, ...@@ -445,34 +428,21 @@ vmod_regex_match(VRT_CTX, struct vmod_pcre2_regex *regex,
if (mctx_call->priv == NULL) { if (mctx_call->priv == NULL) {
pcre2_match_context *mctx; pcre2_match_context *mctx;
#define CHECK_RANGE(limit) do { \
if ((limit) < 0 || (limit) > UINT32_MAX) { \ CHECK_UINT32_RANGE(match_limit, regex->vcl_name, ".match()", 0);
VERR(ctx, #limit " (%lld) out of range in " \ CHECK_UINT32_RANGE(offset_limit, regex->vcl_name, ".match()",
"%s.match() (must be >= 0 and <= %" \ 0);
PRIu32 ")", (long long)(limit), \ CHECK_UINT32_RANGE(recursion_limit, regex->vcl_name, ".match()",
regex->vcl_name, UINT32_MAX); \ 0);
return 0; \
} \
} while(0)
CHECK_RANGE(match_limit);
CHECK_RANGE(offset_limit);
CHECK_RANGE(recursion_limit);
#undef CHECK_RANGE
if ((mctx = pcre2_match_context_create(NULL)) == NULL) { if ((mctx = pcre2_match_context_create(NULL)) == NULL) {
VERRNOMEM(ctx, "creating match context in %s.match()", VERRNOMEM(ctx, "creating match context in %s.match()",
regex->vcl_name); regex->vcl_name);
return 0; return 0;
} }
if (match_limit != 0) SET_CTX_PARAM(mctx, match_limit, uint32_t);
AZ(pcre2_set_match_limit(mctx, (uint32_t)match_limit)); SET_CTX_PARAM(mctx, offset_limit, uint32_t);
if (offset_limit != 0) SET_CTX_PARAM(mctx, recursion_limit, uint32_t);
AZ(pcre2_set_offset_limit(mctx,
(uint32_t)offset_limit));
if (recursion_limit != 0)
AZ(pcre2_set_recursion_limit(mctx,
(uint32_t)recursion_limit));
ALLOC_OBJ(match_opts, VMOD_PCRE2_MATCH_CALL_MAGIC); ALLOC_OBJ(match_opts, VMOD_PCRE2_MATCH_CALL_MAGIC);
AN(match_opts); AN(match_opts);
...@@ -480,20 +450,14 @@ vmod_regex_match(VRT_CTX, struct vmod_pcre2_regex *regex, ...@@ -480,20 +450,14 @@ vmod_regex_match(VRT_CTX, struct vmod_pcre2_regex *regex,
mctx_call->priv = match_opts; mctx_call->priv = match_opts;
mctx_call->free = match_call_free; mctx_call->free = match_call_free;
if (anchored) SET_OPT(match_opts->options, anchored, PCRE2_ANCHORED);
match_opts->options |= PCRE2_ANCHORED; SET_OPT(match_opts->options, notbol, PCRE2_NOTBOL);
if (notbol) SET_OPT(match_opts->options, noteol, PCRE2_NOTEOL);
match_opts->options |= PCRE2_NOTBOL; SET_OPT(match_opts->options, notempty, PCRE2_NOTEMPTY);
if (noteol) SET_OPT(match_opts->options, notempty_atstart,
match_opts->options |= PCRE2_NOTEOL; PCRE2_NOTEMPTY_ATSTART);
if (notempty) SET_OPT(match_opts->options, no_jit, PCRE2_NO_JIT);
match_opts->options |= PCRE2_NOTEMPTY; SET_OPT(match_opts->options, no_utf_check, PCRE2_NO_UTF_CHECK);
if (notempty_atstart)
match_opts->options |= PCRE2_NOTEMPTY_ATSTART;
if (no_jit)
match_opts->options |= PCRE2_NO_JIT;
if (no_utf_check)
match_opts->options |= PCRE2_NO_UTF_CHECK;
if (partials != NULL) { if (partials != NULL) {
VERR(ctx, VERR(ctx,
......
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