Diff
Modified: trunk/LayoutTests/imported/w3c/ChangeLog (292292 => 292293)
--- trunk/LayoutTests/imported/w3c/ChangeLog 2022-04-04 16:59:04 UTC (rev 292292)
+++ trunk/LayoutTests/imported/w3c/ChangeLog 2022-04-04 17:07:24 UTC (rev 292293)
@@ -1,3 +1,16 @@
+2022-04-04 Youenn Fablet <you...@apple.com>
+
+ CORS: Allow particular Range header values without a preflight
+ https://bugs.webkit.org/show_bug.cgi?id=231174
+ <rdar://problem/84101544>
+
+ Reviewed by Alex Christensen.
+
+ * web-platform-tests/fetch/range/general.any-expected.txt:
+ * web-platform-tests/fetch/range/general.any.js:
+ * web-platform-tests/fetch/range/general.any.worker-expected.txt:
+ * web-platform-tests/fetch/range/resources/long-wav.py:
+
2022-04-02 Patrick Griffis <pgrif...@igalia.com>
CSP: Improve compatibility of source matching
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/range/general.any-expected.txt (292292 => 292293)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/range/general.any-expected.txt 2022-04-04 16:59:04 UTC (rev 292292)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/range/general.any-expected.txt 2022-04-04 17:07:24 UTC (rev 292293)
@@ -4,4 +4,6 @@
PASS Range header setting allowed for guard type: request
PASS Privileged header not allowed for guard type: request-no-cors
PASS Fetch with range header will be sent with Accept-Encoding: identity
+PASS Cross Origin Fetch with non safe range header
+PASS Cross Origin Fetch with safe range header
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/range/general.any.js (292292 => 292293)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/range/general.any.js 2022-04-04 16:59:04 UTC (rev 292292)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/range/general.any.js 2022-04-04 17:07:24 UTC (rev 292293)
@@ -1,4 +1,5 @@
// META: global=window,worker
+// META: script=/common/get-host-info.sub.js
// META: script=/common/utils.js
// Helpers that return headers objects with a particular guard
@@ -89,3 +90,47 @@
assert_equals(await response.json(), 'identity', `Expect identity accept-encoding if range header is ${JSON.stringify(rangeHeader)}`);
}
}, `Fetch with range header will be sent with Accept-Encoding: identity`);
+
+promise_test(async () => {
+ const wavURL = new URL(get_host_info().HTTP_REMOTE_ORIGIN + '/fetch/range/resources/long-wav.py');
+ const stashTakeURL = new URL('resources/stash-take.py', location);
+
+ function changeToken() {
+ const stashToken = token();
+ wavURL.searchParams.set('accept-encoding-key', stashToken);
+ stashTakeURL.searchParams.set('key', stashToken);
+ }
+
+ const rangeHeaders = [
+ 'bytes=10-9',
+ 'bytes=-0',
+ 'bytes=0000000000000000000000000000000000000000000000000000000000011-0000000000000000000000000000000000000000000000000000000000111',
+ ];
+
+ for (const rangeHeader of rangeHeaders) {
+ changeToken();
+ await fetch(wavURL, { headers: { Range : rangeHeader} }).then(() => { throw "loaded with range header " + rangeHeader }, () => { });
+ }
+}, `Cross Origin Fetch with non safe range header`);
+
+promise_test(async () => {
+ const wavURL = new URL(get_host_info().HTTP_REMOTE_ORIGIN + '/fetch/range/resources/long-wav.py');
+ const stashTakeURL = new URL('resources/stash-take.py', location);
+
+ function changeToken() {
+ const stashToken = token();
+ wavURL.searchParams.set('accept-encoding-key', stashToken);
+ stashTakeURL.searchParams.set('key', stashToken);
+ }
+
+ const rangeHeaders = [
+ 'bytes=0-10',
+ 'bytes=0-',
+ 'bytes=00000000000000000000000000000000000000000000000000000000011-00000000000000000000000000000000000000000000000000000000000111',
+ ];
+
+ for (const rangeHeader of rangeHeaders) {
+ changeToken();
+ await fetch(wavURL, { headers: { Range: rangeHeader } }).then(() => { }, () => { throw "failed load with range header " + rangeHeader });
+ }
+}, `Cross Origin Fetch with safe range header`);
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/range/general.any.worker-expected.txt (292292 => 292293)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/range/general.any.worker-expected.txt 2022-04-04 16:59:04 UTC (rev 292292)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/range/general.any.worker-expected.txt 2022-04-04 17:07:24 UTC (rev 292293)
@@ -4,4 +4,6 @@
PASS Range header setting allowed for guard type: request
PASS Privileged header not allowed for guard type: request-no-cors
PASS Fetch with range header will be sent with Accept-Encoding: identity
+PASS Cross Origin Fetch with non safe range header
+PASS Cross Origin Fetch with safe range header
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/range/resources/long-wav.py (292292 => 292293)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/range/resources/long-wav.py 2022-04-04 16:59:04 UTC (rev 292292)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/fetch/range/resources/long-wav.py 2022-04-04 17:07:24 UTC (rev 292293)
@@ -46,9 +46,15 @@
def main(request, response):
+ if request.method == u"OPTIONS":
+ response.status = (404, b"Not Found")
+ response.headers.set(b"Content-Type", b"text/plain")
+ return b"Preflight not accepted"
+
response.headers.set(b"Content-Type", b"audio/wav")
response.headers.set(b"Accept-Ranges", b"bytes")
response.headers.set(b"Cache-Control", b"no-cache")
+ response.headers.set(b"Access-Control-Allow-Origin", request.headers.get(b'Origin', b''))
range_header = request.headers.get(b'Range', b'')
range_header_match = range_header and re.search(r'^bytes=(\d*)-(\d*)$', isomorphic_decode(range_header))
Modified: trunk/Source/WebCore/ChangeLog (292292 => 292293)
--- trunk/Source/WebCore/ChangeLog 2022-04-04 16:59:04 UTC (rev 292292)
+++ trunk/Source/WebCore/ChangeLog 2022-04-04 17:07:24 UTC (rev 292293)
@@ -1,3 +1,15 @@
+2022-04-04 Youenn Fablet <you...@apple.com>
+
+ CORS: Allow particular Range header values without a preflight
+ https://bugs.webkit.org/show_bug.cgi?id=231174
+ <rdar://problem/84101544>
+
+ Reviewed by Alex Christensen.
+
+ Covered by updated tests.
+
+ * platform/network/HTTPParsers.cpp:
+
2022-04-04 Jer Noble <jer.no...@apple.com>
[Perf] HTMLVideoElement is performing synchronous paints; causing main thread hangs
Modified: trunk/Source/WebCore/platform/network/HTTPParsers.cpp (292292 => 292293)
--- trunk/Source/WebCore/platform/network/HTTPParsers.cpp 2022-04-04 16:59:04 UTC (rev 292292)
+++ trunk/Source/WebCore/platform/network/HTTPParsers.cpp 2022-04-04 17:07:24 UTC (rev 292293)
@@ -36,6 +36,7 @@
#include "HTTPHeaderField.h"
#include "HTTPHeaderNames.h"
#include "ParsedContentType.h"
+#include <wtf/CheckedArithmetic.h>
#include <wtf/DateMath.h>
#include <wtf/NeverDestroyed.h>
#include <wtf/text/StringBuilder.h>
@@ -168,6 +169,7 @@
}
// See RFC 7231, Section 5.3.5 and 3.1.3.2.
+// https://fetch.spec.whatwg.org/#cors-safelisted-request-header
bool isValidLanguageHeaderValue(const String& value)
{
for (unsigned i = 0; i < value.length(); ++i) {
@@ -176,11 +178,6 @@
continue;
return false;
}
-
- // FIXME: Validate further by splitting into language tags and optional quality
- // values (q=) and then check each language tag.
- // Language tags https://tools.ietf.org/html/rfc7231#section-3.1.3.1
- // Language tag syntax https://tools.ietf.org/html/bcp47#section-2.1
return true;
}
@@ -954,9 +951,47 @@
return accessControlExposeHeaderSet.contains(name);
}
+static bool isSimpleRangeHeaderValue(const String& value)
+{
+ if (!value.startsWith("bytes="_s))
+ return false;
+
+ unsigned start = 0;
+ unsigned end = 0;
+ bool hasHyphen = false;
+
+ for (size_t cptr = 6; cptr < value.length(); ++cptr) {
+ auto character = value[cptr];
+ if (character >= '0' && character <= '9') {
+ if (productOverflows<unsigned>(hasHyphen ? end : start, 10))
+ return false;
+ auto newDecimal = (hasHyphen ? end : start) * 10;
+ auto sum = Checked<unsigned, RecordOverflow>(newDecimal) + Checked<unsigned, RecordOverflow>(character - '0');
+ if (sum.hasOverflowed())
+ return false;
+
+ if (hasHyphen)
+ end = sum.value();
+ else
+ start = sum.value();
+ continue;
+ }
+ if (character == '-' && !hasHyphen) {
+ hasHyphen = true;
+ continue;
+ }
+ return false;
+ }
+
+ return hasHyphen && (!end || start < end);
+}
+
// Implements https://fetch.spec.whatwg.org/#cors-safelisted-request-header
bool isCrossOriginSafeRequestHeader(HTTPHeaderName name, const String& value)
{
+ if (value.length() > 128)
+ return false;
+
switch (name) {
case HTTPHeaderName::Accept:
if (!isValidAcceptHeaderValue(value))
@@ -979,11 +1014,15 @@
return false;
break;
}
+ case HTTPHeaderName::Range:
+ if (!isSimpleRangeHeaderValue(value))
+ return false;
+ break;
default:
// FIXME: Should we also make safe other headers (DPR, Downlink, Save-Data...)? That would require validating their values.
return false;
}
- return value.length() <= 128;
+ return true;
}
// Implements <https://fetch.spec.whatwg.org/#concept-method-normalize>.