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

Side by Side Diff: third_party/WebKit/Source/bindings/core/v8/ScriptController.cpp

Issue 1483733002: Remove support for NPObjects. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 4 years, 8 months 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 /* 1 /*
2 * Copyright (C) 2008, 2009 Google Inc. All rights reserved. 2 * Copyright (C) 2008, 2009 Google Inc. All rights reserved.
3 * Copyright (C) 2009 Apple Inc. All rights reserved. 3 * Copyright (C) 2009 Apple Inc. All rights reserved.
4 * Copyright (C) 2014 Opera Software ASA. All rights reserved. 4 * Copyright (C) 2014 Opera Software ASA. All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are 7 * modification, are permitted provided that the following conditions are
8 * met: 8 * met:
9 * 9 *
10 * * Redistributions of source code must retain the above copyright 10 * * Redistributions of source code must retain the above copyright
(...skipping 15 matching lines...) Expand all
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */ 31 */
32 32
33 #include "bindings/core/v8/ScriptController.h" 33 #include "bindings/core/v8/ScriptController.h"
34 34
35 #include "bindings/core/v8/BindingSecurity.h" 35 #include "bindings/core/v8/BindingSecurity.h"
36 #include "bindings/core/v8/NPV8Object.h"
37 #include "bindings/core/v8/ScriptCallStack.h" 36 #include "bindings/core/v8/ScriptCallStack.h"
38 #include "bindings/core/v8/ScriptSourceCode.h" 37 #include "bindings/core/v8/ScriptSourceCode.h"
39 #include "bindings/core/v8/ScriptValue.h" 38 #include "bindings/core/v8/ScriptValue.h"
40 #include "bindings/core/v8/V8Binding.h" 39 #include "bindings/core/v8/V8Binding.h"
41 #include "bindings/core/v8/V8Event.h" 40 #include "bindings/core/v8/V8Event.h"
42 #include "bindings/core/v8/V8GCController.h" 41 #include "bindings/core/v8/V8GCController.h"
43 #include "bindings/core/v8/V8HTMLElement.h" 42 #include "bindings/core/v8/V8HTMLElement.h"
44 #include "bindings/core/v8/V8NPObject.h"
45 #include "bindings/core/v8/V8PerContextData.h" 43 #include "bindings/core/v8/V8PerContextData.h"
46 #include "bindings/core/v8/V8ScriptRunner.h" 44 #include "bindings/core/v8/V8ScriptRunner.h"
47 #include "bindings/core/v8/V8Window.h" 45 #include "bindings/core/v8/V8Window.h"
48 #include "bindings/core/v8/WindowProxy.h" 46 #include "bindings/core/v8/WindowProxy.h"
49 #include "bindings/core/v8/npruntime_impl.h"
50 #include "bindings/core/v8/npruntime_priv.h"
51 #include "core/dom/Document.h" 47 #include "core/dom/Document.h"
52 #include "core/dom/Node.h" 48 #include "core/dom/Node.h"
53 #include "core/dom/ScriptableDocumentParser.h" 49 #include "core/dom/ScriptableDocumentParser.h"
54 #include "core/events/Event.h" 50 #include "core/events/Event.h"
55 #include "core/events/EventListener.h" 51 #include "core/events/EventListener.h"
56 #include "core/frame/LocalDOMWindow.h" 52 #include "core/frame/LocalDOMWindow.h"
57 #include "core/frame/Settings.h" 53 #include "core/frame/Settings.h"
58 #include "core/frame/UseCounter.h" 54 #include "core/frame/UseCounter.h"
59 #include "core/frame/csp/ContentSecurityPolicy.h" 55 #include "core/frame/csp/ContentSecurityPolicy.h"
60 #include "core/html/HTMLPlugInElement.h" 56 #include "core/html/HTMLPlugInElement.h"
(...skipping 26 matching lines...) Expand all
87 bool ScriptController::canAccessFromCurrentOrigin(v8::Isolate* isolate, Frame* f rame) 83 bool ScriptController::canAccessFromCurrentOrigin(v8::Isolate* isolate, Frame* f rame)
88 { 84 {
89 if (!frame) 85 if (!frame)
90 return false; 86 return false;
91 return !isolate->InContext() || BindingSecurity::shouldAllowAccessToFrame(is olate, callingDOMWindow(isolate), frame, ReportSecurityError); 87 return !isolate->InContext() || BindingSecurity::shouldAllowAccessToFrame(is olate, callingDOMWindow(isolate), frame, ReportSecurityError);
92 } 88 }
93 89
94 ScriptController::ScriptController(LocalFrame* frame) 90 ScriptController::ScriptController(LocalFrame* frame)
95 : m_windowProxyManager(WindowProxyManager::create(*frame)) 91 : m_windowProxyManager(WindowProxyManager::create(*frame))
96 , m_sourceURL(0) 92 , m_sourceURL(0)
97 , m_windowScriptNPObject(0)
98 { 93 {
99 } 94 }
100 95
101 ScriptController::~ScriptController() 96 ScriptController::~ScriptController()
102 { 97 {
103 } 98 }
104 99
105 DEFINE_TRACE(ScriptController) 100 DEFINE_TRACE(ScriptController)
106 { 101 {
107 #if ENABLE(OILPAN) 102 #if ENABLE(OILPAN)
108 visitor->trace(m_windowProxyManager); 103 visitor->trace(m_windowProxyManager);
109 visitor->trace(m_pluginObjects);
110 #endif 104 #endif
111 } 105 }
112 106
113 void ScriptController::clearScriptObjects()
114 {
115 PluginObjectMap::iterator it = m_pluginObjects.begin();
116 for (; it != m_pluginObjects.end(); ++it) {
117 _NPN_UnregisterObject(it->value);
118 _NPN_ReleaseObject(it->value);
119 }
120 m_pluginObjects.clear();
121
122 if (m_windowScriptNPObject) {
123 // Dispose of the underlying V8 object before releasing our reference
124 // to it, so that if a plugin fails to release it properly we will
125 // only leak the NPObject wrapper, not the object, its document, or
126 // anything else they reference.
127 disposeUnderlyingV8Object(isolate(), m_windowScriptNPObject);
128 _NPN_ReleaseObject(m_windowScriptNPObject);
129 m_windowScriptNPObject = 0;
130 }
131 }
132
133 void ScriptController::clearForClose() 107 void ScriptController::clearForClose()
134 { 108 {
135 double start = currentTime(); 109 double start = currentTime();
136 m_windowProxyManager->clearForClose(); 110 m_windowProxyManager->clearForClose();
137 double end = currentTime(); 111 double end = currentTime();
138 DEFINE_STATIC_LOCAL(CustomCountHistogram, clearForCloseHistogram, ("WebCore. ScriptController.clearForClose", 0, 10000, 50)); 112 DEFINE_STATIC_LOCAL(CustomCountHistogram, clearForCloseHistogram, ("WebCore. ScriptController.clearForClose", 0, 10000, 50));
139 clearForCloseHistogram.count((end - start) * 1000); 113 clearForCloseHistogram.count((end - start) * 1000);
140 } 114 }
141 115
142 void ScriptController::updateSecurityOrigin(SecurityOrigin* origin) 116 void ScriptController::updateSecurityOrigin(SecurityOrigin* origin)
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 } 204 }
231 205
232 TextPosition ScriptController::eventHandlerPosition() const 206 TextPosition ScriptController::eventHandlerPosition() const
233 { 207 {
234 ScriptableDocumentParser* parser = frame()->document()->scriptableDocumentPa rser(); 208 ScriptableDocumentParser* parser = frame()->document()->scriptableDocumentPa rser();
235 if (parser) 209 if (parser)
236 return parser->textPosition(); 210 return parser->textPosition();
237 return TextPosition::minimumPosition(); 211 return TextPosition::minimumPosition();
238 } 212 }
239 213
240 // Create a V8 object with an interceptor of NPObjectPropertyGetter.
241 bool ScriptController::bindToWindowObject(LocalFrame* frame, const String& key, NPObject* object)
242 {
243 ScriptState* scriptState = ScriptState::forMainWorld(frame);
244 if (!scriptState)
245 return false;
246
247 ScriptState::Scope scope(scriptState);
248 v8::Local<v8::Object> value = createV8ObjectForNPObject(isolate(), object, 0 );
249
250 // Attach to the global object.
251 return v8CallBoolean(scriptState->context()->Global()->Set(scriptState->cont ext(), v8String(isolate(), key), value));
252 }
253
254 void ScriptController::enableEval() 214 void ScriptController::enableEval()
255 { 215 {
256 v8::HandleScope handleScope(isolate()); 216 v8::HandleScope handleScope(isolate());
257 v8::Local<v8::Context> v8Context = m_windowProxyManager->mainWorldProxy()->c ontextIfInitialized(); 217 v8::Local<v8::Context> v8Context = m_windowProxyManager->mainWorldProxy()->c ontextIfInitialized();
258 if (v8Context.IsEmpty()) 218 if (v8Context.IsEmpty())
259 return; 219 return;
260 v8Context->AllowCodeGenerationFromStrings(true); 220 v8Context->AllowCodeGenerationFromStrings(true);
261 } 221 }
262 222
263 void ScriptController::disableEval(const String& errorMessage) 223 void ScriptController::disableEval(const String& errorMessage)
(...skipping 12 matching lines...) Expand all
276 236
277 if (!widget->isPluginView()) 237 if (!widget->isPluginView())
278 return nullptr; 238 return nullptr;
279 239
280 v8::HandleScope handleScope(isolate()); 240 v8::HandleScope handleScope(isolate());
281 v8::Local<v8::Object> scriptableObject = toPluginView(widget)->scriptableObj ect(isolate()); 241 v8::Local<v8::Object> scriptableObject = toPluginView(widget)->scriptableObj ect(isolate());
282 242
283 if (scriptableObject.IsEmpty()) 243 if (scriptableObject.IsEmpty())
284 return nullptr; 244 return nullptr;
285 245
286 // LocalFrame Memory Management for NPObjects
287 // -------------------------------------
288 // NPObjects are treated differently than other objects wrapped by JS.
289 // NPObjects can be created either by the browser (e.g. the main
290 // window object) or by the plugin (the main plugin object
291 // for a HTMLEmbedElement). Further, unlike most DOM Objects, the frame
292 // is especially careful to ensure NPObjects terminate at frame teardown bec ause
293 // if a plugin leaks a reference, it could leak its objects (or the browser' s objects).
294 //
295 // The LocalFrame maintains a list of plugin objects (m_pluginObjects)
296 // which it can use to quickly find the wrapped embed object.
297 //
298 // Inside the NPRuntime, we've added a few methods for registering
299 // wrapped NPObjects. The purpose of the registration is because
300 // javascript garbage collection is non-deterministic, yet we need to
301 // be able to tear down the plugin objects immediately. When an object
302 // is registered, javascript can use it. When the object is destroyed,
303 // or when the object's "owning" object is destroyed, the object will
304 // be un-registered, and the javascript engine must not use it.
305 //
306 // Inside the javascript engine, the engine can keep a reference to the
307 // NPObject as part of its wrapper. However, before accessing the object
308 // it must consult the _NPN_Registry.
309
310 if (isWrappedNPObject(scriptableObject)) {
311 // Track the plugin object. We've been given a reference to the object.
312 m_pluginObjects.set(widget, v8ObjectToNPObject(scriptableObject));
313 }
314
315 return SharedPersistent<v8::Object>::create(scriptableObject, isolate()); 246 return SharedPersistent<v8::Object>::create(scriptableObject, isolate());
316 } 247 }
317 248
318 void ScriptController::cleanupScriptObjectsForPlugin(Widget* nativeHandle)
319 {
320 PluginObjectMap::iterator it = m_pluginObjects.find(nativeHandle);
321 if (it == m_pluginObjects.end())
322 return;
323 _NPN_UnregisterObject(it->value);
324 _NPN_ReleaseObject(it->value);
325 m_pluginObjects.remove(it);
326 }
327
328 V8Extensions& ScriptController::registeredExtensions() 249 V8Extensions& ScriptController::registeredExtensions()
329 { 250 {
330 DEFINE_STATIC_LOCAL(V8Extensions, extensions, ()); 251 DEFINE_STATIC_LOCAL(V8Extensions, extensions, ());
331 return extensions; 252 return extensions;
332 } 253 }
333 254
334 void ScriptController::registerExtensionIfNeeded(v8::Extension* extension) 255 void ScriptController::registerExtensionIfNeeded(v8::Extension* extension)
335 { 256 {
336 const V8Extensions& extensions = registeredExtensions(); 257 const V8Extensions& extensions = registeredExtensions();
337 for (size_t i = 0; i < extensions.size(); ++i) { 258 for (size_t i = 0; i < extensions.size(); ++i) {
338 if (extensions[i] == extension) 259 if (extensions[i] == extension)
339 return; 260 return;
340 } 261 }
341 v8::RegisterExtension(extension); 262 v8::RegisterExtension(extension);
342 registeredExtensions().append(extension); 263 registeredExtensions().append(extension);
343 } 264 }
344 265
345 static NPObject* createNoScriptObject()
346 {
347 notImplemented();
348 return 0;
349 }
350
351 static NPObject* createScriptObject(LocalFrame* frame, v8::Isolate* isolate)
352 {
353 ScriptState* scriptState = ScriptState::forMainWorld(frame);
354 if (!scriptState)
355 return createNoScriptObject();
356
357 ScriptState::Scope scope(scriptState);
358 LocalDOMWindow* window = frame->localDOMWindow();
359 v8::Local<v8::Value> global = toV8(window, scriptState->context()->Global(), scriptState->isolate());
360 if (global.IsEmpty())
361 return createNoScriptObject();
362 ASSERT(global->IsObject());
363 return npCreateV8ScriptObject(isolate, 0, v8::Local<v8::Object>::Cast(global ), window);
364 }
365
366 NPObject* ScriptController::windowScriptNPObject()
367 {
368 if (m_windowScriptNPObject)
369 return m_windowScriptNPObject;
370
371 if (canExecuteScripts(NotAboutToExecuteScript)) {
372 // JavaScript is enabled, so there is a JavaScript window object.
373 // Return an NPObject bound to the window object.
374 m_windowScriptNPObject = createScriptObject(frame(), isolate());
375 _NPN_RegisterObject(m_windowScriptNPObject, 0);
376 } else {
377 // JavaScript is not enabled, so we cannot bind the NPObject to the
378 // JavaScript window object. Instead, we create an NPObject of a
379 // different class, one which is not bound to a JavaScript object.
380 m_windowScriptNPObject = createNoScriptObject();
381 }
382 return m_windowScriptNPObject;
383 }
384
385 NPObject* ScriptController::createScriptObjectForPluginElement(HTMLPlugInElement * plugin)
386 {
387 // Can't create NPObjects when JavaScript is disabled.
388 if (!canExecuteScripts(NotAboutToExecuteScript))
389 return createNoScriptObject();
390
391 ScriptState* scriptState = ScriptState::forMainWorld(frame());
392 if (!scriptState)
393 return createNoScriptObject();
394
395 ScriptState::Scope scope(scriptState);
396 LocalDOMWindow* window = frame()->localDOMWindow();
397 v8::Local<v8::Value> v8plugin = toV8(plugin, scriptState->context()->Global( ), scriptState->isolate());
398 if (v8plugin.IsEmpty() || !v8plugin->IsObject())
399 return createNoScriptObject();
400
401 return npCreateV8ScriptObject(scriptState->isolate(), 0, v8::Local<v8::Objec t>::Cast(v8plugin), window);
402 }
403
404 void ScriptController::clearWindowProxy() 266 void ScriptController::clearWindowProxy()
405 { 267 {
406 // V8 binding expects ScriptController::clearWindowProxy only be called 268 // V8 binding expects ScriptController::clearWindowProxy only be called
407 // when a frame is loading a new page. This creates a new context for the ne w page. 269 // when a frame is loading a new page. This creates a new context for the ne w page.
408 270
409 double start = currentTime(); 271 double start = currentTime();
410 // The V8 context must be available for |clearScriptObjects()|.
411 // The below call must be before |clearForNavigation()| which disposes the V 8 context.
412 clearScriptObjects();
413 272
414 m_windowProxyManager->clearForNavigation(); 273 m_windowProxyManager->clearForNavigation();
415 double end = currentTime(); 274 double end = currentTime();
416 DEFINE_STATIC_LOCAL(CustomCountHistogram, clearWindowProxyHistogram, ("WebCo re.ScriptController.clearWindowProxy", 0, 10000, 50)); 275 DEFINE_STATIC_LOCAL(CustomCountHistogram, clearWindowProxyHistogram, ("WebCo re.ScriptController.clearWindowProxy", 0, 10000, 50));
417 clearWindowProxyHistogram.count((end - start) * 1000); 276 clearWindowProxyHistogram.count((end - start) * 1000);
418 } 277 }
419 278
420 void ScriptController::setCaptureCallStackForUncaughtExceptions(v8::Isolate* iso late, bool value) 279 void ScriptController::setCaptureCallStackForUncaughtExceptions(v8::Isolate* iso late, bool value)
421 { 280 {
422 isolate->SetCaptureStackTraceForUncaughtExceptions(value, V8StackTrace::maxC allStackSizeToCapture, stackTraceOptions); 281 isolate->SetCaptureStackTraceForUncaughtExceptions(value, V8StackTrace::maxC allStackSizeToCapture, stackTraceOptions);
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
601 for (size_t i = 0; i < resultArray->Length(); ++i) { 460 for (size_t i = 0; i < resultArray->Length(); ++i) {
602 v8::Local<v8::Value> value; 461 v8::Local<v8::Value> value;
603 if (!resultArray->Get(scriptState->context(), i).ToLocal(&value)) 462 if (!resultArray->Get(scriptState->context(), i).ToLocal(&value))
604 return; 463 return;
605 results->append(value); 464 results->append(value);
606 } 465 }
607 } 466 }
608 } 467 }
609 468
610 } // namespace blink 469 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698