diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/bindings/js/JSPopStateEventCustom.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebCore/bindings/js/JSPopStateEventCustom.cpp')
-rw-r--r-- | Source/WebCore/bindings/js/JSPopStateEventCustom.cpp | 51 |
1 files changed, 33 insertions, 18 deletions
diff --git a/Source/WebCore/bindings/js/JSPopStateEventCustom.cpp b/Source/WebCore/bindings/js/JSPopStateEventCustom.cpp index e4d46f792..aadb860a3 100644 --- a/Source/WebCore/bindings/js/JSPopStateEventCustom.cpp +++ b/Source/WebCore/bindings/js/JSPopStateEventCustom.cpp @@ -29,36 +29,51 @@ */ #include "config.h" +#include "JSPopStateEvent.h" -#include "History.h" +#include "DOMWrapperWorld.h" #include "JSHistory.h" -#include "JSPopStateEvent.h" +#include <heap/HeapInlines.h> +#include <runtime/JSCJSValueInlines.h> using namespace JSC; namespace WebCore { // Save the state value to the m_state member of a JSPopStateEvent, and return it, for convenience. -static const JSValue& cacheState(ExecState* exec, JSPopStateEvent* event, const JSValue& state) +static const JSValue& cacheState(ExecState& state, const JSPopStateEvent* event, const JSValue& eventState) { - event->m_state.set(exec->vm(), event, state); - return state; + event->m_state.set(state.vm(), event, eventState); + return eventState; } -JSValue JSPopStateEvent::state(ExecState* exec) const +JSValue JSPopStateEvent::state(ExecState& state) const { JSValue cachedValue = m_state.get(); - if (!cachedValue.isEmpty()) - return cachedValue; - - PopStateEvent& event = impl(); + if (!cachedValue.isEmpty()) { + // We cannot use a cached object if we are in a different world than the one it was created in. + if (!cachedValue.isObject() || &worldForDOMObject(cachedValue.getObject()) == ¤tWorld(&state)) + return cachedValue; + ASSERT_NOT_REACHED(); + } - if (!event.state().hasNoValue()) - return cacheState(exec, const_cast<JSPopStateEvent*>(this), event.state().jsValue()); + PopStateEvent& event = wrapped(); + if (auto eventState = event.state()) { + // We need to make sure a PopStateEvent does not leak objects in its state property across isolated DOM worlds. + // Ideally, we would check that the worlds have different privileges but that's not possible yet. + if (eventState.isObject() && &worldForDOMObject(eventState.getObject()) != ¤tWorld(&state)) { + if (auto serializedValue = event.trySerializeState(state)) + eventState = serializedValue->deserialize(state, globalObject()); + else + eventState = jsNull(); + } + return cacheState(state, this, eventState); + } + History* history = event.history(); if (!history || !event.serializedState()) - return cacheState(exec, const_cast<JSPopStateEvent*>(this), jsNull()); + return cacheState(state, this, jsNull()); // There's no cached value from a previous invocation, nor a state value was provided by the // event, but there is a history object, so first we need to see if the state object has been @@ -66,16 +81,16 @@ JSValue JSPopStateEvent::state(ExecState* exec) const // The current history state object might've changed in the meantime, so we need to take care // of using the correct one, and always share the same deserialization with history.state. - bool isSameState = history->isSameAsCurrentState(event.serializedState().get()); + bool isSameState = history->isSameAsCurrentState(event.serializedState()); JSValue result; if (isSameState) { - JSHistory* jsHistory = jsCast<JSHistory*>(toJS(exec, globalObject(), history).asCell()); - result = jsHistory->state(exec); + JSHistory* jsHistory = jsCast<JSHistory*>(toJS(&state, globalObject(), *history).asCell()); + result = jsHistory->state(state); } else - result = event.serializedState()->deserialize(exec, globalObject(), 0); + result = event.serializedState()->deserialize(state, globalObject()); - return cacheState(exec, const_cast<JSPopStateEvent*>(this), result); + return cacheState(state, this, result); } } // namespace WebCore |