VCL_REGEX: Support concatenation of constant strings

For the REGEX type, we now peek ahead after the first CSTR token if a '+'
operator follows and, if yes, create the pattern as a concatenation.

Fixes #3726
parent 5e1589bf
......@@ -8,7 +8,7 @@ server s1 {
varnish v1 -vcl+backend {
sub vcl_backend_response {
if (beresp.http.foo ~ "bar") {
if (beresp.http.foo ~ "b" + "ar") {
set beresp.http.foo1 = "1";
} else {
set beresp.status = 999;
......
......@@ -8,7 +8,8 @@ varnish v1 -vcl {
# on purpose to ensure we don't treat REGEX expressions
# differently.
if (req.url ~ (debug.just_return_regex(
debug.just_return_regex("hello")))) {
debug.just_return_regex("he" +
"l" + "lo")))) {
return (synth(200));
}
return (synth(500));
......
......@@ -80,6 +80,27 @@ varnish v1 -errvcl {Regexp compilation error:} {
}
}
varnish v1 -errvcl {Regexp compilation error:} {
backend b none;
sub vcl_recv {
if (req.url ~ "[" + "a") {}
}
}
varnish v1 -errvcl {Expected CSTR got 'req'} {
backend b none;
sub vcl_recv {
if (req.url ~ "a" + req.http.foo) {}
}
}
varnish v1 -errvcl {Expected ')' got '-'} {
backend b none;
sub vcl_recv {
if (req.url ~ "a" - "b") {}
}
}
varnish v1 -errvcl {Expression has type directors.shard, expected ACL} {
import directors;
backend b none;
......
......@@ -51,19 +51,38 @@
void
vcc_regexp(struct vcc *tl, struct vsb *vgc_name)
{
struct vsb *pattern;
char buf[BUFSIZ];
vre_t *t;
int error, erroroffset;
struct token *t1;
struct inifin *ifp;
pattern = VSB_new_auto();
AN(pattern);
assert(tl->t->tok == CSTR);
VSB_cat(pattern, tl->t->dec);
t1 = vcc_PeekToken(tl);
AN(t1);
while (t1->tok == '+') {
vcc_NextToken(tl);
SkipToken(tl, '+');
ExpectErr(tl, CSTR);
VSB_cat(pattern, tl->t->dec);
t1 = vcc_PeekToken(tl);
AN(t1);
}
AZ(VSB_finish(pattern));
t = VRE_compile(tl->t->dec, 0, &error, &erroroffset, 0);
t = VRE_compile(VSB_data(pattern), 0, &error, &erroroffset, 0);
if (t == NULL) {
VSB_cat(tl->sb, "Regexp compilation error:\n\n");
AZ(VRE_error(tl->sb, error));
VSB_cat(tl->sb, "\n\n");
vcc_ErrWhere(tl, tl->t);
VSB_destroy(&pattern);
return;
}
VRE_free(&t);
......@@ -74,9 +93,10 @@ vcc_regexp(struct vcc *tl, struct vsb *vgc_name)
Fh(tl, 0, "static struct vre *%s;\n", buf);
ifp = New_IniFin(tl);
VSB_printf(ifp->ini, "\tVPI_re_init(&%s, ",buf);
EncToken(ifp->ini, tl->t);
VSB_quote(ifp->ini, VSB_data(pattern), -1, VSB_QUOTE_CSTR);
VSB_cat(ifp->ini, ");");
VSB_printf(ifp->fin, "\t\tVPI_re_fini(%s);", buf);
VSB_destroy(&pattern);
}
/*
......
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