[master] 8a4a7cc61 VCL_REGEX: Support concatenation of constant strings

Nils Goroll nils.goroll at uplex.de
Tue Nov 23 12:31:08 UTC 2021


commit 8a4a7cc612253267b5ff97d3d52130953618c3c2
Author: Nils Goroll <nils.goroll at uplex.de>
Date:   Fri Oct 29 16:51:04 2021 +0200

    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

diff --git a/bin/varnishtest/tests/b00028.vtc b/bin/varnishtest/tests/b00028.vtc
index 074595956..4280e8e6c 100644
--- a/bin/varnishtest/tests/b00028.vtc
+++ b/bin/varnishtest/tests/b00028.vtc
@@ -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;
diff --git a/bin/varnishtest/tests/c00103.vtc b/bin/varnishtest/tests/c00103.vtc
index 11da0f0b9..75dc18ed3 100644
--- a/bin/varnishtest/tests/c00103.vtc
+++ b/bin/varnishtest/tests/c00103.vtc
@@ -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));
diff --git a/bin/varnishtest/tests/v00016.vtc b/bin/varnishtest/tests/v00016.vtc
index f1971efad..8404b2552 100644
--- a/bin/varnishtest/tests/v00016.vtc
+++ b/bin/varnishtest/tests/v00016.vtc
@@ -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;
diff --git a/lib/libvcc/vcc_utils.c b/lib/libvcc/vcc_utils.c
index 04dca950d..5633f83f4 100644
--- a/lib/libvcc/vcc_utils.c
+++ b/lib/libvcc/vcc_utils.c
@@ -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);
 }
 
 /*


More information about the varnish-commit mailing list