Commit 222d7489 authored by aroben@apple.com's avatar aroben@apple.com

Don't let the inspected page overwrite properties of JS objects in the Inspector

        <https://bugs.webkit.org/show_bug.cgi?id=16011>
        <rdar://problem/5604409>

        <https://bugs.webkit.org/show_bug.cgi?id=16837>
        <rdar://problem/5813850>

        Reviewed by Sam Weinig and Geoff Garen.

        Tests (contributed by Adam Barth and Collin Jackson):
        manual-tests/inspector-wrappers

        * GNUmakefile.am:
        * WebCore.pro:
        * WebCore.vcproj/WebCore.vcproj:
        * WebCore.xcodeproj/project.pbxproj:
        * WebCoreSources.bkl:
        Added new files to the projects.

        * bindings/js/JSQuarantinedObjectWrapper.cpp: Added.
        (WebCore::):
        (WebCore::JSQuarantinedObjectWrapper::asWrapper): Converts a JSValue
        into a JSQuarantinedObjectWrapper, if the JSValue is in fact a
        JSQuarantinedObjectWrapper.
        (WebCore::JSQuarantinedObjectWrapper::cachedValueGetter): Callback to
        be used with PropertySlot.
        (WebCore::JSQuarantinedObjectWrapper::JSQuarantinedObjectWrapper):
        Hold onto the object we're wrapping and its global object. Pass the
        wrapped prototype up to the JSObject constructor.
        (WebCore::JSQuarantinedObjectWrapper::~JSQuarantinedObjectWrapper):
        (WebCore::JSQuarantinedObjectWrapper::unwrappedExecStateMatches):
        Returns true if our underlying object originated from the same global
        object as the passed-in ExecState.
        (WebCore::JSQuarantinedObjectWrapper::unwrappedExecState):
        (WebCore::JSQuarantinedObjectWrapper::transferExceptionToExecState):
        Wraps and moves an exception from our underlying ExecState to the
        passed-in one.
        (WebCore::JSQuarantinedObjectWrapper::mark): Marks ourselves and the
        objects we're holding references to.

        (WebCore::JSQuarantinedObjectWrapper::getOwnPropertySlot):
        (WebCore::JSQuarantinedObjectWrapper::put):
        (WebCore::JSQuarantinedObjectWrapper::deleteProperty):
        (WebCore::JSQuarantinedObjectWrapper::implementsConstruct):
        (WebCore::JSQuarantinedObjectWrapper::construct):
        (WebCore::JSQuarantinedObjectWrapper::implementsHasInstance):
        (WebCore::JSQuarantinedObjectWrapper::hasInstance):
        (WebCore::JSQuarantinedObjectWrapper::implementsCall):
        (WebCore::JSQuarantinedObjectWrapper::callAsFunction):
        (WebCore::JSQuarantinedObjectWrapper::getPropertyNames):
        JSObject overrides. These each check the appropriate permission before
        allowing the call to proceed. We wrap all outgoing values using
        m_wrapOutgoingValue, and we prepare all incoming values with the
        virtual prepareIncomingValue function. If an exception is raised when
        calling the underlying object, we transfer the exception in wrapped
        form to the passed-in ExecState.

        * bindings/js/JSQuarantinedObjectWrapper.h: Added.
        (WebCore::JSQuarantinedObjectWrapper::unwrappedObject):
        (WebCore::JSQuarantinedObjectWrapper::className): We return the
        underlying object's class name so that we can successfully masquerade
        as that underlying object when, e.g., Object.prototype.toString is
        called on us.
        (WebCore::JSQuarantinedObjectWrapper::classInfo):

        (WebCore::JSQuarantinedObjectWrapper::allowsGetProperty):
        (WebCore::JSQuarantinedObjectWrapper::allowsSetProperty):
        (WebCore::JSQuarantinedObjectWrapper::allowsDeleteProperty):
        (WebCore::JSQuarantinedObjectWrapper::allowsConstruct):
        (WebCore::JSQuarantinedObjectWrapper::allowsHasInstance):
        (WebCore::JSQuarantinedObjectWrapper::allowsCallAsFunction):
        (WebCore::JSQuarantinedObjectWrapper::allowsGetPropertyNames):
        These virtual methods let subclasses define the allowed operations on
        the wrapped object. By default all operations are disabled.

        * bindings/js/JSInspectedObjectWrapper.cpp: Added. This subclass of
        JSQuarantinedObjectWrapper is used to wrap objects from the inspected
        page being passed to the Inspector.
        (WebCore::wrappers):
        (WebCore::):
        (WebCore::JSInspectedObjectWrapper::wrap): Wraps the passed-in object
        if needed and returns the wrapper. If this object has been wrapped
        previously we'll return the old wrapper rather than make a new one.
        (WebCore::JSInspectedObjectWrapper::JSInspectedObjectWrapper): Add
        ourselves to the wrapper map.
        (WebCore::JSInspectedObjectWrapper::~JSInspectedObjectWrapper): Remove
        ourselves from the wrapper map.
        (WebCore::JSInspectedObjectWrapper::prepareIncomingValue): Ensure that
        any objects passed to the inspected object are either wrappers around
        objects from the inspected page (in which case we unwrap them so that
        the inspected page never sees the wrapper), or wrapped callbacks from
        the Inspector.
        * bindings/js/JSInspectedObjectWrapper.h: Added.
        (WebCore::JSInspectedObjectWrapper::classInfo):
        (WebCore::JSInspectedObjectWrapper::allowsGetProperty):
        (WebCore::JSInspectedObjectWrapper::allowsSetProperty):
        (WebCore::JSInspectedObjectWrapper::allowsDeleteProperty):
        (WebCore::JSInspectedObjectWrapper::allowsConstruct):
        (WebCore::JSInspectedObjectWrapper::allowsHasInstance):
        (WebCore::JSInspectedObjectWrapper::allowsCallAsFunction):
        (WebCore::JSInspectedObjectWrapper::allowsGetPropertyNames):
        These all return true so that the Inspector can use objects from the
        inspected page however it needs.
        (WebCore::JSInspectedObjectWrapper::wrapOutgoingValue): Wrap all
        outgoing values as JSInspectedObjectWrappers.

        * bindings/js/JSInspectorCallbackWrapper.cpp: Added. This subclass of
        JSQuarantinedObjectWrapper is used to wrap callbacks that the
        Inspector passes to the inspected page (e.g., for event listeners or
        client-side storage callbacks).
        (WebCore::wrappers):
        (WebCore::):
        (WebCore::JSInspectorCallbackWrapper::wrap): Wraps the passed-in
        object if needed and returns the wrapper. If this object has been
        wrapped previously we'll return the old wrapper rather than make a new
        one.
        (WebCore::JSInspectorCallbackWrapper::JSInspectorCallbackWrapper): Add
        ourselves to the wrapper map.
        (WebCore::JSInspectorCallbackWrapper::~JSInspectorCallbackWrapper):
        Remove ourselves from the wrapper map.
        (WebCore::JSInspectorCallbackWrapper::prepareIncomingValue): Ensure
        that values passed from the inspected page to an Inspector callback
        are wrapped in JSInspectedObjectWrappers. We also allow the inspected
        page to pass ourselves in (which will happen in the case of a
        client-side storage callback, where the callback itself is passed as
        the `this` object). In this case we unwrap ourselves so that the
        Inspector doesn't have to deal with the wrapper.
        * bindings/js/JSInspectorCallbackWrapper.h: Added.
        (WebCore::JSInspectorCallbackWrapper::classInfo):
        (WebCore::JSInspectorCallbackWrapper::allowsCallAsFunction):
        This is the only allowed operation on a JSInspectorCallbackWrapper.
        (WebCore::JSInspectorCallbackWrapper::wrapOutgoingValue): Wrap all
        outgoing values as JSInspectorCallbackWrappers.

        * page/InspectorController.cpp:
        (WebCore::getResourceDocumentNode): Wrap the Document before passing
        it to the Inspector.
        (WebCore::highlightDOMNode): Unwrap the Node that the Inspector passed
        to us.
        (WebCore::databaseTableNames): Unwrap the Database that the Inspector
        passed to us.
        (WebCore::inspectedWindow): Wrap the Window before passing it to the
        Inspector.
        (WebCore::InspectorController::focusNode): Wrap the Node before
        passing it to the Inspector.
        (WebCore::wrapCallback): Wraps the passed-in callback in a
        JSInspectorCallbackWrapper.
        (WebCore::InspectorController::addDatabaseScriptResource): Wrap the
        Database beore pasing it to the Inspector.
        (WebCore::InspectorController::windowScriptObjectAvailable): Add the
        new wrapCallback function to the InspectorController JS object.

        * page/inspector/ElementsPanel.js:
        (WebInspector.ElementsPanel.reset): Wrap the contentLoaded callback.

        * page/inspector/DatabaseQueryView.js:
        (WebInspector.DatabaseQueryView._enterKeyPressed):
        * page/inspector/DatabaseTableView.js:
        (WebInspector.DatabaseTableView.update):
        Pass null instead of an empty array to executeSql since we're no
        longer allowed to pass any unwrapped objects to the inspected page.
        We now wrap all callbacks being passed to the inspected page using
        InspectorController.wrapCallback.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@31890 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 6a4003b8
2008-04-14 Adam Roben <aroben@apple.com>
Don't let the inspected page overwrite properties of JS objects in the
Inspector
<https://bugs.webkit.org/show_bug.cgi?id=16011>
<rdar://problem/5604409>
<https://bugs.webkit.org/show_bug.cgi?id=16837>
<rdar://problem/5813850>
Reviewed by Sam Weinig and Geoff Garen.
Tests (contributed by Adam Barth and Collin Jackson):
manual-tests/inspector-wrappers
* GNUmakefile.am:
* WebCore.pro:
* WebCore.vcproj/WebCore.vcproj:
* WebCore.xcodeproj/project.pbxproj:
* WebCoreSources.bkl:
Added new files to the projects.
* bindings/js/JSQuarantinedObjectWrapper.cpp: Added.
(WebCore::):
(WebCore::JSQuarantinedObjectWrapper::asWrapper): Converts a JSValue
into a JSQuarantinedObjectWrapper, if the JSValue is in fact a
JSQuarantinedObjectWrapper.
(WebCore::JSQuarantinedObjectWrapper::cachedValueGetter): Callback to
be used with PropertySlot.
(WebCore::JSQuarantinedObjectWrapper::JSQuarantinedObjectWrapper):
Hold onto the object we're wrapping and its global object. Pass the
wrapped prototype up to the JSObject constructor.
(WebCore::JSQuarantinedObjectWrapper::~JSQuarantinedObjectWrapper):
(WebCore::JSQuarantinedObjectWrapper::unwrappedExecStateMatches):
Returns true if our underlying object originated from the same global
object as the passed-in ExecState.
(WebCore::JSQuarantinedObjectWrapper::unwrappedExecState):
(WebCore::JSQuarantinedObjectWrapper::transferExceptionToExecState):
Wraps and moves an exception from our underlying ExecState to the
passed-in one.
(WebCore::JSQuarantinedObjectWrapper::mark): Marks ourselves and the
objects we're holding references to.
(WebCore::JSQuarantinedObjectWrapper::getOwnPropertySlot):
(WebCore::JSQuarantinedObjectWrapper::put):
(WebCore::JSQuarantinedObjectWrapper::deleteProperty):
(WebCore::JSQuarantinedObjectWrapper::implementsConstruct):
(WebCore::JSQuarantinedObjectWrapper::construct):
(WebCore::JSQuarantinedObjectWrapper::implementsHasInstance):
(WebCore::JSQuarantinedObjectWrapper::hasInstance):
(WebCore::JSQuarantinedObjectWrapper::implementsCall):
(WebCore::JSQuarantinedObjectWrapper::callAsFunction):
(WebCore::JSQuarantinedObjectWrapper::getPropertyNames):
JSObject overrides. These each check the appropriate permission before
allowing the call to proceed. We wrap all outgoing values using
m_wrapOutgoingValue, and we prepare all incoming values with the
virtual prepareIncomingValue function. If an exception is raised when
calling the underlying object, we transfer the exception in wrapped
form to the passed-in ExecState.
* bindings/js/JSQuarantinedObjectWrapper.h: Added.
(WebCore::JSQuarantinedObjectWrapper::unwrappedObject):
(WebCore::JSQuarantinedObjectWrapper::className): We return the
underlying object's class name so that we can successfully masquerade
as that underlying object when, e.g., Object.prototype.toString is
called on us.
(WebCore::JSQuarantinedObjectWrapper::classInfo):
(WebCore::JSQuarantinedObjectWrapper::allowsGetProperty):
(WebCore::JSQuarantinedObjectWrapper::allowsSetProperty):
(WebCore::JSQuarantinedObjectWrapper::allowsDeleteProperty):
(WebCore::JSQuarantinedObjectWrapper::allowsConstruct):
(WebCore::JSQuarantinedObjectWrapper::allowsHasInstance):
(WebCore::JSQuarantinedObjectWrapper::allowsCallAsFunction):
(WebCore::JSQuarantinedObjectWrapper::allowsGetPropertyNames):
These virtual methods let subclasses define the allowed operations on
the wrapped object. By default all operations are disabled.
* bindings/js/JSInspectedObjectWrapper.cpp: Added. This subclass of
JSQuarantinedObjectWrapper is used to wrap objects from the inspected
page being passed to the Inspector.
(WebCore::wrappers):
(WebCore::):
(WebCore::JSInspectedObjectWrapper::wrap): Wraps the passed-in object
if needed and returns the wrapper. If this object has been wrapped
previously we'll return the old wrapper rather than make a new one.
(WebCore::JSInspectedObjectWrapper::JSInspectedObjectWrapper): Add
ourselves to the wrapper map.
(WebCore::JSInspectedObjectWrapper::~JSInspectedObjectWrapper): Remove
ourselves from the wrapper map.
(WebCore::JSInspectedObjectWrapper::prepareIncomingValue): Ensure that
any objects passed to the inspected object are either wrappers around
objects from the inspected page (in which case we unwrap them so that
the inspected page never sees the wrapper), or wrapped callbacks from
the Inspector.
* bindings/js/JSInspectedObjectWrapper.h: Added.
(WebCore::JSInspectedObjectWrapper::classInfo):
(WebCore::JSInspectedObjectWrapper::allowsGetProperty):
(WebCore::JSInspectedObjectWrapper::allowsSetProperty):
(WebCore::JSInspectedObjectWrapper::allowsDeleteProperty):
(WebCore::JSInspectedObjectWrapper::allowsConstruct):
(WebCore::JSInspectedObjectWrapper::allowsHasInstance):
(WebCore::JSInspectedObjectWrapper::allowsCallAsFunction):
(WebCore::JSInspectedObjectWrapper::allowsGetPropertyNames):
These all return true so that the Inspector can use objects from the
inspected page however it needs.
(WebCore::JSInspectedObjectWrapper::wrapOutgoingValue): Wrap all
outgoing values as JSInspectedObjectWrappers.
* bindings/js/JSInspectorCallbackWrapper.cpp: Added. This subclass of
JSQuarantinedObjectWrapper is used to wrap callbacks that the
Inspector passes to the inspected page (e.g., for event listeners or
client-side storage callbacks).
(WebCore::wrappers):
(WebCore::):
(WebCore::JSInspectorCallbackWrapper::wrap): Wraps the passed-in
object if needed and returns the wrapper. If this object has been
wrapped previously we'll return the old wrapper rather than make a new
one.
(WebCore::JSInspectorCallbackWrapper::JSInspectorCallbackWrapper): Add
ourselves to the wrapper map.
(WebCore::JSInspectorCallbackWrapper::~JSInspectorCallbackWrapper):
Remove ourselves from the wrapper map.
(WebCore::JSInspectorCallbackWrapper::prepareIncomingValue): Ensure
that values passed from the inspected page to an Inspector callback
are wrapped in JSInspectedObjectWrappers. We also allow the inspected
page to pass ourselves in (which will happen in the case of a
client-side storage callback, where the callback itself is passed as
the `this` object). In this case we unwrap ourselves so that the
Inspector doesn't have to deal with the wrapper.
* bindings/js/JSInspectorCallbackWrapper.h: Added.
(WebCore::JSInspectorCallbackWrapper::classInfo):
(WebCore::JSInspectorCallbackWrapper::allowsCallAsFunction):
This is the only allowed operation on a JSInspectorCallbackWrapper.
(WebCore::JSInspectorCallbackWrapper::wrapOutgoingValue): Wrap all
outgoing values as JSInspectorCallbackWrappers.
* page/InspectorController.cpp:
(WebCore::getResourceDocumentNode): Wrap the Document before passing
it to the Inspector.
(WebCore::highlightDOMNode): Unwrap the Node that the Inspector passed
to us.
(WebCore::databaseTableNames): Unwrap the Database that the Inspector
passed to us.
(WebCore::inspectedWindow): Wrap the Window before passing it to the
Inspector.
(WebCore::InspectorController::focusNode): Wrap the Node before
passing it to the Inspector.
(WebCore::wrapCallback): Wraps the passed-in callback in a
JSInspectorCallbackWrapper.
(WebCore::InspectorController::addDatabaseScriptResource): Wrap the
Database beore pasing it to the Inspector.
(WebCore::InspectorController::windowScriptObjectAvailable): Add the
new wrapCallback function to the InspectorController JS object.
* page/inspector/ElementsPanel.js:
(WebInspector.ElementsPanel.reset): Wrap the contentLoaded callback.
* page/inspector/DatabaseQueryView.js:
(WebInspector.DatabaseQueryView._enterKeyPressed):
* page/inspector/DatabaseTableView.js:
(WebInspector.DatabaseTableView.update):
Pass null instead of an empty array to executeSql since we're no
longer allowed to pass any unwrapped objects to the inspected page.
We now wrap all callbacks being passed to the inspected page using
InspectorController.wrapCallback.
2008-04-14 Adam Roben <aroben@apple.com>
Use prototypes/constructors from the inspected page when operating on
......@@ -487,6 +487,8 @@ webcore_sources += \
WebCore/bindings/js/JSEventTargetBase.cpp \
WebCore/bindings/js/JSHistoryCustom.cpp \
WebCore/bindings/js/JSImageConstructor.cpp \
WebCore/bindings/js/JSInspectedObjectWrapper.cpp \
WebCore/bindings/js/JSInspectorCallbackWrapper.cpp \
WebCore/bindings/js/JSLocationCustom.cpp \
WebCore/bindings/js/JSEventTargetNode.cpp \
WebCore/bindings/js/JSHTMLAppletElementCustom.cpp \
......@@ -513,6 +515,7 @@ webcore_sources += \
WebCore/bindings/js/JSNodeFilterCustom.cpp \
WebCore/bindings/js/JSNodeIteratorCustom.cpp \
WebCore/bindings/js/JSNodeListCustom.cpp \
WebCore/bindings/js/JSQuarantinedObjectWrapper.cpp \
WebCore/bindings/js/JSRGBColor.cpp \
WebCore/bindings/js/JSPluginArrayCustom.cpp \
WebCore/bindings/js/JSPluginCustom.cpp \
......
......@@ -435,6 +435,8 @@ SOURCES += \
bindings/js/JSHTMLOptionsCollectionCustom.cpp \
bindings/js/JSHTMLSelectElementCustom.cpp \
bindings/js/JSImageConstructor.cpp \
bindings/js/JSInspectedObjectWrapper.cpp \
bindings/js/JSInspectorCallbackWrapper.cpp \
bindings/js/JSLocationCustom.cpp \
bindings/js/JSNamedNodeMapCustom.cpp \
bindings/js/JSNamedNodesCollection.cpp \
......@@ -444,6 +446,7 @@ SOURCES += \
bindings/js/JSNodeFilterCustom.cpp \
bindings/js/JSNodeIteratorCustom.cpp \
bindings/js/JSNodeListCustom.cpp \
bindings/js/JSQuarantinedObjectWrapper.cpp \
bindings/js/JSRGBColor.cpp \
bindings/js/JSStyleSheetCustom.cpp \
bindings/js/JSStyleSheetListCustom.cpp \
......
......@@ -3520,30 +3520,22 @@
RelativePath="..\page\inspector\Console.js"
>
</File>
<File
RelativePath="..\page\inspector\TextPrompt.js"
>
</File>
<File
RelativePath="..\page\inspector\Database.js"
>
</File>
<File
RelativePath="..\page\inspector\DatabasesPanel.js"
RelativePath="..\page\inspector\DatabaseQueryView.js"
>
</File>
<File
RelativePath="..\page\inspector\View.js"
RelativePath="..\page\inspector\DatabasesPanel.js"
>
</File>
<File
RelativePath="..\page\inspector\DatabaseTableView.js"
>
</File>
<File
RelativePath="..\page\inspector\DatabaseQueryView.js"
>
</File>
<File
RelativePath="..\page\inspector\ElementsPanel.js"
>
......@@ -3616,6 +3608,10 @@
RelativePath="..\page\inspector\StylesSidebarPane.js"
>
</File>
<File
RelativePath="..\page\inspector\TextPrompt.js"
>
</File>
<File
RelativePath="..\page\inspector\treeoutline.js"
>
......@@ -3624,6 +3620,10 @@
RelativePath="..\page\inspector\utilities.js"
>
</File>
<File
RelativePath="..\page\inspector\View.js"
>
</File>
</Filter>
</Filter>
<Filter
......@@ -13293,6 +13293,22 @@
RelativePath="..\bindings\js\JSImageConstructor.h"
>
</File>
<File
RelativePath="..\bindings\js\JSInspectedObjectWrapper.cpp"
>
</File>
<File
RelativePath="..\bindings\js\JSInspectedObjectWrapper.h"
>
</File>
<File
RelativePath="..\bindings\js\JSInspectorCallbackWrapper.cpp"
>
</File>
<File
RelativePath="..\bindings\js\JSInspectorCallbackWrapper.h"
>
</File>
<File
RelativePath="..\bindings\js\JSLocationCustom.cpp"
>
......@@ -13349,6 +13365,14 @@
RelativePath="..\bindings\js\JSPluginCustom.cpp"
>
</File>
<File
RelativePath="..\bindings\js\JSQuarantinedObjectWrapper.cpp"
>
</File>
<File
RelativePath="..\bindings\js\JSQuarantinedObjectWrapper.h"
>
</File>
<File
RelativePath="..\bindings\js\JSRGBColor.cpp"
>
......@@ -14750,30 +14774,30 @@
Name="animation"
>
<File
RelativePath="..\svg\animation\SMILTime.cpp"
>
RelativePath="..\svg\animation\SMILTime.cpp"
>
</File>
<File
RelativePath="..\svg\animation\SMILTime.h"
>
RelativePath="..\svg\animation\SMILTime.h"
>
</File>
<File
RelativePath="..\svg\animation\SMILTimeContainer.cpp"
>
RelativePath="..\svg\animation\SMILTimeContainer.cpp"
>
</File>
<File
RelativePath="..\svg\animation\SMILTimeContainer.h"
>
RelativePath="..\svg\animation\SMILTimeContainer.h"
>
</File>
<File
RelativePath="..\svg\animation\SVGSMILElement.cpp"
>
RelativePath="..\svg\animation\SVGSMILElement.cpp"
>
</File>
<File
RelativePath="..\svg\animation\SVGSMILElement.h"
>
RelativePath="..\svg\animation\SVGSMILElement.h"
>
</File>
</Filter>
</Filter>
<Filter
Name="graphics"
>
......@@ -15838,6 +15862,14 @@
RelativePath="..\storage\OriginUsageRecord.h"
>
</File>
<File
RelativePath="..\storage\SessionStorage.cpp"
>
</File>
<File
RelativePath="..\storage\SessionStorage.h"
>
</File>
<File
RelativePath="..\storage\SQLCallback.h"
>
......@@ -15926,14 +15958,6 @@
RelativePath="..\storage\StorageMap.h"
>
</File>
<File
RelativePath="..\storage\SessionStorage.cpp"
>
</File>
<File
RelativePath="..\storage\SessionStorage.h"
>
</File>
<File
RelativePath="..\storage\VersionChangeCallback.h"
>
......
......@@ -3826,6 +3826,12 @@
C02B14C20D81E02A00D8A970 /* JavaScriptDebugListener.h in Headers */ = {isa = PBXBuildFile; fileRef = C02B14BF0D81E02A00D8A970 /* JavaScriptDebugListener.h */; };
C02B14C30D81E02A00D8A970 /* JavaScriptDebugServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C02B14C00D81E02A00D8A970 /* JavaScriptDebugServer.cpp */; };
C02B14C40D81E02A00D8A970 /* JavaScriptDebugServer.h in Headers */ = {isa = PBXBuildFile; fileRef = C02B14C10D81E02A00D8A970 /* JavaScriptDebugServer.h */; };
C091588A0DB4209200E55AF4 /* JSInspectedObjectWrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C09158840DB4209200E55AF4 /* JSInspectedObjectWrapper.cpp */; };
C091588B0DB4209200E55AF4 /* JSInspectedObjectWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = C09158850DB4209200E55AF4 /* JSInspectedObjectWrapper.h */; };
C091588C0DB4209200E55AF4 /* JSInspectorCallbackWrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C09158860DB4209200E55AF4 /* JSInspectorCallbackWrapper.cpp */; };
C091588D0DB4209200E55AF4 /* JSInspectorCallbackWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = C09158870DB4209200E55AF4 /* JSInspectorCallbackWrapper.h */; };
C091588E0DB4209200E55AF4 /* JSQuarantinedObjectWrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C09158880DB4209200E55AF4 /* JSQuarantinedObjectWrapper.cpp */; };
C091588F0DB4209200E55AF4 /* JSQuarantinedObjectWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = C09158890DB4209200E55AF4 /* JSQuarantinedObjectWrapper.h */; };
C6D74AD509AA282E000B0A52 /* ModifySelectionListLevel.h in Headers */ = {isa = PBXBuildFile; fileRef = C6D74AD309AA282E000B0A52 /* ModifySelectionListLevel.h */; };
C6D74AE409AA290A000B0A52 /* ModifySelectionListLevel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C6D74AE309AA290A000B0A52 /* ModifySelectionListLevel.cpp */; };
D05CED290A40BB2C00C5AF38 /* FormatBlockCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D05CED270A40BB2C00C5AF38 /* FormatBlockCommand.cpp */; };
......@@ -8094,6 +8100,12 @@
C02B14BF0D81E02A00D8A970 /* JavaScriptDebugListener.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JavaScriptDebugListener.h; sourceTree = "<group>"; };
C02B14C00D81E02A00D8A970 /* JavaScriptDebugServer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JavaScriptDebugServer.cpp; sourceTree = "<group>"; };
C02B14C10D81E02A00D8A970 /* JavaScriptDebugServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JavaScriptDebugServer.h; sourceTree = "<group>"; };
C09158840DB4209200E55AF4 /* JSInspectedObjectWrapper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSInspectedObjectWrapper.cpp; sourceTree = "<group>"; };
C09158850DB4209200E55AF4 /* JSInspectedObjectWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSInspectedObjectWrapper.h; sourceTree = "<group>"; };
C09158860DB4209200E55AF4 /* JSInspectorCallbackWrapper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSInspectorCallbackWrapper.cpp; sourceTree = "<group>"; };
C09158870DB4209200E55AF4 /* JSInspectorCallbackWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSInspectorCallbackWrapper.h; sourceTree = "<group>"; };
C09158880DB4209200E55AF4 /* JSQuarantinedObjectWrapper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSQuarantinedObjectWrapper.cpp; sourceTree = "<group>"; };
C09158890DB4209200E55AF4 /* JSQuarantinedObjectWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSQuarantinedObjectWrapper.h; sourceTree = "<group>"; };
C6D74AD309AA282E000B0A52 /* ModifySelectionListLevel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ModifySelectionListLevel.h; sourceTree = "<group>"; };
C6D74AE309AA290A000B0A52 /* ModifySelectionListLevel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ModifySelectionListLevel.cpp; sourceTree = "<group>"; };
D05CED270A40BB2C00C5AF38 /* FormatBlockCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = FormatBlockCommand.cpp; sourceTree = "<group>"; };
......@@ -11926,12 +11938,18 @@
A80E7E630A1A82EC007FB8C5 /* JSHTMLInputElementBase.h */,
A826E8AD0A1A8F2300CD1BB6 /* JSHTMLOptionElementConstructor.cpp */,
A826E8AC0A1A8F2300CD1BB6 /* JSHTMLOptionElementConstructor.h */,
C09158840DB4209200E55AF4 /* JSInspectedObjectWrapper.cpp */,
C09158850DB4209200E55AF4 /* JSInspectedObjectWrapper.h */,
C09158860DB4209200E55AF4 /* JSInspectorCallbackWrapper.cpp */,
C09158870DB4209200E55AF4 /* JSInspectorCallbackWrapper.h */,
BC6C49F10D7DBA0500FFA558 /* JSImageConstructor.cpp */,
BC6C49F20D7DBA0500FFA558 /* JSImageConstructor.h */,
BCD9C26C0C17AA81005C90A2 /* JSNamedNodesCollection.cpp */,
BCD9C26D0C17AA81005C90A2 /* JSNamedNodesCollection.h */,
BCB7735E0C17853D00132BA4 /* JSNodeFilterCondition.cpp */,
BCB7735F0C17853D00132BA4 /* JSNodeFilterCondition.h */,
C09158880DB4209200E55AF4 /* JSQuarantinedObjectWrapper.cpp */,
C09158890DB4209200E55AF4 /* JSQuarantinedObjectWrapper.h */,
BC3452410D7E00EA0016574A /* JSRGBColor.cpp */,
BC3452420D7E00EA0016574A /* JSRGBColor.h */,
8574D1F10ADE6122004CBA11 /* JSSVGElementWrapperFactory.cpp */,
......@@ -14809,6 +14827,9 @@
E4AFD0100DAF335500F5F55C /* SVGSMILElement.h in Headers */,
3744570F0DB05FA500AE0992 /* SVGGlyphMap.h in Headers */,
BCB4F8900DB28DD60039139B /* RenderImageGeneratedContent.h in Headers */,
C091588B0DB4209200E55AF4 /* JSInspectedObjectWrapper.h in Headers */,
C091588D0DB4209200E55AF4 /* JSInspectorCallbackWrapper.h in Headers */,
C091588F0DB4209200E55AF4 /* JSQuarantinedObjectWrapper.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -16497,6 +16518,9 @@
E4AFD00D0DAF335500F5F55C /* SMILTimeContainer.cpp in Sources */,
E4AFD00F0DAF335500F5F55C /* SVGSMILElement.cpp in Sources */,
BCB4F8930DB28E530039139B /* RenderImageGeneratedContent.cpp in Sources */,
C091588A0DB4209200E55AF4 /* JSInspectedObjectWrapper.cpp in Sources */,
C091588C0DB4209200E55AF4 /* JSInspectorCallbackWrapper.cpp in Sources */,
C091588E0DB4209200E55AF4 /* JSQuarantinedObjectWrapper.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -74,6 +74,8 @@ This file contains the list of files needed to build WebCore.
bindings/js/JSHTMLOptionsCollectionCustom.cpp
bindings/js/JSHTMLSelectElementCustom.cpp
bindings/js/JSImageConstructor.cpp
bindings/js/JSInspectedObjectWrapper.cpp
bindings/js/JSInspectorCallbackWrapper.cpp
bindings/js/JSLocationCustom.cpp
bindings/js/JSMimeTypeArrayCustom.cpp
bindings/js/JSNamedNodeMapCustom.cpp
......@@ -86,6 +88,7 @@ This file contains the list of files needed to build WebCore.
bindings/js/JSNodeListCustom.cpp
bindings/js/JSPluginCustom.cpp
bindings/js/JSPluginArrayCustom.cpp
bindings/js/JSQuarantinedObjectWrapper.cpp
bindings/js/JSRGBColor.cpp
bindings/js/JSSQLResultSetRowListCustom.cpp
bindings/js/JSSQLTransactionCustom.cpp
......
/*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "JSInspectedObjectWrapper.h"
#include "JSInspectorCallbackWrapper.h"
using namespace KJS;
namespace WebCore {
typedef HashMap<JSObject*, JSInspectedObjectWrapper*> WrapperMap;
static WrapperMap& wrappers()
{
static WrapperMap map;
return map;
}
const ClassInfo JSInspectedObjectWrapper::s_info = { "JSInspectedObjectWrapper", &JSQuarantinedObjectWrapper::s_info, 0 };
JSValue* JSInspectedObjectWrapper::wrap(ExecState* unwrappedExec, JSValue* unwrappedValue)
{
if (!unwrappedValue->isObject())
return unwrappedValue;
JSObject* unwrappedObject = static_cast<JSObject*>(unwrappedValue);
if (unwrappedObject->inherits(&JSInspectedObjectWrapper::s_info))
return unwrappedObject;
if (JSInspectedObjectWrapper* wrapper = wrappers().get(unwrappedObject))
return wrapper;
JSValue* prototype = unwrappedObject->prototype();
JSValue* wrappedPrototype = prototype ? wrap(unwrappedExec, prototype) : 0;
return new JSInspectedObjectWrapper(unwrappedExec, unwrappedObject, wrappedPrototype);
}
JSInspectedObjectWrapper::JSInspectedObjectWrapper(ExecState* unwrappedExec, JSObject* unwrappedObject, JSValue* wrappedPrototype)
: JSQuarantinedObjectWrapper(unwrappedExec, unwrappedObject, wrappedPrototype)
{
ASSERT(!wrappers().contains(unwrappedObject));
wrappers().set(unwrappedObject, this);
}
JSInspectedObjectWrapper::~JSInspectedObjectWrapper()
{
wrappers().remove(unwrappedObject());
}
JSValue* JSInspectedObjectWrapper::prepareIncomingValue(ExecState*, JSValue* value) const
{
// The Inspector is only allowed to pass primitive values and wrapped objects to objects from the inspected page.
if (!value->isObject())
return value;
JSQuarantinedObjectWrapper* wrapper = asWrapper(value);
ASSERT_WITH_MESSAGE(wrapper, "Objects passed to JSInspectedObjectWrapper must be wrapped");
if (!wrapper)
return 0;
if (wrapper->unwrappedExecStateMatches(unwrappedExecState())) {
ASSERT_WITH_MESSAGE(wrapper->inherits(&s_info), "A wrapper contains an object from the inspected page but is not a JSInspectedObjectWrapper");
if (!wrapper->inherits(&s_info))
return 0;
// Return the unwrapped object so the inspected page never sees one of its own objects in wrapped form.
return wrapper->unwrappedObject();
}
ASSERT_WITH_MESSAGE(wrapper->inherits(&JSInspectorCallbackWrapper::s_info), "A wrapper that was not from the inspected page and is not an Inspector callback was passed to a JSInspectedObjectWrapper");
if (!wrapper->inherits(&JSInspectorCallbackWrapper::s_info))
return 0;
return wrapper;
}
} // namespace WebCore
/*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef JSInspectedObjectWrapper_h
#define JSInspectedObjectWrapper_h
#include "JSQuarantinedObjectWrapper.h"
namespace WebCore {
class JSInspectedObjectWrapper : public JSQuarantinedObjectWrapper {
public:
static KJS::JSValue* wrap(KJS::ExecState* unwrappedExec, KJS::JSValue* unwrappedValue);
virtual ~JSInspectedObjectWrapper();
virtual const KJS::ClassInfo* classInfo() const { return &s_info; }
static const KJS::ClassInfo s_info;
protected:
JSInspectedObjectWrapper(KJS::ExecState* unwrappedExec, KJS::JSObject* unwrappedObject, KJS::JSValue* wrappedPrototype);
virtual bool allowsGetProperty() const { return true; }
virtual bool allowsSetProperty() const { return true; }
virtual bool allowsDeleteProperty() const { return true; }
virtual bool allowsConstruct() const { return true; }
virtual bool allowsHasInstance() const { return true; }
virtual bool allowsCallAsFunction() const { return true; }
virtual bool allowsGetPropertyNames() const { return true; }
virtual KJS::JSValue* prepareIncomingValue(KJS::ExecState* unwrappedExec, KJS::JSValue* unwrappedValue) const;
virtual KJS::JSValue* wrapOutgoingValue(KJS::ExecState* unwrappedExec, KJS::JSValue* unwrappedValue) const { return wrap(unwrappedExec, unwrappedValue); }
};
} // namespace WebCore
#endif // JSInspectedObjectWrapper_h
/*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY