Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LibWeb: Add statusText validation for Response constructor #2870

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion Libraries/LibWeb/Fetch/Response.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,28 @@ GC::Ref<Response> Response::create(JS::Realm& realm, GC::Ref<Infrastructure::Res
return response_object;
}

// https://httpwg.org/specs/rfc9112.html#status.line
static bool is_valid_status_text(StringView status_text)
F3n67u marked this conversation as resolved.
Show resolved Hide resolved
{
// A status text is a valid status text if it matches the reason-phrase token production.
// reason-phrase = 1*( HTAB / SP / VCHAR / obs-text )
// VCHAR = %x21-7E
// obs-text = %x80-FF
return all_of(status_text, [](auto c) {
return c == '\t' || c == ' ' || (c >= 0x21 && c <= 0x7E) || (c >= 0x80 && c <= 0xFF);
});
}

// https://fetch.spec.whatwg.org/#initialize-a-response
WebIDL::ExceptionOr<void> Response::initialize_response(ResponseInit const& init, Optional<Infrastructure::BodyWithType> const& body)
{
// 1. If init["status"] is not in the range 200 to 599, inclusive, then throw a RangeError.
if (init.status < 200 || init.status > 599)
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::RangeError, "Status must be in range 200-599"sv };

// FIXME: 2. If init["statusText"] does not match the reason-phrase token production, then throw a TypeError.
// 2. If init["statusText"] does not match the reason-phrase token production, then throw a TypeError.
if (!is_valid_status_text(init.status_text))
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Invalid statusText: does not match the reason-phrase token production"sv };

// 3. Set response’s response’s status to init["status"].
m_response->set_status(init.status);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
Harness status: OK

Found 10 tests

10 Pass
Pass Throws RangeError when responseInit's status is 0
Pass Throws RangeError when responseInit's status is 100
Pass Throws RangeError when responseInit's status is 199
Pass Throws RangeError when responseInit's status is 600
Pass Throws RangeError when responseInit's status is 1000
Pass Throws TypeError when responseInit's statusText is

Pass Throws TypeError when responseInit's statusText is Ā
Pass Throws TypeError when building a response with body and a body status of 204
Pass Throws TypeError when building a response with body and a body status of 205
Pass Throws TypeError when building a response with body and a body status of 304
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!doctype html>
<meta charset=utf-8>
<title>Response error</title>
<script>
self.GLOBAL = {
isWindow: function() { return true; },
isWorker: function() { return false; },
isShadowRealm: function() { return false; },
};
</script>
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>

<div id=log></div>
<script src="../../../fetch/api/response/response-error.any.js"></script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// META: global=window,worker
// META: title=Response error

var invalidStatus = [0, 100, 199, 600, 1000];
invalidStatus.forEach(function(status) {
test(function() {
assert_throws_js(RangeError, function() { new Response("", { "status" : status }); },
"Expect RangeError exception when status is " + status);
},"Throws RangeError when responseInit's status is " + status);
});

var invalidStatusText = ["\n", "Ā"];
invalidStatusText.forEach(function(statusText) {
test(function() {
assert_throws_js(TypeError, function() { new Response("", { "statusText" : statusText }); },
"Expect TypeError exception " + statusText);
},"Throws TypeError when responseInit's statusText is " + statusText);
});

var nullBodyStatus = [204, 205, 304];
nullBodyStatus.forEach(function(status) {
test(function() {
assert_throws_js(TypeError,
function() { new Response("body", {"status" : status }); },
"Expect TypeError exception ");
},"Throws TypeError when building a response with body and a body status of " + status);
});
Loading