Skip to content

Commit 4dd9d6a

Browse files
committed
detection of the window.postMessage() transfer parameter improved
1 parent 3229b01 commit 4dd9d6a

File tree

4 files changed

+68
-3
lines changed

4 files changed

+68
-3
lines changed

src/changes/changes.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88

99
<body>
1010
<release version="4.17.0" date="October xx, 2025" description="Chrome/Edge 140, Firefox 142, css :has(), :is(), :where(), BroadcastChannel, Bugfixes">
11+
<action type="fix" dev="rbri">
12+
Detection of the window.postMessage() transfer parameter improved.
13+
</action>
1114
<action type="remove" dev="rbri">
1215
Deprecated methods HTMLParser.parse(WebResponse, HtmlPage, boolean, boolean),
1316
HTMLParser.parseFragment(DomNode, DomNode, String, boolean),

src/main/java/org/htmlunit/javascript/JavaScriptEngine.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1394,6 +1394,15 @@ public static boolean isNaN(final Object obj) {
13941394
return ScriptRuntime.isNaN(obj);
13951395
}
13961396

1397+
/**
1398+
* @param obj the value to check
1399+
* @return whether obj is an Array
1400+
*/
1401+
public static boolean isArray(final Object obj) {
1402+
return (obj instanceof Scriptable)
1403+
&& "Array".equals(((Scriptable) obj).getClassName());
1404+
}
1405+
13971406
/**
13981407
* @return the top call scope
13991408
*/

src/main/java/org/htmlunit/javascript/host/Window.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1969,13 +1969,21 @@ public static void postMessage(final Context context, final Scriptable scope,
19691969
final Object message = args[0];
19701970

19711971
String targetOrigin = "*";
1972+
Object transfer = JavaScriptEngine.UNDEFINED;
1973+
19721974
if (args.length > 1) {
1973-
targetOrigin = JavaScriptEngine.toString(args[1]);
1975+
if (JavaScriptEngine.isArray(args[1])) {
1976+
transfer = args[1];
1977+
}
1978+
else {
1979+
targetOrigin = JavaScriptEngine.toString(args[1]);
1980+
}
19741981
}
19751982

1976-
Object transfer = JavaScriptEngine.UNDEFINED;
19771983
if (args.length > 2) {
1978-
transfer = args[2];
1984+
if (JavaScriptEngine.isArray(args[2])) {
1985+
transfer = args[2];
1986+
}
19791987
}
19801988

19811989
final Window sender = (Window) scope;

src/test/java/org/htmlunit/javascript/host/WindowPostMessageTest.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,51 @@ public void postMessageWithoutTargetOrigin() throws Exception {
182182
loadPageVerifyTitle2(html);
183183
}
184184

185+
/**
186+
* @throws Exception if the test fails
187+
*/
188+
@Test
189+
@Alerts({"type: message", "bubbles: false", "cancelable: false", "data: hello",
190+
"origin: ", "source: false true", "lastEventId: "})
191+
public void postMessageWithTransferableOnly() throws Exception {
192+
final String[] expectedAlerts = getExpectedAlerts();
193+
expectedAlerts[4] += "http://localhost:" + PORT;
194+
setExpectedAlerts(expectedAlerts);
195+
196+
final String html = DOCTYPE_HTML
197+
+ "<html>\n"
198+
+ "<head></head>\n"
199+
+ "<body>\n"
200+
+ " <iframe id='myFrame' src='" + URL_THIRD + "'></iframe>\n"
201+
202+
+ "<script>\n"
203+
+ LOG_TITLE_FUNCTION
204+
+ " var win = document.getElementById('myFrame').contentWindow;\n"
205+
206+
+ " function receiveMessage(event) {\n"
207+
+ " log('type: ' + event.type);\n"
208+
+ " log('bubbles: ' + event.bubbles);\n"
209+
+ " log('cancelable: ' + event.cancelable);\n"
210+
+ " log('data: ' + event.data);\n"
211+
+ " log('origin: ' + event.origin);\n"
212+
+ " log('source: ' + (event.source === win) + ' ' + (event.source === window));\n"
213+
+ " log('lastEventId: ' + event.lastEventId);\n"
214+
+ " }\n"
215+
216+
+ " win.addEventListener('message', receiveMessage, false);\n"
217+
218+
+ " uInt8Array = new Uint8Array(1);\n"
219+
+ " win.postMessage('hello', [uInt8Array.buffer]);\n"
220+
+ "</script>\n"
221+
+ "</body></html>";
222+
223+
final String iframe = DOCTYPE_HTML
224+
+ "<html><body><p>inside frame</p></body></html>";
225+
226+
getMockWebConnection().setResponse(URL_THIRD, iframe);
227+
loadPageVerifyTitle2(html);
228+
}
229+
185230
/**
186231
* Test for #1589 NullPointerException because of missing context.
187232
*

0 commit comments

Comments
 (0)