Bug 1277475 Part 3: Ensure marquee attribute event handlers don't run when sandboxed scripts flag is set on its owning Document. r=bz, a=sylvestre
authorBob Owen <bobowencode@gmail.com>
Thu, 09 Jun 2016 11:22:23 +0100
changeset 335383 3ce597865e498558b7a9cade56cfd63e0217dc2d
parent 335382 ab01099ea2a55fde40e63275ab3b30fe97a4b12e
child 335384 8ca1f953645f537692e62bb7e2d568d5f5f62eb7
push id1146
push userCallek@gmail.com
push dateMon, 25 Jul 2016 16:35:44 +0000
treeherdermozilla-release@a55778f9cd5a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz, sylvestre
bugs1277475
milestone48.0
Bug 1277475 Part 3: Ensure marquee attribute event handlers don't run when sandboxed scripts flag is set on its owning Document. r=bz, a=sylvestre MozReview-Commit-ID: 4vWafBniv4R
docshell/test/iframesandbox/file_marquee_event_handlers.html
docshell/test/iframesandbox/mochitest.ini
docshell/test/iframesandbox/test_marquee_event_handlers.html
new file mode 100644
--- /dev/null
+++ b/docshell/test/iframesandbox/file_marquee_event_handlers.html
@@ -0,0 +1,17 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Test marquee attribute event handlers in iframe sandbox</title>
+</head>
+<body>
+  <!-- Note that the width here is slightly longer than the contents, to make
+       sure we bounce and finish very quickly. -->
+  <marquee loop="2" width="145" behavior="alternate" truespeed scrolldelay="1"
+    onstart="parent.postMessage(window.name + ' marquee onstart', '*');"
+    onbounce="parent.postMessage(window.name + ' marquee onbounce', '*');"
+    onfinish="parent.postMessage(window.name + ' marquee onfinish', '*');">
+    Will bounce and finish
+  </marquee>
+</body>
+</html>
--- a/docshell/test/iframesandbox/mochitest.ini
+++ b/docshell/test/iframesandbox/mochitest.ini
@@ -1,18 +1,20 @@
 [DEFAULT]
 support-files =
+  file_marquee_event_handlers.html
   file_other_auxiliary_navigation_by_location.html
   file_our_auxiliary_navigation_by_location.html
   file_parent_navigation_by_location.html
   file_sibling_navigation_by_location.html
   file_top_navigation_by_location.html
   file_top_navigation_by_location_exotic.html
 
 [test_child_navigation_by_location.html]
+[test_marquee_event_handlers.html]
 [test_other_auxiliary_navigation_by_location.html]
 skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #bug 948948, NS_ERROR_FAILURE from nsWindowWatcher::GetPrompt
 [test_our_auxiliary_navigation_by_location.html]
 skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #bug 948948, NS_ERROR_FAILURE from nsWindowWatcher::GetPrompt
 [test_parent_navigation_by_location.html]
 [test_sibling_navigation_by_location.html]
 [test_top_navigation_by_location_exotic.html]
 skip-if = (buildapp == 'b2g' && toolkit != 'gonk') || android_version == '18' #bug 948948, NS_ERROR_FAILURE from nsWindowWatcher::GetPrompt
new file mode 100644
--- /dev/null
+++ b/docshell/test/iframesandbox/test_marquee_event_handlers.html
@@ -0,0 +1,95 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1277475
+html5 sandboxed iframe should not run marquee attribute event handlers without allow-scripts
+-->
+<head>
+<meta charset="utf-8">
+<title>Test for Bug 1277475 - html5 sandboxed iframe should not run marquee attribute event handlers without allow-scripts</title>
+<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1277475">Mozilla Bug 1277475</a>
+<p id="display"></p>
+<div id="content">Tests for Bug 1277475</div>
+
+<iframe id="if1" name="if1" src="file_marquee_event_handlers.html"
+   sandbox="allow-same-origin allow-forms allow-top-navigation allow-pointer-lock allow-orientation-lock allow-popups allow-modals allow-popups-to-escape-sandbox">
+</iframe>
+
+<iframe id="if2" name="if2" src="file_marquee_event_handlers.html"
+   sandbox="allow-scripts"></iframe>
+
+<script>
+  SimpleTest.waitForExplicitFinish();
+
+  var expectedMessages = new Set();
+  var numberOfMessagesExpected = 4;
+  var unexpectedMessages = new Set();
+
+  window.onmessage = function (event) {
+    info(event.data + " message received");
+    if (event.data.startsWith("if2") || event.data == "if1 chaser") {
+      expectedMessages.add(event.data);
+      if (expectedMessages.size == numberOfMessagesExpected) {
+        checkRecievedMessages();
+      }
+    } else {
+      unexpectedMessages.add(event.data);
+    }
+  }
+
+  function checkRecievedMessages() {
+    // Check the expected messages explicitly as a cross-check.
+    ok(expectedMessages.has("if1 chaser"),
+       "if1 chaser message should have been received");
+    ok(expectedMessages.has("if2 marquee onstart"),
+       "if2 marquee onstart should have run in iframe sandbox with allow-scripts");
+    ok(expectedMessages.has("if2 marquee onbounce"),
+       "if2 marquee onbounce should have run in iframe sandbox with allow-scripts");
+    ok(expectedMessages.has("if2 marquee onfinish"),
+       "if2 marquee onfinish should have run in iframe sandbox with allow-scripts");
+
+    unexpectedMessages.forEach(
+      (v) => {
+        ok(false, v + " should NOT have run in iframe sandbox without allow-scripts")
+      }
+    );
+
+    SimpleTest.finish();
+  }
+
+  // If things are working properly the attribute event handlers won't run on
+  // the marquee in if1, so add our own capturing listeners on its window, so we
+  // know when they have fired. (These will run as we are not sandboxed.)
+  var if1FiredEvents = new Set();
+  var if1NumberOfEventsExpected = 3;
+  var if1Win = document.getElementById("if1").contentWindow;
+  if1Win.addEventListener("start", () => { checkMarqueeEvent("start"); }, true);
+  if1Win.addEventListener("bounce", () => { checkMarqueeEvent("bounce"); }, true);
+  if1Win.addEventListener("finish", () => { checkMarqueeEvent("finish"); }, true);
+
+  function checkMarqueeEvent(eventType) {
+    info("if1 event " + eventType + " fired");
+    if1FiredEvents.add(eventType);
+    if (if1FiredEvents.size == if1NumberOfEventsExpected) {
+      // Only send the chasing message after a tick of the event loop to allow
+      // event handlers on the marquee to process.
+      SimpleTest.executeSoon(sendChasingMessage);
+    }
+  }
+
+  function sendChasingMessage() {
+    // Add our own message listener to if1's window and echo back a chasing
+    // message to make sure that any messages from incorrectly run marquee
+    // attribute event handlers should have arrived before it.
+    if1Win.addEventListener("message",
+                            (e) => { if1Win.parent.postMessage(e.data, "*"); });
+    if1Win.postMessage("if1 chaser", "*");
+    info("if1 chaser message sent");
+  }
+</script>
+</body>
+</html>