Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: third_party/WebKit/Source/bindings/templates/interface_base.cpp.tmpl

Issue 2439013002: Implement cross-origin attributes using access check interceptors. (Closed)
Patch Set: etc2 Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 {% filter format_blink_cpp_source_code %} 1 {% filter format_blink_cpp_source_code %}
2 2
3 {% include 'copyright_block.txt' %} 3 {% include 'copyright_block.txt' %}
4 #include "{{v8_class_or_partial}}.h" 4 #include "{{v8_class_or_partial}}.h"
5 5
6 {% for filename in cpp_includes if filename != '%s.h' % cpp_class_or_partial %} 6 {% for filename in cpp_includes if filename != '%s.h' % cpp_class_or_partial %}
7 #include "{{filename}}" 7 #include "{{filename}}"
8 {% endfor %} 8 {% endfor %}
9 9
10 namespace blink { 10 namespace blink {
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 {% endif %} 114 {% endif %}
115 {% if attribute.has_setter %} 115 {% if attribute.has_setter %}
116 {% if not attribute.has_custom_setter %} 116 {% if not attribute.has_custom_setter %}
117 {{attribute_setter(attribute, world_suffix)}} 117 {{attribute_setter(attribute, world_suffix)}}
118 {% endif %} 118 {% endif %}
119 {{attribute_setter_callback(attribute, world_suffix)}} 119 {{attribute_setter_callback(attribute, world_suffix)}}
120 {% endif %} 120 {% endif %}
121 {% endfor %} 121 {% endfor %}
122 {% endfor %} 122 {% endfor %}
123 {##############################################################################} 123 {##############################################################################}
124 {% block security_check_functions %}
125 {% if has_access_check_callbacks and not is_partial %}
126 bool securityCheck(v8::Local<v8::Context> accessingContext, v8::Local<v8::Object > accessedObject, v8::Local<v8::Value> data) {
127 {% if interface_name == 'Window' %}
128 v8::Isolate* isolate = v8::Isolate::GetCurrent();
129 v8::Local<v8::Object> window = V8Window::findInstanceInPrototypeChain(accessed Object, isolate);
130 if (window.IsEmpty())
131 return false; // the frame is gone.
132
133 const DOMWindow* targetWindow = V8Window::toImpl(window);
134 return BindingSecurity::shouldAllowAccessTo(toLocalDOMWindow(toDOMWindow(acces singContext)), targetWindow, BindingSecurity::ErrorReportOption::DoNotReport);
135 {% else %}{# if interface_name == 'Window' #}
136 {# Not 'Window' means it\'s Location. #}
137 {{cpp_class}}* impl = {{v8_class}}::toImpl(accessedObject);
138 return BindingSecurity::shouldAllowAccessTo(toLocalDOMWindow(toDOMWindow(acces singContext)), impl, BindingSecurity::ErrorReportOption::DoNotReport);
139 {% endif %}{# if interface_name == 'Window' #}
140 }
141
142 {% endif %}
143 {% endblock %}
144 {##############################################################################}
145 {# Methods #} 124 {# Methods #}
146 {% from 'methods.cpp.tmpl' import generate_method, overload_resolution_method, 125 {% from 'methods.cpp.tmpl' import generate_method, overload_resolution_method,
147 method_callback, origin_safe_method_getter, generate_constructor, 126 method_callback, origin_safe_method_getter, generate_constructor,
148 method_implemented_in_private_script, generate_post_message_impl, 127 method_implemented_in_private_script, generate_post_message_impl,
149 runtime_determined_length_method, runtime_determined_maxarg_method 128 runtime_determined_length_method, runtime_determined_maxarg_method
150 with context %} 129 with context %}
151 {% for method in methods if method.should_be_exposed_to_script %} 130 {% for method in methods if method.should_be_exposed_to_script %}
152 {% for world_suffix in method.world_suffixes %} 131 {% for world_suffix in method.world_suffixes %}
153 {% if not method.is_custom and not method.is_post_message and method.visible %} 132 {% if not method.is_custom and not method.is_post_message and method.visible %}
154 {{generate_method(method, world_suffix)}} 133 {{generate_method(method, world_suffix)}}
(...skipping 14 matching lines...) Expand all
169 {# Document about the following condition: #} 148 {# Document about the following condition: #}
170 {# https://docs.google.com/document/d/1qBC7Therp437Jbt_QYAtNYMZs6zQ_7_tnMkNUG_AC qs/edit?usp=sharing #} 149 {# https://docs.google.com/document/d/1qBC7Therp437Jbt_QYAtNYMZs6zQ_7_tnMkNUG_AC qs/edit?usp=sharing #}
171 {% if (method.overloads and method.overloads.visible and 150 {% if (method.overloads and method.overloads.visible and
172 (not method.overloads.has_partial_overloads or not is_partial)) or 151 (not method.overloads.has_partial_overloads or not is_partial)) or
173 (not method.overloads and method.visible) %} 152 (not method.overloads and method.visible) %}
174 {# A single callback is generated for overloaded methods #} 153 {# A single callback is generated for overloaded methods #}
175 {# with considering partial overloads #} 154 {# with considering partial overloads #}
176 {{method_callback(method, world_suffix)}} 155 {{method_callback(method, world_suffix)}}
177 {% endif %} 156 {% endif %}
178 {% endif %} 157 {% endif %}
179 {% if method.is_do_not_check_security and method.visible %} 158 {% if method.is_cross_origin and method.visible %}
180 {{origin_safe_method_getter(method, world_suffix)}} 159 {{origin_safe_method_getter(method, world_suffix)}}
181 {% endif %} 160 {% endif %}
182 {% endfor %} 161 {% endfor %}
183 {% endfor %} 162 {% endfor %}
184 {% if iterator_method %} 163 {% if iterator_method %}
185 {{generate_method(iterator_method)}} 164 {{generate_method(iterator_method)}}
186 {{method_callback(iterator_method)}} 165 {{method_callback(iterator_method)}}
187 {% endif %} 166 {% endif %}
188 {% block origin_safe_method_setter %}{% endblock %} 167 {% block origin_safe_method_setter %}{% endblock %}
189 {# Constructors #} 168 {# Constructors #}
(...skipping 12 matching lines...) Expand all
202 {% block named_property_query %}{% endblock %} 181 {% block named_property_query %}{% endblock %}
203 {% block named_property_query_callback %}{% endblock %} 182 {% block named_property_query_callback %}{% endblock %}
204 {% block named_property_enumerator %}{% endblock %} 183 {% block named_property_enumerator %}{% endblock %}
205 {% block named_property_enumerator_callback %}{% endblock %} 184 {% block named_property_enumerator_callback %}{% endblock %}
206 {% block indexed_property_getter %}{% endblock %} 185 {% block indexed_property_getter %}{% endblock %}
207 {% block indexed_property_getter_callback %}{% endblock %} 186 {% block indexed_property_getter_callback %}{% endblock %}
208 {% block indexed_property_setter %}{% endblock %} 187 {% block indexed_property_setter %}{% endblock %}
209 {% block indexed_property_setter_callback %}{% endblock %} 188 {% block indexed_property_setter_callback %}{% endblock %}
210 {% block indexed_property_deleter %}{% endblock %} 189 {% block indexed_property_deleter %}{% endblock %}
211 {% block indexed_property_deleter_callback %}{% endblock %} 190 {% block indexed_property_deleter_callback %}{% endblock %}
191 {##############################################################################}
192 {% block security_check_functions %}
193 {% if has_access_check_callbacks and not is_partial %}
194 bool securityCheck(v8::Local<v8::Context> accessingContext, v8::Local<v8::Object > accessedObject, v8::Local<v8::Value> data) {
195 {% if interface_name == 'Window' %}
196 v8::Isolate* isolate = v8::Isolate::GetCurrent();
197 v8::Local<v8::Object> window = V8Window::findInstanceInPrototypeChain(accessed Object, isolate);
198 if (window.IsEmpty())
199 return false; // the frame is gone.
200
201 const DOMWindow* targetWindow = V8Window::toImpl(window);
202 return BindingSecurity::shouldAllowAccessTo(toLocalDOMWindow(toDOMWindow(acces singContext)), targetWindow, BindingSecurity::ErrorReportOption::DoNotReport);
203 {% else %}{# if interface_name == 'Window' #}
204 {# Not 'Window' means it\'s Location. #}
205 {{cpp_class}}* impl = {{v8_class}}::toImpl(accessedObject);
206 return BindingSecurity::shouldAllowAccessTo(toLocalDOMWindow(toDOMWindow(acces singContext)), impl, BindingSecurity::ErrorReportOption::DoNotReport);
207 {% endif %}{# if interface_name == 'Window' #}
208 }
209
210 {% if has_cross_origin_named_getter %}
211 // TODO(dcheng): Can we / should we use AtomicString here? That means using DEFI NE_STATIC_LOCAL here.
212 static const struct {
213 const char* const name;
214 using GetterCallback = void(*)(const v8::PropertyCallbackInfo<v8::Value>&);
215 const GetterCallback getter;
216 } kCrossOriginGetterAttributeInfoList[] = {
217 {##### Cross-origin attributes #####}
218 {% for attribute in attributes if attribute.has_cross_origin_getter %}
219 {"{{attribute.name}}", &{{cpp_class}}V8Internal::{{attribute.name}}AttributeGe tter},
220 {% endfor %}
221 {##### Cross-origin methods #####}
222 {% for method in methods if method.is_cross_origin %}
223 {"{{method.name}}", &{{cpp_class}}V8Internal::{{method.name}}OriginSafeMethodG etter},
224 {% endfor %}
225 };
226
227 void crossOriginNamedGetter(v8::Local<v8::Name> name, const v8::PropertyCallback Info<v8::Value>& info) {
228 if (!name->IsString())
229 return;
230 const AtomicString& propertyName = toCoreAtomicString(name.As<v8::String>());
231
232 for (const auto& attribute: kCrossOriginGetterAttributeInfoList) {
233 if (propertyName == attribute.name) {
234 attribute.getter(info);
235 return;
236 }
237 }
238
239 {% if named_property_getter and named_property_getter.is_cross_origin %}
240 {% if named_property_getter.is_custom %}
241 {{v8_class}}::namedPropertyGetterCustom(propertyName, info);
242 {% else %}
243 {{cpp_class}}V8Internal::namedPropertyGetter(propertyName, info);
244 {% endif %}
245 {% else %}
246 BindingSecurity::failedAccessCheckFor(
247 info.GetIsolate(),
248 {{v8_class}}::toImpl(info.Holder())->frame());
249 {% endif %}
250 }
251 {% endif %}
252
253 {% if has_cross_origin_named_setter %}
254 // TODO(dcheng): Can we / should we use AtomicString here? That means using DEFI NE_STATIC_LOCAL here.
255 static const struct {
256 const char* const name;
257 using SetterCallback = void(*)(v8::Local<v8::Value>, const V8CrossOriginSetter Info&);
258 const SetterCallback setter;
259 } kCrossOriginSetterAttributeInfoList[] = {
260 {##### Cross-origin attributes #####}
261 {% for attribute in attributes if attribute.has_cross_origin_setter %}
262 {"{{attribute.name}}", &{{cpp_class}}V8Internal::{{attribute.name}}AttributeSe tter},
263 {% endfor %}
264 };
265
266 void crossOriginNamedSetter(v8::Local<v8::Name> name, v8::Local<v8::Value> value , const v8::PropertyCallbackInfo<v8::Value>& info) {
267 if (!name->IsString())
268 return;
269 const AtomicString& propertyName = toCoreAtomicString(name.As<v8::String>());
270
271 for (const auto& attribute: kCrossOriginSetterAttributeInfoList) {
272 if (propertyName == attribute.name) {
273 attribute.setter(value, V8CrossOriginSetterInfo(info.GetIsolate(), info.Ho lder()));
274 return;
275 }
276 }
277
278 BindingSecurity::failedAccessCheckFor(
279 info.GetIsolate(),
280 {{v8_class}}::toImpl(info.Holder())->frame());
281 }
282 {% endif %}
283
284 {% if has_cross_origin_named_getter %}
285 void crossOriginNamedEnumerator(const v8::PropertyCallbackInfo<v8::Array>& info) {
286 HashSet<String> names;
287 for (const auto& attribute : kCrossOriginGetterAttributeInfoList)
288 names.add(attribute.name);
289 for (const auto& attribute : kCrossOriginSetterAttributeInfoList)
290 names.add(attribute.name);
291
292 v8SetReturnValue(
293 info,
294 toV8SequenceInternal(
dcheng 2016/12/07 08:19:08 This isn't very nice, but there's no easy way to c
Yuki 2016/12/07 12:03:40 nit: I think the code generator can pre-computes e
295 names, info.Holder(), info.GetIsolate()).As<v8::Array>());
296 }
297 {% endif %}
298
299 {% if has_cross_origin_indexed_getter %}
300 void crossOriginIndexedGetter(uint32_t index, const v8::PropertyCallbackInfo<v8: :Value>& info) {
301 {% if indexed_property_getter.is_custom %}
302 {{v8_class}}::indexedPropertyGetterCustom(index, info);
303 {% else %}
304 {{cpp_class}}V8Internal::indexedPropertyGetter(index, info);
305 {% endif %}
306 }
307 {% endif %}
308
309 {% endif %}
310 {% endblock %}
311 {##############################################################################}
212 } // namespace {{cpp_class_or_partial}}V8Internal 312 } // namespace {{cpp_class_or_partial}}V8Internal
213 313
214 {% block visit_dom_wrapper %}{% endblock %} 314 {% block visit_dom_wrapper %}{% endblock %}
215 {##############################################################################} 315 {##############################################################################}
216 {% block install_attributes %} 316 {% block install_attributes %}
217 {% from 'attributes.cpp.tmpl' import attribute_configuration with context %} 317 {% from 'attributes.cpp.tmpl' import attribute_configuration with context %}
218 {% if attributes | has_attribute_configuration %} 318 {% if attributes | has_attribute_configuration %}
219 // Suppress warning: global constructors, because AttributeConfiguration is triv ial 319 // Suppress warning: global constructors, because AttributeConfiguration is triv ial
220 // and does not depend on another global objects. 320 // and does not depend on another global objects.
221 #if defined(COMPONENT_BUILD) && defined(WIN32) && COMPILER(CLANG) 321 #if defined(COMPONENT_BUILD) && defined(WIN32) && COMPILER(CLANG)
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 {% endif %} 443 {% endif %}
344 {% if attributes | has_accessor_configuration %} 444 {% if attributes | has_accessor_configuration %}
345 V8DOMConfiguration::installAccessors(isolate, world, instanceTemplate, prototy peTemplate, interfaceTemplate, signature, {{'%sAccessors' % v8_class}}, {{'WTF_A RRAY_LENGTH(%sAccessors)' % v8_class}}); 445 V8DOMConfiguration::installAccessors(isolate, world, instanceTemplate, prototy peTemplate, interfaceTemplate, signature, {{'%sAccessors' % v8_class}}, {{'WTF_A RRAY_LENGTH(%sAccessors)' % v8_class}});
346 {% endif %} 446 {% endif %}
347 {% if methods | has_method_configuration(is_partial) %} 447 {% if methods | has_method_configuration(is_partial) %}
348 V8DOMConfiguration::installMethods(isolate, world, instanceTemplate, prototype Template, interfaceTemplate, signature, {{'%sMethods' % v8_class}}, {{'WTF_ARRAY _LENGTH(%sMethods)' % v8_class}}); 448 V8DOMConfiguration::installMethods(isolate, world, instanceTemplate, prototype Template, interfaceTemplate, signature, {{'%sMethods' % v8_class}}, {{'WTF_ARRAY _LENGTH(%sMethods)' % v8_class}});
349 {% endif %} 449 {% endif %}
350 {% endfilter %} 450 {% endfilter %}
351 {%- if has_access_check_callbacks and not is_partial %}{{newline}} 451 {%- if has_access_check_callbacks and not is_partial %}{{newline}}
352 // Cross-origin access check 452 // Cross-origin access check
353 instanceTemplate->SetAccessCheckCallback({{cpp_class}}V8Internal::securityChec k, v8::External::New(isolate, const_cast<WrapperTypeInfo*>(&{{v8_class}}::wrappe rTypeInfo))); 453 {% set cross_origin_named_getter = '%sV8Internal::crossOriginNamedGetter' % cp p_class if has_cross_origin_named_getter else 'nullptr' %}
454 {% set cross_origin_named_setter = '%sV8Internal::crossOriginNamedSetter' % cp p_class if has_cross_origin_named_setter else 'nullptr' %}
455 {# TODO(dcheng): This seems a bit bogus. #}
456 {% set cross_origin_named_enumerator = '%sV8Internal::crossOriginNamedEnumerat or' % cpp_class if has_cross_origin_named_getter else 'nullptr' %}
457 {% set cross_origin_indexed_getter = '%sV8Internal::crossOriginIndexedGetter' % cpp_class if has_cross_origin_indexed_getter else 'nullptr' %}
458 instanceTemplate->SetAccessCheckCallbackAndHandler({{cpp_class}}V8Internal::se curityCheck, v8::NamedPropertyHandlerConfiguration({{cross_origin_named_getter}} , {{cross_origin_named_setter}}, nullptr, nullptr, {{cross_origin_named_enumerat or}}), v8::IndexedPropertyHandlerConfiguration({{cross_origin_indexed_getter}}), v8::External::New(isolate, const_cast<WrapperTypeInfo*>(&{{v8_class}}::wrapperT ypeInfo)));
354 {% endif %} 459 {% endif %}
355 460
356 {%- for group in attributes | purely_runtime_enabled_attributes | groupby('run time_feature_name') %}{{newline}} 461 {%- for group in attributes | purely_runtime_enabled_attributes | groupby('run time_feature_name') %}{{newline}}
357 if ({{group.list[0].runtime_enabled_function}}()) { 462 if ({{group.list[0].runtime_enabled_function}}()) {
358 {% for attribute in group.list | unique_by('name') | sort %} 463 {% for attribute in group.list | unique_by('name') | sort %}
359 {% if attribute.is_data_type_property %} 464 {% if attribute.is_data_type_property %}
360 const V8DOMConfiguration::AttributeConfiguration attribute{{attribute.name}} Configuration = {{attribute_configuration(attribute)}}; 465 const V8DOMConfiguration::AttributeConfiguration attribute{{attribute.name}} Configuration = {{attribute_configuration(attribute)}};
361 V8DOMConfiguration::installAttribute(isolate, world, instanceTemplate, proto typeTemplate, attribute{{attribute.name}}Configuration); 466 V8DOMConfiguration::installAttribute(isolate, world, instanceTemplate, proto typeTemplate, attribute{{attribute.name}}Configuration);
362 {% else %} 467 {% else %}
363 const V8DOMConfiguration::AccessorConfiguration accessor{{attribute.name}}Co nfiguration = {{attribute_configuration(attribute)}}; 468 const V8DOMConfiguration::AccessorConfiguration accessor{{attribute.name}}Co nfiguration = {{attribute_configuration(attribute)}};
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 instanceTemplate->MarkAsUndetectable(); 507 instanceTemplate->MarkAsUndetectable();
403 {% endif %} 508 {% endif %}
404 509
405 {%- if methods | custom_registration(is_partial) %}{{newline}} 510 {%- if methods | custom_registration(is_partial) %}{{newline}}
406 {% for method in methods | custom_registration(is_partial) %} 511 {% for method in methods | custom_registration(is_partial) %}
407 {# install_custom_signature #} 512 {# install_custom_signature #}
408 {% filter exposed(method.overloads.exposed_test_all 513 {% filter exposed(method.overloads.exposed_test_all
409 if method.overloads else method.exposed_test) %} 514 if method.overloads else method.exposed_test) %}
410 {% filter runtime_enabled(method.overloads.runtime_enabled_function_all 515 {% filter runtime_enabled(method.overloads.runtime_enabled_function_all
411 if method.overloads else method.runtime_enabled_func tion) %} 516 if method.overloads else method.runtime_enabled_func tion) %}
412 {% if method.is_do_not_check_security %} 517 {% if method.is_cross_origin %}
413 {{install_do_not_check_security_method(method, '', 'instanceTemplate', 'protot ypeTemplate') | indent(2)}} 518 {# TODO(dcheng): This shouldn't be necessary with cross-origin interceptors,
519 but v8 doesn't support querying the incumbent context. For now, always
520 incorrectly create per-realm representations. #}
521 {{install_origin_safe_method(method, '', 'instanceTemplate', 'prototypeTemplat e') | indent(2)}}
414 {% else %} 522 {% else %}
415 {{install_custom_signature(method, 'instanceTemplate', 'prototypeTemplate', 'i nterfaceTemplate', 'signature') | indent(2)}} 523 {{install_custom_signature(method, 'instanceTemplate', 'prototypeTemplate', 'i nterfaceTemplate', 'signature') | indent(2)}}
416 {% endif %} 524 {% endif %}
417 {% endfilter %} 525 {% endfilter %}
418 {% endfilter %} 526 {% endfilter %}
419 {% endfor %} 527 {% endfor %}
420 {% endif %} 528 {% endif %}
421 } 529 }
422 530
423 {% endif %}{# not is_array_buffer_or_view #} 531 {% endif %}{# not is_array_buffer_or_view #}
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
489 {% for attribute in attributes if attribute.is_implemented_in_private_script %} 597 {% for attribute in attributes if attribute.is_implemented_in_private_script %}
490 {{attribute_getter_implemented_in_private_script(attribute)}} 598 {{attribute_getter_implemented_in_private_script(attribute)}}
491 {% if attribute.has_setter %} 599 {% if attribute.has_setter %}
492 {{attribute_setter_implemented_in_private_script(attribute)}} 600 {{attribute_setter_implemented_in_private_script(attribute)}}
493 {% endif %} 601 {% endif %}
494 {% endfor %} 602 {% endfor %}
495 {% block partial_interface %}{% endblock %} 603 {% block partial_interface %}{% endblock %}
496 } // namespace blink 604 } // namespace blink
497 605
498 {% endfilter %}{# format_blink_cpp_source_code #} 606 {% endfilter %}{# format_blink_cpp_source_code #}
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698