1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "third_party/blink/renderer/bindings/core/v8/referrer_script_info.h"
6 
7 #include "mojo/public/cpp/bindings/enum_utils.h"
8 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
9 #include "v8/include/v8.h"
10 
11 namespace blink {
12 
13 namespace {
14 
15 enum HostDefinedOptionsIndex : size_t {
16   kBaseURL,
17   kCredentialsMode,
18   kNonce,
19   kParserState,
20   kReferrerPolicy,
21   kBaseUrlSource,
22   kLength
23 };
24 
25 }  // namespace
26 
FromV8HostDefinedOptions(v8::Local<v8::Context> context,v8::Local<v8::PrimitiveArray> host_defined_options)27 ReferrerScriptInfo ReferrerScriptInfo::FromV8HostDefinedOptions(
28     v8::Local<v8::Context> context,
29     v8::Local<v8::PrimitiveArray> host_defined_options) {
30   if (host_defined_options.IsEmpty() || !host_defined_options->Length()) {
31     return ReferrerScriptInfo();
32   }
33 
34   v8::Isolate* isolate = context->GetIsolate();
35   v8::Local<v8::Primitive> base_url_value =
36       host_defined_options->Get(isolate, kBaseURL);
37   SECURITY_CHECK(base_url_value->IsString());
38   String base_url_string =
39       ToCoreString(v8::Local<v8::String>::Cast(base_url_value));
40   KURL base_url = base_url_string.IsEmpty() ? KURL() : KURL(base_url_string);
41   DCHECK(base_url.IsNull() || base_url.IsValid());
42 
43   v8::Local<v8::Primitive> credentials_mode_value =
44       host_defined_options->Get(isolate, kCredentialsMode);
45   SECURITY_CHECK(credentials_mode_value->IsUint32());
46   auto credentials_mode = static_cast<network::mojom::CredentialsMode>(
47       credentials_mode_value->IntegerValue(context).ToChecked());
48 
49   v8::Local<v8::Primitive> nonce_value =
50       host_defined_options->Get(isolate, kNonce);
51   SECURITY_CHECK(nonce_value->IsString());
52   String nonce = ToCoreString(v8::Local<v8::String>::Cast(nonce_value));
53 
54   v8::Local<v8::Primitive> parser_state_value =
55       host_defined_options->Get(isolate, kParserState);
56   SECURITY_CHECK(parser_state_value->IsUint32());
57   ParserDisposition parser_state = static_cast<ParserDisposition>(
58       parser_state_value->IntegerValue(context).ToChecked());
59 
60   v8::Local<v8::Primitive> referrer_policy_value =
61       host_defined_options->Get(isolate, kReferrerPolicy);
62   SECURITY_CHECK(referrer_policy_value->IsUint32());
63   int32_t referrer_policy_int32 = base::saturated_cast<int32_t>(
64       referrer_policy_value->IntegerValue(context).ToChecked());
65   network::mojom::ReferrerPolicy referrer_policy =
66       mojo::ConvertIntToMojoEnum<network::mojom::ReferrerPolicy>(
67           referrer_policy_int32)
68           .value_or(network::mojom::ReferrerPolicy::kDefault);
69 
70   v8::Local<v8::Primitive> base_url_source_value =
71       host_defined_options->Get(isolate, kBaseUrlSource);
72   SECURITY_CHECK(base_url_source_value->IsUint32());
73   BaseUrlSource base_url_source = static_cast<BaseUrlSource>(
74       base_url_source_value->IntegerValue(context).ToChecked());
75 
76   return ReferrerScriptInfo(base_url, credentials_mode, nonce, parser_state,
77                             referrer_policy, base_url_source);
78 }
79 
ToV8HostDefinedOptions(v8::Isolate * isolate) const80 v8::Local<v8::PrimitiveArray> ReferrerScriptInfo::ToV8HostDefinedOptions(
81     v8::Isolate* isolate) const {
82   if (IsDefaultValue())
83     return v8::Local<v8::PrimitiveArray>();
84 
85   v8::Local<v8::PrimitiveArray> host_defined_options =
86       v8::PrimitiveArray::New(isolate, HostDefinedOptionsIndex::kLength);
87 
88   v8::Local<v8::Primitive> base_url_value =
89       V8String(isolate, base_url_.GetString());
90   host_defined_options->Set(isolate, HostDefinedOptionsIndex::kBaseURL,
91                             base_url_value);
92 
93   v8::Local<v8::Primitive> credentials_mode_value =
94       v8::Integer::NewFromUnsigned(isolate,
95                                    static_cast<uint32_t>(credentials_mode_));
96   host_defined_options->Set(isolate, HostDefinedOptionsIndex::kCredentialsMode,
97                             credentials_mode_value);
98 
99   v8::Local<v8::Primitive> nonce_value = V8String(isolate, nonce_);
100   host_defined_options->Set(isolate, HostDefinedOptionsIndex::kNonce,
101                             nonce_value);
102 
103   v8::Local<v8::Primitive> parser_state_value = v8::Integer::NewFromUnsigned(
104       isolate, static_cast<uint32_t>(parser_state_));
105   host_defined_options->Set(isolate, HostDefinedOptionsIndex::kParserState,
106                             parser_state_value);
107 
108   v8::Local<v8::Primitive> referrer_policy_value = v8::Integer::NewFromUnsigned(
109       isolate, static_cast<uint32_t>(referrer_policy_));
110   host_defined_options->Set(isolate, HostDefinedOptionsIndex::kReferrerPolicy,
111                             referrer_policy_value);
112 
113   v8::Local<v8::Primitive> base_url_source_value = v8::Integer::NewFromUnsigned(
114       isolate, static_cast<uint32_t>(base_url_source_));
115   host_defined_options->Set(isolate, HostDefinedOptionsIndex::kBaseUrlSource,
116                             base_url_source_value);
117 
118   return host_defined_options;
119 }
120 
121 }  // namespace blink
122