Bug 1371741 - Test getUserMedia in sandboxed srcdoc, blob, data and regular iframes. draft
authorJan-Ivar Bruaroey <jib@mozilla.com>
Fri, 09 Jun 2017 20:10:56 -0400
changeset 592822 52ef199d77fcf8c8b89763df2ed1c79c7c44535a
parent 591912 a7806c834d16e43c32eb5dd7f3db37f6931cb208
child 632933 3dc0e905ad202bea9b43853c37136aa645e6a197
push id63506
push userjbruaroey@mozilla.com
push dateMon, 12 Jun 2017 19:34:10 +0000
bugs1371741
milestone55.0a1
Bug 1371741 - Test getUserMedia in sandboxed srcdoc, blob, data and regular iframes. MozReview-Commit-ID: GUtY5bJy192
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
   !/dom/canvas/test/captureStream_common.js
   !/dom/canvas/test/webgl-mochitest/webgl-util.js
   !/dom/media/test/manifest.js
@@ -34,18 +36,16 @@ skip-if = android_version == '18' # andr
 skip-if = toolkit == 'android'  # Bug 1189784
 [test_dataChannel_basicDataOnly.html]
 [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_noOffer.html]
 [test_enumerateDevices.html]
-[test_enumerateDevices_iframe.html]
-skip-if = true # needed by test_enumerateDevices.html on builders
 [test_ondevicechange.html]
 skip-if = os == 'android'
 [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' # android(Bug 1189784, timeouts on 4.3 emulator)
 [test_getUserMedia_addtrack_removetrack_events.html]
@@ -69,16 +69,17 @@ skip-if = toolkit == 'android' # no wind
 skip-if = android_version == '18' # android(Bug 1189784, timeouts on 4.3 emulator)
 [test_getUserMedia_mediaElementCapture_tracks.html]
 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]
 [test_getUserMedia_mediaStreamConstructors.html]
 [test_getUserMedia_mediaStreamTrackClone.html]
+[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_stopAudioStream.html]
 [test_getUserMedia_stopAudioStreamWithFollowupAudio.html]
new file mode 100644
--- /dev/null
+++ b/dom/media/tests/mochitest/test_getUserMedia_permission.html
@@ -0,0 +1,88 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <script src="mediaStreamPlayback.js"></script>
+</head>
+<body>
+<pre id="test">
+<iframe id="iframeSrcdoc" srcdoc="
+  <script type='application/javascript'>
+  var gUM = c => navigator.mediaDevices.getUserMedia(c);
+  (async () => {
+    let message;
+    try {
+      let stream = await gUM({ video: true });
+      message = 'success';
+    } catch(e) {
+      message = e.name;
+    }
+    parent.postMessage(message, 'http://mochi.test:8888');
+  })().catch(e => setTimeout(() => { throw e; }));
+  </script>">
+</iframe>
+<script type="application/javascript">
+createHTML({ title: "Test getUserMedia in iframes", bug: "1371741" });
+/**
+  Tests covering enumerateDevices API and deviceId constraint. Exercise code.
+*/
+
+let once = (t, msg) => new Promise(r => t.addEventListener(msg, r, { once: true }));
+
+// 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);
+
+  let 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";
+
+  // Test gUM in sandboxed vs. regular iframe.
+
+  for (origin of ["http://mochi.test:8888", "http://test1.mochi.test:8888"]) {
+    let src = origin + path;
+    is(await iframeGum({ src, sandbox: "allow-scripts" }),
+       "SecurityError", "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
+
+  is(await iframeGum({ sandbox: "allow-scripts" }, iframeSrcdoc),
+     "SecurityError", "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
+
+  var blob = new Blob([iframeSrcdoc.srcdoc], {type : 'text/html'});
+	let src = URL.createObjectURL(blob);
+  is(await iframeGum({ src, sandbox: "allow-scripts" }),
+     "SecurityError", "gUM fails in sandboxed blob iframe");
+  is(await iframeGum({ src, sandbox: "allow-scripts allow-same-origin " + origin }),
+     "success", "gUM works in regular blob iframe");
+  URL.revokeObjectURL(src);
+
+  // Test gUM in sandboxed vs regular data iframe
+
+  src = `data:text/html;base64,ICA8c2NyaXB0IHR5cGU9J2FwcGxpY2F0aW9uL2phdmFzY3JpcHQnPg0KICB2YXIgZ1VNID0gYyA9PiBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYShjKTsNCiAgKGFzeW5jICgpID0+IHsNCiAgICBsZXQgbWVzc2FnZTsNCiAgICB0cnkgew0KICAgICAgbGV0IHN0cmVhbSA9IGF3YWl0IGdVTSh7IHZpZGVvOiB0cnVlIH0pOw0KICAgICAgbWVzc2FnZSA9ICdzdWNjZXNzJzsNCiAgICB9IGNhdGNoKGUpIHsNCiAgICAgIG1lc3NhZ2UgPSBlLm5hbWU7DQogICAgfQ0KICAgIHBhcmVudC5wb3N0TWVzc2FnZShtZXNzYWdlLCAnaHR0cDovL21vY2hpLnRlc3Q6ODg4OCcpOw0KICB9KSgpLmNhdGNoKGUgPT4gc2V0VGltZW91dCgoKSA9PiB7IHRocm93IGU7IH0pKTsNCiAgPC9zY3JpcHQ+Ij4NCg==`;
+  is(await iframeGum({ src, sandbox: "allow-scripts" }),
+     "SecurityError", "gUM fails in sandboxed data iframe");
+  is(await iframeGum({ src, sandbox: "allow-scripts allow-same-origin " + origin }),
+     "success", "gUM works 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,25 @@
+<!DOCTYPE HTML>
+<html>
+<body>
+<pre id="test">
+<script type="application/javascript">
+/**
+  Runs inside iframe in test_getUserMedia_permission.html.
+*/
+
+var gUM = c => navigator.mediaDevices.getUserMedia(c);
+
+(async () => {
+  let message;
+  try {
+    let stream = await gUM({ video: true });
+    message = "success";
+  } catch(e) {
+    message = e.name;
+  }
+  parent.postMessage(message, "http://mochi.test:8888");
+})().catch(e => setTimeout(() => { throw e; }));
+</script>
+</pre>
+</body>
+</html>