Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
libvmod-re2
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Nils Goroll
libvmod-re2
Commits
4c0baa24
Commit
4c0baa24
authored
Mar 16, 2016
by
Geoff Simmons
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add support for RE2 options, and take advantage of never_capture to
avoid using workspace for capture data
parent
917c66d3
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
100 additions
and
29 deletions
+100
-29
c02.vtc
src/tests/c02.vtc
+20
-0
vmod_re2.c
src/vmod_re2.c
+41
-21
vmod_re2.vcc
src/vmod_re2.vcc
+5
-1
vre2.cpp
src/vre2/vre2.cpp
+26
-5
vre2.h
src/vre2/vre2.h
+8
-2
No files found.
src/tests/c02.vtc
View file @
4c0baa24
...
@@ -15,6 +15,7 @@ varnish v1 -vcl+backend {
...
@@ -15,6 +15,7 @@ varnish v1 -vcl+backend {
new frobnitz = re2.regex("(frob)(nitz)");
new frobnitz = re2.regex("(frob)(nitz)");
new barbaz = re2.regex("(bar)(baz)");
new barbaz = re2.regex("(bar)(baz)");
new azbc = re2.regex("(a|(z))(bc)");
new azbc = re2.regex("(a|(z))(bc)");
new never = re2.regex("(bar)(baz)", never_capture=true);
}
}
sub vcl_deliver {
sub vcl_deliver {
...
@@ -55,6 +56,17 @@ varnish v1 -vcl+backend {
...
@@ -55,6 +56,17 @@ varnish v1 -vcl+backend {
} else {
} else {
set resp.http.abc = "fail";
set resp.http.abc = "fail";
}
}
if (never.match(resp.http.foo)) {
set resp.http.never = "match";
}
/*
* backrefs always fail, including backref 0, when
* never_capture=true
*/
set resp.http.never0 = never.backref(0, "fallback0");
set resp.http.never1 = never.backref(1, "fallback1");
set resp.http.never2 = never.backref(2, "fallback2");
}
}
} -start
} -start
...
@@ -79,6 +91,10 @@ client c1 {
...
@@ -79,6 +91,10 @@ client c1 {
expect resp.http.abc1 == "a"
expect resp.http.abc1 == "a"
expect resp.http.abc2 == "none"
expect resp.http.abc2 == "none"
expect resp.http.abc3 == "bc"
expect resp.http.abc3 == "bc"
expect resp.http.never == "match"
expect resp.http.never0 == "fallback0"
expect resp.http.never1 == "fallback1"
expect resp.http.never2 == "fallback2"
} -run
} -run
logexpect l1 -v v1 -d 1 -g vxid -q "VCL_Error" {
logexpect l1 -v v1 -d 1 -g vxid -q "VCL_Error" {
...
@@ -91,5 +107,9 @@ logexpect l1 -v v1 -d 1 -g vxid -q "VCL_Error" {
...
@@ -91,5 +107,9 @@ logexpect l1 -v v1 -d 1 -g vxid -q "VCL_Error" {
# would have also failed due to failing prior match
# would have also failed due to failing prior match
expect * = VCL_Error "^vmod re2 error: frobnitz\.backref\(3, \"fallback3\"\): backref out of range \(max 3\)$"
expect * = VCL_Error "^vmod re2 error: frobnitz\.backref\(3, \"fallback3\"\): backref out of range \(max 3\)$"
expect * = VCL_Error "^vmod re2 error: never\.backref\(0, \"fallback0\"\): never_capture is true for object never$"
expect * = VCL_Error "^vmod re2 error: never\.backref\(1, \"fallback1\"\): never_capture is true for object never$"
expect * = VCL_Error "^vmod re2 error: never\.backref\(2, \"fallback2\"\): never_capture is true for object never$"
expect * = End
expect * = End
} -run
} -run
src/vmod_re2.c
View file @
4c0baa24
...
@@ -55,6 +55,7 @@ struct vmod_re2_regex {
...
@@ -55,6 +55,7 @@ struct vmod_re2_regex {
char
*
vcl_name
;
char
*
vcl_name
;
pthread_key_t
matchk
;
pthread_key_t
matchk
;
int
ngroups
;
int
ngroups
;
unsigned
never_capture
;
};
};
static
char
c
;
static
char
c
;
...
@@ -90,7 +91,12 @@ init_matchsz(void)
...
@@ -90,7 +91,12 @@ init_matchsz(void)
VCL_VOID
VCL_VOID
vmod_regex__init
(
const
struct
vrt_ctx
*
ctx
,
struct
vmod_re2_regex
**
rep
,
vmod_regex__init
(
const
struct
vrt_ctx
*
ctx
,
struct
vmod_re2_regex
**
rep
,
const
char
*
vcl_name
,
VCL_STRING
pattern
)
const
char
*
vcl_name
,
VCL_STRING
pattern
,
VCL_BOOL
utf8
,
VCL_BOOL
posix_syntax
,
VCL_BOOL
longest_match
,
VCL_INT
max_mem
,
VCL_BOOL
literal
,
VCL_BOOL
never_nl
,
VCL_BOOL
dot_nl
,
VCL_BOOL
never_capture
,
VCL_BOOL
case_sensitive
,
VCL_BOOL
perl_classes
,
VCL_BOOL
word_boundary
,
VCL_BOOL
one_line
)
{
{
struct
vmod_re2_regex
*
re
;
struct
vmod_re2_regex
*
re
;
const
char
*
err
;
const
char
*
err
;
...
@@ -105,17 +111,23 @@ vmod_regex__init(const struct vrt_ctx *ctx, struct vmod_re2_regex **rep,
...
@@ -105,17 +111,23 @@ vmod_regex__init(const struct vrt_ctx *ctx, struct vmod_re2_regex **rep,
*
rep
=
re
;
*
rep
=
re
;
AZ
(
pthread_key_create
(
&
re
->
matchk
,
NULL
));
AZ
(
pthread_key_create
(
&
re
->
matchk
,
NULL
));
if
((
err
=
vre2_init
(
&
re
->
vre2
,
pattern
))
!=
NULL
)
{
if
((
err
=
vre2_init
(
&
re
->
vre2
,
pattern
,
utf8
,
posix_syntax
,
longest_match
,
max_mem
,
literal
,
never_nl
,
dot_nl
,
never_capture
,
case_sensitive
,
perl_classes
,
word_boundary
,
one_line
))
!=
NULL
)
{
VERR
(
ctx
,
"Cannot compile '%s' in %s constructor: %s"
,
pattern
,
VERR
(
ctx
,
"Cannot compile '%s' in %s constructor: %s"
,
pattern
,
vcl_name
,
err
);
vcl_name
,
err
);
return
;
return
;
}
}
if
((
err
=
vre2_ngroups
(
re
->
vre2
,
&
re
->
ngroups
))
!=
NULL
)
{
if
(
!
never_capture
)
{
VERR
(
ctx
,
"Cannot obtain number of capturing groups in %s "
if
((
err
=
vre2_ngroups
(
re
->
vre2
,
&
re
->
ngroups
))
!=
NULL
)
{
"constructor: %s"
,
vcl_name
,
err
);
VERR
(
ctx
,
"Cannot obtain number of capturing groups in "
return
;
"%s constructor: %s"
,
vcl_name
,
err
);
return
;
}
assert
(
re
->
ngroups
>=
0
);
}
}
assert
(
re
->
ngroups
>=
0
)
;
re
->
never_capture
=
never_capture
;
re
->
vcl_name
=
strdup
(
vcl_name
);
re
->
vcl_name
=
strdup
(
vcl_name
);
AZ
(
pthread_once
(
&
sz_init_once
,
init_matchsz
));
AZ
(
pthread_once
(
&
sz_init_once
,
init_matchsz
));
}
}
...
@@ -139,9 +151,9 @@ VCL_BOOL
...
@@ -139,9 +151,9 @@ VCL_BOOL
vmod_regex_match
(
const
struct
vrt_ctx
*
ctx
,
struct
vmod_re2_regex
*
re
,
vmod_regex_match
(
const
struct
vrt_ctx
*
ctx
,
struct
vmod_re2_regex
*
re
,
VCL_STRING
subject
)
VCL_STRING
subject
)
{
{
int
match
=
0
;
int
match
=
0
,
ngroups
=
0
;
const
char
*
err
;
const
char
*
err
;
char
*
text
;
char
*
text
=
(
void
*
)
subject
;
void
*
group
=
NULL
;
void
*
group
=
NULL
;
CHECK_OBJ_NOTNULL
(
ctx
,
VRT_CTX_MAGIC
);
CHECK_OBJ_NOTNULL
(
ctx
,
VRT_CTX_MAGIC
);
...
@@ -153,13 +165,14 @@ vmod_regex_match(const struct vrt_ctx *ctx, struct vmod_re2_regex *re,
...
@@ -153,13 +165,14 @@ vmod_regex_match(const struct vrt_ctx *ctx, struct vmod_re2_regex *re,
AZ
(
pthread_setspecific
(
re
->
matchk
,
match_failed
));
AZ
(
pthread_setspecific
(
re
->
matchk
,
match_failed
));
if
((
text
=
WS_Copy
(
ctx
->
ws
,
subject
,
-
1
))
==
NULL
)
{
if
(
!
re
->
never_capture
)
{
VERR
(
ctx
,
ERR_PREFIX
"insufficient workspace to copy subject"
,
ngroups
=
re
->
ngroups
+
1
;
re
->
vcl_name
,
subject
);
if
((
text
=
WS_Copy
(
ctx
->
ws
,
subject
,
-
1
))
==
NULL
)
{
return
0
;
VERR
(
ctx
,
ERR_PREFIX
"insufficient workspace to copy "
}
"subject"
,
re
->
vcl_name
,
subject
);
if
(
re
->
ngroups
>=
0
)
{
return
0
;
if
((
group
=
WS_Alloc
(
ctx
->
ws
,
(
re
->
ngroups
+
1
)
*
match_sz
))
}
if
((
group
=
WS_Alloc
(
ctx
->
ws
,
ngroups
*
match_sz
))
==
NULL
)
{
==
NULL
)
{
VERR
(
ctx
,
ERR_PREFIX
"insufficient workspace to "
VERR
(
ctx
,
ERR_PREFIX
"insufficient workspace to "
"allocate match data"
,
re
->
vcl_name
,
subject
);
"allocate match data"
,
re
->
vcl_name
,
subject
);
...
@@ -168,17 +181,19 @@ vmod_regex_match(const struct vrt_ctx *ctx, struct vmod_re2_regex *re,
...
@@ -168,17 +181,19 @@ vmod_regex_match(const struct vrt_ctx *ctx, struct vmod_re2_regex *re,
}
}
}
}
if
((
err
=
vre2_match
(
re
->
vre2
,
text
,
&
match
,
re
->
ngroups
,
group
))
if
((
err
=
vre2_match
(
re
->
vre2
,
text
,
&
match
,
ngroups
,
group
))
!=
NULL
)
{
!=
NULL
)
{
VERR
(
ctx
,
ERR_PREFIX
"%s"
,
re
->
vcl_name
,
subject
,
err
);
VERR
(
ctx
,
ERR_PREFIX
"%s"
,
re
->
vcl_name
,
subject
,
err
);
WS_Reset
(
ctx
->
ws
,
text
);
WS_Reset
(
ctx
->
ws
,
text
);
return
0
;
return
0
;
}
}
if
(
match
)
if
(
!
re
->
never_capture
)
{
AZ
(
pthread_setspecific
(
re
->
matchk
,
group
));
if
(
match
)
else
AZ
(
pthread_setspecific
(
re
->
matchk
,
group
));
WS_Reset
(
ctx
->
ws
,
text
);
else
WS_Reset
(
ctx
->
ws
,
text
);
}
return
match
;
return
match
;
#undef ERR_PREFIX
#undef ERR_PREFIX
...
@@ -200,6 +215,11 @@ vmod_regex_backref(VRT_CTX, struct vmod_re2_regex *re, VCL_INT refnum,
...
@@ -200,6 +215,11 @@ vmod_regex_backref(VRT_CTX, struct vmod_re2_regex *re, VCL_INT refnum,
#define ERR_PREFIX "%s.backref(%ld, \"%s\"): "
#define ERR_PREFIX "%s.backref(%ld, \"%s\"): "
if
(
re
->
never_capture
)
{
VERR
(
ctx
,
ERR_PREFIX
"never_capture is true for object %s"
,
re
->
vcl_name
,
refnum
,
fallback
,
re
->
vcl_name
);
return
fallback
;
}
if
(
refnum
>
re
->
ngroups
)
{
if
(
refnum
>
re
->
ngroups
)
{
VERR
(
ctx
,
ERR_PREFIX
"backref out of range (max %d)"
,
VERR
(
ctx
,
ERR_PREFIX
"backref out of range (max %d)"
,
re
->
vcl_name
,
refnum
,
fallback
,
re
->
ngroups
);
re
->
vcl_name
,
refnum
,
fallback
,
re
->
ngroups
);
...
...
src/vmod_re2.vcc
View file @
4c0baa24
...
@@ -9,7 +9,11 @@
...
@@ -9,7 +9,11 @@
$Module re2 3 access the Google RE2 regular expression engine
$Module re2 3 access the Google RE2 regular expression engine
$Object regex(STRING pattern)
$Object regex(STRING pattern, BOOL utf8=0, BOOL posix_syntax=0,
BOOL longest_match=0, INT max_mem=8388608, BOOL literal=0,
BOOL never_nl=0, BOOL dot_nl=0, BOOL never_capture=0,
BOOL case_sensitive=1, BOOL perl_classes=0,
BOOL word_boundary=0, BOOL one_line=0)
$Method BOOL .match(STRING)
$Method BOOL .match(STRING)
...
...
src/vre2/vre2.cpp
View file @
4c0baa24
...
@@ -42,8 +42,8 @@
...
@@ -42,8 +42,8 @@
using
namespace
std
;
using
namespace
std
;
vre2
::
vre2
(
const
char
*
pattern
)
{
vre2
::
vre2
(
const
char
*
pattern
,
RE2
::
Options
*
const
opt
)
{
re_
=
new
RE2
(
pattern
,
RE2
::
Quie
t
);
re_
=
new
RE2
(
pattern
,
*
op
t
);
if
(
!
re_
->
ok
())
if
(
!
re_
->
ok
())
throw
runtime_error
(
re_
->
error
());
throw
runtime_error
(
re_
->
error
());
}
}
...
@@ -59,7 +59,7 @@ inline bool
...
@@ -59,7 +59,7 @@ inline bool
vre2
::
match
(
const
char
*
subject
,
const
int
ngroups
,
StringPiece
*
groups
)
const
vre2
::
match
(
const
char
*
subject
,
const
int
ngroups
,
StringPiece
*
groups
)
const
{
{
return
re_
->
Match
(
subject
,
0
,
strlen
(
subject
),
RE2
::
UNANCHORED
,
return
re_
->
Match
(
subject
,
0
,
strlen
(
subject
),
RE2
::
UNANCHORED
,
groups
,
ngroups
+
1
);
groups
,
ngroups
);
}
}
inline
const
int
inline
const
int
...
@@ -69,10 +69,31 @@ vre2::ngroups() const
...
@@ -69,10 +69,31 @@ vre2::ngroups() const
}
}
const
char
*
const
char
*
vre2_init
(
vre2
**
vre2p
,
const
char
*
pattern
)
vre2_init
(
vre2
**
vre2p
,
const
char
*
pattern
,
unsigned
utf8
,
unsigned
posix_syntax
,
unsigned
longest_match
,
long
max_mem
,
unsigned
literal
,
unsigned
never_nl
,
unsigned
dot_nl
,
unsigned
never_capture
,
unsigned
case_sensitive
,
unsigned
perl_classes
,
unsigned
word_boundary
,
unsigned
one_line
)
{
{
try
{
try
{
*
vre2p
=
new
vre2
(
pattern
);
RE2
::
Options
opt
;
opt
.
set_log_errors
(
false
);
if
(
utf8
)
opt
.
set_encoding
(
RE2
::
Options
::
EncodingUTF8
);
else
opt
.
set_encoding
(
RE2
::
Options
::
EncodingLatin1
);
opt
.
set_posix_syntax
(
posix_syntax
);
opt
.
set_longest_match
(
longest_match
);
opt
.
set_max_mem
(
max_mem
);
opt
.
set_literal
(
literal
);
opt
.
set_never_nl
(
never_nl
);
opt
.
set_dot_nl
(
dot_nl
);
opt
.
set_never_capture
(
never_capture
);
opt
.
set_case_sensitive
(
case_sensitive
);
opt
.
set_perl_classes
(
perl_classes
);
opt
.
set_word_boundary
(
word_boundary
);
opt
.
set_one_line
(
one_line
);
*
vre2p
=
new
vre2
(
pattern
,
&
opt
);
return
NULL
;
return
NULL
;
}
}
CATCHALL
CATCHALL
...
...
src/vre2/vre2.h
View file @
4c0baa24
...
@@ -41,7 +41,7 @@ private:
...
@@ -41,7 +41,7 @@ private:
RE2
*
re_
;
RE2
*
re_
;
public
:
public
:
vre2
(
const
char
*
pattern
);
vre2
(
const
char
*
pattern
,
RE2
::
Options
*
const
opt
);
virtual
~
vre2
();
virtual
~
vre2
();
bool
match
(
const
char
*
subject
,
int
ngroups
,
StringPiece
*
groups
)
const
;
bool
match
(
const
char
*
subject
,
int
ngroups
,
StringPiece
*
groups
)
const
;
const
int
ngroups
()
const
;
const
int
ngroups
()
const
;
...
@@ -54,7 +54,13 @@ typedef struct vre2 vre2;
...
@@ -54,7 +54,13 @@ typedef struct vre2 vre2;
extern
"C"
{
extern
"C"
{
#endif
#endif
const
char
*
vre2_init
(
vre2
**
vre2
,
const
char
*
pattern
);
const
char
*
vre2_init
(
vre2
**
vre2
,
const
char
*
pattern
,
unsigned
utf8
,
unsigned
posix_syntax
,
unsigned
longest_match
,
long
max_mem
,
unsigned
literal
,
unsigned
never_nl
,
unsigned
dot_nl
,
unsigned
never_capture
,
unsigned
case_sensitive
,
unsigned
perl_classes
,
unsigned
word_boundary
,
unsigned
one_line
);
const
char
*
vre2_fini
(
vre2
**
vre2
);
const
char
*
vre2_fini
(
vre2
**
vre2
);
const
size_t
vre2_matchsz
(
void
);
const
size_t
vre2_matchsz
(
void
);
const
char
*
vre2_ngroups
(
vre2
*
vre2
,
int
*
const
ngroups
);
const
char
*
vre2_ngroups
(
vre2
*
vre2
,
int
*
const
ngroups
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment