[master] fe425ce Avoid infinite loop in regsuball
Tollef Fog Heen
tfheen at varnish-cache.org
Tue Nov 1 09:43:54 CET 2011
commit fe425ce63a03b0de1a9c257c4e27cf1defe6a862
Author: Tollef Fog Heen <tfheen at varnish-software.com>
Date: Tue Nov 1 09:25:22 2011 +0100
Avoid infinite loop in regsuball
Also optimise out a few strlen calls in favour of just tracking the
lengths.
Fixes: #1047
diff --git a/bin/varnishd/cache_vrt_re.c b/bin/varnishd/cache_vrt_re.c
index e6f854b..955b7bf 100644
--- a/bin/varnishd/cache_vrt_re.c
+++ b/bin/varnishd/cache_vrt_re.c
@@ -90,13 +90,16 @@ VRT_regsub(const struct sess *sp, int all, const char *str, void *re,
char *b0;
const char *s;
unsigned u, x;
+ int options = 0;
+ size_t len;
AN(re);
if (str == NULL)
str = "";
t = re;
memset(ovector, 0, sizeof(ovector));
- i = VRE_exec(t, str, strlen(str), 0, 0, ovector, 30,
+ len = strlen(str);
+ i = VRE_exec(t, str, len, 0, options, ovector, 30,
¶ms->vre_limits);
/* If it didn't match, we can return the original string */
@@ -132,10 +135,12 @@ VRT_regsub(const struct sess *sp, int all, const char *str, void *re,
}
}
str += ovector[1];
+ len -= ovector[1];
if (!all)
break;
memset(&ovector, 0, sizeof(ovector));
- i = VRE_exec(t, str, strlen(str), 0, 0, ovector, 30,
+ options |= VRE_NOTEMPTY_ATSTART;
+ i = VRE_exec(t, str, len, 0, options, ovector, 30,
¶ms->vre_limits);
if (i < VRE_ERROR_NOMATCH ) {
WSP(sp, SLT_VCL_Error,
@@ -145,8 +150,7 @@ VRT_regsub(const struct sess *sp, int all, const char *str, void *re,
} while (i != VRE_ERROR_NOMATCH);
/* Copy suffix to match */
- l = strlen(str) + 1;
- Tadd(&res, str, l);
+ Tadd(&res, str, len+1);
if (res.b >= res.e) {
WS_Release(sp->http->ws, 0);
return (str);
diff --git a/bin/varnishtest/tests/c00047.vtc b/bin/varnishtest/tests/c00047.vtc
new file mode 100644
index 0000000..4b23194
--- /dev/null
+++ b/bin/varnishtest/tests/c00047.vtc
@@ -0,0 +1,33 @@
+varnishtest "Test VCL regsuball()"
+
+server s1 {
+ rxreq
+ txresp \
+ -hdr "foo: barbar" \
+ -hdr "bar: bbbar"
+} -start
+
+varnish v1 -vcl+backend {
+ sub vcl_fetch {
+ set beresp.http.baz1 = regsuball(beresp.http.foo, "barb", "zz");
+ set beresp.http.baz2 = regsuball(beresp.http.foo, "ar", "zz");
+ set beresp.http.baz3 = regsuball(beresp.http.foo, "^", "baz");
+ set beresp.http.baz4 = regsuball(beresp.http.foo, "^[;]*", "baz");
+ set beresp.http.baz5 = regsuball(beresp.http.bar, "^b*", "b");
+ set beresp.http.baz6 = regsuball(beresp.http.foo, "^b*", "z");
+ set beresp.http.baz7 = regsuball(beresp.http.foo, "ping", "pong");
+ }
+} -start
+
+client c1 {
+ txreq -url "/"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.baz1 == "zzar"
+ expect resp.http.baz2 == "bzzbzz"
+ expect resp.http.baz3 == "bazbarbar"
+ expect resp.http.baz4 == "bazbarbar"
+ expect resp.http.baz5 == "bar"
+ expect resp.http.baz6 == "zarbar"
+ expect resp.http.baz7 == "barbar"
+} -run
diff --git a/include/vre.h b/include/vre.h
index 29c1b08..a1206e5 100644
--- a/include/vre.h
+++ b/include/vre.h
@@ -49,6 +49,7 @@ typedef struct vre vre_t;
/* And those to PCRE options */
#define VRE_CASELESS 0x00000001
+#define VRE_NOTEMPTY_ATSTART 0x10000000
vre_t *VRE_compile(const char *, int, const char **, int *);
int VRE_exec(const vre_t *code, const char *subject, int length,
More information about the varnish-commit
mailing list