--- /dev/null
+varnishtest "req.body_param must not return a string with a \0 byte"
+feature ignore_unknown_macro
+
+# A string sample cannot contain a \0 byte. req.body_param returns the raw
+# bytes of the body, so a client can put a \0 in a value. Such a value must
+# not be matched by "-m str" on its prefix.
+
+haproxy h1 -conf {
+ global
+ .if feature(THREAD)
+ thread-groups 1
+ .endif
+
+ defaults
+ mode http
+ timeout connect "${HAPROXY_TEST_TIMEOUT-5s}"
+ timeout client "${HAPROXY_TEST_TIMEOUT-5s}"
+ timeout server "${HAPROXY_TEST_TIMEOUT-5s}"
+
+ frontend fe1
+ bind "fd@${fe1}"
+ option http-buffer-request
+ http-request set-var-fmt(txn.v) match if { req.body_param(u) -m str public }
+ http-request return status 200 hdr verdict %[var(txn.v,nomatch)]
+} -start
+
+client c1 -connect ${h1_fe1_sock} {
+ # body "u=public"
+ txreq -req POST -url "/" -body "u=public"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.verdict == "match"
+
+ # body "u=public\0x", sent as hex since a string cannot hold a \0 byte:
+ # "u=" "public" "\0" "x"
+ txreq -req POST -url "/" -hdr "Content-Length: 10"
+ sendhex "753d 7075626c6963 00 78"
+ rxresp
+ expect resp.status == 200
+ expect resp.http.verdict == "nomatch"
+} -run
smp->flags = SMP_F_VOL_1ST | SMP_F_CONST;
}
+ /* a string sample cannot contain a NUL byte */
+ if (memchr(smp->data.u.str.area, 0, smp->data.u.str.data))
+ return 0;
+
/* Update context, check wrapping. */
chunks[0] = vend;
if (chunks[2] && vend >= chunks[2] && vend <= chunks[3]) {