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

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 25 matching lines...) Expand all
86 bool ScriptController::canAccessFromCurrentOrigin(v8::Isolate* isolate, Frame* f rame) 82 bool ScriptController::canAccessFromCurrentOrigin(v8::Isolate* isolate, Frame* f rame)
87 { 83 {
88 if (!frame) 84 if (!frame)
89 return false; 85 return false;
90 return !isolate->InContext() || BindingSecurity::shouldAllowAccessToFrame(is olate, callingDOMWindow(isolate), frame, ReportSecurityError); 86 return !isolate->InContext() || BindingSecurity::shouldAllowAccessToFrame(is olate, callingDOMWindow(isolate), frame, ReportSecurityError);
91 } 87 }
92 88
93 ScriptController::ScriptController(LocalFrame* frame) 89 ScriptController::ScriptController(LocalFrame* frame)
94 : m_windowProxyManager(WindowProxyManager::create(*frame)) 90 : m_windowProxyManager(WindowProxyManager::create(*frame))
95 , m_sourceURL(0) 91 , m_sourceURL(0)
96 , m_windowScriptNPObject(0)
97 { 92 {
98 } 93 }
99 94
100 ScriptController::~ScriptController() 95 ScriptController::~ScriptController()
101 { 96 {
102 } 97 }
103 98
104 DEFINE_TRACE(ScriptController) 99 DEFINE_TRACE(ScriptController)
105 { 100 {
106 #if ENABLE(OILPAN) 101 #if ENABLE(OILPAN)
107 visitor->trace(m_windowProxyManager); 102 visitor->trace(m_windowProxyManager);
108 visitor->trace(m_pluginObjects);
109 #endif 103 #endif
110 } 104 }
111 105
112 void ScriptController::clearScriptObjects()
113 {
114 PluginObjectMap::iterator it = m_pluginObjects.begin();
115 for (; it != m_pluginObjects.end(); ++it) {
116 _NPN_UnregisterObject(it->value);
117 _NPN_ReleaseObject(it->value);
118 }
119 m_pluginObjects.clear();
120
121 if (m_windowScriptNPObject) {
122 // Dispose of the underlying V8 object before releasing our reference
123 // to it, so that if a plugin fails to release it properly we will
124 // only leak the NPObject wrapper, not the object, its document, or
125 // anything else they reference.
126 disposeUnderlyingV8Object(isolate(), m_windowScriptNPObject);
127 _NPN_ReleaseObject(m_windowScriptNPObject);
128 m_windowScriptNPObject = 0;
129 }
130 }
131
132 void ScriptController::clearForClose() 106 void ScriptController::clearForClose()
133 { 107 {
134 double start = currentTime(); 108 double start = currentTime();
135 m_windowProxyManager->clearForClose(); 109 m_windowProxyManager->clearForClose();
136 double end = currentTime(); 110 double end = currentTime();
137 DEFINE_STATIC_LOCAL(CustomCountHistogram, clearForCloseHistogram, ("WebCore. ScriptController.clearForClose", 0, 10000, 50)); 111 DEFINE_STATIC_LOCAL(CustomCountHistogram, clearForCloseHistogram, ("WebCore. ScriptController.clearForClose", 0, 10000, 50));
138 clearForCloseHistogram.count((end - start) * 1000); 112 clearForCloseHistogram.count((end - start) * 1000);
139 } 113 }
140 114
141 void ScriptController::updateSecurityOrigin(SecurityOrigin* origin) 115 void ScriptController::updateSecurityOrigin(SecurityOrigin* origin)
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 } 203 }
230 204
231 TextPosition ScriptController::eventHandlerPosition() const 205 TextPosition ScriptController::eventHandlerPosition() const
232 { 206 {
233 ScriptableDocumentParser* parser = frame()->document()->scriptableDocumentPa rser(); 207 ScriptableDocumentParser* parser = frame()->document()->scriptableDocumentPa rser();
234 if (parser) 208 if (parser)
235 return parser->textPosition(); 209 return parser->textPosition();
236 return TextPosition::minimumPosition(); 210 return TextPosition::minimumPosition();
237 } 211 }
238 212
239 // Create a V8 object with an interceptor of NPObjectPropertyGetter.
240 bool ScriptController::bindToWindowObject(LocalFrame* frame, const String& key, NPObject* object)
241 {
242 ScriptState* scriptState = ScriptState::forMainWorld(frame);
243 if (!scriptState)
244 return false;
245
246 ScriptState::Scope scope(scriptState);
247 v8::Local<v8::Object> value = createV8ObjectForNPObject(isolate(), object, 0 );
248
249 // Attach to the global object.
250 return v8CallBoolean(scriptState->context()->Global()->Set(scriptState->cont ext(), v8String(isolate(), key), value));
251 }
252
253 void ScriptController::enableEval() 213 void ScriptController::enableEval()
254 { 214 {
255 v8::HandleScope handleScope(isolate()); 215 v8::HandleScope handleScope(isolate());
256 v8::Local<v8::Context> v8Context = m_windowProxyManager->mainWorldProxy()->c ontextIfInitialized(); 216 v8::Local<v8::Context> v8Context = m_windowProxyManager->mainWorldProxy()->c ontextIfInitialized();
257 if (v8Context.IsEmpty()) 217 if (v8Context.IsEmpty())
258 return; 218 return;
259 v8Context->AllowCodeGenerationFromStrings(true); 219 v8Context->AllowCodeGenerationFromStrings(true);
260 } 220 }
261 221
262 void ScriptController::disableEval(const String& errorMessage) 222 void ScriptController::disableEval(const String& errorMessage)
(...skipping 12 matching lines...) Expand all
275 235
276 if (!widget->isPluginView()) 236 if (!widget->isPluginView())
277 return nullptr; 237 return nullptr;
278 238
279 v8::HandleScope handleScope(isolate()); 239 v8::HandleScope handleScope(isolate());
280 v8::Local<v8::Object> scriptableObject = toPluginView(widget)->scriptableObj ect(isolate()); 240 v8::Local<v8::Object> scriptableObject = toPluginView(widget)->scriptableObj ect(isolate());
281 241
282 if (scriptableObject.IsEmpty()) 242 if (scriptableObject.IsEmpty())
283 return nullptr; 243 return nullptr;
284 244
285 // LocalFrame Memory Management for NPObjects
286 // -------------------------------------
287 // NPObjects are treated differently than other objects wrapped by JS.
288 // NPObjects can be created either by the browser (e.g. the main
289 // window object) or by the plugin (the main plugin object
290 // for a HTMLEmbedElement). Further, unlike most DOM Objects, the frame
291 // is especially careful to ensure NPObjects terminate at frame teardown bec ause
292 // if a plugin leaks a reference, it could leak its objects (or the browser' s objects).
293 //
294 // The LocalFrame maintains a list of plugin objects (m_pluginObjects)
295 // which it can use to quickly find the wrapped embed object.
296 //
297 // Inside the NPRuntime, we've added a few methods for registering
298 // wrapped NPObjects. The purpose of the registration is because
299 // javascript garbage collection is non-deterministic, yet we need to
300 // be able to tear down the plugin objects immediately. When an object
301 // is registered, javascript can use it. When the object is destroyed,
302 // or when the object's "owning" object is destroyed, the object will
303 // be un-registered, and the javascript engine must not use it.
304 //
305 // Inside the javascript engine, the engine can keep a reference to the
306 // NPObject as part of its wrapper. However, before accessing the object
307 // it must consult the _NPN_Registry.
308
309 if (isWrappedNPObject(scriptableObject)) {
310 // Track the plugin object. We've been given a reference to the object.
311 m_pluginObjects.set(widget, v8ObjectToNPObject(scriptableObject));
312 }
313
314 return SharedPersistent<v8::Object>::create(scriptableObject, isolate()); 245 return SharedPersistent<v8::Object>::create(scriptableObject, isolate());
315 } 246 }
316 247
317 void ScriptController::cleanupScriptObjectsForPlugin(Widget* nativeHandle)
318 {
319 PluginObjectMap::iterator it = m_pluginObjects.find(nativeHandle);
320 if (it == m_pluginObjects.end())
321 return;
322 _NPN_UnregisterObject(it->value);
323 _NPN_ReleaseObject(it->value);
324 m_pluginObjects.remove(it);
325 }
326
327 V8Extensions& ScriptController::registeredExtensions() 248 V8Extensions& ScriptController::registeredExtensions()
328 { 249 {
329 DEFINE_STATIC_LOCAL(V8Extensions, extensions, ()); 250 DEFINE_STATIC_LOCAL(V8Extensions, extensions, ());
330 return extensions; 251 return extensions;
331 } 252 }
332 253
333 void ScriptController::registerExtensionIfNeeded(v8::Extension* extension) 254 void ScriptController::registerExtensionIfNeeded(v8::Extension* extension)
334 { 255 {
335 const V8Extensions& extensions = registeredExtensions(); 256 const V8Extensions& extensions = registeredExtensions();
336 for (size_t i = 0; i < extensions.size(); ++i) { 257 for (size_t i = 0; i < extensions.size(); ++i) {
337 if (extensions[i] == extension) 258 if (extensions[i] == extension)
338 return; 259 return;
339 } 260 }
340 v8::RegisterExtension(extension); 261 v8::RegisterExtension(extension);
341 registeredExtensions().append(extension); 262 registeredExtensions().append(extension);
342 } 263 }
343 264
344 static NPObject* createNoScriptObject()
345 {
346 NOTIMPLEMENTED();
347 return nullptr;
348 }
349
350 static NPObject* createScriptObject(LocalFrame* frame, v8::Isolate* isolate)
351 {
352 ScriptState* scriptState = ScriptState::forMainWorld(frame);
353 if (!scriptState)
354 return createNoScriptObject();
355
356 ScriptState::Scope scope(scriptState);
357 LocalDOMWindow* window = frame->localDOMWindow();
358 v8::Local<v8::Value> global = toV8(window, scriptState->context()->Global(), scriptState->isolate());
359 if (global.IsEmpty())
360 return createNoScriptObject();
361 ASSERT(global->IsObject());
362 return npCreateV8ScriptObject(isolate, 0, v8::Local<v8::Object>::Cast(global ), window);
363 }
364
365 NPObject* ScriptController::windowScriptNPObject()
366 {
367 if (m_windowScriptNPObject)
368 return m_windowScriptNPObject;
369
370 if (canExecuteScripts(NotAboutToExecuteScript)) {
371 // JavaScript is enabled, so there is a JavaScript window object.
372 // Return an NPObject bound to the window object.
373 m_windowScriptNPObject = createScriptObject(frame(), isolate());
374 _NPN_RegisterObject(m_windowScriptNPObject, 0);
375 } else {
376 // JavaScript is not enabled, so we cannot bind the NPObject to the
377 // JavaScript window object. Instead, we create an NPObject of a
378 // different class, one which is not bound to a JavaScript object.
379 m_windowScriptNPObject = createNoScriptObject();
380 }
381 return m_windowScriptNPObject;
382 }
383
384 NPObject* ScriptController::createScriptObjectForPluginElement(HTMLPlugInElement * plugin)
385 {
386 // Can't create NPObjects when JavaScript is disabled.
387 if (!canExecuteScripts(NotAboutToExecuteScript))
388 return createNoScriptObject();
389
390 ScriptState* scriptState = ScriptState::forMainWorld(frame());
391 if (!scriptState)
392 return createNoScriptObject();
393
394 ScriptState::Scope scope(scriptState);
395 LocalDOMWindow* window = frame()->localDOMWindow();
396 v8::Local<v8::Value> v8plugin = toV8(plugin, scriptState->context()->Global( ), scriptState->isolate());
397 if (v8plugin.IsEmpty() || !v8plugin->IsObject())
398 return createNoScriptObject();
399
400 return npCreateV8ScriptObject(scriptState->isolate(), 0, v8::Local<v8::Objec t>::Cast(v8plugin), window);
401 }
402
403 void ScriptController::clearWindowProxy() 265 void ScriptController::clearWindowProxy()
404 { 266 {
405 // V8 binding expects ScriptController::clearWindowProxy only be called 267 // V8 binding expects ScriptController::clearWindowProxy only be called
406 // when a frame is loading a new page. This creates a new context for the ne w page. 268 // when a frame is loading a new page. This creates a new context for the ne w page.
407 269
408 double start = currentTime(); 270 double start = currentTime();
409 // The V8 context must be available for |clearScriptObjects()|.
410 // The below call must be before |clearForNavigation()| which disposes the V 8 context.
411 clearScriptObjects();
412 271
413 m_windowProxyManager->clearForNavigation(); 272 m_windowProxyManager->clearForNavigation();
414 double end = currentTime(); 273 double end = currentTime();
415 DEFINE_STATIC_LOCAL(CustomCountHistogram, clearWindowProxyHistogram, ("WebCo re.ScriptController.clearWindowProxy", 0, 10000, 50)); 274 DEFINE_STATIC_LOCAL(CustomCountHistogram, clearWindowProxyHistogram, ("WebCo re.ScriptController.clearWindowProxy", 0, 10000, 50));
416 clearWindowProxyHistogram.count((end - start) * 1000); 275 clearWindowProxyHistogram.count((end - start) * 1000);
417 } 276 }
418 277
419 void ScriptController::setCaptureCallStackForUncaughtExceptions(v8::Isolate* iso late, bool value) 278 void ScriptController::setCaptureCallStackForUncaughtExceptions(v8::Isolate* iso late, bool value)
420 { 279 {
421 isolate->SetCaptureStackTraceForUncaughtExceptions(value, V8StackTrace::maxC allStackSizeToCapture, stackTraceOptions); 280 isolate->SetCaptureStackTraceForUncaughtExceptions(value, V8StackTrace::maxC allStackSizeToCapture, stackTraceOptions);
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
600 for (size_t i = 0; i < resultArray->Length(); ++i) { 459 for (size_t i = 0; i < resultArray->Length(); ++i) {
601 v8::Local<v8::Value> value; 460 v8::Local<v8::Value> value;
602 if (!resultArray->Get(scriptState->context(), i).ToLocal(&value)) 461 if (!resultArray->Get(scriptState->context(), i).ToLocal(&value))
603 return; 462 return;
604 results->append(value); 463 results->append(value);
605 } 464 }
606 } 465 }
607 } 466 }
608 467
609 } // namespace blink 468 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698