Commit b66d10ef authored by Dominic Farolino's avatar Dominic Farolino Committed by Commit Bot

Enforce RequestInit enum values

This makes the Fetch API more standards compliant by
enforcing the enum values in the RequestInit dictionary,
as this is not taken care of by the IDL bindings themselves.
This enforces the mode, credentials, cache, and redirect properties
of RequestInit.

R=yhirano@chromium.org, yoav@yoav.ws

Bug: 777116
Change-Id: I8db5fd991b5ffa039dc2f67b4d8f525647fbf915
Reviewed-on: https://chromium-review.googlesource.com/841270
Commit-Queue: Yoav Weiss <yoav@yoav.ws>
Reviewed-by: default avatarYoav Weiss <yoav@yoav.ws>
Reviewed-by: default avatarYutaka Hirano <yhirano@chromium.org>
Cr-Commit-Position: refs/heads/master@{#541515}
parent 3b95aabf
......@@ -11,10 +11,10 @@ PASS RequestInit's cache mode is only-if-cached and mode is not same-origin
PASS Request with cache mode: only-if-cached and fetch mode cors
PASS Request with cache mode: only-if-cached and fetch mode no-cors
PASS Bad referrerPolicy init parameter value
FAIL Bad mode init parameter value assert_throws: Expect TypeError exception function "() => new Request(...args)" did not throw
FAIL Bad credentials init parameter value assert_throws: Expect TypeError exception function "() => new Request(...args)" did not throw
FAIL Bad cache init parameter value assert_throws: Expect TypeError exception function "() => new Request(...args)" did not throw
FAIL Bad redirect init parameter value assert_throws: Expect TypeError exception function "() => new Request(...args)" did not throw
PASS Bad mode init parameter value
PASS Bad credentials init parameter value
PASS Bad cache init parameter value
PASS Bad redirect init parameter value
PASS Request should get its content-type from the init request
PASS Request should not get its content-type from the init request if init headers are provided
PASS Request should get its content-type from the body if none is provided
......
......@@ -95,9 +95,9 @@ promise_test(t => {
url += '?url=' + get_host_info().HTTPS_REMOTE_ORIGIN + '/media/foo.vtt';
// Add '&mode' to tell the service worker to do a CORS request.
url += '&mode=cors';
// Add '&credentials=anonymous' to allow Access-Control-Allow-Origin=* so
// Add '&credentials=same-origin' to allow Access-Control-Allow-Origin=* so
// that CORS will succeed if the service approves it.
url += '&credentials=anonymous';
url += '&credentials=same-origin';
return load_track(url)
.then(result => {
assert_equals(result, 'load event');
......@@ -142,9 +142,9 @@ promise_test(t => {
url += '?url=' + encodeURIComponent(redirector_url + encodeURIComponent(redirect_target));
// Add '&mode' to tell the service worker to do a CORS request.
url += '&mode=cors';
// Add '&credentials=anonymous' to allow Access-Control-Allow-Origin=* so
// Add '&credentials=same-origin' to allow Access-Control-Allow-Origin=* so
// that CORS will succeed if the server approves it.
url += '&credentials=anonymous';
url += '&credentials=same-origin';
return load_track(url)
.then(result => {
assert_equals(result, 'error event');
......@@ -160,9 +160,9 @@ promise_test(t => {
url += '?url=' + encodeURIComponent(redirector_url + encodeURIComponent(redirect_target));
// Add '&mode' to tell the service worker to do a CORS request.
url += '&mode=cors';
// Add '&credentials=anonymous' to allow Access-Control-Allow-Origin=* so
// Add '&credentials=same-origin' to allow Access-Control-Allow-Origin=* so
// that CORS will succeed if the server approves it.
url += '&credentials=anonymous';
url += '&credentials=same-origin';
return load_track(url)
.then(result => {
assert_equals(result, 'load event');
......
......@@ -125,13 +125,14 @@ RequestInit::RequestInit(ExecutionContext* context,
if (exception_state.HadException())
return;
auto v8_credentials = h.Get<IDLPassThrough>("credentials");
credentials_ = h.Get<IDLUSVString>("credentials").value_or(String());
if (exception_state.HadException())
return;
are_any_members_set_ = h.AreAnyMembersSet();
SetUpReferrer(referrer_string, referrer_policy_string, exception_state);
CheckEnumValues(referrer_string, referrer_policy_string, exception_state);
if (exception_state.HadException())
return;
......@@ -145,12 +146,6 @@ RequestInit::RequestInit(ExecutionContext* context,
return;
}
if (v8_credentials.has_value()) {
SetUpCredentials(context, isolate, *v8_credentials, exception_state);
if (exception_state.HadException())
return;
}
if (v8_signal.has_value()) {
if ((*v8_signal)->IsNull()) {
// Override any existing value.
......@@ -175,12 +170,42 @@ WTF::Optional<AbortSignal*> RequestInit::Signal() const {
: WTF::nullopt;
}
void RequestInit::SetUpReferrer(
void RequestInit::CheckEnumValues(
const WTF::Optional<String>& referrer_string,
const WTF::Optional<String>& referrer_policy_string,
ExceptionState& exception_state) {
if (!are_any_members_set_)
TRACE_EVENT0("blink", "RequestInit::CheckEnumValues");
// Validate cache_
if (!cache_.IsNull() && cache_ != "default" && cache_ != "no-store" &&
cache_ != "reload" && cache_ != "no-cache" && cache_ != "force-cache" &&
cache_ != "only-if-cached") {
exception_state.ThrowTypeError("Invalid cache mode");
return;
}
// Validate credentials_
if (!credentials_.IsNull() && credentials_ != "omit" &&
credentials_ != "same-origin" && credentials_ != "include") {
exception_state.ThrowTypeError("Invalid credentials mode");
return;
}
// Validate mode_
if (!mode_.IsNull() && mode_ != "navigate" && mode_ != "same-origin" &&
mode_ != "no-cors" && mode_ != "cors") {
exception_state.ThrowTypeError("Invalid mode");
return;
}
// Validate redirect_
if (!redirect_.IsNull() && redirect_ != "follow" && redirect_ != "error" &&
redirect_ != "manual") {
exception_state.ThrowTypeError("Invalid redirect mode");
return;
}
// Validate referrer policy
// A part of the Request constructor algorithm is performed here. See
// the comments in the Request constructor code for the detail.
......@@ -191,6 +216,7 @@ void RequestInit::SetUpReferrer(
referrer_ = Referrer("about:client", kReferrerPolicyDefault);
if (referrer_string.has_value())
referrer_.referrer = AtomicString(*referrer_string);
if (referrer_policy_string.has_value()) {
if (*referrer_policy_string == "") {
referrer_.referrer_policy = kReferrerPolicyDefault;
......@@ -218,18 +244,6 @@ void RequestInit::SetUpReferrer(
}
}
void RequestInit::SetUpCredentials(ExecutionContext* context,
v8::Isolate* isolate,
v8::Local<v8::Value> v8_credentials,
ExceptionState& exception_state) {
if (v8_credentials->IsString()) {
credentials_ = NativeValueTraits<IDLUSVString>::NativeValue(
isolate, v8_credentials, exception_state);
if (exception_state.HadException())
return;
}
}
void RequestInit::SetUpBody(ExecutionContext* context,
v8::Isolate* isolate,
v8::Local<v8::Value> v8_body,
......
......@@ -50,13 +50,9 @@ class RequestInit {
friend struct NativeValueTraits<IDLPassThrough>;
friend struct NativeValueTraitsBase<IDLPassThrough>;
void SetUpReferrer(const WTF::Optional<String>& referrer_string,
const WTF::Optional<String>& referrer_policy_string,
ExceptionState&);
void SetUpCredentials(ExecutionContext*,
v8::Isolate*,
v8::Local<v8::Value> v8_credentials,
ExceptionState&);
void CheckEnumValues(const WTF::Optional<String>& referrer_string,
const WTF::Optional<String>& referrer_policy_string,
ExceptionState&);
void SetUpBody(ExecutionContext*,
v8::Isolate*,
v8::Local<v8::Value> v8_body,
......
......@@ -48,7 +48,7 @@ enum ReferrerPolicy : uint8_t {
// https://w3c.github.io/webappsec/specs/referrer-policy/#referrer-policy-state-origin-when-cross-origin
kReferrerPolicyOriginWhenCrossOrigin,
// https://w3c.github.io/webappsec-referrer-policy/#referrer-policy-strict-origin-when-cross-origin
// Also used as the default policy when reduced-referrer-grnaularity is
// Also used as the default policy when reduced-referrer-granularity is
// enabled (not spec conformant).
// TODO(estark): rename to kReferrerPolicyStrictOriginWhenCrossOrigin to
// match spec.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment