From 4de2cf34e6c1bbb4037d08d630ea665ecdce10c4 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Mon, 7 Nov 2022 05:52:24 -0800 Subject: [PATCH] Allow HTTP range past EOF Fixes #683 --- net/http/parsehttprange.c | 5 ++++- test/net/http/parsehttprange_test.c | 20 ++++++++++++++++---- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/net/http/parsehttprange.c b/net/http/parsehttprange.c index 869e909fd..76c9f5db9 100644 --- a/net/http/parsehttprange.c +++ b/net/http/parsehttprange.c @@ -77,8 +77,11 @@ bool ParseHttpRange(const char *p, size_t n, long resourcelength, if (n) return false; if (start < 0) return false; if (length < 1) return false; + if (start > resourcelength) return false; if (__builtin_add_overflow(start, length, &ending)) return false; - if (ending > resourcelength) return false; + if (ending > resourcelength) { + length = resourcelength - start; + } *out_start = start; *out_length = length; return true; diff --git a/test/net/http/parsehttprange_test.c b/test/net/http/parsehttprange_test.c index 6a3f7e323..299a2f5a1 100644 --- a/test/net/http/parsehttprange_test.c +++ b/test/net/http/parsehttprange_test.c @@ -46,7 +46,11 @@ TEST(ParseHttpRange, testEmptyRangeOfOneByteFile_itWorks) { TEST(ParseHttpRange, testEmptyRangeOfEmptyFile_outOfRange) { long start, length; - const char *s = "bytes=0-0"; + const char *s = "bytes=0-0"; // requesting 1 byte, but have 0 + EXPECT_TRUE(ParseHttpRange(s, strlen(s), 0, &start, &length)); + EXPECT_EQ(0, start); + EXPECT_EQ(0, length); + s = "bytes=1-1"; // but this can't be truncated EXPECT_FALSE(ParseHttpRange(s, strlen(s), 0, &start, &length)); EXPECT_EQ(0, start); EXPECT_EQ(0, length); @@ -94,10 +98,10 @@ TEST(ParseHttpRange, testFromEnd) { TEST(ParseHttpRange, testOutOfRange) { long start, length; - const char *s = "bytes=0-100"; - EXPECT_FALSE(ParseHttpRange(s, strlen(s), 100, &start, &length)); + const char *s = "bytes=0-100"; // requesting 101 bytes, but have 100 + EXPECT_TRUE(ParseHttpRange(s, strlen(s), 100, &start, &length)); EXPECT_EQ(0, start); - EXPECT_EQ(0, length); + EXPECT_EQ(100, length); } TEST(ParseHttpRange, testInvalidRange) { @@ -131,3 +135,11 @@ TEST(ParseHttpRange, testMultipartRange_notImplemented) { EXPECT_EQ(0, start); EXPECT_EQ(0, length); } + +TEST(ParseHttpRange, rangeTooLong_shortensToActualLength) { + long start, length; + const char *s = "bytes=0-134217727"; + EXPECT_TRUE(ParseHttpRange(s, strlen(s), 1000, &start, &length)); + EXPECT_EQ(0, start); + EXPECT_EQ(1000, length); +}