[master] 29b1b0666 range: Distinguish missing separator from unknown unit

Dridi Boukelmoune dridi.boukelmoune at gmail.com
Thu Sep 2 08:11:08 UTC 2021


commit 29b1b066626d0cf3578feeacf757004f6757151c
Author: Dridi Boukelmoune <dridi.boukelmoune at gmail.com>
Date:   Thu Sep 2 08:49:02 2021 +0200

    range: Distinguish missing separator from unknown unit

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index 245b7aa98..6955c1c8b 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -669,7 +669,7 @@ extern const char H__Reason[];
 #define http_expect_eq(str, tok)	http_tok_eq(str, #tok)
 
 // rfc7233,l,1207,1208
-#define http_range_at(str, tok)		http_ctok_at(str, #tok)
+#define http_range_at(str, tok, l)	http_tok_at(str, #tok, l)
 
 /* cache_main.c */
 #define VXID(u) ((u) & VSL_IDENTMASK)
diff --git a/bin/varnishd/cache/cache_http.c b/bin/varnishd/cache/cache_http.c
index 35f0f4a67..c30d21ee6 100644
--- a/bin/varnishd/cache/cache_http.c
+++ b/bin/varnishd/cache/cache_http.c
@@ -846,7 +846,7 @@ ssize_t
 http_GetContentRange(const struct http *hp, ssize_t *lo, ssize_t *hi)
 {
 	ssize_t tmp, cl;
-	const char *b;
+	const char *b, *t;
 
 	CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
 
@@ -860,14 +860,14 @@ http_GetContentRange(const struct http *hp, ssize_t *lo, ssize_t *hi)
 	if (!http_GetHdr(hp, H_Content_Range, &b))
 		return (-1);
 
-	if (strncasecmp("bytes", b, strlen("bytes")))
-		return (-1);		// Unknown range unit, ignore
-	b += strlen("bytes");
+	t = strchr(b, ' ');
+	if (t == NULL)
+		return (-2);		// Missing space after range unit
 
-	if (!vct_islws(*b))
+	if (!http_range_at(b, bytes, t - b))
 		return (-1);		// Unknown range unit, ignore
-	while (vct_islws(*b))
-		b++;
+	b = t + 1;
+
 	if (*b == '*') {		// Content-Range: bytes */123
 		*lo = *hi = -1;
 		b++;
@@ -908,7 +908,7 @@ const char *
 http_GetRange(const struct http *hp, ssize_t *lo, ssize_t *hi)
 {
 	ssize_t tmp;
-	const char *b;
+	const char *b, *t;
 
 	CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
 
@@ -922,9 +922,13 @@ http_GetRange(const struct http *hp, ssize_t *lo, ssize_t *hi)
 	if (!http_GetHdr(hp, H_Range, &b))
 		return (NULL);
 
-	if (!http_range_at(b, bytes=))
+	t = strchr(b, '=');
+	if (t == NULL)
+		return ("Missing '='");
+
+	if (!http_range_at(b, bytes, t - b))
 		return ("Not Bytes");
-	b += strlen("bytes=");
+	b = t + 1;
 
 	*lo = VNUM_uint(b, NULL, &b);
 	if (*lo == -2)
diff --git a/bin/varnishtest/tests/c00034.vtc b/bin/varnishtest/tests/c00034.vtc
index 9f68605f1..bc2af742e 100644
--- a/bin/varnishtest/tests/c00034.vtc
+++ b/bin/varnishtest/tests/c00034.vtc
@@ -259,6 +259,11 @@ server s1 {
 	expect req.http.range == <undef>
 	txresp -hdr "content-range: bytes */100" -bodylen 100
 
+	rxreq
+	expect req.url == "/?invalid=content-range"
+	expect req.http.range == <undef>
+	txresp -hdr "content-range: bytes=0-99/100" -bodylen 100
+
 	rxreq
 	expect req.http.range == "bytes=0-0"
 	txresp -hdr "content-range: bytes */*" -bodylen 100
@@ -295,6 +300,10 @@ client c8 {
 	rxresp
 	expect resp.status == 503
 
+	txreq -url "/?invalid=content-range"
+	rxresp
+	expect resp.status == 503
+
 	txreq -hdr "range: bytes=0-0" -hdr "return: pass"
 	rxresp
 	expect resp.status == 503


More information about the varnish-commit mailing list