Bug 1371741 - Test getUserMedia in sandboxed srcdoc, blob, data and regular iframes. r=jib
authorJohann Hofmann <jhofmann@mozilla.com>
Fri, 11 Jan 2019 10:50:08 +0000
changeset 513450 10f070a6edc0ebb8dabdc8a96fdbc92b249acaaa
parent 513449 12ad92939684c46011a669702252bca382e33a58
child 513451 897f95b6d3fcfe4f15f4901f9dbb713d0e7430d9
push id1953
push userffxbld-merge
push dateMon, 11 Mar 2019 12:10:20 +0000
treeherdermozilla-release@9c35dcbaa899 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjib
bugs1371741
milestone66.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1371741 - Test getUserMedia in sandboxed srcdoc, blob, data and regular iframes. r=jib Differential Revision: https://phabricator.services.mozilla.com/D16221
dom/media/tests/mochitest/mochitest.ini
dom/media/tests/mochitest/test_getUserMedia_permission.html
dom/media/tests/mochitest/test_getUserMedia_permission_iframe.html
--- a/dom/media/tests/mochitest/mochitest.ini
+++ b/dom/media/tests/mochitest/mochitest.ini
@@ -4,16 +4,18 @@ subsuite = media
 support-files =
   head.js
   dataChannel.js
   mediaStreamPlayback.js
   network.js
   nonTrickleIce.js
   pc.js
   templates.js
+  test_enumerateDevices_iframe.html
+  test_getUserMedia_permission_iframe.html
   NetworkPreparationChromeScript.js
   blacksilence.js
   turnConfig.js
   sdpUtils.js
   addTurnsSelfsignedCert.js
   parser_rtp.js
   peerconnection_audio_forced_sample_rate.js
   !/dom/canvas/test/captureStream_common.js
@@ -39,18 +41,16 @@ skip-if = toolkit == 'android'  # Bug 11
 [test_dataChannel_basicVideo.html]
 skip-if = android_version == '18' # android(Bug 1189784, timeouts on 4.3 emulator)
 [test_dataChannel_bug1013809.html]
 skip-if = android_version == '18' # android(Bug 1189784, timeouts on 4.3 emulator)
 [test_dataChannel_dataOnlyBufferedAmountLow.html]
 skip-if = android_version == '18' # android(Bug 1189784, timeouts on 4.3 emulator)
 [test_dataChannel_noOffer.html]
 [test_enumerateDevices.html]
-[test_enumerateDevices_iframe.html]
-skip-if = true # needed by test_enumerateDevices.html on builders
 [test_enumerateDevices_navigation.html]
 [test_ondevicechange.html]
 skip-if = os == 'android' || verify
 [test_getUserMedia_active_autoplay.html]
 [test_getUserMedia_audioCapture.html]
 skip-if = toolkit == 'android' # android(Bug 1189784, timeouts on 4.3 emulator), android(Bug 1264333)
 [test_getUserMedia_addTrackRemoveTrack.html]
 skip-if = android_version == '18' || os == 'linux' # android(Bug 1189784, timeouts on 4.3 emulator), linux bug 1377450
@@ -92,16 +92,17 @@ skip-if = android_version == '18' # andr
 skip-if = android_version == '18' # android(Bug 1189784, timeouts on 4.3 emulator)
 [test_getUserMedia_mediaElementCapture_video.html]
 skip-if = android_version == '18' # android(Bug 1189784, timeouts on 4.3 emulator)
 [test_getUserMedia_mediaStreamClone.html]
 skip-if = android_version == '18' # android(Bug 1189784, timeouts on 4.3 emulator)
 [test_getUserMedia_mediaStreamConstructors.html]
 [test_getUserMedia_mediaStreamTrackClone.html]
 skip-if = android_version == '18' # android(Bug 1189784, timeouts on 4.3 emulator)
+[test_getUserMedia_permission.html]
 [test_getUserMedia_playAudioTwice.html]
 [test_getUserMedia_playVideoAudioTwice.html]
 [test_getUserMedia_playVideoTwice.html]
 [test_getUserMedia_scarySources.html]
 skip-if = toolkit == 'android' # no screenshare or windowshare on android
 [test_getUserMedia_spinEventLoop.html]
 [test_getUserMedia_trackCloneCleanup.html]
 [test_getUserMedia_trackEnded.html]
new file mode 100644
--- /dev/null
+++ b/dom/media/tests/mochitest/test_getUserMedia_permission.html
@@ -0,0 +1,96 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <script src="mediaStreamPlayback.js"></script>
+</head>
+<body>
+<pre id="test">
+<script type="application/javascript">
+createHTML({ title: "Test getUserMedia in iframes", bug: "1371741" });
+/**
+  Tests covering enumerateDevices API and deviceId constraint. Exercise code.
+*/
+
+// Call gUM in iframe.
+async function iframeGum(dict, iframe = document.createElement("iframe")) {
+  Object.assign(iframe, dict);
+  if (dict.src) {
+    info(`<iframe src="${dict.src}" sandbox="${dict.sandbox}">`);
+  } else {
+    info(`<iframe srcdoc sandbox="${dict.sandbox}">`);
+  }
+  document.documentElement.appendChild(iframe);
+
+  const once = (t, msg) => new Promise(r => t.addEventListener(msg, r, { once: true }));
+  const haveMessage = once(window, "message");
+  await new Promise(resolve => iframe.onload = resolve);
+  return (await haveMessage).data;
+};
+
+runTest(async () => {
+  const path = "/tests/dom/media/tests/mochitest/test_getUserMedia_permission_iframe.html";
+
+  async function sourceFn() {
+    try {
+      const gUM = c => navigator.mediaDevices.getUserMedia(c);
+      let message;
+      let stream;
+      try {
+        stream = await gUM({ video: true });
+        message = 'success';
+      } catch(e) {
+        message = e.name;
+      }
+      parent.postMessage(message, 'http://mochi.test:8888');
+
+      if (message == "success") {
+        stream.getTracks().forEach(track => track.stop());
+      }
+    } catch (e) {
+      setTimeout(() => { throw e; });
+    }
+  }
+
+  const source = `<html\><script\>(${sourceFn.toString()})()</script\></html\>`;
+
+  // Test gUM in sandboxed vs. regular iframe.
+
+  for (const origin of ["http://mochi.test:8888", "https://example.com", "http://test1.mochi.test:8888"]) {
+    const src = origin + path;
+    is(await iframeGum({ src, sandbox: "allow-scripts" }),
+       "NotAllowedError", "gUM fails in sandboxed iframe " + origin);
+    is(await iframeGum({ src, sandbox: "allow-scripts allow-same-origin " + origin }),
+       "success", "gUM works in regular iframe");
+  }
+
+  // Test gUM in sandboxed vs regular srcdoc iframe
+
+  const iframeSrcdoc = document.createElement("iframe");
+  iframeSrcdoc.srcdoc = source;
+  is(await iframeGum({ sandbox: "allow-scripts" }, iframeSrcdoc),
+     "NotAllowedError", "gUM fails in sandboxed srcdoc iframe");
+  is(await iframeGum({ sandbox: "allow-scripts allow-same-origin" }, iframeSrcdoc),
+     "success", "gUM works in regular srcdoc iframe");
+
+  // Test gUM in sandboxed vs regular blob iframe
+
+  const blob = new Blob([source], {type : "text/html"});
+	let src = URL.createObjectURL(blob);
+  is(await iframeGum({ src, sandbox: "allow-scripts" }),
+     "NotAllowedError", "gUM fails in sandboxed blob iframe");
+  is(await iframeGum({ src, sandbox: "allow-scripts allow-same-origin"}),
+     "success", "gUM works in regular blob iframe");
+  URL.revokeObjectURL(src);
+
+  // data iframes always have null-principals
+
+  src = `data:text/html;base64,${btoa(source)}`;
+  is(await iframeGum({ src, sandbox: "allow-scripts" }),
+     "NotAllowedError", "gUM fails in sandboxed data iframe");
+  is(await iframeGum({ src, sandbox: "allow-scripts allow-same-origin"}),
+     "NotAllowedError", "gUM fails in regular data iframe");
+});
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/media/tests/mochitest/test_getUserMedia_permission_iframe.html
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML>
+<html>
+<body>
+<pre id="test">
+<script type="application/javascript">
+/**
+  Runs inside iframe in test_getUserMedia_permission.html.
+*/
+
+const gUM = c => navigator.mediaDevices.getUserMedia(c);
+
+(async () => {
+  let message;
+  let stream;
+  try {
+    stream = await gUM({ video: true });
+    message = "success";
+  } catch(e) {
+    message = e.name;
+  }
+  parent.postMessage(message, "http://mochi.test:8888");
+
+  if (message == "success") {
+    stream.getTracks().forEach(track => track.stop());
+  }
+})().catch(e => setTimeout(() => { throw e; }));
+</script>
+</pre>
+</body>
+</html>