[webkit-changes] [WebKit/WebKit] acece6: window.postMessage with OffscreenCanvas is broken ...

Chris Dumez noreply at github.com
Mon Jul 31 22:22:37 PDT 2023


  Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: acece69bd261c37f0a66d82d4abc80bed8b09bd7
      https://github.com/WebKit/WebKit/commit/acece69bd261c37f0a66d82d4abc80bed8b09bd7
  Author: Chris Dumez <cdumez at apple.com>
  Date:   2023-07-31 (Mon, 31 Jul 2023)

  Changed paths:
    M Source/WebCore/bindings/js/JSDOMWrapper.cpp
    M Source/WebCore/bindings/js/SerializedScriptValue.cpp
    M Source/WebCore/bindings/js/SerializedScriptValue.h
    M Source/WebCore/dom/MessageEvent.cpp
    M Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
    M Tools/TestWebKitAPI/Tests/WebKitCocoa/UserContentWorld.mm
    A Tools/TestWebKitAPI/Tests/WebKitCocoa/postMessage-various-types.html

  Log Message:
  -----------
  window.postMessage with OffscreenCanvas is broken with isolated world message listener
https://bugs.webkit.org/show_bug.cgi?id=259362
rdar://112618195

Reviewed by Darin Adler.

When constructing a MessageEvent, we would deserialize the `data` SerializedScriptValue
and cache the resulting JSValue. When accessing MessageEvent.data from the main world,
we would return the cached JSValue and everything would work fine.
However, upon accessing MessageEvent.data from a non-main world, the cached JSValue
would not be usable and we would deserialize the original SerializedScriptValue again.

The issue is that a SerializedScriptValue is not meant to be deserialized several times.
This is because the deserialization "consumes" certain internal objects. For examples,
OffscreenCanvas are stored as DetachedOffscreenCanvas internally and consumed upon
deserialization to construct OffscreenCanvas objects again.

To address the issue, this patch makes several changes:
1. MessageEvent::create() now stores the deserialized JSValue inside the MessageEvent
   object instead of the SerializedScriptValue. As a result, when accessing
   MessageEvent.data from the main world, we'll just return the internal JSValue.
   When accessing MessageEvent.data from a non-main world, cachedPropertyValue() will
   detect that the internal JSValue is no compatible with this world and call
   cloneAcrossWorlds() on the internal JSValue to generate one suitable for the non-main
   world. Internally, cloneAcrossWorlds() creates a SerializedScriptValue from the JSValue
   and then deserializes that SerializedScriptValue in the target world.
2. As currently implemented, cloneAcrossWorlds() would drop transferrable objects such
   as OffscreenCanvas and MessagePort. To address the issue, we now introduce a new
   CloneAcrossWorlds SerializationContext. When in this context, SerializedScriptValue
   serialization will store OffscreenCanvas/MessagePort in the JSValue inside internal
   vectors and merely serialize indexes inside those vectors. Upon deserialization, we
   deserialize the index and lookup the OffscreenCanvas/MessagePort from the internal
   vector. Then, we call toJS() on the implementation object to get a JS wrapper for the
   target world.

* Source/WebCore/bindings/js/JSDOMWrapper.cpp:
(WebCore::cloneAcrossWorlds):
* Source/WebCore/bindings/js/SerializedScriptValue.cpp:
(WebCore::isTypeExposedToGlobalObject):
(WebCore::CloneSerializer::serialize):
(WebCore::CloneSerializer::CloneSerializer):
(WebCore::CloneSerializer::dumpOffscreenCanvas):
(WebCore::CloneSerializer::dumpIfTerminal):
(WebCore::CloneDeserializer::deserialize):
(WebCore::CloneDeserializer::CloneDeserializer):
(WebCore::CloneDeserializer::readInMemoryOffscreenCanvas):
(WebCore::CloneDeserializer::readTerminal):
(WebCore::SerializedScriptValue::SerializedScriptValue):
(WebCore::SerializedScriptValue::create):
(WebCore::SerializedScriptValue::deserialize):
* Source/WebCore/bindings/js/SerializedScriptValue.h:
* Source/WebCore/dom/MessageEvent.cpp:
(WebCore::MessageEvent::create):
* Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* Tools/TestWebKitAPI/Tests/WebKitCocoa/UserContentWorld.mm:
(-[UserContentWorldMessageHandler userContentController:didReceiveScriptMessage:]):
(TEST):
* Tools/TestWebKitAPI/Tests/WebKitCocoa/postMessage-various-types.html: Added.

Canonical link: https://commits.webkit.org/266465@main




More information about the webkit-changes mailing list