Bug 1176941 - Capturing more error info from IdP sandbox, r=jib
authorMartin Thomson <martin.thomson@gmail.com>
Fri, 28 Aug 2015 15:40:44 -0700
changeset 296601 c4595abfd436b11fd33ddcdb3f63e634543c0115
parent 296600 ceb030473647d4ee4079d4a6d6d08ddc21d4a50f
child 296602 9a5fd09d1589e8d37c1db651896f5a2e480d9e5d
push id962
push userjlund@mozilla.com
push dateFri, 04 Dec 2015 23:28:54 +0000
treeherdermozilla-release@23a2d286e80f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjib
bugs1176941
milestone43.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 1176941 - Capturing more error info from IdP sandbox, r=jib
dom/media/IdpSandbox.jsm
dom/media/tests/mochitest/identity/idp-bad.js
dom/media/tests/mochitest/identity/mochitest.ini
dom/media/tests/mochitest/identity/test_getIdentityAssertion.html
dom/media/tests/mochitest/identity/test_idpproxy.html
--- a/dom/media/IdpSandbox.jsm
+++ b/dom/media/IdpSandbox.jsm
@@ -213,19 +213,35 @@ IdpSandbox.prototype = {
     let registrar = this.sandbox.rtcIdentityProvider;
     if (!Cu.isXrayWrapper(registrar)) {
       throw new Error('IdP setup failed');
     }
 
     // have to use the ultimate URI, not the starting one to avoid
     // that origin stealing from the one that redirected to it
     this._populateSandbox(result.request.URI);
-    // putting a javascript version of 1.8 here seems fragile
-    Cu.evalInSandbox(result.data, this.sandbox,
-                     '1.8', result.request.URI.spec, 1);
+    try {
+      Cu.evalInSandbox(result.data, this.sandbox,
+                       'latest', result.request.URI.spec, 1);
+    } catch (e) {
+      if (e.name === 'IdpError' || e.name === 'IdpLoginError') {
+        throw e;
+      }
+      // Capture all the details from the error and log them to the console.
+      // This can't rethrow anything else because that could leak information
+      // about the internal workings of the IdP across origins.
+      let scriptErrorClass = Cc["@mozilla.org/scripterror;1"];
+      let scriptError = scriptErrorClass.createInstance(Ci.nsIScriptError);
+      scriptError.init(e.message, e.fileName, null, e.lineNumber, e.columnNumber,
+                       Ci.nsIScriptError.errorFlag, "content javascript");
+      let consoleService = Cc['@mozilla.org/consoleservice;1']
+          .getService(Ci.nsIConsoleService);
+      consoleService.logMessage(scriptError);
+      throw new Error('Error in IdP, check console for details');
+    }
 
     if (!registrar.idp) {
       throw new Error('IdP failed to call rtcIdentityProvider.register()');
     }
     return registrar;
   },
 
   stop: function() {
new file mode 100644
--- /dev/null
+++ b/dom/media/tests/mochitest/identity/idp-bad.js
@@ -0,0 +1,1 @@
+<This isn't valid JS>
--- a/dom/media/tests/mochitest/identity/mochitest.ini
+++ b/dom/media/tests/mochitest/identity/mochitest.ini
@@ -16,16 +16,17 @@ support-files =
   /.well-known/idp-proxy/idp-redirect-http-trick.js^headers^
   /.well-known/idp-proxy/idp-redirect-https.js
   /.well-known/idp-proxy/idp-redirect-https.js^headers^
   /.well-known/idp-proxy/idp-redirect-https-double.js
   /.well-known/idp-proxy/idp-redirect-https-double.js^headers^
   /.well-known/idp-proxy/idp-redirect-https-odd-path.js
   /.well-known/idp-proxy/idp-redirect-https-odd-path.js^headers^
   /.well-known/idp-min.js
+  /.well-known/idp-proxy/idp-bad.js
 
 [test_fingerprints.html]
 [test_getIdentityAssertion.html]
 [test_setIdentityProvider.html]
 [test_setIdentityProviderWithErrors.html]
 [test_peerConnection_peerIdentity.html]
 [test_peerConnection_asymmetricIsolation.html]
 [test_loginNeeded.html]
--- a/dom/media/tests/mochitest/identity/test_getIdentityAssertion.html
+++ b/dom/media/tests/mochitest/identity/test_getIdentityAssertion.html
@@ -33,16 +33,26 @@ function theTest() {
   test.chain.removeAfter('PC_REMOTE_CHECK_INITIAL_SIGNALINGSTATE');
   test.chain.append([
     function PC_LOCAL_IDENTITY_ASSERTION_FAILS_WITHOUT_PROVIDER(t) {
       return t.pcLocal._pc.getIdentityAssertion()
         .then(a => ok(false, 'should fail without provider'),
               e => ok(e, 'should fail without provider'));
     },
 
+    function PC_LOCAL_IDENTITY_ASSERTION_FAILS_WITH_BAD_PROVIDER(t) {
+      t.pcLocal._pc.setIdentityProvider('example.com', 'idp-bad.js', '');
+      return t.pcLocal._pc.getIdentityAssertion()
+        .then(a => ok(false, 'should fail with bad provider'),
+              e => {
+                is(e.name, 'IdpError', 'should fail with bad provider');
+                ok(e.message, 'should include a nice message');
+              });
+    },
+
     function PC_LOCAL_GET_TWO_ASSERTIONS(t) {
       return Promise.all([
         getAssertion(t, ''),
         getAssertion(t, '')
       ]).then(assertions => {
         is(assertions.length, 2, "Two assertions generated");
         assertions.forEach(a => checkIdentity(a, 'someone@example.com'));
       });
--- a/dom/media/tests/mochitest/identity/test_idpproxy.html
+++ b/dom/media/tests/mochitest/identity/test_idpproxy.html
@@ -121,16 +121,22 @@ function test_redirect_ok(from) {
 function test_redirect_fail(from) {
   return () => {
     return makeSandbox(from)
       .then(() => ok(false, 'Redirect to https should fail'),
             e => ok(e, 'Redirect to https should fail'));
   };
 }
 
+function test_bad_js() {
+  return makeSandbox('idp-bad.js')
+    .then(() => ok(false, 'Bad JS should not load'),
+          e => ok(e, 'Bad JS should not load'));
+}
+
 function run_all_tests() {
   [
     test_domain_sandbox,
     test_protocol_sandbox,
     test_generate_assertion,
     test_validate_assertion,
 
     // fail of the IdP fails
@@ -146,17 +152,19 @@ function run_all_tests() {
     // Two redirects is fine too
     test_redirect_ok('idp-redirect-https-double.js'),
     // A secure redirect to a path other than /.well-known/idp-proxy/* should
     // also work fine.
     test_redirect_ok('idp-redirect-https-odd-path.js'),
     // A redirect to HTTP is not-cool
     test_redirect_fail('idp-redirect-http.js'),
     // Also catch tricks like https->http->https
-    test_redirect_fail('idp-redirect-http-trick.js')
+    test_redirect_fail('idp-redirect-http-trick.js'),
+
+    test_bad_js
   ].reduce((p, test) => {
     return p.then(test)
       .catch(e => ok(false, test.name + ' failed: ' +
                      SpecialPowers.wrap(e).message + '\n' +
                      SpecialPowers.wrap(e).stack));
   }, Promise.resolve())
     .then(() => SimpleTest.finish());
 }