Backed out changesets 5a3092c456c0,8dcbfd14f1e5 (bug 1218433) for M3, W3 failures and M10 failure on Android. r=backout
authorSebastian Hengst <archaeopteryx@coole-files.de>
Thu, 12 Nov 2015 18:44:51 +0100
changeset 308655 89f3fe7202921aaf81b78cc1287b5e99940dc85b
parent 308654 d34f0bd09295241efba3c390e0b0c1b612984f41
child 308656 309cf6675d4e3b36f7b6dac968cdcede47616294
push id7513
push useratolfsen@mozilla.com
push dateFri, 13 Nov 2015 14:03:43 +0000
reviewersbackout
bugs1218433
milestone45.0a1
backs out5a3092c456c0fe7fd9886e87b4ecf7119670476b
8dcbfd14f1e5555b8fb893b61bdaa1483649beab
Backed out changesets 5a3092c456c0,8dcbfd14f1e5 (bug 1218433) for M3, W3 failures and M10 failure on Android. r=backout * * * Backed out changeset 8dcbfd14f1e5 (bug 1218433) 462 INFO TEST-UNEXPECTED-FAIL | dom/security/test/csp/test_child-src_worker-redirect.html | CSP child-src worker test other-src-worker_redir-same - got "Error: Failed to load script (nsresult = 0x805e0006)", expected "blocked" 479 INFO TEST-UNEXPECTED-FAIL | dom/security/test/csp/test_child-src_worker.html | Test timed out. 486 INFO TEST-UNEXPECTED-FAIL | dom/security/test/csp/test_child-src_worker_data.html | Test timed out.
dom/html/test/file_iframe_sandbox_g_if1.html
dom/tests/mochitest/general/frameStoragePrevented.html
dom/workers/ScriptLoader.cpp
dom/workers/test/test_csp.js
dom/workers/test/test_loadError.html
testing/web-platform/meta/workers/constructors/SharedWorker/same-origin.html.ini
testing/web-platform/meta/workers/constructors/Worker/same-origin.html.ini
testing/web-platform/meta/workers/interfaces/WorkerUtils/importScripts/004.html.ini
testing/web-platform/meta/workers/interfaces/WorkerUtils/importScripts/006.html.ini
testing/web-platform/tests/content-security-policy/blink-contrib/self-doesnt-match-blob.sub.html
testing/web-platform/tests/content-security-policy/blink-contrib/star-doesnt-match-blob.sub.html
testing/web-platform/tests/content-security-policy/child-src/child-src-worker-blocked.sub.html
testing/web-platform/tests/mixed-content/generic/common.js
testing/web-platform/tests/workers/Worker_cross_origin_security_err.htm
testing/web-platform/tests/workers/constructors/SharedWorker/same-origin.html
testing/web-platform/tests/workers/constructors/Worker/same-origin.html
--- a/dom/html/test/file_iframe_sandbox_g_if1.html
+++ b/dom/html/test/file_iframe_sandbox_g_if1.html
@@ -37,19 +37,24 @@
       ok(true, "a worker in a sandboxed document should be able to be loaded from a blob URI " +
          "created by that sandboxed document");
     }, false);
 
     worker_blob.postMessage("engage!");
 
     // test loading with relative url - this should fail since we are
     // sandboxed and have a null principal
-    var worker_js = new Worker('file_iframe_sandbox_worker.js');
+    try {
+      var worker_js = new Worker('file_iframe_sandbox_worker.js');
+    } catch (e) {
+      ok(e.name === "SecurityError", "a worker in a sandboxed document should throw when loading from a relative URI");
+    }
+
     worker_js.onerror = function(error) {
-      ok(true, "a worker in a sandboxed document should tell the load error via error event");
+      ok(false, "a worker in a sandboxed document should not tell the load error via error event");
     }
 
     worker_js.addEventListener('message', function(event) {
       ok(false, "a worker in a sandboxed document should not be able to load from a relative URI");
     }, false);
 
     worker_js.postMessage('engage');
   }
--- a/dom/tests/mochitest/general/frameStoragePrevented.html
+++ b/dom/tests/mochitest/general/frameStoragePrevented.html
@@ -1,41 +1,29 @@
 
 <html xmlns="http://www.w3.org/1999/xhtml">
 <head>
 <title>frame for storage prevented test</title>
 
 <script type="text/javascript" src="https://example.com/tests/dom/tests/mochitest/general/storagePermissionsUtils.js"></script>
-<script  type="text/javascript;version=1.7">
+<script type="text/javascript">
 
   task(function* () {
     // We shouldn't be able to access storage
     yield storagePrevented();
 
     // This hash of the URI is set to #nullprincipal by the test if the current page has a null principal,
     // and thus attempting to create a dedicated worker will throw
     if (location.hash == "#nullprincipal") {
-      function createWorker() {
-        return new Promise((resolve, reject) => {
-          var w;
-          try {
-            w = new Worker("workerStoragePrevented.js");
-          } catch (e) {
-            ok(true, "Running workers was prevented");
-            resolve();
-          }
-
-          w.onerror = function() {
-            ok(true, "Running workers was prevented");
-            resolve();
-         }
-        });
+      try {
+        new Worker("workerStoragePrevented.js");
+        ok(false, "Running workers should not have been allowed");
+      } catch (e) {
+        ok(true, "Running workers was prevented");
       }
-
-      yield createWorker();
       return;
     }
 
     // Try to run a worker, which shouldn't be able to access storage
     yield runWorker("workerStoragePrevented.js");
   });
 
 </script>
--- a/dom/workers/ScriptLoader.cpp
+++ b/dom/workers/ScriptLoader.cpp
@@ -117,65 +117,79 @@ ChannelFromScriptURL(nsIPrincipal* princ
   nsCOMPtr<nsIURI> uri;
   rv = nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(uri),
                                                  aScriptURL, parentDoc,
                                                  baseURI);
   if (NS_FAILED(rv)) {
     return NS_ERROR_DOM_SYNTAX_ERR;
   }
 
-  aLoadFlags |= nsIChannel::LOAD_CLASSIFY_URI;
-  uint32_t secFlags = aIsMainScript ? nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED
-                                    : nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS;
+  int16_t shouldLoad = nsIContentPolicy::ACCEPT;
+  rv = NS_CheckContentLoadPolicy(aContentPolicyType, uri,
+                                 principal, parentDoc,
+                                 NS_LITERAL_CSTRING("text/javascript"),
+                                 nullptr, &shouldLoad,
+                                 nsContentUtils::GetContentPolicy(),
+                                 secMan);
+  if (NS_FAILED(rv) || NS_CP_REJECTED(shouldLoad)) {
+    if (NS_FAILED(rv) || shouldLoad != nsIContentPolicy::REJECT_TYPE) {
+      return rv = NS_ERROR_CONTENT_BLOCKED;
+    }
+    return rv = NS_ERROR_CONTENT_BLOCKED_SHOW_ALT;
+  }
 
   if (aWorkerScriptType == DebuggerScript) {
-    // A DebuggerScript needs to be a local resource like chrome: or resource:
-    bool isUIResource = false;
-    rv = NS_URIChainHasFlags(uri, nsIProtocolHandler::URI_IS_UI_RESOURCE,
-                             &isUIResource);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
+    bool isChrome = false;
+    NS_ENSURE_SUCCESS(uri->SchemeIs("chrome", &isChrome),
+                      NS_ERROR_DOM_SECURITY_ERR);
 
-    if (!isUIResource) {
+    bool isResource = false;
+    NS_ENSURE_SUCCESS(uri->SchemeIs("resource", &isResource),
+                      NS_ERROR_DOM_SECURITY_ERR);
+
+    if (!isChrome && !isResource) {
       return NS_ERROR_DOM_SECURITY_ERR;
     }
-
-    secFlags |= nsILoadInfo::SEC_ALLOW_CHROME;
+  } else if (aIsMainScript) {
+    // We pass true as the 3rd argument to checkMayLoad here.
+    // This allows workers in sandboxed documents to load data URLs
+    // (and other URLs that inherit their principal from their
+    // creator.)
+    rv = principal->CheckMayLoad(uri, false, true);
+    NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_SECURITY_ERR);
+  }
+  else {
+    rv = secMan->CheckLoadURIWithPrincipal(principal, uri, 0);
+    NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_SECURITY_ERR);
   }
 
-  // Note: this is for backwards compatibility and goes against spec.
-  // We should find a better solution.
-  bool isData = false;
-  if (aIsMainScript && NS_SUCCEEDED(uri->SchemeIs("data", &isData)) && isData) {
-    secFlags = nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL;
-  }
+  aLoadFlags |= nsIChannel::LOAD_CLASSIFY_URI;
 
   nsCOMPtr<nsIChannel> channel;
   // If we have the document, use it
   if (parentDoc) {
     rv = NS_NewChannel(getter_AddRefs(channel),
                        uri,
                        parentDoc,
-                       secFlags,
+                       nsILoadInfo::SEC_NORMAL,
                        aContentPolicyType,
                        loadGroup,
                        nullptr, // aCallbacks
                        aLoadFlags,
                        ios);
   } else {
     // We must have a loadGroup with a load context for the principal to
     // traverse the channel correctly.
     MOZ_ASSERT(loadGroup);
     MOZ_ASSERT(NS_LoadGroupMatchesPrincipal(loadGroup, principal));
 
     rv = NS_NewChannel(getter_AddRefs(channel),
                        uri,
                        principal,
-                       secFlags,
+                       nsILoadInfo::SEC_NORMAL,
                        aContentPolicyType,
                        loadGroup,
                        nullptr, // aCallbacks
                        aLoadFlags,
                        ios);
   }
 
   NS_ENSURE_SUCCESS(rv, rv);
@@ -467,61 +481,24 @@ private:
 
   RefPtr<ScriptLoaderRunnable> mRunnable;
   ScriptLoadInfo& mLoadInfo;
   uint32_t mIndex;
 };
 
 NS_IMPL_ISUPPORTS0(CachePromiseHandler)
 
-class LoaderListener final : public nsIStreamLoaderObserver
-                           , public nsIRequestObserver
-{
-public:
-  NS_DECL_ISUPPORTS
-
-  LoaderListener(ScriptLoaderRunnable* aRunnable, uint32_t aIndex)
-    : mRunnable(aRunnable)
-    , mIndex(aIndex)
-  {
-    MOZ_ASSERT(mRunnable);
-  }
-
-  NS_IMETHOD
-  OnStreamComplete(nsIStreamLoader* aLoader, nsISupports* aContext,
-                   nsresult aStatus, uint32_t aStringLen,
-                   const uint8_t* aString) override;
-
-  NS_IMETHOD
-  OnStartRequest(nsIRequest* aRequest, nsISupports* aContext) override;
-
-  NS_IMETHOD
-  OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
-                nsresult aStatusCode) override
-  {
-    // Nothing to do here!
-    return NS_OK;
-  }
-
-private:
-  ~LoaderListener() {}
-
-  RefPtr<ScriptLoaderRunnable> mRunnable;
-  uint32_t mIndex;
-};
-
-NS_IMPL_ISUPPORTS(LoaderListener, nsIStreamLoaderObserver, nsIRequestObserver)
-
-class ScriptLoaderRunnable final : public WorkerFeature
-                                 , public nsIRunnable
+class ScriptLoaderRunnable final : public WorkerFeature,
+                                   public nsIRunnable,
+                                   public nsIStreamLoaderObserver,
+                                   public nsIRequestObserver
 {
   friend class ScriptExecutorRunnable;
   friend class CachePromiseHandler;
   friend class CacheScriptLoader;
-  friend class LoaderListener;
 
   WorkerPrivate* mWorkerPrivate;
   nsCOMPtr<nsIEventTarget> mSyncLoopTarget;
   nsTArray<ScriptLoadInfo> mLoadInfos;
   RefPtr<CacheCreator> mCacheCreator;
   nsCOMPtr<nsIInputStream> mReader;
   bool mIsMainScript;
   WorkerScriptType mWorkerScriptType;
@@ -589,37 +566,55 @@ private:
 
     // We execute the last step if we don't have a pending operation with the
     // cache and the loading is completed.
     if (loadInfo.Finished()) {
       ExecuteFinishedScripts();
     }
   }
 
-  nsresult
-  OnStreamComplete(nsIStreamLoader* aLoader, uint32_t aIndex,
+  NS_IMETHOD
+  OnStreamComplete(nsIStreamLoader* aLoader, nsISupports* aContext,
                    nsresult aStatus, uint32_t aStringLen,
-                   const uint8_t* aString)
+                   const uint8_t* aString) override
   {
     AssertIsOnMainThread();
-    MOZ_ASSERT(aIndex < mLoadInfos.Length());
+
+    nsCOMPtr<nsISupportsPRUint32> indexSupports(do_QueryInterface(aContext));
+    NS_ASSERTION(indexSupports, "This should never fail!");
 
-    nsresult rv = OnStreamCompleteInternal(aLoader, aStatus, aStringLen,
-                                           aString, mLoadInfos[aIndex]);
-    LoadingFinished(aIndex, rv);
+    uint32_t index = UINT32_MAX;
+    if (NS_FAILED(indexSupports->GetData(&index)) ||
+        index >= mLoadInfos.Length()) {
+      NS_ERROR("Bad index!");
+    }
+
+    ScriptLoadInfo& loadInfo = mLoadInfos[index];
+
+    nsresult rv = OnStreamCompleteInternal(aLoader, aContext, aStatus,
+                                           aStringLen, aString, loadInfo);
+    LoadingFinished(index, rv);
     return NS_OK;
   }
 
-  nsresult
-  OnStartRequest(nsIRequest* aRequest, uint32_t aIndex)
+  NS_IMETHOD
+  OnStartRequest(nsIRequest* aRequest, nsISupports* aContext) override
   {
     AssertIsOnMainThread();
-    MOZ_ASSERT(aIndex < mLoadInfos.Length());
+
+    nsCOMPtr<nsISupportsPRUint32> indexSupports(do_QueryInterface(aContext));
+    MOZ_ASSERT(indexSupports, "This should never fail!");
 
-    ScriptLoadInfo& loadInfo = mLoadInfos[aIndex];
+    uint32_t index = UINT32_MAX;
+    if (NS_FAILED(indexSupports->GetData(&index)) ||
+        index >= mLoadInfos.Length()) {
+      MOZ_CRASH("Bad index!");
+    }
+
+    ScriptLoadInfo& loadInfo = mLoadInfos[index];
 
     nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
     MOZ_ASSERT(channel == loadInfo.mChannel);
 
     // We synthesize the result code, but its never exposed to content.
     RefPtr<mozilla::dom::InternalResponse> ir =
       new mozilla::dom::InternalResponse(200, NS_LITERAL_CSTRING("OK"));
     ir->SetBody(mReader);
@@ -663,25 +658,33 @@ private:
       mCacheCreator->Cache_()->Put(request, *response, error);
     if (NS_WARN_IF(error.Failed())) {
       nsresult rv = error.StealNSResult();
       channel->Cancel(rv);
       return rv;
     }
 
     RefPtr<CachePromiseHandler> promiseHandler =
-      new CachePromiseHandler(this, loadInfo, aIndex);
+      new CachePromiseHandler(this, loadInfo, index);
     cachePromise->AppendNativeHandler(promiseHandler);
 
     loadInfo.mCachePromise.swap(cachePromise);
     loadInfo.mCacheStatus = ScriptLoadInfo::WritingToCache;
 
     return NS_OK;
   }
 
+  NS_IMETHOD
+  OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
+                nsresult aStatusCode) override
+  {
+    // Nothing to do here!
+    return NS_OK;
+  }
+
   virtual bool
   Notify(JSContext* aCx, Status aStatus) override
   {
     mWorkerPrivate->AssertIsOnWorkerThread();
 
     if (aStatus >= Terminating && !mCanceled) {
       mCanceled = true;
 
@@ -774,17 +777,16 @@ private:
     }
 
     if (!mWorkerPrivate->IsServiceWorker() ||
         !mWorkerPrivate->LoadScriptAsPartOfLoadingServiceWorkerScript()) {
       for (uint32_t index = 0, len = mLoadInfos.Length(); index < len;
            ++index) {
         nsresult rv = LoadScript(index);
         if (NS_WARN_IF(NS_FAILED(rv))) {
-          LoadingFinished(index, rv);
           return rv;
         }
       }
 
       return NS_OK;
     }
 
     MOZ_ASSERT(!mCacheCreator);
@@ -872,28 +874,37 @@ private:
                                 getter_AddRefs(channel));
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
     }
 
     // We need to know which index we're on in OnStreamComplete so we know
     // where to put the result.
-    RefPtr<LoaderListener> listener = new LoaderListener(this, aIndex);
+    nsCOMPtr<nsISupportsPRUint32> indexSupports =
+      do_CreateInstance(NS_SUPPORTS_PRUINT32_CONTRACTID, &rv);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
+
+    rv = indexSupports->SetData(aIndex);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
 
     // We don't care about progress so just use the simple stream loader for
     // OnStreamComplete notification only.
     nsCOMPtr<nsIStreamLoader> loader;
-    rv = NS_NewStreamLoader(getter_AddRefs(loader), listener);
+    rv = NS_NewStreamLoader(getter_AddRefs(loader), this);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
 
     if (loadInfo.mCacheStatus != ScriptLoadInfo::ToBeCached) {
-      rv = channel->AsyncOpen2(loader);
+      rv = channel->AsyncOpen(loader, indexSupports);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
     } else {
       nsCOMPtr<nsIOutputStream> writer;
 
       // In case we return early.
       loadInfo.mCacheStatus = ScriptLoadInfo::Cancel;
@@ -902,36 +913,36 @@ private:
                       UINT32_MAX, // unlimited size to avoid writer WOULD_BLOCK case
                       true, false); // non-blocking reader, blocking writer
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
 
       nsCOMPtr<nsIStreamListenerTee> tee =
         do_CreateInstance(NS_STREAMLISTENERTEE_CONTRACTID);
-      rv = tee->Init(loader, writer, listener);
+      rv = tee->Init(loader, writer, this);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
 
-      nsresult rv = channel->AsyncOpen2(tee);
+      nsresult rv = channel->AsyncOpen(tee, indexSupports);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
     }
 
     loadInfo.mChannel.swap(channel);
 
     return NS_OK;
   }
 
   nsresult
-  OnStreamCompleteInternal(nsIStreamLoader* aLoader, nsresult aStatus,
-                           uint32_t aStringLen, const uint8_t* aString,
-                           ScriptLoadInfo& aLoadInfo)
+  OnStreamCompleteInternal(nsIStreamLoader* aLoader, nsISupports* aContext,
+                           nsresult aStatus, uint32_t aStringLen,
+                           const uint8_t* aString, ScriptLoadInfo& aLoadInfo)
   {
     AssertIsOnMainThread();
 
     if (!aLoadInfo.mChannel) {
       return NS_BINDING_ABORTED;
     }
 
     aLoadInfo.mChannel = nullptr;
@@ -1078,16 +1089,23 @@ private:
             // Assign the system principal to the resource:// worker only if it
             // was loaded from code using the system principal.
             channelPrincipal = loadPrincipal;
           } else {
             return NS_ERROR_DOM_BAD_URI;
           }
         }
       }
+      else  {
+        // We exempt data urls and other URI's that inherit their
+        // principal again.
+        if (NS_FAILED(loadPrincipal->CheckMayLoad(finalURI, false, true))) {
+          return NS_ERROR_DOM_BAD_URI;
+        }
+      }
 
       // The principal can change, but it should still match the original
       // load group's appId and browser element flag.
       MOZ_ASSERT(NS_LoadGroupMatchesPrincipal(channelLoadGroup, channelPrincipal));
 
       mWorkerPrivate->SetPrincipal(channelPrincipal, channelLoadGroup);
     }
 
@@ -1221,31 +1239,19 @@ private:
                                    firstIndex, lastIndex);
       if (!runnable->Dispatch(nullptr)) {
         MOZ_ASSERT(false, "This should never fail!");
       }
     }
   }
 };
 
-NS_IMPL_ISUPPORTS(ScriptLoaderRunnable, nsIRunnable)
-
-NS_IMETHODIMP
-LoaderListener::OnStreamComplete(nsIStreamLoader* aLoader, nsISupports* aContext,
-                                 nsresult aStatus, uint32_t aStringLen,
-                                 const uint8_t* aString)
-{
-  return mRunnable->OnStreamComplete(aLoader, mIndex, aStatus, aStringLen, aString);
-}
-
-NS_IMETHODIMP
-LoaderListener::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
-{
-  return mRunnable->OnStartRequest(aRequest, mIndex);
-}
+NS_IMPL_ISUPPORTS(ScriptLoaderRunnable, nsIRunnable,
+                                        nsIStreamLoaderObserver,
+                                        nsIRequestObserver)
 
 void
 CachePromiseHandler::ResolvedCallback(JSContext* aCx,
                                       JS::Handle<JS::Value> aValue)
 {
   AssertIsOnMainThread();
   // May already have been canceled by CacheScriptLoader::Fail from
   // CancelMainThread.
@@ -1497,32 +1503,27 @@ CacheScriptLoader::ResolvedCallback(JSCo
   AssertIsOnMainThread();
   // If we have already called 'Fail', we should not proceed.
   if (mFailed) {
     return;
   }
 
   MOZ_ASSERT(mLoadInfo.mCacheStatus == ScriptLoadInfo::Uncached);
 
-  nsresult rv;
-
   if (aValue.isUndefined()) {
     mLoadInfo.mCacheStatus = ScriptLoadInfo::ToBeCached;
-    rv = mRunnable->LoadScript(mIndex);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      Fail(rv);
-    }
+    mRunnable->LoadScript(mIndex);
     return;
   }
 
   MOZ_ASSERT(aValue.isObject());
 
   JS::Rooted<JSObject*> obj(aCx, &aValue.toObject());
   mozilla::dom::Response* response = nullptr;
-  rv = UNWRAP_OBJECT(Response, obj, response);
+  nsresult rv = UNWRAP_OBJECT(Response, obj, response);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     Fail(rv);
     return;
   }
 
   nsCOMPtr<nsIInputStream> inputStream;
   response->GetBody(getter_AddRefs(inputStream));
   mChannelInfo = response->GetChannelInfo();
--- a/dom/workers/test/test_csp.js
+++ b/dom/workers/test/test_csp.js
@@ -34,15 +34,17 @@ worker.onmessage = function(event) {
 msg = "ImportScripts javascript:";
 worker = new Worker("csp_worker.js");
 worker.postMessage(-2);
 worker.onmessage = function(event) {
   ok(false, "Eval succeeded!");
 }
 
 msg = "Loading data:something";
-worker = new Worker("data:application/javascript;base64,ZHVtcCgnaGVsbG8gd29ybGQnKQo=");
-worker.onerror = function() {
+try {
+  worker = new Worker("data:application/javascript;base64,ZHVtcCgnaGVsbG8gd29ybGQnKQo=");
+  ok(false, "Should have thrown!");
+} catch (e) {
   ok(true, "Threw as expected.");
 }
 
 worker = new Worker("javascript:dump(123);");
 SimpleTest.waitForExplicitFinish();
--- a/dom/workers/test/test_loadError.html
+++ b/dom/workers/test/test_loadError.html
@@ -8,63 +8,65 @@
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 "use strict";
 
-function nextTest() {
-  (function(){
-    function workerfunc() {
-      var subworker = new Worker("about:blank");
-      subworker.onerror = function(e) {
-        e.preventDefault();
-        postMessage(e.message);
-      }
-    }
-    var b = new Blob([workerfunc+'workerfunc();']);
-    var u = URL.createObjectURL(b);
-    function callworker(i) {
-      try {
-        var w = new Worker(u);
-        URL.revokeObjectURL(u);
-        is(i, 0, 'worker creation succeeded');
-      } catch (e) {
-        is(i, 1, 'worker creation failed');
-        SimpleTest.finish();
-        return;
-      }
-      w.onmessage = function(e) {
-        is(e.data.indexOf('Error: Failed to load script'), 0, "Error: Failed to load script");
-        if (++i < 2) callworker(i);
-        else SimpleTest.finish();
-      };
-    }
-    callworker(0);
-  })();
-}
-
 try {
   var worker = new Worker("about:blank");
-  worker.onerror = function(e) {
-    e.preventDefault();
-    ok(true, "Shouldn't success!");
-    nextTest();
-  }
+  ok(false, "Shouldn't success!");
 
   worker.onmessage = function(event) {
     ok(false, "Shouldn't get a message!");
     SimpleTest.finish();
   }
+
+  worker.onerror = function(event) {
+    ok(false, "Shouldn't get a error message!");
+    SimpleTest.finish();
+  }
 } catch (e) {
-  ok(false, "This should not happen.");
+  ok(!worker, "worker should not be created");
+  is(e.name, "SecurityError", "SecurityError should be thrown");
+  is(e.code, DOMException.SECURITY_ERR, "SECURITY_ERR should be thrown");
 }
 
+(function(){
+  function workerfunc() {
+    try {
+      var subworker = new Worker("about:blank");
+      postMessage({});
+    } catch (e) {
+      postMessage({name: e.name, code: e.code});
+    }
+  }
+  var b = new Blob([workerfunc+'workerfunc();']);
+  var u = URL.createObjectURL(b);
+  function callworker(i) {
+    try {
+      var w = new Worker(u);
+      URL.revokeObjectURL(u);
+      is(i, 0, 'worker creation succeeded');
+    } catch (e) {
+      is(i, 1, 'worker creation failed');
+      SimpleTest.finish();
+      return;
+    }
+    w.onmessage = function(e) {
+      is(e.data.name, "SecurityError", "SecurityError should be thrown");
+      is(e.data.code, DOMException.SECURITY_ERR, "SECURITY_ERR should be thrown");
+      if (++i < 2) callworker(i);
+      else SimpleTest.finish();
+    };
+  }
+  callworker(0);
+})();
 
 SimpleTest.waitForExplicitFinish();
 
 </script>
 </pre>
 </body>
 </html>
 
--- a/testing/web-platform/meta/workers/constructors/SharedWorker/same-origin.html.ini
+++ b/testing/web-platform/meta/workers/constructors/SharedWorker/same-origin.html.ini
@@ -1,4 +1,8 @@
 [same-origin.html]
   type: testharness
   [unsupported_scheme]
     expected: FAIL
+
+  [javascript_url]
+    expected: FAIL
+
--- a/testing/web-platform/meta/workers/constructors/Worker/same-origin.html.ini
+++ b/testing/web-platform/meta/workers/constructors/Worker/same-origin.html.ini
@@ -1,4 +1,8 @@
 [same-origin.html]
   type: testharness
   [unsupported_scheme]
     expected: FAIL
+
+  [javascript_url]
+    expected: FAIL
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/workers/interfaces/WorkerUtils/importScripts/004.html.ini
@@ -0,0 +1,4 @@
+[004.html]
+  type: testharness
+  [importScripts broken script]
+    expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/workers/interfaces/WorkerUtils/importScripts/006.html.ini
@@ -0,0 +1,6 @@
+[006.html]
+  type: testharness
+  expected: ERROR
+  [importScripts uncaught exception]
+    expected: TIMEOUT
+
--- a/testing/web-platform/tests/content-security-policy/blink-contrib/self-doesnt-match-blob.sub.html
+++ b/testing/web-platform/tests/content-security-policy/blink-contrib/self-doesnt-match-blob.sub.html
@@ -26,20 +26,16 @@ connect-src 'self'; script-src 'self' 'u
                 "postMessage('TEST COMPLETE');"
                 ],
                 {type : 'application/javascript'});
             var url = URL.createObjectURL(blob);
             var worker = new Worker(url);
             worker.onmessage = function(event) {
                 alert_assert(event.data);
             };
-            worker.onerror = function(event) {
-                alert_assert('TEST COMPLETE');
-                event.preventDefault();
-            }
         } catch (e) {
             alert_assert('TEST COMPLETE');
         }
         function timeout() {
             alert_assert('TEST COMPLETE');
         }
     </script>
     <div id="log"></div>
--- a/testing/web-platform/tests/content-security-policy/blink-contrib/star-doesnt-match-blob.sub.html
+++ b/testing/web-platform/tests/content-security-policy/blink-contrib/star-doesnt-match-blob.sub.html
@@ -26,20 +26,16 @@ connect-src 'self'; script-src 'self' 'u
                 "postMessage('TEST COMPLETE');"
                 ],
                 {type : 'application/javascript'});
             var url = URL.createObjectURL(blob);
             var worker = new Worker(url);
             worker.onmessage = function(event) {
                 alert_assert(event.data);
             };
-            worker.onerror = function(event) {
-                event.preventDefault();
-                alert_assert('TEST COMPLETE');
-            }
         } catch (e) {
             alert_assert('TEST COMPLETE');
         }
         function timeout() {
             alert_assert('TEST COMPLETE');
         }
     </script>
     <div id="log"></div>
--- a/testing/web-platform/tests/content-security-policy/child-src/child-src-worker-blocked.sub.html
+++ b/testing/web-platform/tests/content-security-policy/child-src/child-src-worker-blocked.sub.html
@@ -15,19 +15,16 @@ child-src 'none'; script-src 'self' 'uns
 
 <body>
     <script>
         try {
             var foo = new Worker('http://{{host}}:{{ports[http][0]}}/content-security-policy/blink-contrib/resources/post-message.js');
             foo.onmessage = function(event) {
                 alert_assert("FAIL");
             };
-            foo.onerror = function(e) {
-                alert_assert("PASS");
-            }
         } catch (e) {
             alert_assert("PASS");
         }
 
     </script>
     <div id="log"></div>
     <script async defer src="../support/checkReport.sub.js?reportExists=true&amp;reportField=violated-directive&amp;reportValue=child-src%20&apos;none&apos;"></script>
 </body>
--- a/testing/web-platform/tests/mixed-content/generic/common.js
+++ b/testing/web-platform/tests/mixed-content/generic/common.js
@@ -78,18 +78,17 @@ function setAttributes(el, attrs) {
  * @param {object} element An object supporting events on which to bind the
  *     promise.
  * @param {string} resolveEventName [="load"] The event name to bind resolve to.
  * @param {string} rejectEventName [="error"] The event name to bind reject to.
  */
 function bindEvents(element, resolveEventName, rejectEventName) {
   element.eventPromise = new Promise(function(resolve, reject) {
     element.addEventListener(resolveEventName  || "load", resolve);
-    element.addEventListener(rejectEventName || "error",
-                             function(e) { e.preventDefault(); reject(); } );
+    element.addEventListener(rejectEventName || "error", reject);
   });
 }
 
 /**
  * Creates a new DOM element.
  * @param {string} tagName The type of the DOM element.
  * @param {object} attrs A JSON with attributes to apply to the element.
  * @param {DOMElement} parent Optional - an existing DOM element to append to
--- a/testing/web-platform/tests/workers/Worker_cross_origin_security_err.htm
+++ b/testing/web-platform/tests/workers/Worker_cross_origin_security_err.htm
@@ -1,17 +1,12 @@
 <!DOCTYPE html>
 <title> Worker cross-origin URL </title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <div id=log></div>
 <script>
-async_test(function(t) {
-  try {
-    var w = new Worker("ftp://example.org/support/WorkerBasic.js");
-    w.onerror = t.step_func_done(function(e) {
-      assert_true(e instanceof ErrorEvent);
-    });
-  } catch (e) {
-    t.step_func_done(function(e) { assert_true(true); });
-  }
+test(function() {
+  assert_throws("SECURITY_ERR", function() {
+    new Worker("ftp://example.org/support/WorkerBasic.js");
+  });
 });
 </script>
--- a/testing/web-platform/tests/workers/constructors/SharedWorker/same-origin.html
+++ b/testing/web-platform/tests/workers/constructors/SharedWorker/same-origin.html
@@ -7,61 +7,42 @@
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <div id="log"></div>
 <script>
 // Needed to prevent a race condition if a worker throws an exception that may or may
 // not propogate to the window before the tests finish
 setup({allow_uncaught_exception: true});
 
-function testSharedWorkerHelper(t, script) {
-  try {
-    var worker = new SharedWorker(script, '');
-    worker.onerror = t.step_func_done(function(e) {
-      assert_true(e instanceof ErrorEvent);
-    });
-  } catch (e) {
-    t.step_func_done(function(e) { assert_true(true); });
-  }
-}
-
 test(function() {
   assert_throws("SecurityError", function() { new SharedWorker('unsupported:', ''); });
 }, "unsupported_scheme");
-
 async_test(function() {
   var worker = new SharedWorker('data:,onconnect = function(e) { e.ports[0].postMessage(1); }', '');
   worker.port.onmessage = this.step_func_done(function(e) {
     assert_equals(e.data, 1);
   });
 }, "data_url");
-
-async_test(function(t) {
-  testSharedWorkerHelper(this, 'javascript:""');
+test(function() {
+  assert_throws("SecurityError", function() { new SharedWorker('javascript:""', ''); });
 }, "javascript_url");
-
-async_test(function(t) {
-  testSharedWorkerHelper(this, 'about:blank');
+test(function() {
+  assert_throws("SecurityError", function() { new SharedWorker('about:blank', ''); });
 }, "about_blank");
-
-async_test(function(t) {
-  testSharedWorkerHelper(this, 'http://www.opera.com/');
+test(function() {
+  assert_throws("SecurityError", function() { new SharedWorker('http://www.opera.com/', ''); });
 }, "opera_com");
-
-async_test(function(t) {
-  testSharedWorkerHelper(this, location.protocol+'//'+location.hostname+':81/');
+test(function() {
+  assert_throws("SecurityError", function() { new SharedWorker(location.protocol+'//'+location.hostname+':81/', ''); });
 }, "port_81");
-
-async_test(function(t) {
-  testSharedWorkerHelper(this, 'https://'+location.hostname+':80/');
+test(function() {
+  assert_throws("SecurityError", function() { new SharedWorker('https://'+location.hostname+':80/', ''); });
 }, "https_port_80");
-
-async_test(function(t) {
-  testSharedWorkerHelper(this, 'https://'+location.hostname+':8000/');
+test(function() {
+  assert_throws("SecurityError", function() { new SharedWorker('https://'+location.hostname+':8000/', ''); });
 }, "https_port_8000");
-
-async_test(function(t) {
-  testSharedWorkerHelper(this, 'http://'+location.hostname+':8012/');
+test(function() {
+  assert_throws("SecurityError", function() { new SharedWorker('http://'+location.hostname+':8012/', ''); });
 }, "http_port_8012");
 </script>
 <!--
 */
 //-->
--- a/testing/web-platform/tests/workers/constructors/Worker/same-origin.html
+++ b/testing/web-platform/tests/workers/constructors/Worker/same-origin.html
@@ -5,59 +5,47 @@
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <div id="log"></div>
 <script>
 // Needed to prevent a race condition if a worker throws an exception that may or may
 // not propogate to the window before the tests finish
 setup({allow_uncaught_exception: true});
 
-function testSharedWorkerHelper(t, script) {
-  try {
-    var worker = new SharedWorker(script, '');
-    worker.onerror = t.step_func_done(function(e) {
-      assert_true(e instanceof ErrorEvent);
-    });
-  } catch (e) {
-    t.step_func_done(function(e) { assert_true(true); });
-  }
-}
-
 test(function() {
   assert_throws("SecurityError", function() { new Worker('unsupported:'); });
 }, "unsupported_scheme");
 
 async_test(function() {
   var worker = new Worker('data:,postMessage(1);');
   worker.onmessage = this.step_func_done(function(e) {
     assert_equals(e.data, 1);
   });
 }, "data_url");
 
-async_test(function(t) {
-  testSharedWorkerHelper(t, 'about:blank');
+test(function() {
+  assert_throws("SecurityError", function() { new Worker('about:blank'); });
 }, "about_blank");
 
-async_test(function(t) {
-  testSharedWorkerHelper(t, 'http://www.example.invalid/');
+test(function() {
+  assert_throws("SecurityError", function() { new Worker('http://www.example.invalid/'); });
 }, "example_invalid");
 
-async_test(function(t) {
-  testSharedWorkerHelper(t, location.protocol+'//'+location.hostname+':81/');
+test(function() {
+  assert_throws("SecurityError", function() { new Worker(location.protocol+'//'+location.hostname+':81/'); });
 }, "port_81");
 
-async_test(function(t) {
-  testSharedWorkerHelper(t, 'https://'+location.hostname+':80/');
+test(function() {
+  assert_throws("SecurityError", function() { new Worker('https://'+location.hostname+':80/'); });
 }, "https_port_80");
 
-async_test(function(t) {
-  testSharedWorkerHelper(t, 'https://'+location.hostname+':8000/');
+test(function() {
+  assert_throws("SecurityError", function() { new Worker('https://'+location.hostname+':8000/'); });
 }, "https_port_8000");
 
-async_test(function(t) {
-  testSharedWorkerHelper(t, 'http://'+location.hostname+':8012/');
+test(function() {
+  assert_throws("SecurityError", function() { new Worker('http://'+location.hostname+':8012/'); });
 }, "http_post_8012");
 
-async_test(function(t) {
-  testSharedWorkerHelper(t,'javascript:""');
+test(function() {
+  assert_throws("SecurityError", function() { new Worker('javascript:""'); });
 }, "javascript_url");
-
 </script>