[master] b9e53ea Fix lookbehind handling in regsuball

Federico G. Schwindt fgsch at lodoss.net
Tue Oct 14 02:52:18 CEST 2014


commit b9e53ea2ebbb59d739bb2307b16743a9179090a4
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 822f373..d784c13 100644
--- a/bin/varnishd/cache/cache_vrt_re.c
+++ b/bin/varnishd/cache/cache_vrt_re.c
@@ -107,6 +107,7 @@ VRT_regsub(VRT_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);
@@ -135,7 +136,7 @@ VRT_regsub(VRT_CTX, int all, const char *str, void *re,
 
 	do {
 		/* Copy prefix to match */
-		Tadd(&res_b, res_e, str, ovector[0]);
+		Tadd(&res_b, res_e, str + offset, ovector[0] - offset);
 		for (s = sub ; *s != '\0'; s++ ) {
 			if (*s != '\\' || s[1] == '\0') {
 				if (res_b < res_e)
@@ -153,13 +154,12 @@ VRT_regsub(VRT_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);
@@ -170,7 +170,7 @@ VRT_regsub(VRT_CTX, int all, const char *str, void *re,
 	} while (i != VRE_ERROR_NOMATCH);
 
 	/* Copy suffix to match */
-	Tadd(&res_b, res_e, str, len+1);
+	Tadd(&res_b, res_e, 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