diff options
author | pmarch@chromium.org <pmarch@chromium.org@bbb929c8-8fbe-4397-9dbb-9b2b20218538> | 2014-06-23 14:40:51 +0000 |
---|---|---|
committer | pmarch@chromium.org <pmarch@chromium.org@bbb929c8-8fbe-4397-9dbb-9b2b20218538> | 2014-06-23 14:40:51 +0000 |
commit | 7f2876b460e2ce0e6936fe5b766b0efe682dda59 (patch) | |
tree | 4ee6a82dfda9489b99934de5ee15bc2db4dc7d1a | |
parent | 38baf77572d74b05ec12707424e2b373feee3d23 (diff) | |
download | chromium-7f2876b460e2ce0e6936fe5b766b0efe682dda59.tar.gz chromium-7f2876b460e2ce0e6936fe5b766b0efe682dda59.tar.bz2 chromium-7f2876b460e2ce0e6936fe5b766b0efe682dda59.zip |
Enable Activity Log to log creation of event handlers by extension content
scripts, and disable logging of event handler assignments.
Review URL: https://codereview.chromium.org/333713006
git-svn-id: svn://svn.chromium.org/blink/trunk@176757 bbb929c8-8fbe-4397-9dbb-9b2b20218538
-rw-r--r-- | Source/bindings/v8/V8DOMActivityLogger.cpp | 30 | ||||
-rw-r--r-- | Source/bindings/v8/V8DOMActivityLogger.h | 7 | ||||
-rw-r--r-- | Source/core/dom/Document.idl | 2 | ||||
-rw-r--r-- | Source/core/dom/Element.idl | 2 | ||||
-rw-r--r-- | Source/core/dom/GlobalEventHandlers.idl | 44 | ||||
-rw-r--r-- | Source/core/events/EventTarget.cpp | 10 | ||||
-rw-r--r-- | Source/core/frame/Window.idl | 2 | ||||
-rw-r--r-- | Source/web/WebDOMActivityLogger.cpp | 8 | ||||
-rw-r--r-- | Source/web/tests/ActivityLoggerTest.cpp | 129 | ||||
-rw-r--r-- | Source/web/web.gypi | 1 | ||||
-rw-r--r-- | public/web/WebDOMActivityLogger.h | 1 |
11 files changed, 211 insertions, 25 deletions
diff --git a/Source/bindings/v8/V8DOMActivityLogger.cpp b/Source/bindings/v8/V8DOMActivityLogger.cpp index 20ead4f4ce06..93ca79b7f199 100644 --- a/Source/bindings/v8/V8DOMActivityLogger.cpp +++ b/Source/bindings/v8/V8DOMActivityLogger.cpp @@ -69,4 +69,34 @@ V8DOMActivityLogger* V8DOMActivityLogger::activityLogger(int worldId, const KURL return activityLogger(worldId, url.host()); } +V8DOMActivityLogger* V8DOMActivityLogger::currentActivityLogger() +{ + v8::Isolate* isolate = v8::Isolate::GetCurrent(); + if (!isolate->InContext()) + return 0; + + V8PerContextData* contextData = ScriptState::current(isolate)->perContextData(); + if (!contextData) + return 0; + + return contextData->activityLogger(); +} + +V8DOMActivityLogger* V8DOMActivityLogger::currentActivityLoggerIfIsolatedWorld() +{ + v8::Isolate* isolate = v8::Isolate::GetCurrent(); + if (!isolate->InContext()) + return 0; + + ScriptState* scriptState = ScriptState::current(isolate); + if (!scriptState->world().isIsolatedWorld()) + return 0; + + V8PerContextData* contextData = scriptState->perContextData(); + if (!contextData) + return 0; + + return contextData->activityLogger(); +} + } // namespace WebCore diff --git a/Source/bindings/v8/V8DOMActivityLogger.h b/Source/bindings/v8/V8DOMActivityLogger.h index 0f6b05c8e3c4..0e62eb610549 100644 --- a/Source/bindings/v8/V8DOMActivityLogger.h +++ b/Source/bindings/v8/V8DOMActivityLogger.h @@ -47,6 +47,7 @@ public: virtual void logSetter(const String& apiName, const v8::Handle<v8::Value>& newValue) { } virtual void logSetter(const String& apiName, const v8::Handle<v8::Value>& newValue, const v8::Handle<v8::Value>& oldValue) { } virtual void logMethod(const String& apiName, int argc, const v8::Handle<v8::Value>* argv) { } + virtual void logEvent(const String& eventName, int argc, const String* argv) { } // Associates a logger with the world identified by worldId (worlId may be 0 // identifying the main world) and extension ID. Extension ID is used to @@ -63,6 +64,12 @@ public: static V8DOMActivityLogger* activityLogger(int worldId, const String& extensionId); static V8DOMActivityLogger* activityLogger(int worldId, const KURL&); + // Returns activity logger for current V8 context or 0. + static V8DOMActivityLogger* currentActivityLogger(); + // Returns activity logger for current V8 context if the context belongs to + // an isolated world or 0. + static V8DOMActivityLogger* currentActivityLoggerIfIsolatedWorld(); + }; } // namespace WebCore diff --git a/Source/core/dom/Document.idl b/Source/core/dom/Document.idl index c0b3801f4d3e..512d8c038d47 100644 --- a/Source/core/dom/Document.idl +++ b/Source/core/dom/Document.idl @@ -189,7 +189,7 @@ typedef (CanvasRenderingContext2D or WebGLRenderingContext) RenderingContext; attribute EventHandler onwebkitfullscreenerror; attribute EventHandler onwebkitpointerlockchange; attribute EventHandler onwebkitpointerlockerror; - [LogActivity=SetterOnly] attribute EventHandler onwheel; + attribute EventHandler onwheel; [RuntimeEnabled=Touch] Touch createTouch([Default=Undefined] optional Window window, [Default=Undefined] optional EventTarget target, diff --git a/Source/core/dom/Element.idl b/Source/core/dom/Element.idl index b4f745d34bf3..666b01cdbe68 100644 --- a/Source/core/dom/Element.idl +++ b/Source/core/dom/Element.idl @@ -141,7 +141,7 @@ [RuntimeEnabled=Touch] attribute EventHandler ontouchstart; attribute EventHandler onwebkitfullscreenchange; attribute EventHandler onwebkitfullscreenerror; - [LogActivity=SetterOnly] attribute EventHandler onwheel; + attribute EventHandler onwheel; }; Element implements ParentNode; diff --git a/Source/core/dom/GlobalEventHandlers.idl b/Source/core/dom/GlobalEventHandlers.idl index c835461307dd..6a7f1c1860e7 100644 --- a/Source/core/dom/GlobalEventHandlers.idl +++ b/Source/core/dom/GlobalEventHandlers.idl @@ -41,41 +41,41 @@ attribute EventHandler oncanplay; attribute EventHandler oncanplaythrough; attribute EventHandler onchange; - [LogActivity=SetterOnly] attribute EventHandler onclick; + attribute EventHandler onclick; attribute EventHandler onclose; attribute EventHandler oncontextmenu; attribute EventHandler oncuechange; - [LogActivity=SetterOnly] attribute EventHandler ondblclick; - [LogActivity=SetterOnly] attribute EventHandler ondrag; - [LogActivity=SetterOnly] attribute EventHandler ondragend; - [LogActivity=SetterOnly] attribute EventHandler ondragenter; - //[LogActivity=SetterOnly] attribute EventHandler ondragexit; - [LogActivity=SetterOnly] attribute EventHandler ondragleave; - [LogActivity=SetterOnly] attribute EventHandler ondragover; - [LogActivity=SetterOnly] attribute EventHandler ondragstart; - [LogActivity=SetterOnly] attribute EventHandler ondrop; + attribute EventHandler ondblclick; + attribute EventHandler ondrag; + attribute EventHandler ondragend; + attribute EventHandler ondragenter; + //attribute EventHandler ondragexit; + attribute EventHandler ondragleave; + attribute EventHandler ondragover; + attribute EventHandler ondragstart; + attribute EventHandler ondrop; attribute EventHandler ondurationchange; attribute EventHandler onemptied; attribute EventHandler onended; attribute EventHandler onerror; attribute EventHandler onfocus; - [LogActivity=SetterOnly] attribute EventHandler oninput; + attribute EventHandler oninput; attribute EventHandler oninvalid; - [LogActivity=SetterOnly] attribute EventHandler onkeydown; - [LogActivity=SetterOnly] attribute EventHandler onkeypress; - [LogActivity=SetterOnly] attribute EventHandler onkeyup; + attribute EventHandler onkeydown; + attribute EventHandler onkeypress; + attribute EventHandler onkeyup; attribute EventHandler onload; attribute EventHandler onloadeddata; attribute EventHandler onloadedmetadata; attribute EventHandler onloadstart; - [LogActivity=SetterOnly] attribute EventHandler onmousedown; - [LogActivity=SetterOnly] attribute EventHandler onmouseenter; - [LogActivity=SetterOnly] attribute EventHandler onmouseleave; - [LogActivity=SetterOnly] attribute EventHandler onmousemove; - [LogActivity=SetterOnly] attribute EventHandler onmouseout; - [LogActivity=SetterOnly] attribute EventHandler onmouseover; - [LogActivity=SetterOnly] attribute EventHandler onmouseup; - [LogActivity=SetterOnly] attribute EventHandler onmousewheel; + attribute EventHandler onmousedown; + attribute EventHandler onmouseenter; + attribute EventHandler onmouseleave; + attribute EventHandler onmousemove; + attribute EventHandler onmouseout; + attribute EventHandler onmouseover; + attribute EventHandler onmouseup; + attribute EventHandler onmousewheel; attribute EventHandler onpause; attribute EventHandler onplay; attribute EventHandler onplaying; diff --git a/Source/core/events/EventTarget.cpp b/Source/core/events/EventTarget.cpp index 6b9af4b44883..ad6922a650a5 100644 --- a/Source/core/events/EventTarget.cpp +++ b/Source/core/events/EventTarget.cpp @@ -33,6 +33,7 @@ #include "core/events/EventTarget.h" #include "bindings/v8/ExceptionState.h" +#include "bindings/v8/V8DOMActivityLogger.h" #include "core/dom/ExceptionCode.h" #include "core/dom/NoEventDispatchAssertion.h" #include "core/editing/Editor.h" @@ -88,6 +89,15 @@ bool EventTarget::addEventListener(const AtomicString& eventType, PassRefPtr<Eve // generated bindings), but breaks legacy content. http://crbug.com/249598 if (!listener) return false; + + V8DOMActivityLogger* activityLogger = V8DOMActivityLogger::currentActivityLoggerIfIsolatedWorld(); + if (activityLogger) { + Vector<String> argv; + argv.append(toNode() ? toNode()->nodeName() : interfaceName()); + argv.append(eventType); + activityLogger->logEvent("blinkAddEventListener", 2, argv.data()); + } + return ensureEventTargetData().eventListenerMap.add(eventType, listener, useCapture); } diff --git a/Source/core/frame/Window.idl b/Source/core/frame/Window.idl index 3e75b0b9529c..dc32ee67505c 100644 --- a/Source/core/frame/Window.idl +++ b/Source/core/frame/Window.idl @@ -193,7 +193,7 @@ attribute EventHandler onwebkitanimationiteration; attribute EventHandler onwebkitanimationstart; attribute EventHandler onwebkittransitionend; - [LogActivity=SetterOnly] attribute EventHandler onwheel; + attribute EventHandler onwheel; [MeasureAs=WindowCaptureEvents] void captureEvents(); [MeasureAs=WindowReleaseEvents] void releaseEvents(); diff --git a/Source/web/WebDOMActivityLogger.cpp b/Source/web/WebDOMActivityLogger.cpp index 88f8baee60b1..9f0587aff225 100644 --- a/Source/web/WebDOMActivityLogger.cpp +++ b/Source/web/WebDOMActivityLogger.cpp @@ -69,6 +69,14 @@ public: m_domActivityLogger->logMethod(WebString(apiName), argc, argv, getURL(), getTitle()); } + virtual void logEvent(const String& eventName, int argc, const String* argv) OVERRIDE + { + Vector<WebString> webStringArgv; + for (int i = 0; i < argc; i++) + webStringArgv.append(argv[i]); + m_domActivityLogger->logEvent(WebString(eventName), argc, webStringArgv.data(), getURL(), getTitle()); + } + private: WebURL getURL() { diff --git a/Source/web/tests/ActivityLoggerTest.cpp b/Source/web/tests/ActivityLoggerTest.cpp new file mode 100644 index 000000000000..22fd2b92db20 --- /dev/null +++ b/Source/web/tests/ActivityLoggerTest.cpp @@ -0,0 +1,129 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "config.h" + +#include "FrameTestHelpers.h" +#include "bindings/v8/ScriptController.h" +#include "bindings/v8/V8DOMActivityLogger.h" +#include "web/WebLocalFrameImpl.h" +#include "wtf/Forward.h" +#include "wtf/text/Base64.h" +#include <gtest/gtest.h> +#include <v8.h> + +using WebCore::ScriptController; +using WebCore::ScriptSourceCode; +using WebCore::V8DOMActivityLogger; +using WebCore::toCoreStringWithUndefinedOrNullCheck; +using blink::FrameTestHelpers::WebViewHelper; +using blink::FrameTestHelpers::runPendingTasks; + +namespace { + +class TestActivityLogger : public V8DOMActivityLogger { +public: + virtual ~TestActivityLogger() { } + + void logGetter(const String& apiName) OVERRIDE + { + m_loggedActivities.append(apiName); + } + + void logSetter(const String& apiName, const v8::Handle<v8::Value>& newValue) OVERRIDE + { + m_loggedActivities.append(apiName + " | " + toCoreStringWithUndefinedOrNullCheck(newValue)); + } + + void logSetter(const String& apiName, const v8::Handle<v8::Value>& newValue, const v8::Handle<v8::Value>& oldValue) OVERRIDE + { + m_loggedActivities.append(apiName + " | " + toCoreStringWithUndefinedOrNullCheck(oldValue) + " | " + toCoreStringWithUndefinedOrNullCheck(newValue)); + } + + void logMethod(const String& apiName, int argc, const v8::Handle<v8::Value>* argv) OVERRIDE + { + String activityString = apiName; + for (int i = 0; i < argc; i++) + activityString = activityString + " | " + toCoreStringWithUndefinedOrNullCheck(argv[i]); + m_loggedActivities.append(activityString); + } + + void logEvent(const String& eventName, int argc, const String* argv) OVERRIDE + { + String activityString = eventName; + for (int i = 0; i < argc; i++) { + activityString = activityString + " | " + argv[i]; + } + m_loggedActivities.append(activityString); + } + + void clear() { m_loggedActivities.clear(); } + bool verifyActivities(const Vector<String>& activities) const { return m_loggedActivities == activities; } + +private: + Vector<String> m_loggedActivities; +}; + +class ActivityLoggerTest : public testing::Test { +protected: + ActivityLoggerTest() + { + m_activityLogger = new TestActivityLogger(); + V8DOMActivityLogger::setActivityLogger(isolatedWorldId, String(), adoptPtr(m_activityLogger)); + m_webViewHelper.initialize(true); + m_scriptController = &m_webViewHelper.webViewImpl()->mainFrameImpl()->frame()->script(); + } + + void executeScriptInMainWorld(const String& script) const + { + m_scriptController->executeScriptInMainWorld(script); + } + + void executeScriptInIsolatedWorld(const String& script) const + { + Vector<ScriptSourceCode> sources; + sources.append(ScriptSourceCode(script)); + Vector<v8::Local<v8::Value> > results; + m_scriptController->executeScriptInIsolatedWorld(isolatedWorldId, sources, extensionGroup, 0); + } + + bool verifyActivities(const String& activities) + { + Vector<String> activityVector; + activities.split(";", activityVector); + return m_activityLogger->verifyActivities(activityVector); + } + +private: + static const int isolatedWorldId = 1; + static const int extensionGroup = 0; + + WebViewHelper m_webViewHelper; + ScriptController* m_scriptController; + // TestActivityLogger is owned by a static table within V8DOMActivityLogger + // and should be alive as long as not overwritten. + TestActivityLogger* m_activityLogger; +}; + +TEST_F(ActivityLoggerTest, EventHandler) +{ + v8::HandleScope scope(v8::Isolate::GetCurrent()); + const char* code = + "document.body.innerHTML = '<a onclick=\\\'do()\\\'>test</a>';" + "document.body.onchange = function(){};" + "document.body.setAttribute('onfocus', 'fnc()');" + "document.body.addEventListener('onload', function(){});"; + const char* expectedActivities = + "Element.innerHTML | <a onclick='do()'>test</a>;" + "blinkAddEventListener | A | click;" + "blinkAddEventListener | BODY | change;" + "blinkAddEventListener | LocalDOMWindow | focus;" + "blinkAddEventListener | BODY | onload"; + executeScriptInMainWorld(code); + ASSERT_TRUE(verifyActivities("")); + executeScriptInIsolatedWorld(code); + ASSERT_TRUE(verifyActivities(expectedActivities)); +} + +} // namespace diff --git a/Source/web/web.gypi b/Source/web/web.gypi index bf0bcd890163..2eebe2b13774 100644 --- a/Source/web/web.gypi +++ b/Source/web/web.gypi @@ -264,6 +264,7 @@ 'win/WebFontRendering.cpp', ], 'web_unittest_files': [ + 'tests/ActivityLoggerTest.cpp', 'tests/AssociatedURLLoaderTest.cpp', 'tests/ChromeClientImplTest.cpp', 'tests/CustomEventTest.cpp', diff --git a/public/web/WebDOMActivityLogger.h b/public/web/WebDOMActivityLogger.h index 7cc4d205c5f7..afad4c8e98e5 100644 --- a/public/web/WebDOMActivityLogger.h +++ b/public/web/WebDOMActivityLogger.h @@ -46,6 +46,7 @@ public: virtual void logSetter(const WebString& apiName, const v8::Handle<v8::Value>& newValue, const WebURL& url, const WebString& title) { } virtual void logSetter(const WebString& apiName, const v8::Handle<v8::Value>& newValue, const v8::Handle<v8::Value>& oldValue, const WebURL& url, const WebString& title) { } virtual void logMethod(const WebString& apiName, int argc, const v8::Handle<v8::Value>* argv, const WebURL& url, const WebString& title) { } + virtual void logEvent(const WebString& eventName, int argc, const WebString* argv, const WebURL& url, const WebString& title) { } }; // Checks if a logger already exists for the world identified by worldId and |