Commit 314288e9 authored by Yutaka Hirano's avatar Yutaka Hirano Committed by Commit Bot

Fix RequestInit IDL compatibility issues

RequestInit is manually implemented and has some compatibility issues.

 1. undefined value is treated as a real value, e.g.,
    (new Request('/', {method: undefined}).method
    returns "undefined".
 2. Exceptions are silently ignored, e.g.,
    new Request('/', {get method() { throw Error(); }})
    doesn't throw.

This change fixes the issues.

Bug: 775318
Change-Id: I3d5b2b49f47cfdf92ba0707f6af0260653e386d9
Reviewed-on: https://chromium-review.googlesource.com/722543
Commit-Queue: Yutaka Hirano <yhirano@chromium.org>
Reviewed-by: default avatarAdam Rice <ricea@chromium.org>
Reviewed-by: default avatarKouhei Ueno <kouhei@chromium.org>
Cr-Commit-Position: refs/heads/master@{#509714}
parent 88d99072
...@@ -560,6 +560,72 @@ test(() => { ...@@ -560,6 +560,72 @@ test(() => {
assert_throws({name: 'TypeError'}, () => { req.clone(); }); assert_throws({name: 'TypeError'}, () => { req.clone(); });
}, 'Used => clone'); }, 'Used => clone');
test(() => {
// We implement RequestInit manually so we need to test the functionality
// here.
function undefined_notpresent(property_name) {
assert_not_equals(property_name, 'referrer', 'property_name');
const request = new Request('/', {referrer: '/'});
let init = {};
init[property_name] = undefined;
assert_equals((new Request(request, init)).referrer, request.url,
property_name);
}
undefined_notpresent('method');
undefined_notpresent('headers');
undefined_notpresent('body');
undefined_notpresent('referrerPolicy');
undefined_notpresent('mode');
undefined_notpresent('credentials');
undefined_notpresent('cache');
undefined_notpresent('redirect');
undefined_notpresent('integrity');
undefined_notpresent('keepalive');
undefined_notpresent('signal');
undefined_notpresent('window');
// |undefined_notpresent| uses referrer for testing, so we need to test
// the property manually.
const request = new Request('/', {referrerPolicy: 'same-origin'});
assert_equals(new Request(request, {referrer: undefined}).referrerPolicy,
'same-origin', 'referrer');
}, 'An undefined member should be treated as not-present');
test(() => {
// We implement RequestInit manually so we need to test the functionality
// here.
const e = Error();
assert_throws(e, () => {
new Request('/', {get method() { throw e; }})}, 'method');
assert_throws(e, () => {
new Request('/', {get headers() { throw e; }})}, 'headers');
assert_throws(e, () => {
new Request('/', {get body() { throw e; }})}, 'body');
assert_throws(e, () => {
new Request('/', {get referrer() { throw e; }})}, 'referrer');
assert_throws(e, () => {
new Request('/', {get referrerPolicy() { throw e; }})}, 'referrerPolicy');
assert_throws(e, () => {
new Request('/', {get mode() { throw e; }})}, 'mode');
assert_throws(e, () => {
new Request('/', {get credentials() { throw e; }})}, 'credentials');
assert_throws(e, () => {
new Request('/', {get cache() { throw e; }})}, 'cache');
assert_throws(e, () => {
new Request('/', {get redirect() { throw e; }})}, 'redirect');
assert_throws(e, () => {
new Request('/', {get integrity() { throw e; }})}, 'integrity');
// Not implemented
// assert_throws(e, () => {
// new Request('/', {get keepalive() { throw e; }})}, 'keepalive');
// assert_throws(e, () => {
// new Request('/', {get signal() { throw e; }})}, 'signal');
// assert_throws(e, () => {
// new Request('/', {get window() { throw e; }})}, 'window');
}, 'Getter exceptions should not be silently ignored');
promise_test(function() { promise_test(function() {
var headers = new Headers; var headers = new Headers;
headers.set('Content-Language', 'ja'); headers.set('Content-Language', 'ja');
......
...@@ -162,16 +162,6 @@ struct DictionaryHelper { ...@@ -162,16 +162,6 @@ struct DictionaryHelper {
template <typename T> template <typename T>
static bool Get(const Dictionary&, const StringView& key, T& value); static bool Get(const Dictionary&, const StringView& key, T& value);
template <typename T> template <typename T>
static bool GetWithUndefinedCheck(const Dictionary& dictionary,
const StringView& key,
T& value) {
v8::Local<v8::Value> v8_value;
if (!dictionary.Get(key, v8_value) || v8_value.IsEmpty() ||
v8_value->IsUndefined())
return false;
return DictionaryHelper::Get(dictionary, key, value);
}
template <typename T>
static bool Get(const Dictionary&, const StringView& key, Nullable<T>& value); static bool Get(const Dictionary&, const StringView& key, Nullable<T>& value);
}; };
......
...@@ -5,11 +5,13 @@ ...@@ -5,11 +5,13 @@
#ifndef RequestInit_h #ifndef RequestInit_h
#define RequestInit_h #define RequestInit_h
#include "bindings/core/v8/NativeValueTraits.h"
#include "bindings/modules/v8/byte_string_sequence_sequence_or_byte_string_byte_string_record.h" #include "bindings/modules/v8/byte_string_sequence_sequence_or_byte_string_byte_string_record.h"
#include "modules/fetch/Headers.h" #include "modules/fetch/Headers.h"
#include "platform/heap/Handle.h" #include "platform/heap/Handle.h"
#include "platform/network/EncodedFormData.h" #include "platform/network/EncodedFormData.h"
#include "platform/weborigin/Referrer.h" #include "platform/weborigin/Referrer.h"
#include "platform/wtf/Optional.h"
#include "platform/wtf/RefPtr.h" #include "platform/wtf/RefPtr.h"
#include "platform/wtf/text/WTFString.h" #include "platform/wtf/text/WTFString.h"
...@@ -41,6 +43,24 @@ class RequestInit { ...@@ -41,6 +43,24 @@ class RequestInit {
bool AreAnyMembersSet() const { return are_any_members_set_; } bool AreAnyMembersSet() const { return are_any_members_set_; }
private: private:
// These are defined here to avoid JUMBO ambiguity.
class GetterHelper;
struct IDLPassThrough;
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 SetUpBody(ExecutionContext*,
v8::Isolate*,
v8::Local<v8::Value> v8_body,
ExceptionState&);
String method_; String method_;
HeadersInit headers_; HeadersInit headers_;
String content_type_; String content_type_;
......
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