[master] 8cd84febf Enforce RFC8941 limits on INT/REAL et al. when converting to strings.

Poul-Henning Kamp phk at FreeBSD.org
Wed May 19 12:29:07 UTC 2021


commit 8cd84febfde4c168a9ef1b44b1baa7d573687ce0
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Wed May 19 12:28:05 2021 +0000

    Enforce RFC8941 limits on INT/REAL et al. when converting to strings.

diff --git a/bin/varnishd/cache/cache_vrt.c b/bin/varnishd/cache/cache_vrt.c
index 82cd54e53..4939e6dd5 100644
--- a/bin/varnishd/cache/cache_vrt.c
+++ b/bin/varnishd/cache/cache_vrt.c
@@ -829,6 +829,9 @@ VRT_INT_string(VRT_CTX, VCL_INT num)
 {
 
 	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
+	if (!VRT_INT_is_valid(num))
+		VRT_fail(ctx, "INT overflow converting to string (%jX)",
+		    (intmax_t)num);
 	return (WS_Printf(ctx->ws, "%jd", (intmax_t)num));
 }
 
@@ -843,6 +846,8 @@ VRT_REAL_string(VRT_CTX, VCL_REAL num)
 {
 
 	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
+	if (!VRT_REAL_is_valid(num))
+		VRT_fail(ctx, "REAL overflow converting to string (%e)", num);
 	return (WS_Printf(ctx->ws, "%.3f", num));
 }
 
diff --git a/bin/varnishtest/tests/i00001.vtc b/bin/varnishtest/tests/i00001.vtc
new file mode 100644
index 000000000..52c5a1a02
--- /dev/null
+++ b/bin/varnishtest/tests/i00001.vtc
@@ -0,0 +1,34 @@
+varnishtest "SF-decimal/SF-integer ranges"
+
+server s1 {
+	rxreq
+	txresp
+} -start
+
+varnish v1 -vcl+backend {
+	sub vcl_deliver {
+		if (req.http.foo) {
+			set resp.http.foo = obj.ttl * 10000000000;
+		}
+		if (req.http.bar) {
+			set resp.http.bar = storage.Transient.free_space * 1000000000000000;
+		}
+	}
+} -start
+
+logexpect l1 -v v1 -g raw {
+	expect * 1001	VCL_Error	"REAL overflow converting to string.*"
+	expect * 1004	VCL_Error	"INT overflow converting to string.*"
+} -start
+
+client c1 {
+	txreq -hdr "foo: 1"
+	rxresp
+} -run
+
+client c1 {
+	txreq -hdr "bar: 1"
+	rxresp
+} -run
+
+logexpect l1 -wait
diff --git a/bin/varnishtest/tests/m00007.vtc b/bin/varnishtest/tests/m00007.vtc
index 51840f5dd..784c887df 100644
--- a/bin/varnishtest/tests/m00007.vtc
+++ b/bin/varnishtest/tests/m00007.vtc
@@ -80,32 +80,32 @@ client c1 {
 	expect resp.http.converted == 0
 
 	# VCL_INT_MAX
-	txreq -hdr "foo: 9007199254740991" \
-	      -hdr "bytes: 9007199254740991b" \
-	      -hdr "duration: 9007199254740991s" \
-	      -hdr "real: 9007199254740991" \
-	      -hdr "time: 9007199254740991"
+	txreq -hdr "foo: 999999999999999" \
+	      -hdr "bytes: 999999999999999b" \
+	      -hdr "duration: 999999999999.999s" \
+	      -hdr "real: 999999999999.999" \
+	      -hdr "time: 999999999999.999"
 	rxresp
 	expect resp.http.gtzero == true
 	expect resp.http.ltzero == false
 	expect resp.http.iszero == false
-	expect resp.http.converted == 9007199254740991
-	expect resp.http.bytes == 9007199254740991
-	expect resp.http.duration == 9007199254740991
-	expect resp.http.real == 9007199254740991
-	expect resp.http.time == 9007199254740991
+	expect resp.http.converted == 999999999999999
+	expect resp.http.bytes == 999999999999999
+	expect resp.http.duration == 999999999999
+	expect resp.http.real == 999999999999
+	expect resp.http.time == 999999999999
 
 	# VCL_INT_MIN
-	txreq -hdr "foo: -9007199254740991" \
-	      -hdr "duration: -9007199254740991s" \
-	      -hdr "real: -9007199254740991"
+	txreq -hdr "foo: -999999999999999" \
+	      -hdr "duration: -999999999999s" \
+	      -hdr "real: -999999999999"
 	rxresp
 	expect resp.http.gtzero == false
 	expect resp.http.ltzero == true
 	expect resp.http.iszero == false
-	expect resp.http.converted == -9007199254740991
-	expect resp.http.duration == -9007199254740991
-	expect resp.http.real == -9007199254740991
+	expect resp.http.converted == -999999999999999
+	expect resp.http.duration == -999999999999
+	expect resp.http.real == -999999999999
 
 	txreq -hdr "foo: bar"
 	rxresp
diff --git a/bin/varnishtest/tests/m00015.vtc b/bin/varnishtest/tests/m00015.vtc
index 3e7974958..3aebc7e4d 100644
--- a/bin/varnishtest/tests/m00015.vtc
+++ b/bin/varnishtest/tests/m00015.vtc
@@ -95,38 +95,31 @@ client c1 {
 	expect resp.http.converted == 0.000
 
 	# VCL_INT_MAX
-	txreq -hdr "foo: 9007199254740991" \
-	      -hdr "bytes: 9007199254740991b" \
-	      -hdr "duration: 9007199254740991s" \
-	      -hdr "integer: 9007199254740991" \
-	      -hdr "time: 9007199254740991"
+	txreq -hdr "foo: 999999999999.999" \
+	      -hdr "bytes: 999999999999b" \
+	      -hdr "duration: 999999999999.999s" \
+	      -hdr "integer: 999999999999.999" \
+	      -hdr "time: 999999999999.999"
 	rxresp
-	expect resp.http.converted == 9007199254740991.000
-	expect resp.http.bytes == 9007199254740991.000
-	expect resp.http.duration == 9007199254740991.000
-	expect resp.http.integer == 9007199254740991.000
-	expect resp.http.time == 9007199254740991.000
+	expect resp.http.converted == 999999999999.999
+	expect resp.http.bytes == 999999999999.000
+	expect resp.http.duration == 999999999999.999
+	expect resp.http.integer == 999999999999.000
+	expect resp.http.time == 999999999999.999
 
 	# VCL_INT_MIN
-	txreq -hdr "foo: -9007199254740991" \
-	      -hdr "duration: -9007199254740991s" \
-	      -hdr "integer: -9007199254740991"
+	txreq -hdr "foo: -999999999999.999" \
+	      -hdr "duration: -999999999999.999s" \
+	      -hdr "integer: -999999999999"
 	rxresp
-	expect resp.http.converted == -9007199254740991.000
-	expect resp.http.duration == -9007199254740991.000
-	expect resp.http.integer == -9007199254740991.000
+	expect resp.http.converted == -999999999999.999
+	expect resp.http.duration == -999999999999.999
+	expect resp.http.integer == -999999999999.000
 
 	txreq -hdr "foo: bar"
 	rxresp
 	expect resp.http.converted == 0.000
 
-	txreq -hdr "foo: 9007199254740992"
-	rxresp
-	expect resp.http.converted == 9007199254740992.000
-
-	txreq -hdr "foo: -9007199254740992"
-	rxresp
-	expect resp.http.converted == -9007199254740992.000
 } -run
 client c1 {
 	txreq -hdr "nofb: NAN"
diff --git a/bin/varnishtest/tests/v00020.vtc b/bin/varnishtest/tests/v00020.vtc
index d5df60d4a..e29e4ff4f 100644
--- a/bin/varnishtest/tests/v00020.vtc
+++ b/bin/varnishtest/tests/v00020.vtc
@@ -430,8 +430,8 @@ varnish v1 -vcl+backend {
 		set resp.http.bar = true == false;
 	}
 	sub vcl_deliver {
-		set resp.http.p = (0 + 9223372036854775807);
-		set resp.http.n = (0 - 9223372036854775807);
+		set resp.http.p = (0 + 999999999999999);
+		set resp.http.n = (0 - 999999999999999);
 		if (resp.status == -(-200)) {
 			set resp.http.o = -std.integer("-200");
 		}
@@ -444,8 +444,8 @@ client c1 {
 	expect resp.http.rst == "0"
 	expect resp.http.foo == "true"
 	expect resp.http.bar == "false"
-	expect resp.http.p == 9223372036854775807
-	expect resp.http.n == -9223372036854775807
+	expect resp.http.p == 999999999999999
+	expect resp.http.n == -999999999999999
 	expect resp.http.o == 200
 } -run
 
diff --git a/vmod/vmod_std_conversions.c b/vmod/vmod_std_conversions.c
index accc57f9d..838cd60af 100644
--- a/vmod/vmod_std_conversions.c
+++ b/vmod/vmod_std_conversions.c
@@ -319,14 +319,16 @@ vmod_time(VRT_CTX, struct VARGS(time)* a)
 VCL_INT v_matchproto_(td_std_real2integer)
 vmod_real2integer(VRT_CTX, VCL_REAL r, VCL_INT i)
 {
+	VCL_INT retval;
+
 	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
 
-	if (!isfinite(r))
+	if (!VRT_REAL_is_valid(r))
 		return (i);
-	r = round(r);
-	if (r > VCL_INT_MAX || r < VCL_INT_MIN)
+	retval = round(r);
+	if (!VRT_INT_is_valid(r))
 		return (i);
-	return ((VCL_INT)r);
+	return (retval);
 }
 
 VCL_TIME v_matchproto_(td_std_real2time)


More information about the varnish-commit mailing list