Commit 29d126fd authored by Tollef Fog Heen's avatar Tollef Fog Heen

Avoid infinite loop in regsuball

Also optimise out a few strlen calls in favour of just tracking the
lengths.

Fixes: #1047
parent d8f894b5
......@@ -95,13 +95,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,
&params->vre_limits);
/* If it didn't match, we can return the original string */
......@@ -137,10 +140,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,
&params->vre_limits);
if (i < VRE_ERROR_NOMATCH ) {
WSP(sp, SLT_VCL_error,
......@@ -150,8 +155,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);
......
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
......@@ -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,
......
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