Commit 2ab4f12c authored by Geoff Simmons's avatar Geoff Simmons

implement range restrictions on match options match_limit, offset_limit

and recursion_limit, and test compile option use_offset_limit
parent 2c4e4804
......@@ -61,7 +61,7 @@ regex.match
::
BOOL regex.match(PRIV_CALL, PRIV_TASK, STRING, INT len=0, BOOL anchored=0, INT match_limit=0, INT offset_limit=0, BOOL notbol=0, BOOL noteol=0, BOOL notempty=0, BOOL notempty_atstart=0, BOOL no_jit=0, BOOL no_utf_check=0, ENUM {HARD,SOFT} partial=0, INT recursion_limit=0)
BOOL regex.match(PRIV_CALL, PRIV_TASK, STRING subject, INT len=0, BOOL anchored=0, INT match_limit=0, INT offset_limit=0, BOOL notbol=0, BOOL noteol=0, BOOL notempty=0, BOOL notempty_atstart=0, BOOL no_jit=0, BOOL no_utf_check=0, ENUM {HARD,SOFT} partial=0, INT recursion_limit=0)
.. _func_config_bool:
......
......@@ -12,16 +12,18 @@ varnishtest "compile options"
# extended option is tested in compile.vtc and match.vtc
# XXX
# - tests for alt_circumflex will require backrefs
# - tests for alt_circumflex, no_auto_capture and ungreedy require
# backrefs
# - tests for alt_verbnames will require retrieving the mark
# - auto_callout not implemented yet
# - test for dupnames will require capturing named refs
# - how to test never_backslash_c? pcre2 testdata only mentions it in
# one test, and vtc can't parse the pattern, since it has more {'s
# than }'s.
# - test for no_auto_capture requires backrefs
# - test for no_auto_possess, no_dotstar_anchor and no_start_optimize
# require callouts and/or pattern_info
# - some of the tests for use_offset_limit should use the startoffset
# option for match() (not yet implemented)
# allow_empty_class
varnish v1 -vcl {
......@@ -777,3 +779,64 @@ varnish v1 -errvcl {vmod pcre2 error: parens_nest_limit (4294967296) out of rang
new r = pcre2.regex("a", parens_nest_limit=4294967296);
}
}
# use_offset_limit
varnish v1 -vcl {
import pcre2 from "${vmod_topbuild}/src/.libs/libvmod_pcre2.so";
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new r1 = pcre2.regex("abc", use_offset_limit=true);
new r2 = pcre2.regex("(?<=abc)", use_offset_limit=true);
new r3 = pcre2.regex("abc");
new r4 = pcre2.regex("^\w", use_offset_limit=true,
multiline=true);
}
sub vcl_recv {
return(synth(200));
}
sub vcl_synth {
set resp.http.r1-1 = r1.match("1234abcde", offset_limit=100);
set resp.http.r1-2 = r1.match("1234abcde", offset_limit=9);
set resp.http.r1-3 = r1.match("1234abcde", offset_limit=4);
# set resp.http.r1-4 = r1.match("1234abcde", offset_limit=4,
# startoffset=4);
# set resp.http.r1-5 = r1.match("1234abcde", offset_limit=4,
# startoffset=5);
set resp.http.r1-6 = r1.match("1234abcde", offset_limit=3);
set resp.http.r2-1 = r2.match("1234abc", offset_limit=7);
set resp.http.r2-2 = r2.match("1234abc", offset_limit=6);
set resp.http.r3 = r3.match("1234abcde", offset_limit=4);
set resp.http.r4-1 = r4.match(offset_limit=3, subject={"
..
aa"});
set resp.http.r4-2 = r4.match(offset_limit=4, subject={"
..
aa"});
}
}
logexpect l1 -v v1 -d 0 -g vxid -q "VCL_Error" {
expect 0 * Begin req
expect * = VCL_Error "^vmod pcre2 error: in r3.match..: offset limit set without PCRE2_USE_OFFSET_LIMIT"
expect * = End
} -start
client c1 {
txreq
rxresp
expect resp.status == "200"
expect resp.http.r1-1 == "true"
expect resp.http.r1-2 == "true"
expect resp.http.r1-3 == "true"
expect resp.http.r1-6 == "false"
expect resp.http.r2-1 == "true"
expect resp.http.r2-2 == "false"
expect resp.http.r3 == "false"
expect resp.http.r4-1 == "false"
expect resp.http.r4-2 == "true"
} -run
logexpect l1 -wait
......@@ -445,6 +445,29 @@ vmod_regex_match(VRT_CTX, struct vmod_pcre2_regex *regex,
if (mctx_call->priv == NULL) {
pcre2_match_context *mctx;
/* XXX DRY */
if (match_limit < 0 || match_limit > UINT32_MAX) {
VERR(ctx, "match_limit (%lld) out of range in "
"%s.match() (must be >= 0 and <= %" PRIu32 ")",
(long long)match_limit, regex->vcl_name,
UINT32_MAX);
return 0;
}
if (offset_limit < 0 || offset_limit > UINT32_MAX) {
VERR(ctx, "offset_limit (%lld) out of range in "
"%s.match() (must be >= 0 and <= %" PRIu32 ")",
(long long)offset_limit, regex->vcl_name,
UINT32_MAX);
return 0;
}
if (recursion_limit < 0 || recursion_limit > UINT32_MAX) {
VERR(ctx, "recursion_limit (%lld) out of range in "
"%s.match() (must be >= 0 and <= %" PRIu32 ")",
(long long)recursion_limit, regex->vcl_name,
UINT32_MAX);
return 0;
}
if ((mctx = pcre2_match_context_create(NULL)) == NULL) {
VERRNOMEM(ctx, "creating match context in %s.match()",
regex->vcl_name);
......
......@@ -32,11 +32,12 @@ $Object regex(STRING pattern, BOOL allow_empty_class=0, BOOL anchored=0,
# XXX options for dfa_match, jit fast path, start_offset
# XXX option to make saving the match ctx with PRIV_CALL optional
$Method BOOL .match(PRIV_CALL, PRIV_TASK, STRING, INT len=0, BOOL anchored=0,
INT match_limit=0, INT offset_limit=0, BOOL notbol=0,
BOOL noteol=0, BOOL notempty=0, BOOL notempty_atstart=0,
BOOL no_jit=0, BOOL no_utf_check = 0,
ENUM {HARD, SOFT} partial=0, INT recursion_limit=0)
$Method BOOL .match(PRIV_CALL, PRIV_TASK, STRING subject, INT len=0,
BOOL anchored=0, INT match_limit=0, INT offset_limit=0,
BOOL notbol=0, BOOL noteol=0, BOOL notempty=0,
BOOL notempty_atstart=0, BOOL no_jit=0,
BOOL no_utf_check = 0, ENUM {HARD, SOFT} partial=0,
INT recursion_limit=0)
$Function BOOL config_bool(ENUM {JIT, STACKRECURSE, UNICODE})
......
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