[4.0] efdd025 Fix lookbehind handling in regsuball

Lasse Karstensen lkarsten at varnish-software.com
Thu Jan 15 16:35:41 CET 2015


commit efdd025439d5914fb256ae2b2576a36c0be424a7
Author: Federico G. Schwindt <fgsch at lodoss.net>
Date:   Tue Oct 14 01:41:57 2014 +0100

    Fix lookbehind handling in regsuball
    
    Do not advance the subject but use the ovector information as offset,
    pcre might need to peek back when handling lookbehinds.
    
    Original patch from MegaMaddin via github.
    
    Fixes: #1557

diff --git a/bin/varnishd/cache/cache_vrt_re.c b/bin/varnishd/cache/cache_vrt_re.c
index d0ecb78..fd6353a 100644
--- a/bin/varnishd/cache/cache_vrt_re.c
+++ b/bin/varnishd/cache/cache_vrt_re.c
@@ -92,6 +92,7 @@ VRT_regsub(const struct vrt_ctx *ctx, int all, const char *str, void *re,
 	const char *s;
 	unsigned u, x;
 	int options = 0;
+	int offset = 0;
 	size_t len;
 
 	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
@@ -120,7 +121,7 @@ VRT_regsub(const struct vrt_ctx *ctx, int all, const char *str, void *re,
 
 	do {
 		/* Copy prefix to match */
-		Tadd(&res, str, ovector[0]);
+		Tadd(&res, str + offset, ovector[0] - offset);
 		for (s = sub ; *s != '\0'; s++ ) {
 			if (*s != '\\' || s[1] == '\0') {
 				if (res.b < res.e)
@@ -138,13 +139,12 @@ VRT_regsub(const struct vrt_ctx *ctx, int all, const char *str, void *re,
 					*res.b++ = *s;
 			}
 		}
-		str += ovector[1];
-		len -= ovector[1];
+		offset = ovector[1];
 		if (!all)
 			break;
 		memset(&ovector, 0, sizeof(ovector));
 		options |= VRE_NOTEMPTY;
-		i = VRE_exec(t, str, len, 0, options, ovector, 30,
+		i = VRE_exec(t, str, len, offset, options, ovector, 30,
 		    &cache_param->vre_limits);
 		if (i < VRE_ERROR_NOMATCH ) {
 			WS_Release(ctx->ws, 0);
@@ -155,7 +155,7 @@ VRT_regsub(const struct vrt_ctx *ctx, int all, const char *str, void *re,
 	} while (i != VRE_ERROR_NOMATCH);
 
 	/* Copy suffix to match */
-	Tadd(&res, str, len+1);
+	Tadd(&res, str + offset, len - offset + 1);
 	if (res.b >= res.e) {
 		WS_Release(ctx->ws, 0);
 		return (str);
diff --git a/bin/varnishtest/tests/r01557.vtc b/bin/varnishtest/tests/r01557.vtc
new file mode 100644
index 0000000..8ada32f
--- /dev/null
+++ b/bin/varnishtest/tests/r01557.vtc
@@ -0,0 +1,19 @@
+varnishtest "Test case for #1557"
+
+server s1 {
+	rxreq
+	expect req.url == "/?foobar=2"
+	txresp
+} -start
+
+varnish v1 -vcl+backend {
+	sub vcl_recv {
+		set req.url = regsuball(req.url,
+		    "(?<=[&\?])(foo|bar)=[^&]+(?:&|$)", "");
+	}
+} -start
+
+client c1 {
+	txreq -url "/?foo=0&bar=1&foobar=2"
+	rxresp
+} -run



More information about the varnish-commit mailing list