Open Bug 1681638 Opened 4 years ago Updated 5 months ago

browser.runtime.connectNative().postMessage fails to handle JavaScript object with nested array

Categories

(GeckoView :: Extensions, defect, P3)

Firefox 84
Unspecified
All
defect

Tracking

(Not tracked)

UNCONFIRMED

People

(Reporter: ugling88, Unassigned)

Details

(Whiteboard: [geckoview:2023?])

User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36

Steps to reproduce:

I am using GeckoView's connection-based messaging feature following the official documentation here: https://firefox-source-docs.mozilla.org/mobile/android/geckoview/consumer/web-extensions.html.

On the JavaScript side, when using the port.postMessage function, it fails to post JavaScript object with a nested array.
Steps:

  1. Create a nativePort using let aport = browser.runtime.connectNative("browser");
  2. Send a simple empty array object: aport.postMessage([]), Android side receives the correct message.
  3. Send a simple empty object with a nested array: aport.postMessage([[]]), Android side does not receive any message

Actual results:

On JavaScript running inside GeckoView.

  1. Send a simple empty array object: aport.postMessage([]), Android side receives the correct message.
  2. Send a simple empty object with a nested array: aport.postMessage([[]]), Android side does not receive any message.

GeckoView logs in the console:

  1. [Warning] Error dispatching GeckoView:WebExtension:PortMessage Messaging.jsm:76:24
  2. [Error] Invalid event data property data

Expected results:

JavaScript objects [] and [[]] shoule be correctly serialized & encoded, Android side onPortMessage callback should receive the correct message object.

Severity: -- → S3
Priority: -- → P2

According to the documentation, a message should be either a JS object or a primitive type. JS array is neither of those, so it's not supposed to work. Some type validation with clear error messages might be nice though - adding those is relevant.

Priority: P2 → P3
Whiteboard: [geckoview:2023?]

In the WebExtensions API definition level, an array is a valid type for the message. In general, any JSON-serializable value is valid, including nested arrays. The WebExtension API itself supports structured cloning (up to the sender of "GeckoView:WebExtension:PortMessage"), but since structured cloning outside of Gecko doesn't make sense, we only claim support for JSON-serializable values.

At the GeckoView layer, somehow the documentation states that it can only be a primitive or an object: https://searchfox.org/mozilla-central/rev/be684f13a4ce71e7ca5e0b354a0f56a665842922/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/WebExtension.java#393-401

This requirement is also propagated further down to A-C: https://searchfox.org/mozilla-central/rev/be684f13a4ce71e7ca5e0b354a0f56a665842922/mobile/android/android-components/components/concept/engine/src/main/java/mozilla/components/concept/engine/webextension/WebExtension.kt#257-258

I'm curious why support for org.json.JSONArray is not documented.

The error message in the report is:

[Error] Invalid event data property data

... that comes either from UnboxBundle in EventDispatcher.cpp or BoxObject in GeckoBundleUtils.cpp.

You need to log in before you can comment on or make changes to this bug.