Browse Source

Backport bug 1222008 plus regressions

Ian Neal 5 months ago
parent
commit
2baccc3467

+ 401 - 0
mozilla-release/patches/1222008-1-59a1.patch

@@ -0,0 +1,401 @@
+# HG changeset patch
+# User Tom Tung <shes050117@gmail.com>
+# Date 1509522335 -28800
+# Node ID e5aff04d76e0818e9b1f27ec5a76ba9fd6793607
+# Parent  cc3e67d904b2d515be4d01ce90e4a7f6528c1963
+Bug 1222008 - P1: Propagate the URLs from respondWith() if the response's URL is different from the request's. r=bkelly
+
+diff --git a/dom/workers/ServiceWorkerEvents.cpp b/dom/workers/ServiceWorkerEvents.cpp
+--- a/dom/workers/ServiceWorkerEvents.cpp
++++ b/dom/workers/ServiceWorkerEvents.cpp
+@@ -337,18 +337,18 @@ public:
+     auto castLoadInfo = static_cast<LoadInfo*>(loadInfo.get());
+     castLoadInfo->SynthesizeServiceWorkerTainting(mInternalResponse->GetTainting());
+ 
+     nsCOMPtr<nsIInputStream> body;
+     mInternalResponse->GetUnfilteredBody(getter_AddRefs(body));
+     RefPtr<BodyCopyHandle> copyHandle;
+     copyHandle = new BodyCopyHandle(Move(mClosure));
+ 
+-    rv = mChannel->StartSynthesizedResponse(body, copyHandle,
+-                                            mResponseURLSpec);
++    rv = mChannel->StartSynthesizedResponse(body, copyHandle, mResponseURLSpec,
++                                            mInternalResponse->IsRedirected());
+     if (NS_WARN_IF(NS_FAILED(rv))) {
+       mChannel->CancelInterception(NS_ERROR_INTERCEPTION_FAILED);
+       return NS_OK;
+     }
+ 
+     nsCOMPtr<nsIObserverService> obsService = services::GetObserverService();
+     if (obsService) {
+       obsService->NotifyObservers(underlyingChannel, "service-worker-synthesized-response", nullptr);
+@@ -653,29 +653,37 @@ RespondWithHandler::ResolvedCallback(JSC
+       NS_LITERAL_CSTRING("InterceptedUsedResponseWithURL"), mRequestURL);
+     return;
+   }
+ 
+   RefPtr<InternalResponse> ir = response->GetInternalResponse();
+   if (NS_WARN_IF(!ir)) {
+     return;
+   }
+-  // When an opaque response is encountered, we need the original channel's principal
+-  // to reflect the final URL. Non-opaque responses are either same-origin or CORS-enabled
+-  // cross-origin responses, which are treated as same-origin by consumers.
+-  nsCString responseURL;
+-  if (response->Type() == ResponseType::Opaque) {
+-    responseURL = ir->GetUnfilteredURL();
+-    if (NS_WARN_IF(responseURL.IsEmpty())) {
+-      return;
+-    }
++
++  // An extra safety check to make sure our invariant that opaque and cors
++  // responses always have a URL does not break.
++  if (NS_WARN_IF((response->Type() == ResponseType::Opaque ||
++                  response->Type() == ResponseType::Cors) &&
++                 ir->GetUnfilteredURL().IsEmpty())) {
++    MOZ_DIAGNOSTIC_ASSERT(false, "Cors or opaque Response without a URL");
++    return;
+   }
+ 
+   if (mRequestMode == RequestMode::Same_origin &&
+       response->Type() == ResponseType::Cors) {
++    // XXXtt: quirkResponse, will be implement in the follow-up patch.
++  }
++
++  // Propagate the URL to the content if the request mode is not "navigate".
++  // Note that, we only reflect the final URL if the response.redirected is
++  // false. We propagate all the URLs if the response.redirected is true.
++  nsCString responseURL;
++  if (mRequestMode != RequestMode::Navigate) {
++    responseURL = ir->GetUnfilteredURL();
+   }
+ 
+   UniquePtr<RespondWithClosure> closure(new RespondWithClosure(mInterceptedChannel,
+                                                                mRegistration,
+                                                                mRequestURL,
+                                                                mRespondWithScriptSpec,
+                                                                mRespondWithLineNumber,
+                                                                mRespondWithColumnNumber));
+diff --git a/netwerk/base/nsINetworkInterceptController.idl b/netwerk/base/nsINetworkInterceptController.idl
+--- a/netwerk/base/nsINetworkInterceptController.idl
++++ b/netwerk/base/nsINetworkInterceptController.idl
+@@ -73,20 +73,25 @@ interface nsIInterceptedChannel : nsISup
+      *   empty body is assumed.
+      * - A callback may be optionally passed.  It will be invoked
+      *   when the body is complete.  For a nullptr body this may be
+      *   synchronously on the current thread.  Otherwise it will be invoked
+      *   asynchronously on the current thread.
+      * - The caller may optionally pass a spec for a URL that this response
+      *   originates from; an empty string will cause the original
+      *   intercepted request's URL to be used instead.
++     * - The responseRedirected flag is false will cause the channel do an
++     *   internal redirect when the original intercepted reauest's URL is
++     *   different from the response's URL. The flag is true will cause the
++     *   chaanel do a non-internal redirect when the URLs are different.
+      */
+     void startSynthesizedResponse(in nsIInputStream body,
+                                   in nsIInterceptedBodyCallback callback,
+-                                  in ACString finalURLSpec);
++                                  in ACString finalURLSpec,
++                                  in bool responseRedirected);
+ 
+     /**
+      * Instruct a channel that has been intercepted that response synthesis
+      * has completed and all outstanding resources can be closed.
+      */
+     void finishSynthesizedResponse();
+ 
+     /**
+diff --git a/netwerk/protocol/http/HttpChannelChild.cpp b/netwerk/protocol/http/HttpChannelChild.cpp
+--- a/netwerk/protocol/http/HttpChannelChild.cpp
++++ b/netwerk/protocol/http/HttpChannelChild.cpp
+@@ -1821,24 +1821,33 @@ HttpChannelChild::Redirect1Begin(const u
+   }
+ 
+   if (NS_FAILED(rv))
+     OnRedirectVerifyCallback(rv);
+ }
+ 
+ void
+ HttpChannelChild::BeginNonIPCRedirect(nsIURI* responseURI,
+-                                      const nsHttpResponseHead* responseHead)
++                                      const nsHttpResponseHead* responseHead,
++                                      bool aResponseRedirected)
+ {
+   LOG(("HttpChannelChild::BeginNonIPCRedirect [this=%p]\n", this));
+ 
++  // If the response has been redirected, propagate all the URLs to content.
++  // Thus, the exact value of the redirect flag does not matter as long as it's
++  // not REDIRECT_INTERNAL.
++  const uint32_t redirectFlag =
++    aResponseRedirected ? nsIChannelEventSink::REDIRECT_TEMPORARY
++                        : nsIChannelEventSink::REDIRECT_INTERNAL;
++
++
+   nsCOMPtr<nsIChannel> newChannel;
+   nsresult rv = SetupRedirect(responseURI,
+                               responseHead,
+-                              nsIChannelEventSink::REDIRECT_INTERNAL,
++                              redirectFlag,
+                               getter_AddRefs(newChannel));
+ 
+   if (NS_SUCCEEDED(rv)) {
+     // Ensure that the new channel shares the original channel's security information,
+     // since it won't be provided via IPC. In particular, if the target of this redirect
+     // is a synthesized response that has its own security info, the pre-redirect channel
+     // has already received it and it must be propagated to the post-redirect channel.
+     nsCOMPtr<nsIHttpChannelChild> channelChild = do_QueryInterface(newChannel);
+@@ -1847,17 +1856,17 @@ HttpChannelChild::BeginNonIPCRedirect(ns
+       httpChannelChild->OverrideSecurityInfoForNonIPCRedirect(mSecurityInfo);
+     }
+ 
+     nsCOMPtr<nsIEventTarget> target = GetNeckoTarget();
+     MOZ_ASSERT(target);
+ 
+     rv = gHttpHandler->AsyncOnChannelRedirect(this,
+                                               newChannel,
+-                                              nsIChannelEventSink::REDIRECT_INTERNAL,
++                                              redirectFlag,
+                                               target);
+   }
+ 
+   if (NS_FAILED(rv))
+     OnRedirectVerifyCallback(rv);
+ }
+ 
+ void
+diff --git a/netwerk/protocol/http/HttpChannelChild.h b/netwerk/protocol/http/HttpChannelChild.h
+--- a/netwerk/protocol/http/HttpChannelChild.h
++++ b/netwerk/protocol/http/HttpChannelChild.h
+@@ -429,17 +429,18 @@ private:
+   // response headers.
+   MOZ_MUST_USE nsresult SetupRedirect(nsIURI* uri,
+                                       const nsHttpResponseHead* responseHead,
+                                       const uint32_t& redirectFlags,
+                                       nsIChannel** outChannel);
+ 
+   // Perform a redirection without communicating with the parent process at all.
+   void BeginNonIPCRedirect(nsIURI* responseURI,
+-                           const nsHttpResponseHead* responseHead);
++                           const nsHttpResponseHead* responseHead,
++                           bool responseRedirected);
+ 
+   // Override the default security info pointer during a non-IPC redirection.
+   void OverrideSecurityInfoForNonIPCRedirect(nsISupports* securityInfo);
+ 
+   friend class AssociateApplicationCacheEvent;
+   friend class StartRequestEvent;
+   friend class StopRequestEvent;
+   friend class TransportAndDataEvent;
+diff --git a/netwerk/protocol/http/HttpChannelParentListener.cpp b/netwerk/protocol/http/HttpChannelParentListener.cpp
+--- a/netwerk/protocol/http/HttpChannelParentListener.cpp
++++ b/netwerk/protocol/http/HttpChannelParentListener.cpp
+@@ -315,17 +315,17 @@ public:
+     , mChannel(aChannel)
+   {
+   }
+ 
+   NS_IMETHOD Run() override
+   {
+     // The URL passed as an argument here doesn't matter, since the child will
+     // receive a redirection notification as a result of this synthesized response.
+-    mChannel->StartSynthesizedResponse(nullptr, nullptr, EmptyCString());
++    mChannel->StartSynthesizedResponse(nullptr, nullptr, EmptyCString(), false);
+     mChannel->FinishSynthesizedResponse();
+     return NS_OK;
+   }
+ };
+ 
+ NS_IMETHODIMP
+ HttpChannelParentListener::ChannelIntercepted(nsIInterceptedChannel* aChannel)
+ {
+diff --git a/netwerk/protocol/http/InterceptedChannel.cpp b/netwerk/protocol/http/InterceptedChannel.cpp
+--- a/netwerk/protocol/http/InterceptedChannel.cpp
++++ b/netwerk/protocol/http/InterceptedChannel.cpp
+@@ -254,17 +254,18 @@ InterceptedChannelContent::SynthesizeHea
+   }
+ 
+   return DoSynthesizeHeader(aName, aValue);
+ }
+ 
+ NS_IMETHODIMP
+ InterceptedChannelContent::StartSynthesizedResponse(nsIInputStream* aBody,
+                                                     nsIInterceptedBodyCallback* aBodyCallback,
+-                                                    const nsACString& aFinalURLSpec)
++                                                    const nsACString& aFinalURLSpec,
++                                                    bool aResponseRedirected)
+ {
+   if (NS_WARN_IF(mClosed)) {
+     return NS_ERROR_NOT_AVAILABLE;
+   }
+ 
+   EnsureSynthesizedResponse();
+ 
+   nsCOMPtr<nsIURI> originalURI;
+@@ -281,17 +282,18 @@ InterceptedChannelContent::StartSynthesi
+   } else {
+     responseURI = originalURI;
+   }
+ 
+   bool equal = false;
+   originalURI->Equals(responseURI, &equal);
+   if (!equal) {
+     mChannel->ForceIntercepted(aBody, aBodyCallback);
+-    mChannel->BeginNonIPCRedirect(responseURI, *mSynthesizedResponseHead.ptr());
++    mChannel->BeginNonIPCRedirect(responseURI, *mSynthesizedResponseHead.ptr(),
++                                  aResponseRedirected);
+   } else {
+     mChannel->OverrideWithSynthesizedResponse(mSynthesizedResponseHead.ref(),
+                                               aBody, aBodyCallback,
+                                               mStreamListener);
+   }
+ 
+   return NS_OK;
+ }
+diff --git a/netwerk/protocol/http/InterceptedChannel.h b/netwerk/protocol/http/InterceptedChannel.h
+--- a/netwerk/protocol/http/InterceptedChannel.h
++++ b/netwerk/protocol/http/InterceptedChannel.h
+@@ -177,17 +177,18 @@ public:
+   InterceptedChannelContent(HttpChannelChild* aChannel,
+                             nsINetworkInterceptController* aController,
+                             InterceptStreamListener* aListener,
+                             bool aSecureUpgrade);
+ 
+   NS_IMETHOD ResetInterception() override;
+   NS_IMETHOD StartSynthesizedResponse(nsIInputStream* aBody,
+                                       nsIInterceptedBodyCallback* aBodyCallback,
+-                                      const nsACString& aFinalURLSpec) override;
++                                      const nsACString& aFinalURLSpec,
++                                      bool aResponseRedirected) override;
+   NS_IMETHOD FinishSynthesizedResponse() override;
+   NS_IMETHOD GetChannel(nsIChannel** aChannel) override;
+   NS_IMETHOD GetSecureUpgradedChannelURI(nsIURI** aURI) override;
+   NS_IMETHOD SynthesizeStatus(uint16_t aStatus, const nsACString& aReason) override;
+   NS_IMETHOD SynthesizeHeader(const nsACString& aName, const nsACString& aValue) override;
+   NS_IMETHOD CancelInterception(nsresult aStatus) override;
+   NS_IMETHOD SetChannelInfo(mozilla::dom::ChannelInfo* aChannelInfo) override;
+   NS_IMETHOD GetInternalContentPolicyType(nsContentPolicyType *aInternalContentPolicyType) override;
+diff --git a/netwerk/protocol/http/InterceptedHttpChannel.cpp b/netwerk/protocol/http/InterceptedHttpChannel.cpp
+--- a/netwerk/protocol/http/InterceptedHttpChannel.cpp
++++ b/netwerk/protocol/http/InterceptedHttpChannel.cpp
+@@ -228,23 +228,25 @@ InterceptedHttpChannel::FollowSyntheticR
+   if (NS_WARN_IF(NS_FAILED(rv))) {
+     OnRedirectVerifyCallback(rv);
+   }
+ 
+   return rv;
+ }
+ 
+ nsresult
+-InterceptedHttpChannel::RedirectForOpaqueResponse(nsIURI* aResponseURI)
++InterceptedHttpChannel::RedirectForResponseURL(nsIURI* aResponseURI,
++                                               bool aResponseRedirected)
+ {
+-  // Perform an internal redirect to another InterceptedHttpChannel using
+-  // the given cross-origin response URL.  The resulting channel will then
+-  // process the synthetic response as normal.  This extra redirect is
+-  // performed so that listeners treat the result as unsafe cross-origin
+-  // data.
++  // Perform a service worker redirect to another InterceptedHttpChannel using
++  // the given response URL. It allows content to see the final URL where
++  // appropriate and also helps us enforce cross-origin restrictions. The
++  // resulting channel will then process the synthetic response as normal. This
++  // extra redirect is performed so that listeners treat the result as unsafe
++  // cross-origin data.
+ 
+   nsresult rv = NS_OK;
+ 
+   // We want to pass ownership of the body callback to the new synthesized
+   // channel.  We need to hold a reference to the callbacks on the stack
+   // as well, though, so we can call them if a failure occurs.
+   nsCOMPtr<nsIInterceptedBodyCallback> bodyCallback = mBodyCallback.forget();
+ 
+@@ -252,17 +254,21 @@ InterceptedHttpChannel::RedirectForOpaqu
+     CreateForSynthesis(mResponseHead, mBodyReader, bodyCallback,
+                        mChannelCreationTime, mChannelCreationTimestamp,
+                        mAsyncOpenTime);
+ 
+   rv = newChannel->Init(aResponseURI, mCaps,
+                         static_cast<nsProxyInfo*>(mProxyInfo.get()),
+                         mProxyResolveFlags, mProxyURI, mChannelId);
+ 
+-  uint32_t flags = nsIChannelEventSink::REDIRECT_INTERNAL;
++  // If the response has been redirected, propagate all the URLs to content.
++  // Thus, the exact value of the redirect flag does not matter as long as it's
++  // not REDIRECT_INTERNAL.
++  uint32_t flags = aResponseRedirected ? nsIChannelEventSink::REDIRECT_TEMPORARY
++                                       : nsIChannelEventSink::REDIRECT_INTERNAL;
+ 
+   nsCOMPtr<nsILoadInfo> redirectLoadInfo =
+     CloneLoadInfoForRedirect(aResponseURI, flags);
+   newChannel->SetLoadInfo(redirectLoadInfo);
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
+   rv = SetupReplacementChannel(aResponseURI, newChannel, true, flags);
+   NS_ENSURE_SUCCESS(rv, rv);
+@@ -725,17 +731,18 @@ InterceptedHttpChannel::SynthesizeHeader
+   nsresult rv = mSynthesizedResponseHead->ParseHeaderLine(header);
+   NS_ENSURE_SUCCESS(rv, rv);
+   return NS_OK;
+ }
+ 
+ NS_IMETHODIMP
+ InterceptedHttpChannel::StartSynthesizedResponse(nsIInputStream* aBody,
+                                                  nsIInterceptedBodyCallback* aBodyCallback,
+-                                                 const nsACString& aFinalURLSpec)
++                                                 const nsACString& aFinalURLSpec,
++                                                 bool aResponseRedirected)
+ {
+   nsresult rv = NS_OK;
+ 
+   auto autoCleanup = MakeScopeExit([&] {
+     // Auto-cancel on failure.  Do this first to get mStatus set, if necessary.
+     if (NS_FAILED(rv)) {
+       Cancel(rv);
+     }
+@@ -791,17 +798,17 @@ InterceptedHttpChannel::StartSynthesized
+     NS_ENSURE_SUCCESS(rv, rv);
+   } else {
+     responseURI = mURI;
+   }
+ 
+   bool equal = false;
+   Unused << mURI->Equals(responseURI, &equal);
+   if (!equal) {
+-    rv = RedirectForOpaqueResponse(responseURI);
++    rv = RedirectForResponseURL(responseURI, aResponseRedirected);
+     NS_ENSURE_SUCCESS(rv, rv);
+ 
+     return NS_OK;
+   }
+ 
+   rv = StartPump();
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
+diff --git a/netwerk/protocol/http/InterceptedHttpChannel.h b/netwerk/protocol/http/InterceptedHttpChannel.h
+--- a/netwerk/protocol/http/InterceptedHttpChannel.h
++++ b/netwerk/protocol/http/InterceptedHttpChannel.h
+@@ -109,18 +109,22 @@ private:
+   AsyncOpenInternal();
+ 
+   bool
+   ShouldRedirect() const;
+ 
+   nsresult
+   FollowSyntheticRedirect();
+ 
++  // If the response's URL is different from the request's then do a service
++  // worker redirect. If Response.redirected is false we do an internal
++  // redirect. Otherwise, if Response.redirect is true do a non-internal
++  // redirect so end consumers detect the redirected state.
+   nsresult
+-  RedirectForOpaqueResponse(nsIURI* aResponseURI);
++  RedirectForResponseURL(nsIURI* aResponseURI, bool aResponseRedirected);
+ 
+   nsresult
+   StartPump();
+ 
+   nsresult
+   OpenRedirectChannel();
+ 
+   void

+ 105 - 0
mozilla-release/patches/1222008-2-59a1.patch

@@ -0,0 +1,105 @@
+# HG changeset patch
+# User Tom Tung <shes050117@gmail.com>
+# Date 1509675873 -28800
+# Node ID cc17f19f55986bad0c1dd70939b949152c0de9b7
+# Parent  1140095d6feea249383e51c243d5d5019cf18d70
+Bug 1222008 - P2: Fix the netwerk xpcshell test since adding an argument to startSynthesizedResponse(). r=bkelly
+
+diff --git a/netwerk/test/unit/test_synthesized_response.js b/netwerk/test/unit/test_synthesized_response.js
+--- a/netwerk/test/unit/test_synthesized_response.js
++++ b/netwerk/test/unit/test_synthesized_response.js
+@@ -58,17 +58,17 @@ function make_channel(url, body, cb) {
+     },
+     channelIntercepted: function(channel) {
+       channel.QueryInterface(Ci.nsIInterceptedChannel);
+       if (body) {
+         var synthesized = Cc["@mozilla.org/io/string-input-stream;1"]
+                             .createInstance(Ci.nsIStringInputStream);
+         synthesized.data = body;
+ 
+-        channel.startSynthesizedResponse(synthesized, null, '');
++        channel.startSynthesizedResponse(synthesized, null, '', false);
+         channel.finishSynthesizedResponse();
+       }
+       if (cb) {
+         cb(channel);
+       }
+       return {
+         dispatch: function() { }
+       };
+@@ -147,17 +147,17 @@ add_test(function() {
+ // ensure that the channel waits for a decision and synthesizes headers correctly
+ add_test(function() {
+   var chan = make_channel(URL + '/body', null, function(channel) {
+     do_timeout(100, function() {
+       var synthesized = Cc["@mozilla.org/io/string-input-stream;1"]
+                           .createInstance(Ci.nsIStringInputStream);
+       synthesized.data = NON_REMOTE_BODY;
+       channel.synthesizeHeader("Content-Length", NON_REMOTE_BODY.length);
+-      channel.startSynthesizedResponse(synthesized, null, '');
++      channel.startSynthesizedResponse(synthesized, null, '', false);
+       channel.finishSynthesizedResponse();
+     });
+   });
+   chan.asyncOpen2(new ChannelListener(handle_synthesized_response, null));
+ });
+ 
+ // ensure that the channel waits for a decision
+ add_test(function() {
+@@ -174,17 +174,17 @@ add_test(function() {
+   var chan = make_channel(URL + '/body', null, function(intercepted) {
+     var synthesized = Cc["@mozilla.org/io/string-input-stream;1"]
+                         .createInstance(Ci.nsIStringInputStream);
+     synthesized.data = NON_REMOTE_BODY;
+ 
+     // set the content-type to ensure that the stream converter doesn't hold up notifications
+     // and cause the test to fail
+     intercepted.synthesizeHeader("Content-Type", "text/plain");
+-    intercepted.startSynthesizedResponse(synthesized, null, '');
++    intercepted.startSynthesizedResponse(synthesized, null, '', false);
+     intercepted.finishSynthesizedResponse();
+   });
+   chan.asyncOpen2(new ChannelListener(handle_synthesized_response, null,
+ 				     CL_ALLOW_UNKNOWN_CL | CL_SUSPEND | CL_EXPECT_3S_DELAY));
+ });
+ 
+ // ensure that the intercepted channel can be cancelled
+ add_test(function() {
+@@ -214,17 +214,17 @@ add_test(function() {
+ // ensure that the intercepted channel can be canceled during the response
+ add_test(function() {
+   var chan = make_channel(URL + '/body', null, function(intercepted) {
+     var synthesized = Cc["@mozilla.org/io/string-input-stream;1"]
+                         .createInstance(Ci.nsIStringInputStream);
+     synthesized.data = NON_REMOTE_BODY;
+ 
+     let channel = intercepted.channel;
+-    intercepted.startSynthesizedResponse(synthesized, null, '');
++    intercepted.startSynthesizedResponse(synthesized, null, '', false);
+     intercepted.finishSynthesizedResponse();
+     channel.cancel(Cr.NS_BINDING_ABORTED);
+   });
+   chan.asyncOpen2(new ChannelListener(run_next_test, null,
+                                      CL_EXPECT_FAILURE | CL_ALLOW_UNKNOWN_CL));
+ });
+ 
+ // ensure that the intercepted channel can be canceled before the response
+@@ -233,17 +233,17 @@ add_test(function() {
+     var synthesized = Cc["@mozilla.org/io/string-input-stream;1"]
+                         .createInstance(Ci.nsIStringInputStream);
+     synthesized.data = NON_REMOTE_BODY;
+ 
+     intercepted.channel.cancel(Cr.NS_BINDING_ABORTED);
+ 
+     // This should not throw, but result in the channel firing callbacks
+     // with an error status.
+-    intercepted.startSynthesizedResponse(synthesized, null, '');
++    intercepted.startSynthesizedResponse(synthesized, null, '', false);
+     intercepted.finishSynthesizedResponse();
+   });
+   chan.asyncOpen2(new ChannelListener(run_next_test, null,
+                                      CL_EXPECT_FAILURE | CL_ALLOW_UNKNOWN_CL));
+ });
+ 
+ // Ensure that nsIInterceptedChannel.channelIntercepted() can return an error.
+ // In this case we should automatically ResetInterception() and complete the

+ 52 - 0
mozilla-release/patches/1222008-3-59a1.patch

@@ -0,0 +1,52 @@
+# HG changeset patch
+# User Tom Tung <shes050117@gmail.com>
+# Date 1509676747 -28800
+# Node ID 1beda261a70875f1155d7ea0f3bcb7d329de1789
+# Parent  12e6185d5c3294f9a2c681780a80f6af59cac0fb
+Bug 1222008 - P3: Fix the test_fetch_basic_http_sw_reroute.html since we decide to propagate the response's URLs to the content. r=bkelly
+
+Correct the redirected URL if it's hijacked by a service worker.
+
+diff --git a/dom/tests/mochitest/fetch/test_fetch_basic_http.js b/dom/tests/mochitest/fetch/test_fetch_basic_http.js
+--- a/dom/tests/mochitest/fetch/test_fetch_basic_http.js
++++ b/dom/tests/mochitest/fetch/test_fetch_basic_http.js
+@@ -7,18 +7,17 @@ var passFiles = [['file_XHR_pass1.xml', 
+ 
+ function testURL() {
+   var promises = [];
+   passFiles.forEach(function(entry) {
+     var p = fetch(path + entry[0]).then(function(res) {
+       ok(res.type !== "error", "Response should not be an error for " + entry[0]);
+       is(res.status, entry[2], "Status should match expected for " + entry[0]);
+       is(res.statusText, entry[3], "Status text should match expected for " + entry[0]);
+-      // This file redirects to pass2, but that is invisible if a SW is present.
+-      if (entry[0] != "file_XHR_pass3.txt" || isSWPresent)
++      if (entry[0] != "file_XHR_pass3.txt")
+         ok(res.url.endsWith(path + entry[0]), "Response url should match request for simple fetch for " + entry[0]);
+       else
+         ok(res.url.endsWith(path + "file_XHR_pass2.txt"), "Response url should match request for simple fetch for " + entry[0]);
+       is(res.headers.get('content-type'), entry[4], "Response should have content-type for " + entry[0]);
+     });
+     promises.push(p);
+   });
+ 
+@@ -44,18 +43,17 @@ function testURLFail() {
+ function testRequestGET() {
+   var promises = [];
+   passFiles.forEach(function(entry) {
+     var req = new Request(path + entry[0], { method: entry[1] });
+     var p = fetch(req).then(function(res) {
+       ok(res.type !== "error", "Response should not be an error for " + entry[0]);
+       is(res.status, entry[2], "Status should match expected for " + entry[0]);
+       is(res.statusText, entry[3], "Status text should match expected for " + entry[0]);
+-      // This file redirects to pass2, but that is invisible if a SW is present.
+-      if (entry[0] != "file_XHR_pass3.txt" || isSWPresent)
++      if (entry[0] != "file_XHR_pass3.txt")
+         ok(res.url.endsWith(path + entry[0]), "Response url should match request for simple fetch for " + entry[0]);
+       else
+         ok(res.url.endsWith(path + "file_XHR_pass2.txt"), "Response url should match request for simple fetch for " + entry[0]);
+       is(res.headers.get('content-type'), entry[4], "Response should have content-type for " + entry[0]);
+     });
+     promises.push(p);
+   });
+ 

+ 85 - 0
mozilla-release/patches/1222008-4no5-59a1.patch

@@ -0,0 +1,85 @@
+# HG changeset patch
+# User Tom Tung <shes050117@gmail.com>
+# Date 1511400367 -28800
+# Node ID efa0d71107dfcc5b30fac1e5dd72f10e7226e6a8
+# Parent  589faba06d08f243620c80c0566ad30d1505b8f0
+Bug 1222008 - P4: Fix the interception test since we decide to propagate the response's URLs to the content. r=bkelly
+
+diff --git a/dom/workers/test/serviceworkers/browser_devtools_serviceworker_interception.js b/dom/workers/test/serviceworkers/browser_devtools_serviceworker_interception.js
+--- a/dom/workers/test/serviceworkers/browser_devtools_serviceworker_interception.js
++++ b/dom/workers/test/serviceworkers/browser_devtools_serviceworker_interception.js
+@@ -15,31 +15,28 @@ const sw = BASE_URI + "fetch.js";
+ // XXXtt: We should be able to move this check to chrome process after we move
+ // the interception logic to chrome process.
+ async function checkObserverInContent(aInput) {
+   let interceptedChannel = null;
+ 
+   // We always get two channels which receive the "http-on-stop-request"
+   // notification if the service worker hijacks the request and respondWith an
+   // another fetch. One is for the "outer" window request when the other one is
+-  // for the "inner" service worker request. We used to distinguish them by the
+-  // channel.URI.spec, but it doesn't work fine with internal redirect case. The
+-  // reason is that the two different channels will have the same channel.URI
+-  // if it's an internal redirect. Therefore, distinguish them by the order.
+-  let waitForSecondOnStopRequest = aInput.redirect;
++  // for the "inner" service worker request. Therefore, distinguish them by the
++  // order.
++  let waitForSecondOnStopRequest = aInput.intercepted;
+ 
+   let promiseResolve;
+ 
+   function observer(aSubject) {
+     let channel = aSubject.QueryInterface(Ci.nsIChannel);
+     // Since we cannot make sure that the network event triggered by the fetch()
+     // in this testcase is the very next event processed by ObserverService, we
+     // have to wait until we catch the one we want.
+-    if (!(aInput.redirect && channel.URI.spec.includes(aInput.redirect)) &&
+-        !(!aInput.redirect && channel.URI.spec.includes(aInput.url))) {
++    if (!channel.URI.spec.includes(aInput.expectedURL)) {
+       return;
+     }
+ 
+     if (waitForSecondOnStopRequest) {
+       waitForSecondOnStopRequest = false;
+       return;
+     }
+ 
+@@ -190,34 +187,38 @@ add_task(async function test_serivce_wor
+   info("Open the tab for observing");
+   let tab_observer = BrowserTestUtils.addTab(gBrowser, emptyDoc);
+   let tabBrowser_observer = gBrowser.getBrowserForTab(tab_observer);
+   await BrowserTestUtils.browserLoaded(tabBrowser_observer);
+ 
+   let testcases = [
+     {
+       url: helloDoc,
++      expectedURL: helloDoc,
+       swPresent: false,
+       intercepted: false,
+       fetch: true
+     },
+     {
+       url: fakeDoc,
++      expectedURL: helloDoc,
+       swPresent: true,
+       intercepted: true,
+       fetch: false // should use HTTP cache
+     },
+     { // Bypass http cache
+       url: helloDoc + "?ForBypassingHttpCache=" + Date.now(),
++      expectedURL: helloDoc,
+       swPresent: true,
+       intercepted: false,
+       fetch: true
+     },
+     { // no-cors mode redirect to no-cors mode (trigger internal redirect)
+       url: crossRedirect + "?url=" + crossHelloDoc + "&mode=no-cors",
++      expectedURL: crossHelloDoc,
+       swPresent: true,
+       redirect: "hello.html",
+       intercepted: true,
+       fetch: true
+     }
+   ];
+ 
+   info("Test 1: Verify simple fetch");

+ 58 - 0
mozilla-release/patches/1222008-6-59a1.patch

@@ -0,0 +1,58 @@
+# HG changeset patch
+# User Tom Tung <shes050117@gmail.com>
+# Date 1511835667 -28800
+# Node ID c29e6b8b00b618f67b83c20527b449b98834e1eb
+# Parent  d839c18c92cf32ab8c24c03b11094011206bb212
+Bug 1222008 - P6: Reject the cors synthesized response for same-origin request. r=bkelly
+
+diff --git a/dom/locales/en-US/chrome/dom/dom.properties b/dom/locales/en-US/chrome/dom/dom.properties
+--- a/dom/locales/en-US/chrome/dom/dom.properties
++++ b/dom/locales/en-US/chrome/dom/dom.properties
+@@ -197,16 +197,18 @@ AppCacheWarning=The Application Cache AP
+ # LOCALIZATION NOTE: Do not translate "Worker".
+ EmptyWorkerSourceWarning=Attempting to create a Worker from an empty source. This is probably unintentional.
+ WebrtcDeprecatedPrefixWarning=WebRTC interfaces with the “moz” prefix (mozRTCPeerConnection, mozRTCSessionDescription, mozRTCIceCandidate) have been deprecated.
+ NavigatorGetUserMediaWarning=navigator.mozGetUserMedia has been replaced by navigator.mediaDevices.getUserMedia
+ # LOCALIZATION NOTE: Do not translate "RTCPeerConnection", "getLocalStreams", "getRemoteStreams", "getSenders" or "getReceivers".
+ RTCPeerConnectionGetStreamsWarning=RTCPeerConnection.getLocalStreams/getRemoteStreams are deprecated. Use RTCPeerConnection.getSenders/getReceivers instead.
+ # LOCALIZATION NOTE: Do not translate "ServiceWorker". %S is a URL.
+ InterceptionFailedWithURL=Failed to load ‘%S’. A ServiceWorker intercepted the request and encountered an unexpected error.
++# LOCALIZATION NOTE: Do not translate "ServiceWorker", "cors", "Response", "same-origin" or "Request". %1$S is a URL, %2$S is a URL.
++CorsResponseForSameOriginRequest=Failed to load ‘%1$S’ by responding ‘%2$S’. A ServiceWorker is not allowed to synthesize a cors Response for a same-origin Request.
+ # LOCALIZATION NOTE: Do not translate "ServiceWorker", "FetchEvent.respondWith()", "FetchEvent", "no-cors", "opaque", "Response", or "RequestMode". %1$S is a URL. %2$S is a RequestMode value.
+ BadOpaqueInterceptionRequestModeWithURL=Failed to load ‘%1$S’. A ServiceWorker passed an opaque Response to FetchEvent.respondWith() while handling a ‘%2$S’ FetchEvent. Opaque Response objects are only valid when the RequestMode is ‘no-cors’.
+ # LOCALIZATION NOTE: Do not translate "ServiceWorker", "Error", "Response", "FetchEvent.respondWith()", or "fetch()". %S is a URL.
+ InterceptedErrorResponseWithURL=Failed to load ‘%S’. A ServiceWorker passed an Error Response to FetchEvent.respondWith(). This typically means the ServiceWorker performed an invalid fetch() call.
+ # LOCALIZATION NOTE: Do not translate "ServiceWorker", "Response", "FetchEvent.respondWith()", or "Response.clone()". %S is a URL.
+ InterceptedUsedResponseWithURL=Failed to load ‘%S’. A ServiceWorker passed a used Response to FetchEvent.respondWith(). The body of a Response may only be read once. Use Response.clone() to access the body multiple times.
+ # LOCALIZATION NOTE: Do not translate "ServiceWorker", "opaqueredirect", "Response", "FetchEvent.respondWith()", or "FetchEvent". %s is a URL.
+ BadOpaqueRedirectInterceptionWithURL=Failed to load ‘%S’. A ServiceWorker passed an opaqueredirect Response to FetchEvent.respondWith() while handling a non-navigation FetchEvent.
+diff --git a/dom/workers/ServiceWorkerEvents.cpp b/dom/workers/ServiceWorkerEvents.cpp
+--- a/dom/workers/ServiceWorkerEvents.cpp
++++ b/dom/workers/ServiceWorkerEvents.cpp
+@@ -665,17 +665,24 @@ RespondWithHandler::ResolvedCallback(JSC
+                   response->Type() == ResponseType::Cors) &&
+                  ir->GetUnfilteredURL().IsEmpty())) {
+     MOZ_DIAGNOSTIC_ASSERT(false, "Cors or opaque Response without a URL");
+     return;
+   }
+ 
+   if (mRequestMode == RequestMode::Same_origin &&
+       response->Type() == ResponseType::Cors) {
+-    // XXXtt: quirkResponse, will be implement in the follow-up patch.
++    // XXXtt: Will have a pref to enable the quirk response in bug 1419684.
++    // The variadic template provided by StringArrayAppender requires exactly
++    // an nsString.
++    NS_ConvertUTF8toUTF16 responseURL(ir->GetUnfilteredURL());
++    autoCancel.SetCancelMessage(
++      NS_LITERAL_CSTRING("CorsResponseForSameOriginRequest"), mRequestURL,
++      responseURL);
++    return;
+   }
+ 
+   // Propagate the URL to the content if the request mode is not "navigate".
+   // Note that, we only reflect the final URL if the response.redirected is
+   // false. We propagate all the URLs if the response.redirected is true.
+   nsCString responseURL;
+   if (mRequestMode != RequestMode::Navigate) {
+     responseURL = ir->GetUnfilteredURL();

+ 288 - 0
mozilla-release/patches/1222008-7no8-59a1.patch

@@ -0,0 +1,288 @@
+# HG changeset patch
+# User Tom Tung <shes050117@gmail.com>
+# Date 1509694655 -28800
+# Node ID 8e66dd4b9241a14d7cb5be77404011569d498dcb
+# Parent  ccb7495c2f593f37bf8ce12ad94a5ec6564a327b
+Bug 1222008 - P7: Freeze the tainting if a service worker responds with a synthesize response. r=bkelly
+
+diff --git a/ipc/glue/BackgroundUtils.cpp b/ipc/glue/BackgroundUtils.cpp
+--- a/ipc/glue/BackgroundUtils.cpp
++++ b/ipc/glue/BackgroundUtils.cpp
+@@ -392,17 +392,18 @@ LoadInfoToLoadInfoArgs(nsILoadInfo *aLoa
+       aLoadInfo->GetOriginAttributes(),
+       redirectChainIncludingInternalRedirects,
+       redirectChain,
+       ancestorPrincipals,
+       aLoadInfo->AncestorOuterWindowIDs(),
+       aLoadInfo->CorsUnsafeHeaders(),
+       aLoadInfo->GetForcePreflight(),
+       aLoadInfo->GetIsPreflight(),
+-      aLoadInfo->GetLoadTriggeredFromExternal()
++      aLoadInfo->GetLoadTriggeredFromExternal(),
++      aLoadInfo->GetServiceWorkerTaintingSynthesized()
+       );
+ 
+   return NS_OK;
+ }
+ 
+ nsresult
+ LoadInfoArgsToLoadInfo(const OptionalLoadInfoArgs& aOptionalLoadInfoArgs,
+                        nsILoadInfo** outLoadInfo)
+@@ -497,17 +498,18 @@ LoadInfoArgsToLoadInfo(const OptionalLoa
+                           loadInfoArgs.originAttributes(),
+                           redirectChainIncludingInternalRedirects,
+                           redirectChain,
+                           Move(ancestorPrincipals),
+                           loadInfoArgs.ancestorOuterWindowIDs(),
+                           loadInfoArgs.corsUnsafeHeaders(),
+                           loadInfoArgs.forcePreflight(),
+                           loadInfoArgs.isPreflight(),
+-                          loadInfoArgs.loadTriggeredFromExternal()
++                          loadInfoArgs.loadTriggeredFromExternal(),
++                          loadInfoArgs.serviceWorkerTaintingSynthesized()
+                           );
+ 
+    loadInfo.forget(outLoadInfo);
+    return NS_OK;
+ }
+ 
+ } // namespace ipc
+ } // namespace mozilla
+diff --git a/netwerk/base/LoadInfo.cpp b/netwerk/base/LoadInfo.cpp
+--- a/netwerk/base/LoadInfo.cpp
++++ b/netwerk/base/LoadInfo.cpp
+@@ -68,16 +68,17 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadin
+   , mTopOuterWindowID(0)
+   , mFrameOuterWindowID(0)
+   , mEnforceSecurity(false)
+   , mInitialSecurityCheckDone(false)
+   , mIsThirdPartyContext(false)
+   , mForcePreflight(false)
+   , mIsPreflight(false)
+   , mLoadTriggeredFromExternal(false)
++  , mServiceWorkerTaintingSynthesized(false)
+ {
+   MOZ_ASSERT(mLoadingPrincipal);
+   MOZ_ASSERT(mTriggeringPrincipal);
+ 
+ #ifdef DEBUG
+   // TYPE_DOCUMENT loads initiated by javascript tests will go through
+   // nsIOService and use the wrong constructor.  Don't enforce the
+   // !TYPE_DOCUMENT check in those cases
+@@ -257,16 +258,17 @@ LoadInfo::LoadInfo(nsPIDOMWindowOuter* a
+   , mTopOuterWindowID(0)
+   , mFrameOuterWindowID(0)
+   , mEnforceSecurity(false)
+   , mInitialSecurityCheckDone(false)
+   , mIsThirdPartyContext(false) // NB: TYPE_DOCUMENT implies not third-party.
+   , mForcePreflight(false)
+   , mIsPreflight(false)
+   , mLoadTriggeredFromExternal(false)
++  , mServiceWorkerTaintingSynthesized(false)
+ {
+   // Top-level loads are never third-party
+   // Grab the information we can out of the window.
+   MOZ_ASSERT(aOuterWindow);
+   MOZ_ASSERT(mTriggeringPrincipal);
+ 
+   // if the load is sandboxed, we can not also inherit the principal
+   if (mSecurityFlags & nsILoadInfo::SEC_SANDBOXED) {
+@@ -334,16 +336,17 @@ LoadInfo::LoadInfo(const LoadInfo& rhs)
+       rhs.mRedirectChainIncludingInternalRedirects)
+   , mRedirectChain(rhs.mRedirectChain)
+   , mAncestorPrincipals(rhs.mAncestorPrincipals)
+   , mAncestorOuterWindowIDs(rhs.mAncestorOuterWindowIDs)
+   , mCorsUnsafeHeaders(rhs.mCorsUnsafeHeaders)
+   , mForcePreflight(rhs.mForcePreflight)
+   , mIsPreflight(rhs.mIsPreflight)
+   , mLoadTriggeredFromExternal(rhs.mLoadTriggeredFromExternal)
++  , mServiceWorkerTaintingSynthesized(rhs.mServiceWorkerTaintingSynthesized)
+ {
+ }
+ 
+ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal,
+                    nsIPrincipal* aTriggeringPrincipal,
+                    nsIPrincipal* aPrincipalToInherit,
+                    nsIPrincipal* aSandboxedLoadingPrincipal,
+                    nsIURI* aResultPrincipalURI,
+@@ -366,17 +369,18 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadin
+                    const OriginAttributes& aOriginAttributes,
+                    RedirectHistoryArray& aRedirectChainIncludingInternalRedirects,
+                    RedirectHistoryArray& aRedirectChain,
+                    nsTArray<nsCOMPtr<nsIPrincipal>>&& aAncestorPrincipals,
+                    const nsTArray<uint64_t>& aAncestorOuterWindowIDs,
+                    const nsTArray<nsCString>& aCorsUnsafeHeaders,
+                    bool aForcePreflight,
+                    bool aIsPreflight,
+-                   bool aLoadTriggeredFromExternal)
++                   bool aLoadTriggeredFromExternal,
++                   bool aServiceWorkerTaintingSynthesized)
+   : mLoadingPrincipal(aLoadingPrincipal)
+   , mTriggeringPrincipal(aTriggeringPrincipal)
+   , mPrincipalToInherit(aPrincipalToInherit)
+   , mResultPrincipalURI(aResultPrincipalURI)
+   , mSecurityFlags(aSecurityFlags)
+   , mInternalContentPolicyType(aContentPolicyType)
+   , mTainting(aTainting)
+   , mUpgradeInsecureRequests(aUpgradeInsecureRequests)
+@@ -394,16 +398,17 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadin
+   , mIsThirdPartyContext(aIsThirdPartyContext)
+   , mOriginAttributes(aOriginAttributes)
+   , mAncestorPrincipals(Move(aAncestorPrincipals))
+   , mAncestorOuterWindowIDs(aAncestorOuterWindowIDs)
+   , mCorsUnsafeHeaders(aCorsUnsafeHeaders)
+   , mForcePreflight(aForcePreflight)
+   , mIsPreflight(aIsPreflight)
+   , mLoadTriggeredFromExternal(aLoadTriggeredFromExternal)
++  , mServiceWorkerTaintingSynthesized(aServiceWorkerTaintingSynthesized)
+ {
+   // Only top level TYPE_DOCUMENT loads can have a null loadingPrincipal
+   MOZ_ASSERT(mLoadingPrincipal || aContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT);
+   MOZ_ASSERT(mTriggeringPrincipal);
+ 
+   mRedirectChainIncludingInternalRedirects.SwapElements(
+     aRedirectChainIncludingInternalRedirects);
+ 
+@@ -1056,39 +1061,56 @@ LoadInfo::SetLoadTriggeredFromExternal(b
+ NS_IMETHODIMP
+ LoadInfo::GetLoadTriggeredFromExternal(bool* aLoadTriggeredFromExternal)
+ {
+   *aLoadTriggeredFromExternal = mLoadTriggeredFromExternal;
+   return NS_OK;
+ }
+ 
+ NS_IMETHODIMP
++LoadInfo::GetServiceWorkerTaintingSynthesized(bool* aServiceWorkerTaintingSynthesized)
++{
++  MOZ_ASSERT(aServiceWorkerTaintingSynthesized);
++  *aServiceWorkerTaintingSynthesized = mServiceWorkerTaintingSynthesized;
++  return NS_OK;
++}
++
++NS_IMETHODIMP
+ LoadInfo::GetTainting(uint32_t* aTaintingOut)
+ {
+   MOZ_ASSERT(aTaintingOut);
+   *aTaintingOut = static_cast<uint32_t>(mTainting);
+   return NS_OK;
+ }
+ 
+ NS_IMETHODIMP
+ LoadInfo::MaybeIncreaseTainting(uint32_t aTainting)
+ {
+   NS_ENSURE_ARG(aTainting <= TAINTING_OPAQUE);
++
++  // Skip if the tainting has been set by the service worker.
++  if (mServiceWorkerTaintingSynthesized) {
++    return NS_OK;
++  }
++
+   LoadTainting tainting = static_cast<LoadTainting>(aTainting);
+   if (tainting > mTainting) {
+     mTainting = tainting;
+   }
+   return NS_OK;
+ }
+ 
+ void
+ LoadInfo::SynthesizeServiceWorkerTainting(LoadTainting aTainting)
+ {
+   MOZ_DIAGNOSTIC_ASSERT(aTainting <= LoadTainting::Opaque);
+   mTainting = aTainting;
++
++  // Flag to prevent the tainting from being increased.
++  mServiceWorkerTaintingSynthesized = true;
+ }
+ 
+ NS_IMETHODIMP
+ LoadInfo::GetIsTopLevelLoad(bool *aResult)
+ {
+   *aResult = mFrameOuterWindowID ? mFrameOuterWindowID == mOuterWindowID
+                                  : mParentOuterWindowID == mOuterWindowID;
+   return NS_OK;
+diff --git a/netwerk/base/LoadInfo.h b/netwerk/base/LoadInfo.h
+--- a/netwerk/base/LoadInfo.h
++++ b/netwerk/base/LoadInfo.h
+@@ -118,17 +118,18 @@ private:
+            const OriginAttributes& aOriginAttributes,
+            RedirectHistoryArray& aRedirectChainIncludingInternalRedirects,
+            RedirectHistoryArray& aRedirectChain,
+            nsTArray<nsCOMPtr<nsIPrincipal>>&& aAncestorPrincipals,
+            const nsTArray<uint64_t>& aAncestorOuterWindowIDs,
+            const nsTArray<nsCString>& aUnsafeHeaders,
+            bool aForcePreflight,
+            bool aIsPreflight,
+-           bool aLoadTriggeredFromExternal);
++           bool aLoadTriggeredFromExternal,
++           bool aServiceWorkerTaintingSynthesized);
+   LoadInfo(const LoadInfo& rhs);
+ 
+   NS_IMETHOD GetRedirects(JSContext* aCx, JS::MutableHandle<JS::Value> aRedirects,
+                           const RedirectHistoryArray& aArra);
+ 
+   friend nsresult
+   mozilla::ipc::LoadInfoArgsToLoadInfo(
+     const mozilla::net::OptionalLoadInfoArgs& aLoadInfoArgs,
+@@ -179,15 +180,16 @@ private:
+   RedirectHistoryArray             mRedirectChainIncludingInternalRedirects;
+   RedirectHistoryArray             mRedirectChain;
+   nsTArray<nsCOMPtr<nsIPrincipal>> mAncestorPrincipals;
+   nsTArray<uint64_t>               mAncestorOuterWindowIDs;
+   nsTArray<nsCString>              mCorsUnsafeHeaders;
+   bool                             mForcePreflight;
+   bool                             mIsPreflight;
+   bool                             mLoadTriggeredFromExternal;
++  bool                             mServiceWorkerTaintingSynthesized;
+ };
+ 
+ } // namespace net
+ } // namespace mozilla
+ 
+ #endif // mozilla_LoadInfo_h
+ 
+diff --git a/netwerk/base/nsILoadInfo.idl b/netwerk/base/nsILoadInfo.idl
+--- a/netwerk/base/nsILoadInfo.idl
++++ b/netwerk/base/nsILoadInfo.idl
+@@ -645,16 +645,21 @@ interface nsILoadInfo : nsISupports
+   /**
+    * Returns true if the load was triggered from an external application
+    * (e.g. Thunderbird). Please note that this flag will only ever be true
+    * if the load is of TYPE_DOCUMENT. 
+    */
+   [infallible] attribute boolean loadTriggeredFromExternal;
+ 
+   /**
++   * True if the tainting has been set by the service worker.
++   */
++  [noscript, infallible] readonly attribute boolean serviceWorkerTaintingSynthesized;
++
++  /**
+    * Whenever a channel gets redirected, append the redirect history entry of
+    * the channel which contains principal referrer and remote address [before
+    * the channels got redirected] to the loadinfo, so that at every point this
+    * array provides us information about all the redirects this channel went
+    * through.
+    * @param entry, the nsIRedirectHistoryEntry before the channel
+    *         got redirected.
+    * @param aIsInternalRedirect should be true if the channel is going
+diff --git a/netwerk/ipc/NeckoChannelParams.ipdlh b/netwerk/ipc/NeckoChannelParams.ipdlh
+--- a/netwerk/ipc/NeckoChannelParams.ipdlh
++++ b/netwerk/ipc/NeckoChannelParams.ipdlh
+@@ -67,16 +67,17 @@ struct LoadInfoArgs
+    */
+   PrincipalInfo[]             ancestorPrincipals;
+   uint64_t[]                  ancestorOuterWindowIDs;
+ 
+   nsCString[]                 corsUnsafeHeaders;
+   bool                        forcePreflight;
+   bool                        isPreflight;
+   bool                        loadTriggeredFromExternal;
++  bool                        serviceWorkerTaintingSynthesized;
+ };
+ 
+ /**
+  * Not every channel necessarily has a loadInfo attached.
+  */
+ union OptionalLoadInfoArgs
+ {
+   void_t;

+ 34 - 0
mozilla-release/patches/1222008-9-59a1.patch

@@ -0,0 +1,34 @@
+# HG changeset patch
+# User Tom Tung <shes050117@gmail.com>
+# Date 1511946393 -28800
+# Node ID 22450268a82f78f84c1db8776f0059c1a1fe7d97
+# Parent  4a7ed01915d23df60989b6b38b2916889fb79914
+Bug 1222008 - P9: Expected failure for loading a same origin XML Document but being responded with a cors response. r=bkelly
+
+Modify test to be expected failure to load cross origin XML Document via a
+same origin request.
+
+diff --git a/dom/workers/test/serviceworkers/fetch/index.html b/dom/workers/test/serviceworkers/fetch/index.html
+--- a/dom/workers/test/serviceworkers/fetch/index.html
++++ b/dom/workers/test/serviceworkers/fetch/index.html
+@@ -135,17 +135,18 @@
+     finish();
+   };
+ 
+   gExpected++;
+   var xmlDoc = document.implementation.createDocument(null, null, null);
+   xmlDoc.load('load_cross_origin_xml_document_cors.xml');
+   xmlDoc.onload = function(evt) {
+     var content = new XMLSerializer().serializeToString(evt.target);
+-    my_ok(!content.includes('parsererror'), "Load CORS cross origin XML Document should be allowed");
++    // issue: https://github.com/whatwg/fetch/issues/629
++    my_ok(content.includes('parsererror'), "Load CORS cross origin XML Document should not be allowed");
+     finish();
+   };
+ 
+   gExpected++;
+   var xmlDoc = document.implementation.createDocument(null, null, null);
+   xmlDoc.load('load_cross_origin_xml_document_opaque.xml');
+   xmlDoc.onload = function(evt) {
+     var content = new XMLSerializer().serializeToString(evt.target);
+

+ 78 - 90
mozilla-release/patches/1434686-4-60a1.patch

@@ -3,7 +3,7 @@
 # Date 1517512874 18000
 #      Thu Feb 01 14:21:14 2018 -0500
 # Node ID a3d5547b0b7f7aa9a3e5eaed7b3151cadff42334
-# Parent  9a7e6f40c118f72fdb7b9b2403d54b07f45e6752
+# Parent  727dd8b63526d310fd1dfb753e7a78c269607ed4
 Bug 1434686 part 4.  Use IgnoreErrors() in dom/.  r=mystor
 
 MozReview-Commit-ID: GwVDrTLPTOb
@@ -197,7 +197,7 @@ new file mode 100644
 diff --git a/dom/base/nsGlobalWindow.h b/dom/base/nsGlobalWindow.h
 --- a/dom/base/nsGlobalWindow.h
 +++ b/dom/base/nsGlobalWindow.h
-@@ -1218,19 +1218,19 @@ public:
+@@ -1226,19 +1226,19 @@ public:
                         mozilla::ErrorResult& aError);
    void GetContent(JSContext* aCx,
                    JS::MutableHandle<JSObject*> aRetval,
@@ -242,37 +242,33 @@ diff --git a/dom/base/nsINode.cpp b/dom/base/nsINode.cpp
    for (nsIContent* child = GetFirstChild();
         child;
         child = child->GetNextSibling()) {
-diff --git a/dom/clients/manager/ClientSource.cpp.1434686.later b/dom/clients/manager/ClientSource.cpp.1434686.later
-new file mode 100644
---- /dev/null
-+++ b/dom/clients/manager/ClientSource.cpp.1434686.later
-@@ -0,0 +1,22 @@
-+--- ClientSource.cpp
-++++ ClientSource.cpp
-+@@ -398,18 +398,17 @@ ClientSource::SetController(const Servic
-+   nsPIDOMWindowInner* window = GetInnerWindow();
-+   if (window) {
-+     swc = window->Navigator()->ServiceWorker();
-+   }
-+ 
-+   // TODO: Also self.navigator.serviceWorker on workers when its exposed there
-+ 
-+   if (swc && nsContentUtils::IsSafeToRunScript()) {
-+-    IgnoredErrorResult ignored;
-+-    swc->ControllerChanged(ignored);
-++    swc->ControllerChanged(IgnoreErrors());
-+   }
-+ }
-+ 
-+ RefPtr<ClientOpPromise>
-+ ClientSource::Control(const ClientControlledArgs& aArgs)
-+ {
-+   NS_ASSERT_OWNINGTHREAD(ClientSource);
-+ 
+diff --git a/dom/clients/manager/ClientSource.cpp b/dom/clients/manager/ClientSource.cpp
+--- a/dom/clients/manager/ClientSource.cpp
++++ b/dom/clients/manager/ClientSource.cpp
+@@ -406,18 +406,17 @@ ClientSource::SetController(const Servic
+     if (navigator) {
+       swc = navigator->ServiceWorker();
+     }
+   }
+ 
+   // TODO: Also self.navigator.serviceWorker on workers when its exposed there
+ 
+   if (swc && nsContentUtils::IsSafeToRunScript()) {
+-    IgnoredErrorResult ignored;
+-    swc->ControllerChanged(ignored);
++    swc->ControllerChanged(IgnoreErrors());
+   }
+ }
+ 
+ RefPtr<ClientOpPromise>
+ ClientSource::Control(const ClientControlledArgs& aArgs)
+ {
+   NS_ASSERT_OWNINGTHREAD(ClientSource);
+ 
 diff --git a/dom/console/Console.cpp b/dom/console/Console.cpp
 --- a/dom/console/Console.cpp
 +++ b/dom/console/Console.cpp
-@@ -2664,18 +2664,17 @@ Console::MaybeExecuteDumpFunctionForTrac
+@@ -2650,18 +2650,17 @@ Console::MaybeExecuteDumpFunctionForTrac
    message.AppendLiteral("\n");
    ExecuteDumpFunction(message);
  }
@@ -441,7 +437,7 @@ diff --git a/dom/html/HTMLImageElement.cpp b/dom/html/HTMLImageElement.cpp
 diff --git a/dom/html/HTMLInputElement.cpp b/dom/html/HTMLInputElement.cpp
 --- a/dom/html/HTMLInputElement.cpp
 +++ b/dom/html/HTMLInputElement.cpp
-@@ -743,18 +743,17 @@ nsColorPickerShownCallback::UpdateIntern
+@@ -744,18 +744,17 @@ nsColorPickerShownCallback::UpdateIntern
  
    nsAutoString oldValue;
    if (aTrustedUpdate) {
@@ -461,7 +457,7 @@ diff --git a/dom/html/HTMLInputElement.cpp b/dom/html/HTMLInputElement.cpp
        valueChanged = true;
      }
    }
-@@ -1902,25 +1901,23 @@ HTMLInputElement::GetList(nsIDOMHTMLElem
+@@ -1903,25 +1902,23 @@ HTMLInputElement::GetList(nsIDOMHTMLElem
  }
  
  void
@@ -489,7 +485,7 @@ diff --git a/dom/html/HTMLInputElement.cpp b/dom/html/HTMLInputElement.cpp
    if (!IsDateTimeInputType(mType)) {
      return Nullable<Date>();
    }
-@@ -6699,18 +6696,17 @@ HTMLInputElement::RestoreState(nsPresSta
+@@ -6685,18 +6682,17 @@ HTMLInputElement::RestoreState(nsPresSta
          // before the type change.)
          SetValueInternal(inputState->GetValue(),
                           nsTextEditorState::eSetValue_Notify);
@@ -685,7 +681,7 @@ diff --git a/dom/html/HTMLTextAreaElement.cpp b/dom/html/HTMLTextAreaElement.cpp
 diff --git a/dom/html/ImageDocument.cpp b/dom/html/ImageDocument.cpp
 --- a/dom/html/ImageDocument.cpp
 +++ b/dom/html/ImageDocument.cpp
-@@ -363,26 +363,20 @@ ImageDocument::ShrinkToFit()
+@@ -364,26 +364,20 @@ ImageDocument::ShrinkToFit()
        classList->Remove(NS_LITERAL_STRING("overflowingVertical"), ignored);
      }
      ignored.SuppressException();
@@ -807,60 +803,6 @@ diff --git a/dom/promise/PromiseDebugging.cpp b/dom/promise/PromiseDebugging.cpp
  
  } // namespace dom
  } // namespace mozilla
-diff --git a/dom/serviceworkers/ServiceWorkerEvents.cpp.1434686.later b/dom/serviceworkers/ServiceWorkerEvents.cpp.1434686.later
-new file mode 100644
---- /dev/null
-+++ b/dom/serviceworkers/ServiceWorkerEvents.cpp.1434686.later
-@@ -0,0 +1,21 @@
-+--- ServiceWorkerEvents.cpp
-++++ ServiceWorkerEvents.cpp
-+@@ -732,17 +732,17 @@ RespondWithHandler::ResolvedCallback(JSC
-+                                                           mScriptSpec,
-+                                                           responseURL,
-+                                                           Move(closure));
-+ 
-+   nsCOMPtr<nsIInputStream> body;
-+   ir->GetUnfilteredBody(getter_AddRefs(body));
-+   // Errors and redirects may not have a body.
-+   if (body) {
-+-    IgnoredErrorResult error;
-++    ErrorResult error;
-+     response->SetBodyUsed(aCx, error);
-+     if (NS_WARN_IF(error.Failed())) {
-+       autoCancel.SetCancelErrorResult(aCx, error);
-+       return;
-+     }
-+   }
-+ 
-+   MOZ_ALWAYS_SUCCEEDS(worker->DispatchToMainThread(startRunnable.forget()));
-diff --git a/dom/serviceworkers/ServiceWorkerScriptCache.cpp.1434686.later b/dom/serviceworkers/ServiceWorkerScriptCache.cpp.1434686.later
-new file mode 100644
---- /dev/null
-+++ b/dom/serviceworkers/ServiceWorkerScriptCache.cpp.1434686.later
-@@ -0,0 +1,23 @@
-+--- ServiceWorkerScriptCache.cpp
-++++ ServiceWorkerScriptCache.cpp
-+@@ -613,19 +613,18 @@ private:
-+     ir->SetURLList(aCN->URLList());
-+ 
-+     ir->InitChannelInfo(aCN->GetChannelInfo());
-+     UniquePtr<PrincipalInfo> principalInfo = aCN->TakePrincipalInfo();
-+     if (principalInfo) {
-+       ir->SetPrincipalInfo(Move(principalInfo));
-+     }
-+ 
-+-    IgnoredErrorResult ignored;
-+     RefPtr<InternalHeaders> internalHeaders = aCN->GetInternalHeaders();
-+-    ir->Headers()->Fill(*(internalHeaders.get()), ignored);
-++    ir->Headers()->Fill(*(internalHeaders.get()), IgnoreErrors());
-+ 
-+     RefPtr<Response> response =
-+       new Response(aCache->GetGlobalObject(), ir, nullptr);
-+ 
-+     RequestOrUSVString request;
-+     request.SetAsUSVString().Rebind(aCN->URL().Data(), aCN->URL().Length());
-+ 
-+     // For now we have to wait until the Put Promise is fulfilled before we can
 diff --git a/dom/svg/SVGAnimationElement.cpp b/dom/svg/SVGAnimationElement.cpp
 --- a/dom/svg/SVGAnimationElement.cpp
 +++ b/dom/svg/SVGAnimationElement.cpp
@@ -1045,7 +987,7 @@ new file mode 100644
 diff --git a/dom/workers/ScriptLoader.cpp b/dom/workers/ScriptLoader.cpp
 --- a/dom/workers/ScriptLoader.cpp
 +++ b/dom/workers/ScriptLoader.cpp
-@@ -1563,18 +1563,17 @@ CacheCreator::DeleteCache()
+@@ -1582,18 +1582,17 @@ CacheCreator::DeleteCache()
  {
    AssertIsOnMainThread();
  
@@ -1065,7 +1007,7 @@ diff --git a/dom/workers/ScriptLoader.cpp b/dom/workers/ScriptLoader.cpp
    FailLoaders(NS_ERROR_FAILURE);
  }
  
-@@ -1695,23 +1694,22 @@ CacheScriptLoader::ResolvedCallback(JSCo
+@@ -1714,23 +1713,22 @@ CacheScriptLoader::ResolvedCallback(JSCo
    rv = UNWRAP_OBJECT(Response, &obj, response);
    if (NS_WARN_IF(NS_FAILED(rv))) {
      Fail(rv);
@@ -1092,6 +1034,52 @@ diff --git a/dom/workers/ScriptLoader.cpp b/dom/workers/ScriptLoader.cpp
    if (pInfo) {
      mPrincipalInfo = mozilla::MakeUnique<PrincipalInfo>(*pInfo);
    }
+diff --git a/dom/workers/ServiceWorkerEvents.cpp b/dom/workers/ServiceWorkerEvents.cpp
+--- a/dom/workers/ServiceWorkerEvents.cpp
++++ b/dom/workers/ServiceWorkerEvents.cpp
+@@ -701,17 +701,17 @@ RespondWithHandler::ResolvedCallback(JSC
+                                                           mScriptSpec,
+                                                           responseURL,
+                                                           Move(closure));
+ 
+   nsCOMPtr<nsIInputStream> body;
+   ir->GetUnfilteredBody(getter_AddRefs(body));
+   // Errors and redirects may not have a body.
+   if (body) {
+-    IgnoredErrorResult error;
++    ErrorResult error;
+     response->SetBodyUsed(aCx, error);
+     if (NS_WARN_IF(error.Failed())) {
+       autoCancel.SetCancelErrorResult(aCx, error);
+       return;
+     }
+   }
+ 
+   MOZ_ALWAYS_SUCCEEDS(worker->DispatchToMainThread(startRunnable.forget()));
+diff --git a/dom/workers/ServiceWorkerScriptCache.cpp b/dom/workers/ServiceWorkerScriptCache.cpp
+--- a/dom/workers/ServiceWorkerScriptCache.cpp
++++ b/dom/workers/ServiceWorkerScriptCache.cpp
+@@ -589,19 +589,18 @@ private:
+     ir->SetBody(body, aCN->Buffer().Length());
+ 
+     ir->InitChannelInfo(aCN->GetChannelInfo());
+     UniquePtr<PrincipalInfo> principalInfo = aCN->TakePrincipalInfo();
+     if (principalInfo) {
+       ir->SetPrincipalInfo(Move(principalInfo));
+     }
+ 
+-    IgnoredErrorResult ignored;
+     RefPtr<InternalHeaders> internalHeaders = aCN->GetInternalHeaders();
+-    ir->Headers()->Fill(*(internalHeaders.get()), ignored);
++    ir->Headers()->Fill(*(internalHeaders.get()), IgnoreErrors());
+ 
+     RefPtr<Response> response =
+       new Response(aCache->GetGlobalObject(), ir, nullptr);
+ 
+     RequestOrUSVString request;
+     request.SetAsUSVString().Rebind(aCN->URL().Data(), aCN->URL().Length());
+ 
+     // For now we have to wait until the Put Promise is fulfilled before we can
 diff --git a/dom/xbl/nsXBLBinding.cpp b/dom/xbl/nsXBLBinding.cpp
 --- a/dom/xbl/nsXBLBinding.cpp
 +++ b/dom/xbl/nsXBLBinding.cpp

+ 103 - 0
mozilla-release/patches/1437760-1-60a1.patch

@@ -0,0 +1,103 @@
+# HG changeset patch
+# User Ben Kelly <ben@wanderview.com>
+# Date 1519226912 28800
+# Node ID c6b9c2cb220d504dd68263f8d7291d4cdaa0f54c
+# Parent  17f688152743607ec7cdcbb007a00ac3f86f1854
+Bug 1437760 P1 Propagate the FetchEvent.request.url fragment to the synthesized Response.url. r=asuth
+
+diff --git a/dom/workers/ServiceWorkerEvents.cpp b/dom/workers/ServiceWorkerEvents.cpp
+--- a/dom/workers/ServiceWorkerEvents.cpp
++++ b/dom/workers/ServiceWorkerEvents.cpp
+@@ -387,41 +387,44 @@ class RespondWithHandler final : public 
+   nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo> mRegistration;
+   const RequestMode mRequestMode;
+   const RequestRedirect mRequestRedirectMode;
+ #ifdef DEBUG
+   const bool mIsClientRequest;
+ #endif
+   const nsCString mScriptSpec;
+   const nsString mRequestURL;
++  const nsCString mRequestFragment;
+   const nsCString mRespondWithScriptSpec;
+   const uint32_t mRespondWithLineNumber;
+   const uint32_t mRespondWithColumnNumber;
+   bool mRequestWasHandled;
+ public:
+   NS_DECL_ISUPPORTS
+ 
+   RespondWithHandler(nsMainThreadPtrHandle<nsIInterceptedChannel>& aChannel,
+                      nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo>& aRegistration,
+                      RequestMode aRequestMode, bool aIsClientRequest,
+                      RequestRedirect aRedirectMode,
+                      const nsACString& aScriptSpec,
+                      const nsAString& aRequestURL,
++                     const nsACString& aRequestFragment,
+                      const nsACString& aRespondWithScriptSpec,
+                      uint32_t aRespondWithLineNumber,
+                      uint32_t aRespondWithColumnNumber)
+     : mInterceptedChannel(aChannel)
+     , mRegistration(aRegistration)
+     , mRequestMode(aRequestMode)
+     , mRequestRedirectMode(aRedirectMode)
+ #ifdef DEBUG
+     , mIsClientRequest(aIsClientRequest)
+ #endif
+     , mScriptSpec(aScriptSpec)
+     , mRequestURL(aRequestURL)
++    , mRequestFragment(aRequestFragment)
+     , mRespondWithScriptSpec(aRespondWithScriptSpec)
+     , mRespondWithLineNumber(aRespondWithLineNumber)
+     , mRespondWithColumnNumber(aRespondWithColumnNumber)
+     , mRequestWasHandled(false)
+   {
+   }
+ 
+   void ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override;
+@@ -681,16 +684,28 @@ RespondWithHandler::ResolvedCallback(JSC
+   }
+ 
+   // Propagate the URL to the content if the request mode is not "navigate".
+   // Note that, we only reflect the final URL if the response.redirected is
+   // false. We propagate all the URLs if the response.redirected is true.
+   nsCString responseURL;
+   if (mRequestMode != RequestMode::Navigate) {
+     responseURL = ir->GetUnfilteredURL();
++
++    // Similar to how we apply the request fragment to redirects automatically
++    // we also want to apply it automatically when propagating the response
++    // URL from a service worker interception.  Currently response.url strips
++    // the fragment, so this will never conflict with an existing fragment
++    // on the response.  In the future we will have to check for a response
++    // fragment and avoid overriding in that case.
++    if (!mRequestFragment.IsEmpty()) {
++      MOZ_ASSERT(!responseURL.Contains('#'));
++      responseURL.Append(NS_LITERAL_CSTRING("#"));
++      responseURL.Append(mRequestFragment);
++    }
+   }
+ 
+   UniquePtr<RespondWithClosure> closure(new RespondWithClosure(mInterceptedChannel,
+                                                                mRegistration,
+                                                                mRequestURL,
+                                                                mRespondWithScriptSpec,
+                                                                mRespondWithLineNumber,
+                                                                mRespondWithColumnNumber));
+@@ -781,17 +796,17 @@ FetchEvent::RespondWith(JSContext* aCx, 
+   ir->GetURL(requestURL);
+ 
+   StopImmediatePropagation();
+   mWaitToRespond = true;
+   RefPtr<RespondWithHandler> handler =
+     new RespondWithHandler(mChannel, mRegistration, mRequest->Mode(),
+                            ir->IsClientRequest(), mRequest->Redirect(),
+                            mScriptSpec, NS_ConvertUTF8toUTF16(requestURL),
+-                           spec, line, column);
++                           ir->GetFragment(), spec, line, column);
+   aArg.AppendNativeHandler(handler);
+ 
+   if (!WaitOnPromise(aArg)) {
+     aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
+   }
+ }
+ 
+ void

+ 19 - 19
mozilla-release/patches/1465585-3-std-62a1.patch

@@ -2,7 +2,7 @@
 # User Emilio Cobos Alvarez <emilio@crisal.io>
 # Date 1527707735 -7200
 # Node ID b54db66223586b4e04f5cb926fccdacf8a176b91
-# Parent  38ef5d6fc958c59fcbfe428c480cc5a3d5a13ec2
+# Parent  c54e0c22368c1168237ef5350898bafaa517301f
 Bug 1465585: Switch from mozilla::Move to std::move. r=froydnj
 
 This was done automatically replacing:
@@ -17952,14 +17952,14 @@ diff --git a/dom/workers/ServiceWorkerEvents.cpp b/dom/workers/ServiceWorkerEven
 -    copyHandle = new BodyCopyHandle(Move(mClosure));
 +    copyHandle = new BodyCopyHandle(std::move(mClosure));
  
-     rv = mChannel->StartSynthesizedResponse(body, copyHandle,
-                                             mResponseURLSpec);
+     rv = mChannel->StartSynthesizedResponse(body, copyHandle, mResponseURLSpec,
+                                             mInternalResponse->IsRedirected());
      if (NS_WARN_IF(NS_FAILED(rv))) {
        mChannel->CancelInterception(NS_ERROR_INTERCEPTION_FAILED);
        return NS_OK;
      }
  
-@@ -676,17 +676,17 @@ RespondWithHandler::ResolvedCallback(JSC
+@@ -710,17 +710,17 @@ RespondWithHandler::ResolvedCallback(JSC
                                                                 mRespondWithLineNumber,
                                                                 mRespondWithColumnNumber));
  
@@ -17975,10 +17975,10 @@ diff --git a/dom/workers/ServiceWorkerEvents.cpp b/dom/workers/ServiceWorkerEven
    ir->GetUnfilteredBody(getter_AddRefs(body));
    // Errors and redirects may not have a body.
    if (body) {
-     IgnoredErrorResult error;
+     ErrorResult error;
      response->SetBodyUsed(aCx, error);
      if (NS_WARN_IF(error.Failed())) {
-@@ -1008,17 +1008,17 @@ ExtractBytesFromData(const OwningArrayBu
+@@ -1042,17 +1042,17 @@ ExtractBytesFromData(const OwningArrayBu
    }
    NS_NOTREACHED("Unexpected push message data");
    return NS_ERROR_FAILURE;
@@ -17997,7 +17997,7 @@ diff --git a/dom/workers/ServiceWorkerEvents.cpp b/dom/workers/ServiceWorkerEven
  NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(PushMessageData, mOwner)
  
  NS_IMPL_CYCLE_COLLECTING_ADDREF(PushMessageData)
-@@ -1127,17 +1127,17 @@ PushEvent::Constructor(mozilla::dom::Eve
+@@ -1161,17 +1161,17 @@ PushEvent::Constructor(mozilla::dom::Eve
    e->SetComposed(aOptions.mComposed);
    if(aOptions.mData.WasPassed()){
      nsTArray<uint8_t> bytes;
@@ -18133,13 +18133,13 @@ diff --git a/dom/workers/ServiceWorkerScriptCache.cpp b/dom/workers/ServiceWorke
 +      ir->SetPrincipalInfo(std::move(principalInfo));
      }
  
-     IgnoredErrorResult ignored;
      RefPtr<InternalHeaders> internalHeaders = aCN->GetInternalHeaders();
-     ir->Headers()->Fill(*(internalHeaders.get()), ignored);
+     ir->Headers()->Fill(*(internalHeaders.get()), IgnoreErrors());
  
      RefPtr<Response> response =
        new Response(aCache->GetGlobalObject(), ir, nullptr);
-@@ -890,17 +890,17 @@ CompareNetwork::SetPrincipalInfo(nsIChan
+ 
+@@ -889,17 +889,17 @@ CompareNetwork::SetPrincipalInfo(nsIChan
  
    UniquePtr<PrincipalInfo> principalInfo = MakeUnique<PrincipalInfo>();
    rv = PrincipalToPrincipalInfo(channelPrincipal, principalInfo.get());
@@ -28598,7 +28598,7 @@ diff --git a/ipc/glue/BackgroundUtils.cpp b/ipc/glue/BackgroundUtils.cpp
    nsCOMPtr<nsIURI> uri;
    rv = aPrincipal->GetURI(getter_AddRefs(uri));
    if (NS_WARN_IF(NS_FAILED(rv))) {
-@@ -492,17 +492,17 @@ LoadInfoArgsToLoadInfo(const OptionalLoa
+@@ -493,17 +493,17 @@ LoadInfoArgsToLoadInfo(const OptionalLoa
                            loadInfoArgs.topOuterWindowID(),
                            loadInfoArgs.frameOuterWindowID(),
                            loadInfoArgs.enforceSecurity(),
@@ -28613,10 +28613,10 @@ diff --git a/ipc/glue/BackgroundUtils.cpp b/ipc/glue/BackgroundUtils.cpp
                            loadInfoArgs.corsUnsafeHeaders(),
                            loadInfoArgs.forcePreflight(),
                            loadInfoArgs.isPreflight(),
-                           loadInfoArgs.loadTriggeredFromExternal()
+                           loadInfoArgs.loadTriggeredFromExternal(),
+                           loadInfoArgs.serviceWorkerTaintingSynthesized()
                            );
  
-    loadInfo.forget(outLoadInfo);
 diff --git a/ipc/glue/FileDescriptor.cpp b/ipc/glue/FileDescriptor.cpp
 --- a/ipc/glue/FileDescriptor.cpp
 +++ b/ipc/glue/FileDescriptor.cpp
@@ -46444,7 +46444,7 @@ diff --git a/modules/libjar/zipwriter/nsZipHeader.cpp b/modules/libjar/zipwriter
 diff --git a/modules/libpref/Preferences.cpp b/modules/libpref/Preferences.cpp
 --- a/modules/libpref/Preferences.cpp
 +++ b/modules/libpref/Preferences.cpp
-@@ -3077,17 +3077,17 @@ NS_IMPL_ISUPPORTS(Preferences,
+@@ -3069,17 +3069,17 @@ NS_IMPL_ISUPPORTS(Preferences,
                    nsIPrefBranch,
                    nsISupportsWeakReference)
  
@@ -46757,7 +46757,7 @@ diff --git a/mozglue/misc/interceptor/VMSharingPolicies.h b/mozglue/misc/interce
 diff --git a/netwerk/base/LoadInfo.cpp b/netwerk/base/LoadInfo.cpp
 --- a/netwerk/base/LoadInfo.cpp
 +++ b/netwerk/base/LoadInfo.cpp
-@@ -384,17 +384,17 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadin
+@@ -388,17 +388,17 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadin
    , mOuterWindowID(aOuterWindowID)
    , mParentOuterWindowID(aParentOuterWindowID)
    , mTopOuterWindowID(aTopOuterWindowID)
@@ -46773,10 +46773,10 @@ diff --git a/netwerk/base/LoadInfo.cpp b/netwerk/base/LoadInfo.cpp
    , mForcePreflight(aForcePreflight)
    , mIsPreflight(aIsPreflight)
    , mLoadTriggeredFromExternal(aLoadTriggeredFromExternal)
+   , mServiceWorkerTaintingSynthesized(aServiceWorkerTaintingSynthesized)
  {
    // Only top level TYPE_DOCUMENT loads can have a null loadingPrincipal
-   MOZ_ASSERT(mLoadingPrincipal || aContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT);
-@@ -1115,29 +1115,29 @@ LoadInfo::GetClientInfo()
+@@ -1137,29 +1137,29 @@ LoadInfo::GetClientInfo()
  {
    return mClientInfo;
  }
@@ -47362,7 +47362,7 @@ diff --git a/netwerk/protocol/http/HttpChannelChild.cpp b/netwerk/protocol/http/
  NS_IMPL_ADDREF(HttpChannelChild)
  
  NS_IMETHODIMP_(MozExternalRefCountType) HttpChannelChild::Release()
-@@ -2125,17 +2125,17 @@ HttpChannelChild::ConnectParent(uint32_t
+@@ -2134,17 +2134,17 @@ HttpChannelChild::ConnectParent(uint32_t
  
      MOZ_RELEASE_ASSERT(gSocketTransportService);
  
@@ -47381,7 +47381,7 @@ diff --git a/netwerk/protocol/http/HttpChannelChild.cpp b/netwerk/protocol/http/
  
      mBgChild = bgChild.forget();
    }
-@@ -3839,17 +3839,17 @@ HttpChannelChild::RecvSetPriority(const 
+@@ -3848,17 +3848,17 @@ HttpChannelChild::RecvSetPriority(const 
  {
    mPriority = aPriority;
    return IPC_OK();

+ 185 - 0
mozilla-release/patches/1467852-62a1.patch

@@ -0,0 +1,185 @@
+# HG changeset patch
+# User Ben Kelly <ben@wanderview.com>
+# Date 1528681478 25200
+# Node ID 29598a3b4cc09aef566178a33b3c5d7dbd36da17
+# Parent  405e41836ee9f375adb4345965965ab9253d294a
+Bug 1467852 Align LoadInfo::mServiceWorkerTaintingSynthesized handling with other service worker fields. r=valentin
+
+diff --git a/netwerk/base/LoadInfo.cpp b/netwerk/base/LoadInfo.cpp
+--- a/netwerk/base/LoadInfo.cpp
++++ b/netwerk/base/LoadInfo.cpp
+@@ -332,17 +332,18 @@ LoadInfo::LoadInfo(const LoadInfo& rhs)
+       rhs.mRedirectChainIncludingInternalRedirects)
+   , mRedirectChain(rhs.mRedirectChain)
+   , mAncestorPrincipals(rhs.mAncestorPrincipals)
+   , mAncestorOuterWindowIDs(rhs.mAncestorOuterWindowIDs)
+   , mCorsUnsafeHeaders(rhs.mCorsUnsafeHeaders)
+   , mForcePreflight(rhs.mForcePreflight)
+   , mIsPreflight(rhs.mIsPreflight)
+   , mLoadTriggeredFromExternal(rhs.mLoadTriggeredFromExternal)
+-  , mServiceWorkerTaintingSynthesized(rhs.mServiceWorkerTaintingSynthesized)
++  // mServiceWorkerTaintingSynthesized must be handled specially during redirect
++  , mServiceWorkerTaintingSynthesized(false)
+ {
+ }
+ 
+ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal,
+                    nsIPrincipal* aTriggeringPrincipal,
+                    nsIPrincipal* aPrincipalToInherit,
+                    nsIPrincipal* aSandboxedLoadingPrincipal,
+                    nsIURI* aResultPrincipalURI,
+diff --git a/netwerk/base/LoadInfo.h b/netwerk/base/LoadInfo.h
+--- a/netwerk/base/LoadInfo.h
++++ b/netwerk/base/LoadInfo.h
+@@ -73,24 +73,16 @@ public:
+   // nsBaseChannel::Redirect()
+   already_AddRefed<nsILoadInfo>
+   CloneWithNewSecFlags(nsSecurityFlags aSecurityFlags) const;
+   // creates a copy of the loadinfo which is appropriate to use for a
+   // separate request. I.e. not for a redirect or an inner channel, but
+   // when a separate request is made with the same security properties.
+   already_AddRefed<nsILoadInfo> CloneForNewRequest() const;
+ 
+-  // The service worker and fetch specifications require returning the
+-  // exact tainting level of the Response passed to FetchEvent.respondWith().
+-  // This method allows us to override the tainting level in that case.
+-  //
+-  // NOTE: This should not be used outside of service worker code! Use
+-  //       nsILoadInfo::MaybeIncreaseTainting() instead.
+-  void SynthesizeServiceWorkerTainting(LoadTainting aTainting);
+-
+   void SetIsPreflight();
+   void SetUpgradeInsecureRequests();
+ 
+ private:
+   // private constructor that is only allowed to be called from within
+   // HttpChannelParent and FTPChannelParent declared as friends undeneath.
+   // In e10s we can not serialize nsINode, hence we store the innerWindowID.
+   // Please note that aRedirectChain uses swapElements.
+diff --git a/netwerk/base/nsILoadInfo.idl b/netwerk/base/nsILoadInfo.idl
+--- a/netwerk/base/nsILoadInfo.idl
++++ b/netwerk/base/nsILoadInfo.idl
+@@ -37,16 +37,17 @@ native OriginAttributes(mozilla::OriginA
+ [ref] native Uint64ArrayRef(const nsTArray<uint64_t>);
+ [ref] native PrincipalArrayRef(const nsTArray<nsCOMPtr<nsIPrincipal>>);
+ [ref] native const_ClientInfoRef(const mozilla::dom::ClientInfo);
+       native UniqueClientSource(mozilla::UniquePtr<mozilla::dom::ClientSource>);
+       native UniqueClientSourceMove(mozilla::UniquePtr<mozilla::dom::ClientSource>&&);
+ [ref] native const_MaybeClientInfoRef(const mozilla::Maybe<mozilla::dom::ClientInfo>);
+ [ref] native const_ServiceWorkerDescriptorRef(const mozilla::dom::ServiceWorkerDescriptor);
+ [ref] native const_MaybeServiceWorkerDescriptorRef(const mozilla::Maybe<mozilla::dom::ServiceWorkerDescriptor>);
++      native LoadTainting(mozilla::LoadTainting);
+ 
+ typedef unsigned long nsSecurityFlags;
+ 
+ /**
+  * The LoadInfo object contains information about a network load, why it
+  * was started, and how we plan on using the resulting response.
+  * If a network request is redirected, the new channel will receive a new
+  * LoadInfo object. The new object will contain mostly the same
+@@ -929,9 +930,19 @@ interface nsILoadInfo : nsISupports
+   void ClearController();
+ 
+   /**
+    * Get the service worker controlling this network request, if one has
+    * been set.
+    */
+   [noscript, nostdcall, notxpcom]
+   const_MaybeServiceWorkerDescriptorRef GetController();
++
++  /* The service worker and fetch specifications require returning the
++   * exact tainting level of the Response passed to FetchEvent.respondWith().
++   * This method allows us to override the tainting level in that case.
++   *
++   * NOTE: This should not be used outside of service worker code! Use
++   *       nsILoadInfo::MaybeIncreaseTainting() instead.
++   */
++  [noscript, nostdcall, notxpcom]
++  void SynthesizeServiceWorkerTainting(in LoadTainting aTainting);
+ };
+diff --git a/netwerk/protocol/http/HttpChannelChild.cpp b/netwerk/protocol/http/HttpChannelChild.cpp
+--- a/netwerk/protocol/http/HttpChannelChild.cpp
++++ b/netwerk/protocol/http/HttpChannelChild.cpp
+@@ -1826,16 +1826,20 @@ HttpChannelChild::Redirect1Begin(const u
+ 
+ void
+ HttpChannelChild::BeginNonIPCRedirect(nsIURI* responseURI,
+                                       const nsHttpResponseHead* responseHead,
+                                       bool aResponseRedirected)
+ {
+   LOG(("HttpChannelChild::BeginNonIPCRedirect [this=%p]\n", this));
+ 
++  // This method is only used by child-side service workers.  It should not be
++  // used by new code.  We want to remove it in the future.
++  MOZ_DIAGNOSTIC_ASSERT(mSynthesizedResponse);
++
+   // If the response has been redirected, propagate all the URLs to content.
+   // Thus, the exact value of the redirect flag does not matter as long as it's
+   // not REDIRECT_INTERNAL.
+   const uint32_t redirectFlag =
+     aResponseRedirected ? nsIChannelEventSink::REDIRECT_TEMPORARY
+                         : nsIChannelEventSink::REDIRECT_INTERNAL;
+ 
+ 
+@@ -1851,16 +1855,30 @@ HttpChannelChild::BeginNonIPCRedirect(ns
+     // is a synthesized response that has its own security info, the pre-redirect channel
+     // has already received it and it must be propagated to the post-redirect channel.
+     nsCOMPtr<nsIHttpChannelChild> channelChild = do_QueryInterface(newChannel);
+     if (mSecurityInfo && channelChild) {
+       HttpChannelChild* httpChannelChild = static_cast<HttpChannelChild*>(channelChild.get());
+       httpChannelChild->OverrideSecurityInfoForNonIPCRedirect(mSecurityInfo);
+     }
+ 
++    // Normally we don't propagate the LoadInfo's service worker tainting
++    // synthesis flag on redirect.  A real redirect normally will want to allow
++    // normal tainting to proceed from its starting taint.  For this particular
++    // redirect, though, we are performing a redirect to communicate the URL of
++    // the service worker synthetic response itself.  This redirect still represents
++    // the synthetic response, so we must preserve the flag.
++    if (mLoadInfo && mLoadInfo->GetServiceWorkerTaintingSynthesized()) {
++      nsCOMPtr<nsILoadInfo> newChannelLoadInfo;
++      Unused << newChannel->GetLoadInfo(getter_AddRefs(newChannelLoadInfo));
++      if (newChannelLoadInfo) {
++        newChannelLoadInfo->SynthesizeServiceWorkerTainting(mLoadInfo->GetTainting());
++      }
++    }
++
+     nsCOMPtr<nsIEventTarget> target = GetNeckoTarget();
+     MOZ_ASSERT(target);
+ 
+     rv = gHttpHandler->AsyncOnChannelRedirect(this,
+                                               newChannel,
+                                               redirectFlag,
+                                               target);
+   }
+diff --git a/netwerk/protocol/http/InterceptedHttpChannel.cpp b/netwerk/protocol/http/InterceptedHttpChannel.cpp
+--- a/netwerk/protocol/http/InterceptedHttpChannel.cpp
++++ b/netwerk/protocol/http/InterceptedHttpChannel.cpp
+@@ -265,16 +265,27 @@ InterceptedHttpChannel::RedirectForRespo
+   uint32_t flags = aResponseRedirected ? nsIChannelEventSink::REDIRECT_TEMPORARY
+                                        : nsIChannelEventSink::REDIRECT_INTERNAL;
+ 
+   nsCOMPtr<nsILoadInfo> redirectLoadInfo =
+     CloneLoadInfoForRedirect(aResponseURI, flags);
+   newChannel->SetLoadInfo(redirectLoadInfo);
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
++  // Normally we don't propagate the LoadInfo's service worker tainting
++  // synthesis flag on redirect.  A real redirect normally will want to allow
++  // normal tainting to proceed from its starting taint.  For this particular
++  // redirect, though, we are performing a redirect to communicate the URL of
++  // the service worker synthetic response itself.  This redirect still represents
++  // the synthetic response, so we must preserve the flag.
++  if (redirectLoadInfo && mLoadInfo &&
++      mLoadInfo->GetServiceWorkerTaintingSynthesized()) {
++    redirectLoadInfo->SynthesizeServiceWorkerTainting(mLoadInfo->GetTainting());
++  }
++
+   rv = SetupReplacementChannel(aResponseURI, newChannel, true, flags);
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
+   mRedirectChannel = newChannel;
+ 
+   rv = gHttpHandler->AsyncOnChannelRedirect(this, mRedirectChannel, flags);
+ 
+   if (NS_FAILED(rv)) {

+ 141 - 0
mozilla-release/patches/1486445-1-64a1.patch

@@ -0,0 +1,141 @@
+# HG changeset patch
+# User Tom Tung <shes050117@gmail.com>
+# Date 1536756270 0
+# Node ID bd73949fded436506986d1d724d3d4878c3ba235
+# Parent  2a2ebc0a23ea8ff9ecd67a43f0c79d4bf320dd4e
+Bug 1486445 - P1 - Propagate the sw internally redirected URL to fetching request; r=asuth
+
+Bug 1222008 didn't propagate a sw redirected URL to outer response properly. To
+fix that this patch mainly make a redirecting request be overwritten while it's
+redirected by a service worker. This patch also add a private setter function
+for InternalRequest and a public checking function to avoid that function from
+being used widely.
+
+Differential Revision: https://phabricator.services.mozilla.com/D4762
+
+diff --git a/dom/fetch/FetchDriver.cpp b/dom/fetch/FetchDriver.cpp
+--- a/dom/fetch/FetchDriver.cpp
++++ b/dom/fetch/FetchDriver.cpp
+@@ -897,37 +897,41 @@ FetchDriver::AsyncOnChannelRedirect(nsIC
+     Unused << oldHttpChannel->GetResponseHeader(NS_LITERAL_CSTRING("referrer-policy"),
+                                                 tRPHeaderCValue);
+   }
+ 
+   // "HTTP-redirect fetch": step 14 "Append locationURL to request's URL list."
+   // However, ignore internal redirects here.  We don't want to flip
+   // Response.redirected to true if an internal redirect occurs.  These
+   // should be transparent to script.
+-  if (!(aFlags & nsIChannelEventSink::REDIRECT_INTERNAL)) {
+-    nsCOMPtr<nsIURI> uri;
+-    MOZ_ALWAYS_SUCCEEDS(aNewChannel->GetURI(getter_AddRefs(uri)));
++  nsCOMPtr<nsIURI> uri;
++  MOZ_ALWAYS_SUCCEEDS(aNewChannel->GetURI(getter_AddRefs(uri)));
+ 
+-    nsCOMPtr<nsIURI> uriClone;
+-    nsresult rv = uri->CloneIgnoringRef(getter_AddRefs(uriClone));
+-    if(NS_WARN_IF(NS_FAILED(rv))){
+-      return rv;
+-    }
+-    nsCString spec;
+-    rv = uriClone->GetSpec(spec);
+-    if(NS_WARN_IF(NS_FAILED(rv))){
+-      return rv;
+-    }
+-    nsCString fragment;
+-    rv = uri->GetRef(fragment);
+-    if(NS_WARN_IF(NS_FAILED(rv))){
+-      return rv;
+-    }
++  nsCOMPtr<nsIURI> uriClone;
++  nsresult rv = uri->CloneIgnoringRef(getter_AddRefs(uriClone));
++  if(NS_WARN_IF(NS_FAILED(rv))){
++    return rv;
++  }
++  nsCString spec;
++  rv = uriClone->GetSpec(spec);
++  if(NS_WARN_IF(NS_FAILED(rv))){
++    return rv;
++  }
++  nsCString fragment;
++  rv = uri->GetRef(fragment);
++  if(NS_WARN_IF(NS_FAILED(rv))){
++    return rv;
++  }
+ 
++  if (!(aFlags & nsIChannelEventSink::REDIRECT_INTERNAL)) {
+     mRequest->AddURL(spec, fragment);
++  } else {
++    // Overwrite the URL only when the request is redirected by a service
++    // worker.
++    mRequest->SetURLForInternalRedirect(aFlags, spec, fragment);
+   }
+ 
+   NS_ConvertUTF8toUTF16 tRPHeaderValue(tRPHeaderCValue);
+   // updates request’s associated referrer policy according to the
+   // Referrer-Policy header (if any).
+   if (!tRPHeaderValue.IsEmpty()) {
+     net::ReferrerPolicy net_referrerPolicy =
+       nsContentUtils::GetReferrerPolicyFromHeader(tRPHeaderValue);
+diff --git a/dom/fetch/InternalRequest.h b/dom/fetch/InternalRequest.h
+--- a/dom/fetch/InternalRequest.h
++++ b/dom/fetch/InternalRequest.h
+@@ -148,16 +148,30 @@ public:
+   const nsCString&
+   GetURLWithoutFragment() const
+   {
+     MOZ_RELEASE_ASSERT(!mURLList.IsEmpty(),
+                        "Internal Request's urlList should not be empty.");
+ 
+     return mURLList.LastElement();
+   }
++
++  // A safe guard for ensuring that request's URL is only allowed to be set in a
++  // sw internal redirect.
++  void
++  SetURLForInternalRedirect(const uint32_t aFlag,
++                            const nsACString& aURL,
++                            const nsACString& aFragment)
++  {
++    // Only check in debug build to prevent it from being used unexpectedly.
++    MOZ_ASSERT(aFlag & nsIChannelEventSink::REDIRECT_INTERNAL);
++
++    return SetURL(aURL, aFragment);
++  }
++
+   // AddURL should append the url into url list.
+   // Normally we strip the fragment from the URL in Request::Constructor and
+   // pass the fragment as the second argument into it.
+   // If a fragment is present in the URL it must be stripped and passed in
+   // separately.
+   void
+   AddURL(const nsACString& aURL, const nsACString& aFragment)
+   {
+@@ -544,16 +558,28 @@ private:
+   MapContentPolicyTypeToRequestContext(nsContentPolicyType aContentPolicyType);
+ 
+   static bool
+   IsNavigationContentPolicy(nsContentPolicyType aContentPolicyType);
+ 
+   static bool
+   IsWorkerContentPolicy(nsContentPolicyType aContentPolicyType);
+ 
++  // It should only be called while there is a service-worker-internal-redirect.
++  void
++  SetURL(const nsACString& aURL, const nsACString& aFragment)
++  {
++    MOZ_ASSERT(!aURL.IsEmpty());
++    MOZ_ASSERT(!aURL.Contains('#'));
++    MOZ_ASSERT(mURLList.Length() > 0);
++
++    mURLList.LastElement() = aURL;
++    mFragment.Assign(aFragment);
++  }
++
+   nsCString mMethod;
+   // mURLList: a list of one or more fetch URLs
+   nsTArray<nsCString> mURLList;
+   RefPtr<InternalHeaders> mHeaders;
+   nsCOMPtr<nsIInputStream> mBodyStream;
+   int64_t mBodyLength;
+ 
+   nsContentPolicyType mContentPolicyType;

+ 10 - 0
mozilla-release/patches/series

@@ -526,6 +526,13 @@ NOBUG-20170803-promisehelper-57a1.patch
 1037335-6-59a1.patch
 1401942-1-59a1.patch
 1401942-2-59a1.patch
+1222008-1-59a1.patch
+1222008-2-59a1.patch
+1222008-3-59a1.patch
+1222008-4no5-59a1.patch
+1222008-6-59a1.patch
+1222008-7no8-59a1.patch
+1222008-9-59a1.patch
 1333140-2no1-59a1.patch
 1421582-59a1.patch
 1403536-59a1.patch
@@ -2185,6 +2192,7 @@ servo-20082-60a1.patch
 1438389-60a1.patch
 1439923-60a1.patch
 1438118-60a1.patch
+1437760-1-60a1.patch
 1434593-60a1.patch
 1439736-60a1.patch
 1439437-60a1.patch
@@ -3932,6 +3940,7 @@ NOBUG-20180505-lint-61a1.patch
 1437942-62a1.patch
 1439383-62a1.patch
 1467938-62a1.patch
+1467852-62a1.patch
 1465709-1-62a1.patch
 1468272-62a1.patch
 1435813-1a-62a1.patch
@@ -4357,6 +4366,7 @@ NOBUG-20180824-buildsetting-63a1.patch
 1484611-2b-64a1.patch
 1417646-1-64a1.patch
 1487419-64a1.patch
+1486445-1-64a1.patch
 1489944-64a1.patch
 1489744-64a1.patch
 1490115-1-64a1.patch