<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE bugzilla SYSTEM "https://bugs.webkit.org/page.cgi?id=bugzilla.dtd">

<bugzilla version="5.0.4.1"
          urlbase="https://bugs.webkit.org/"
          
          maintainer="admin@webkit.org"
>

    <bug>
          <bug_id>254777</bug_id>
          
          <creation_ts>2023-03-30 15:09:03 -0700</creation_ts>
          <short_desc>REGRESSION (Safari 16.4): PostMessage with transfer object is broken between contexts</short_desc>
          <delta_ts>2023-07-20 10:42:39 -0700</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>WebKit</product>
          <component>WebCore Misc.</component>
          <version>Safari 16</version>
          <rep_platform>All</rep_platform>
          <op_sys>All</op_sys>
          <bug_status>RESOLVED</bug_status>
          <resolution>FIXED</resolution>
          
          <see_also>https://bugs.webkit.org/show_bug.cgi?id=171216</see_also>
    
    <see_also>https://bugs.webkit.org/show_bug.cgi?id=259362</see_also>
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords>BrowserCompat, InRadar</keywords>
          <priority>P2</priority>
          <bug_severity>Major</bug_severity>
          <target_milestone>---</target_milestone>
          
          
          <everconfirmed>1</everconfirmed>
          <reporter name="Justin Mayfield">tooker</reporter>
          <assigned_to name="Chris Dumez">cdumez</assigned_to>
          <cc>ajuma</cc>
    
    <cc>ap</cc>
    
    <cc>cdumez</cc>
    
    <cc>cockscomb</cc>
    
    <cc>karlcow</cc>
    
    <cc>michaeldo</cc>
    
    <cc>webkit-bug-importer</cc>
    
    <cc>wilander</cc>
          

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>1945507</commentid>
    <comment_count>0</comment_count>
    <who name="Justin Mayfield">tooker</who>
    <bug_when>2023-03-30 15:09:03 -0700</bug_when>
    <thetext>Sending a transferable object like a MessagePort to communicate between different contexts no longer works properly.  When I use the transfer argument to postMessage the event handler gets an event with a null data property.

Steps to reproduce:

1. Call postMessage({foo: &apos;bar&apos;, port}, self.origin, [port]) from page script.
2. Add window.message event handler to a different context such as an
   extension&apos;s content script context and evaluate the event callback arg.
3. Observe the ev.data is null instead of {foo: &apos;bar&apos;, port: port}

Expected behavior:
For the message handler to get an event object with a non-null data property filed with the contents sent from the postMessage caller.

I first noticed this on the Orion Safari fork and filed a bug with them, https://orionfeedback.org/d/4730-postmessage-with-transfer-object-is-broken, but after updating to Safari 16.4 on the macOS 13.3 I see the same bug there, which leads me to believe this is a core WebKit regression.  This is directly affecting my Safari extension which no longer works on anyone&apos;s 16.4 based Safari browsers.  The same code works fine on all Chromium and Firefox.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1945514</commentid>
    <comment_count>1</comment_count>
    <who name="Justin Mayfield">tooker</who>
    <bug_when>2023-03-30 15:53:49 -0700</bug_when>
    <thetext>More observations.

1. I can only reproduce with MessagePort transferables.  Using ArrayBuffer for example works as expected.
2. The data property of the MessageEvent is null but the ports[] array is populated with the MessagePort object.
3. Excluding the MessagePort from the sending side&apos;s data object works as expected.  The data property of the MessageEvent is correctly set to the cloned object and the ports[] property contains the transferred MessagePort.


I&apos;ll be refactoring my use case to use the technique from #3;  It&apos;s slightly less safe because I need to make assumptions about the ordering of the ports[] property on the receiver side instead of being able to directly access the transferables from the data object property but at least I&apos;ll be able to get my Safari 16.4 users working again and support Orion.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1946072</commentid>
    <comment_count>2</comment_count>
    <who name="Karl Dubost">karlcow</who>
    <bug_when>2023-04-02 17:49:53 -0700</bug_when>
    <thetext>It would be nice to have a simplified testcase</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1946077</commentid>
    <comment_count>3</comment_count>
    <who name="Justin Mayfield">tooker</who>
    <bug_when>2023-04-02 18:18:47 -0700</bug_when>
    <thetext>(In reply to Karl Dubost from comment #2)
&gt; It would be nice to have a simplified testcase

I&apos;m not familiar enough with WebKit to simulate an extension&apos;s content-script context.  I tried a simple test with a Worker and an iframe but neither are affected.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1946082</commentid>
    <comment_count>4</comment_count>
    <who name="Alexey Proskuryakov">ap</who>
    <bug_when>2023-04-02 18:34:14 -0700</bug_when>
    <thetext>Would it be possible to provide easy to reproduce test steps, even if not minimized? This way, someone who isn&apos;t deeply familiar with the code could e.g. bisect to find the culprit change.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1946083</commentid>
    <comment_count>5</comment_count>
    <who name="Radar WebKit Bug Importer">webkit-bug-importer</who>
    <bug_when>2023-04-02 18:34:24 -0700</bug_when>
    <thetext>&lt;rdar://problem/107538083&gt;</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1946094</commentid>
    <comment_count>6</comment_count>
    <who name="Justin Mayfield">tooker</who>
    <bug_when>2023-04-02 18:55:20 -0700</bug_when>
    <thetext>Safari requires a significant amount of tooling and xcode interaction so I&apos;ll just skip that, but with Orion you can create a local extension folder and populate it with a manifest.json such as this...

  {
    &quot;manifest_version&quot;: 2,
    &quot;content_scripts&quot;: [{
        &quot;run_at&quot;: &quot;document_start&quot;,
        &quot;matches&quot;: [&quot;*://*/*&quot;],
        &quot;js&quot;: [&quot;ext-context.js&quot;]
    }]
    ...
  }


ext-context.js should do this...

  addEventListener(&apos;message&apos;, ev =&gt; {
    if (ev.data &amp;&amp; ev.data.port instanceof MessagePort) {
        console.info(&quot;pass&quot;);
    } else {
        console.error(&quot;fail&quot;);
    }
  });



And then visit a mock page that runs this script...

  const ch = new MessageChannel();
  const port = ch.port2;
  postMessage({port}, self.origin, [port]);


I&apos;ll see if I can find where the regression came in too;  I realize this is probably not helpful.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1947562</commentid>
    <comment_count>7</comment_count>
    <who name="Karl Dubost">karlcow</who>
    <bug_when>2023-04-09 19:12:52 -0700</bug_when>
    <thetext>Justin Mayfield,

does it work if you exclude the port in the data argument of postMessage?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1947563</commentid>
    <comment_count>8</comment_count>
    <who name="Justin Mayfield">tooker</who>
    <bug_when>2023-04-09 19:29:35 -0700</bug_when>
    <thetext>Yes, and that is the exact workaround I&apos;m using in my extension.  It only works because there is the .ports[] array to save the day when you transfer a MessagePort specifically.  But then again, this only seems to affect MessagePort transfer objects.

This is pattern I&apos;m using now that works on all browsers..
    const transfer = [port];
    postMessage({portIndex: transfer.indexOf(port)}, transfer);

And from my handler I do..
    const port = event.ports[event.data.portIndex];</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1948049</commentid>
    <comment_count>9</comment_count>
    <who name="John Wilander">wilander</who>
    <bug_when>2023-04-11 16:34:58 -0700</bug_when>
    <thetext>Hi, Justin! Thanks for filing. Could you share which extension this is for? And am I right in that you have already deployed a workaround so the bug won&apos;t reproduce with your extension? Thanks!</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1948095</commentid>
    <comment_count>10</comment_count>
    <who name="Justin Mayfield">tooker</who>
    <bug_when>2023-04-11 17:32:36 -0700</bug_when>
    <thetext>(In reply to John Wilander from comment #9)
&gt; Hi, Justin! Thanks for filing. Could you share which extension this is for?
&gt; And am I right in that you have already deployed a workaround so the bug
&gt; won&apos;t reproduce with your extension? Thanks!

Hello John,

This is my extension:
   https://github.com/SauceLLC/sauce4strava
   https://apps.apple.com/us/app/sauce-for-strava/id1570922521
   https://addons.mozilla.org/en-US/firefox/addon/sauce4strava/
   https://chrome.google.com/webstore/detail/eigiefcapdcdmncdghkeahgfmnobigha

And you are correct, I already released patched builds (v8.2.2) on the Apple and Firefox stores.

This is the commit with my workaround: https://github.com/SauceLLC/sauce4strava/commit/9100e2db6245b5db7bf104b3044029d0b936ec7a

I don&apos;t know how to get you a Safari based build with the old behavior from the app-store, but if you use Onion you can install this unpatched firefox build: https://addons.mozilla.org/firefox/downloads/file/4078653/sauce4strava-8.2.1.xpi

I should warn you that you&apos;ll probably need to create an account with strava.com first.  It&apos;s free, but there would be some tedium in trying to repro from my particular extension.  You&apos;ll also need to be on a page that invokes these postMessage calls, such as this example: https://www.strava.com/activities/8355858982</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1949620</commentid>
    <comment_count>11</comment_count>
    <who name="Hiroki Kato">cockscomb</who>
    <bug_when>2023-04-18 17:58:35 -0700</bug_when>
    <thetext>Hello.

This issue probably affects Chrome iOS as well. I encountered a similar situation, and at first I thought it was a problem on Chrome&apos;s side, but it seems that a change on the WebKit side was having an effect instead.

https://bugs.chromium.org/p/chromium/issues/detail?id=1431021</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1949624</commentid>
    <comment_count>12</comment_count>
    <who name="Justin Mayfield">tooker</who>
    <bug_when>2023-04-18 18:16:42 -0700</bug_when>
    <thetext>(In reply to Hiroki Kato from comment #11)
&gt; Hello.
&gt; 
&gt; This issue probably affects Chrome iOS as well. I encountered a similar
&gt; situation, and at first I thought it was a problem on Chrome&apos;s side, but it
&gt; seems that a change on the WebKit side was having an effect instead.
&gt; 
&gt; https://bugs.chromium.org/p/chromium/issues/detail?id=1431021

Very interesting.  This comment in particular is very interesting: https://bugs.chromium.org/p/chromium/issues/detail?id=1431021#c6

Thanks for cross referencing here Hiroki!</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1949717</commentid>
    <comment_count>13</comment_count>
    <who name="Ali Juma">ajuma</who>
    <bug_when>2023-04-19 05:57:56 -0700</bug_when>
    <thetext>(In reply to Justin Mayfield from comment #12)
&gt; (In reply to Hiroki Kato from comment #11)
&gt; &gt; Hello.
&gt; &gt; 
&gt; &gt; This issue probably affects Chrome iOS as well. I encountered a similar
&gt; &gt; situation, and at first I thought it was a problem on Chrome&apos;s side, but it
&gt; &gt; seems that a change on the WebKit side was having an effect instead.
&gt; &gt; 
&gt; &gt; https://bugs.chromium.org/p/chromium/issues/detail?id=1431021
&gt; 
&gt; Very interesting.  This comment in particular is very interesting:
&gt; https://bugs.chromium.org/p/chromium/issues/detail?id=1431021#c6

https://bugs.chromium.org/p/chromium/issues/detail?id=1431021#c4b also has a small test app and test page.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1949718</commentid>
    <comment_count>14</comment_count>
    <who name="Ali Juma">ajuma</who>
    <bug_when>2023-04-19 05:58:32 -0700</bug_when>
    <thetext>(In reply to Ali Juma from comment #13)
&gt; (In reply to Justin Mayfield from comment #12)
&gt; &gt; (In reply to Hiroki Kato from comment #11)
&gt; &gt; &gt; Hello.
&gt; &gt; &gt; 
&gt; &gt; &gt; This issue probably affects Chrome iOS as well. I encountered a similar
&gt; &gt; &gt; situation, and at first I thought it was a problem on Chrome&apos;s side, but it
&gt; &gt; &gt; seems that a change on the WebKit side was having an effect instead.
&gt; &gt; &gt; 
&gt; &gt; &gt; https://bugs.chromium.org/p/chromium/issues/detail?id=1431021
&gt; &gt; 
&gt; &gt; Very interesting.  This comment in particular is very interesting:
&gt; &gt; https://bugs.chromium.org/p/chromium/issues/detail?id=1431021#c6
&gt; 
&gt; https://bugs.chromium.org/p/chromium/issues/detail?id=1431021#c4b also has a
&gt; small test app and test page.

Sorry, typo, I meant https://bugs.chromium.org/p/chromium/issues/detail?id=1431021#c4</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1949821</commentid>
    <comment_count>15</comment_count>
    <who name="Chris Dumez">cdumez</who>
    <bug_when>2023-04-19 13:17:11 -0700</bug_when>
    <thetext>Pull request: https://github.com/WebKit/WebKit/pull/12929</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1949901</commentid>
    <comment_count>16</comment_count>
    <who name="EWS">ews-feeder</who>
    <bug_when>2023-04-19 16:39:58 -0700</bug_when>
    <thetext>Committed 263155@main (ca6ca7d1895d): &lt;https://commits.webkit.org/263155@main&gt;

Reviewed commits have been landed. Closing PR #12929 and removing active labels.</thetext>
  </long_desc>
      
      

    </bug>

</bugzilla>