Browse Source

nit fixes from reshuffle and a few backports

Frank-Rainer Grahl 1 year ago
parent
commit
250d188f62

+ 28 - 0
mozilla-release/patches/1344613-60a1.patch

@@ -0,0 +1,28 @@
+# HG changeset patch
+# User Arthur Edelstein <arthuredelstein@gmail.com>
+# Date 1518196200 -7200
+# Node ID e9ac867e3e3752422ef146c4247b7d19ac147462
+# Parent  66e0e987e150e700c5fbf929291c933e68a096a8
+Bug 1344613 - Avoid possibility of null pointer crash in nsSOCKSIOLayer.cpp r=mayhemer
+
+diff --git a/netwerk/socket/nsSOCKSIOLayer.cpp b/netwerk/socket/nsSOCKSIOLayer.cpp
+--- a/netwerk/socket/nsSOCKSIOLayer.cpp
++++ b/netwerk/socket/nsSOCKSIOLayer.cpp
+@@ -226,16 +226,17 @@ private:
+ };
+ 
+ nsSOCKSSocketInfo::nsSOCKSSocketInfo()
+     : mState(SOCKS_INITIAL)
+     , mDataIoPtr(nullptr)
+     , mDataLength(0)
+     , mReadOffset(0)
+     , mAmountToRead(0)
++    , mFD(nullptr)
+     , mVersion(-1)
+     , mDestinationFamily(AF_INET)
+     , mFlags(0)
+     , mTlsFlags(0)
+     , mTimeout(PR_INTERVAL_NO_TIMEOUT)
+ {
+     mData = new uint8_t[BUFFER_SIZE];
+ 

+ 208 - 0
mozilla-release/patches/1367861-59a1.patch

@@ -0,0 +1,208 @@
+# HG changeset patch
+# User Nicholas Hurley <hurley@mozilla.com>
+# Date 1515620102 28800
+# Node ID 06d10d09e6ee155539ed64bcb26a220639eaba00
+# Parent  a7df4254d962d6b236e0e8d290493921daae19fb
+Bug 1367861 - enable throttling for http/2. r=mayhemer
+
+This also fixes the bug that prevented throttled http/2 streams from
+ever re-starting by calling TransactionHasDataToRecv.
+
+MozReview-Commit-ID: 5dFotZGhQk9
+
+diff --git a/netwerk/protocol/http/Http2Session.cpp b/netwerk/protocol/http/Http2Session.cpp
+--- a/netwerk/protocol/http/Http2Session.cpp
++++ b/netwerk/protocol/http/Http2Session.cpp
+@@ -439,17 +439,17 @@ Http2Session::AddStream(nsAHttpTransacti
+                this, aHttpTransaction, trans, static_cast<uint32_t>(rv)));
+         }
+         return true;
+       }
+     }
+   }
+ 
+   aHttpTransaction->SetConnection(this);
+-  aHttpTransaction->OnActivated(true);
++  aHttpTransaction->OnActivated();
+ 
+   if (aUseTunnel) {
+     LOG3(("Http2Session::AddStream session=%p trans=%p OnTunnel",
+           this, aHttpTransaction));
+     DispatchOnTunnel(aHttpTransaction, aCallbacks);
+     return true;
+   }
+ 
+diff --git a/netwerk/protocol/http/nsAHttpTransaction.h b/netwerk/protocol/http/nsAHttpTransaction.h
+--- a/netwerk/protocol/http/nsAHttpTransaction.h
++++ b/netwerk/protocol/http/nsAHttpTransaction.h
+@@ -42,17 +42,17 @@ class nsAHttpTransaction : public nsSupp
+ public:
+     NS_DECLARE_STATIC_IID_ACCESSOR(NS_AHTTPTRANSACTION_IID)
+ 
+     // called by the connection when it takes ownership of the transaction.
+     virtual void SetConnection(nsAHttpConnection *) = 0;
+ 
+     // called by the connection after a successfull activation of this transaction
+     // in other words, tells the transaction it transitioned to the "active" state.
+-    virtual void OnActivated(bool h2) {}
++    virtual void OnActivated() {}
+ 
+     // used to obtain the connection associated with this transaction
+     virtual nsAHttpConnection *Connection() = 0;
+ 
+     // called by the connection to get security callbacks to set on the
+     // socket transport.
+     virtual void GetSecurityCallbacks(nsIInterfaceRequestor **) = 0;
+ 
+diff --git a/netwerk/protocol/http/nsHttpConnection.cpp b/netwerk/protocol/http/nsHttpConnection.cpp
+--- a/netwerk/protocol/http/nsHttpConnection.cpp
++++ b/netwerk/protocol/http/nsHttpConnection.cpp
+@@ -687,17 +687,17 @@ nsHttpConnection::Activate(nsAHttpTransa
+     }
+ 
+     if (mTLSFilter) {
+         rv = mTLSFilter->SetProxiedTransaction(trans);
+         NS_ENSURE_SUCCESS(rv, rv);
+         mTransaction = mTLSFilter;
+     }
+ 
+-    trans->OnActivated(false);
++    trans->OnActivated();
+ 
+     rv = OnOutputStreamReady(mSocketOut);
+ 
+ failed_activation:
+     if (NS_FAILED(rv)) {
+         mTransaction = nullptr;
+     }
+ 
+diff --git a/netwerk/protocol/http/nsHttpTransaction.cpp b/netwerk/protocol/http/nsHttpTransaction.cpp
+--- a/netwerk/protocol/http/nsHttpTransaction.cpp
++++ b/netwerk/protocol/http/nsHttpTransaction.cpp
+@@ -106,17 +106,16 @@ nsHttpTransaction::nsHttpTransaction()
+     , mCurrentHttpResponseHeaderSize(0)
+     , mThrottlingReadAllowance(THROTTLE_NO_LIMIT)
+     , mCapsToClear(0)
+     , mResponseIsComplete(false)
+     , mReadingStopped(false)
+     , mClosed(false)
+     , mConnected(false)
+     , mActivated(false)
+-    , mActivatedAsH2(false)
+     , mHaveStatusLine(false)
+     , mHaveAllHeaders(false)
+     , mTransactionDone(false)
+     , mDidContentStart(false)
+     , mNoContent(false)
+     , mSentData(false)
+     , mReceivedData(false)
+     , mStatusEventPending(false)
+@@ -168,16 +167,17 @@ void nsHttpTransaction::ResumeReading()
+ 
+     mReadingStopped = false;
+ 
+     // This with either reengage the limit when still throttled in WriteSegments or
+     // simply reset to allow unlimeted reading again.
+     mThrottlingReadAllowance = THROTTLE_NO_LIMIT;
+ 
+     if (mConnection) {
++        mConnection->TransactionHasDataToRecv(this);
+         nsresult rv = mConnection->ResumeRecv();
+         if (NS_FAILED(rv)) {
+             LOG(("  resume failed with rv=%" PRIx32, static_cast<uint32_t>(rv)));
+         }
+     }
+ }
+ 
+ bool nsHttpTransaction::EligibleForThrottling() const
+@@ -520,21 +520,20 @@ nsHttpTransaction::SetConnection(nsAHttp
+ {
+     {
+         MutexAutoLock lock(mLock);
+         mConnection = conn;
+     }
+ }
+ 
+ void
+-nsHttpTransaction::OnActivated(bool h2)
++nsHttpTransaction::OnActivated()
+ {
+     MOZ_ASSERT(OnSocketThread());
+ 
+-    mActivatedAsH2 = h2;
+     if (mActivated) {
+         return;
+     }
+ 
+     mActivated = true;
+     gHttpHandler->ConnMgr()->AddActiveTransaction(this);
+ }
+ 
+@@ -856,27 +855,16 @@ nsHttpTransaction::WritePipeSegment(nsIO
+     if (NS_FAILED(rv))
+         trans->Close(rv);
+ 
+     return rv; // failure code only stops WriteSegments; it is not propagated.
+ }
+ 
+ bool nsHttpTransaction::ShouldThrottle()
+ {
+-    if (mActivatedAsH2) {
+-        // Throttling feature is now disabled for http/2 transactions
+-        // because of bug 1367861.  The logic around mActivatedAsH2
+-        // will be removed when that is fixed.
+-        // 
+-        // Calling ShouldThrottle on the manager just to make sure
+-        // the throttling time window is correctly updated by this transaction.
+-        Unused << gHttpHandler->ConnMgr()->ShouldThrottle(this);
+-        return false;
+-    }
+-
+     if (mClassOfService & nsIClassOfService::DontThrottle) {
+         // We deliberately don't touch the throttling window here since
+         // DontThrottle requests are expected to be long-standing media
+         // streams and would just unnecessarily block running downloads.
+         // If we want to ballance bandwidth for media responses against
+         // running downloads, we need to find something smarter like 
+         // changing the suspend/resume throttling intervals at-runtime.
+         return false;
+diff --git a/netwerk/protocol/http/nsHttpTransaction.h b/netwerk/protocol/http/nsHttpTransaction.h
+--- a/netwerk/protocol/http/nsHttpTransaction.h
++++ b/netwerk/protocol/http/nsHttpTransaction.h
+@@ -84,17 +84,17 @@ public:
+                                uint64_t               reqContentLength,
+                                bool                   reqBodyIncludesHeaders,
+                                nsIEventTarget        *consumerTarget,
+                                nsIInterfaceRequestor *callbacks,
+                                nsITransportEventSink *eventsink,
+                                uint64_t               topLevelOuterContentWindowId,
+                                nsIAsyncInputStream  **responseBody);
+ 
+-    void OnActivated(bool h2) override;
++    void OnActivated() override;
+ 
+     // attributes
+     nsHttpResponseHead    *ResponseHead()   { return mHaveAllHeaders ? mResponseHead : nullptr; }
+     nsISupports           *SecurityInfo()   { return mSecurityInfo; }
+ 
+     nsIEventTarget        *ConsumerTarget() { return mConsumerTarget; }
+     nsISupports           *HttpChannel()    { return mChannel; }
+ 
+@@ -339,17 +339,16 @@ private:
+     // to resume reading.
+     bool                            mReadingStopped;
+ 
+     // state flags, all logically boolean, but not packed together into a
+     // bitfield so as to avoid bitfield-induced races.  See bug 560579.
+     bool                            mClosed;
+     bool                            mConnected;
+     bool                            mActivated;
+-    bool                            mActivatedAsH2;
+     bool                            mHaveStatusLine;
+     bool                            mHaveAllHeaders;
+     bool                            mTransactionDone;
+     bool                            mDidContentStart;
+     bool                            mNoContent; // expecting an empty entity body
+     bool                            mSentData;
+     bool                            mReceivedData;
+     bool                            mStatusEventPending;

+ 154 - 0
mozilla-release/patches/1397740-60a1.patch

@@ -0,0 +1,154 @@
+# HG changeset patch
+# User vinoth <cegvinoth@gmail.com>
+# Date 1515145397 -3600
+# Node ID c42ad5edc8833c30c2cedcc3229ce66784f237d9
+# Parent  5e27fbfeaba6e123621c53b8c37b695d2766cc6d
+Bug 1397740 - Removed security.xcto_nosniff_block_images from about:config r=ckerschb,fkiefer
+
+MozReview-Commit-ID: HTalMWq694W
+
+diff --git a/dom/security/test/general/test_nosniff.html b/dom/security/test/general/test_nosniff.html
+--- a/dom/security/test/general/test_nosniff.html
++++ b/dom/security/test/general/test_nosniff.html
+@@ -11,40 +11,34 @@
+   <link rel="stylesheet" id="cssWrongType">
+ </head>
+ <body>
+ 
+ <!-- add the two script tests -->
+ <script id="scriptCorrectType"></script>
+ <script id="scriptWrongType"></script>
+ 
+-<!-- add the two img tests -->
+-<img id="imgCorrectType" />
+-<img id="imgWrongType" />
+-
+ <script class="testbody" type="text/javascript">
+ /* Description of the test:
+  * We load 2 css files, 2 script files and 2 image files, where
+  * the sever either responds with the right mime type or
+  * the wrong mime type for each test.
+  */
+ 
+ SimpleTest.waitForExplicitFinish();
+-const NUM_TESTS = 6;
++const NUM_TESTS = 4;
+ 
+ var testCounter = 0;
+ function checkFinish() {
+ 	testCounter++;
+ 	if (testCounter === NUM_TESTS) {
+ 		SimpleTest.finish();
+ 	}
+ }
+ 
+-SpecialPowers.pushPrefEnv({set: [["security.xcto_nosniff_block_images", true]]}, function() {
+-
+   // 1) Test CSS with correct mime type
+   var cssCorrectType = document.getElementById("cssCorrectType");
+   cssCorrectType.onload = function() {
+     ok(true, "style nosniff correct type should load");
+     checkFinish();
+   }
+   cssCorrectType.onerror = function() {
+     ok(false, "style nosniff correct type should load");
+@@ -83,36 +77,12 @@ SpecialPowers.pushPrefEnv({set: [["secur
+     checkFinish();
+   }
+   scriptWrongType.onerror = function() {
+     ok(true, "script nosniff wrong type should not load");
+     checkFinish();
+   }
+   scriptWrongType.src = "file_nosniff_testserver.sjs?scriptWrongType";
+ 
+-  // 5) Test IMG with correct mime type
+-  var imgCorrectType = document.getElementById("imgCorrectType");
+-  imgCorrectType.onload = function() {
+-    ok(true, "img nosniff correct type should load");
+-    checkFinish();
+-  }
+-  imgCorrectType.onerror = function() {
+-    ok(false, "img nosniff correct type should load");
+-    checkFinish();
+-  }
+-  imgCorrectType.src = "file_nosniff_testserver.sjs?imgCorrectType";
+-
+-  // 6) Test IMG with wrong mime type
+-  var imgWrongType = document.getElementById("imgWrongType");
+-  imgWrongType.onload = function() {
+-    ok(false, "img nosniff wrong type should not load");
+-    checkFinish();
+-  }
+-  imgWrongType.onerror = function() {
+-    ok(true, "img nosniff wrong type should not load");
+-    checkFinish();
+-  }
+-  imgWrongType.src = "file_nosniff_testserver.sjs?imgWrongType";
+-});
+ 
+ </script>
+ </body>
+ </html>
+diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js
+--- a/modules/libpref/init/all.js
++++ b/modules/libpref/init/all.js
+@@ -2795,19 +2795,16 @@ pref("security.mixed_content.block_activ
+ pref("security.mixed_content.block_display_content", false);
+ 
+ // Sub-resource integrity
+ pref("security.sri.enable", true);
+ 
+ // Block scripts with wrong MIME type such as image/ or video/.
+ pref("security.block_script_with_wrong_mime", true);
+ 
+-// Block images of wrong MIME for XCTO: nosniff.
+-pref("security.xcto_nosniff_block_images", false);
+-
+ // OCSP must-staple
+ pref("security.ssl.enable_ocsp_must_staple", true);
+ 
+ // Insecure Form Field Warning
+ pref("security.insecure_field_warning.contextual.enabled", false);
+ pref("security.insecure_field_warning.ignore_local_ip_address", true);
+ 
+ // Disable pinning checks by default.
+diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp
+--- a/netwerk/protocol/http/nsHttpChannel.cpp
++++ b/netwerk/protocol/http/nsHttpChannel.cpp
+@@ -1277,36 +1277,16 @@ ProcessXCTO(nsIURI* aURI, nsHttpResponse
+     if (aLoadInfo->GetExternalContentPolicyType() == nsIContentPolicy::TYPE_STYLESHEET) {
+         if (contentType.EqualsLiteral(TEXT_CSS)) {
+             return NS_OK;
+         }
+         ReportTypeBlocking(aURI, aLoadInfo, "MimeTypeMismatch");
+         return NS_ERROR_CORRUPTED_CONTENT;
+     }
+ 
+-    if (aLoadInfo->GetExternalContentPolicyType() == nsIContentPolicy::TYPE_IMAGE) {
+-        if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("image/"))) {
+-            return NS_OK;
+-        }
+-        // Instead of consulting Preferences::GetBool() all the time we
+-        // can cache the result to speed things up.
+-        static bool sXCTONosniffBlockImages = false;
+-        static bool sIsInited = false;
+-        if (!sIsInited) {
+-            sIsInited = true;
+-            Preferences::AddBoolVarCache(&sXCTONosniffBlockImages,
+-            "security.xcto_nosniff_block_images");
+-        }
+-        if (!sXCTONosniffBlockImages) {
+-            return NS_OK;
+-        }
+-        ReportTypeBlocking(aURI, aLoadInfo, "MimeTypeMismatch");
+-        return NS_ERROR_CORRUPTED_CONTENT;
+-    }
+-
+     if (aLoadInfo->GetExternalContentPolicyType() == nsIContentPolicy::TYPE_SCRIPT) {
+         if (nsContentUtils::IsJavascriptMIMEType(NS_ConvertUTF8toUTF16(contentType))) {
+             return NS_OK;
+         }
+         ReportTypeBlocking(aURI, aLoadInfo, "MimeTypeMismatch");
+         return NS_ERROR_CORRUPTED_CONTENT;
+     }
+     return NS_OK;

+ 657 - 0
mozilla-release/patches/1405446-59a1.patch

@@ -0,0 +1,657 @@
+# HG changeset patch
+# User Honza Bambas <honzab.moz@firemni.cz>
+# Date 1515502680 18000
+# Node ID f6bd79484f2311acb4ebd7c1ee2071d9d2e29710
+# Parent  ac072dbb697e9bbc91f0ba70f128dee4582da0b9
+Bug 1405446 - Connections created for urgent-start requests are of limits for non-urgent-start ones, r=dragana
+
+diff --git a/netwerk/protocol/http/nsHttpConnection.cpp b/netwerk/protocol/http/nsHttpConnection.cpp
+--- a/netwerk/protocol/http/nsHttpConnection.cpp
++++ b/netwerk/protocol/http/nsHttpConnection.cpp
+@@ -14,16 +14,17 @@
+ #define LOG_ENABLED() LOG5_ENABLED()
+ 
+ #include "ASpdySession.h"
+ #include "mozilla/ChaosMode.h"
+ #include "nsHttpConnection.h"
+ #include "nsHttpHandler.h"
+ #include "nsHttpRequestHead.h"
+ #include "nsHttpResponseHead.h"
++#include "nsIClassOfService.h"
+ #include "nsIOService.h"
+ #include "nsISocketTransport.h"
+ #include "nsSocketTransportService2.h"
+ #include "nsISSLSocketControl.h"
+ #include "nsISupportsPriority.h"
+ #include "nsPreloadedStream.h"
+ #include "nsProxyRelease.h"
+ #include "nsSocketTransport2.h"
+@@ -46,16 +47,18 @@ nsHttpConnection::nsHttpConnection()
+     , mCallbacksLock("nsHttpConnection::mCallbacksLock")
+     , mConsiderReusedAfterInterval(0)
+     , mConsiderReusedAfterEpoch(0)
+     , mCurrentBytesRead(0)
+     , mMaxBytesRead(0)
+     , mTotalBytesRead(0)
+     , mTotalBytesWritten(0)
+     , mContentBytesWritten(0)
++    , mUrgentStartPreferred(false)
++    , mUrgentStartPreferredKnown(false)
+     , mConnectedTransport(false)
+     , mKeepAlive(true) // assume to keep-alive by default
+     , mKeepAliveMask(true)
+     , mDontReuse(false)
+     , mIsReused(false)
+     , mCompletedProxyConnect(false)
+     , mLastTransactionExpectedNoContent(false)
+     , mIdleMonitoring(false)
+@@ -591,16 +594,17 @@ nsHttpConnection::Activate(nsAHttpTransa
+ 
+     if (!mExperienced && !trans->IsNullTransaction()) {
+         if (!mFastOpen) {
+             mExperienced = true;
+         }
+         nsHttpTransaction *hTrans = trans->QueryHttpTransaction();
+         if (hTrans) {
+             hTrans->BootstrapTimings(mBootstrappedTimings);
++            SetUrgentStartPreferred(hTrans->ClassOfService() & nsIClassOfService::UrgentStart);
+         }
+         mBootstrappedTimings = TimingStruct();
+     }
+ 
+     mTransactionCaps = caps;
+     mPriority = pri;
+     if (mTransaction && mUsingSpdyVersion) {
+         return AddTransaction(trans, pri);
+@@ -1032,16 +1036,27 @@ nsHttpConnection::IsAlive()
+         LOG(("pretending socket is still alive to test restart logic\n"));
+         alive = true;
+     }
+ #endif
+ 
+     return alive;
+ }
+ 
++void
++nsHttpConnection::SetUrgentStartPreferred(bool urgent)
++{
++  if (mExperienced && !mUrgentStartPreferredKnown) {
++    // Set only according the first ever dispatched non-null transaction
++    mUrgentStartPreferredKnown = true;
++    mUrgentStartPreferred = urgent;
++    LOG(("nsHttpConnection::SetUrgentStartPreferred [this=%p urgent=%d]", this, urgent));
++  }
++}
++
+ //----------------------------------------------------------------------------
+ // nsHttpConnection::nsAHttpConnection compatible methods
+ //----------------------------------------------------------------------------
+ 
+ nsresult
+ nsHttpConnection::OnHeadersAvailable(nsAHttpTransaction *trans,
+                                      nsHttpRequestHead *requestHead,
+                                      nsHttpResponseHead *responseHead,
+@@ -2431,17 +2446,23 @@ nsHttpConnection::CloseConnectionFastOpe
+ 
+ void
+ nsHttpConnection::SetFastOpen(bool aFastOpen)
+ {
+     mFastOpen = aFastOpen;
+     if (!mFastOpen &&
+         mTransaction &&
+         !mTransaction->IsNullTransaction()) {
++
+         mExperienced = true;
++
++        nsHttpTransaction *hTrans = mTransaction->QueryHttpTransaction();
++        if (hTrans) {
++            SetUrgentStartPreferred(hTrans->ClassOfService() & nsIClassOfService::UrgentStart);
++        }
+     }
+ }
+ 
+ void
+ nsHttpConnection::SetFastOpenStatus(uint8_t tfoStatus) {
+     mFastOpenStatus = tfoStatus;
+     if ((mFastOpenStatus >= TFO_FAILED_CONNECTION_REFUSED) &&
+         (mFastOpenStatus <= TFO_FAILED_BACKUP_CONNECTION_TFO_DATA_COOKIE_NOT_ACCEPTED) &&
+diff --git a/netwerk/protocol/http/nsHttpConnection.h b/netwerk/protocol/http/nsHttpConnection.h
+--- a/netwerk/protocol/http/nsHttpConnection.h
++++ b/netwerk/protocol/http/nsHttpConnection.h
+@@ -130,16 +130,19 @@ public:
+ 
+     // A connection is forced into plaintext when it is intended to be used as a CONNECT
+     // tunnel but the setup fails. The plaintext only carries the CONNECT error.
+     void ForcePlainText()
+     {
+         mForcePlainText = true;
+     }
+ 
++    bool IsUrgentStartPreferred() const { return mUrgentStartPreferredKnown && mUrgentStartPreferred; }
++    void SetUrgentStartPreferred(bool urgent);
++
+     nsISocketTransport   *Transport()      { return mSocketTransport; }
+     nsAHttpTransaction   *Transaction()    { return mTransaction; }
+     nsHttpConnectionInfo *ConnectionInfo() { return mConnInfo; }
+ 
+     // nsAHttpConnection compatible methods (non-virtual):
+     MOZ_MUST_USE nsresult OnHeadersAvailable(nsAHttpTransaction *,
+                                              nsHttpRequestHead *,
+                                              nsHttpResponseHead *, bool *reset);
+@@ -321,16 +324,21 @@ private:
+     int64_t                         mTotalBytesRead;     // total data read
+     int64_t                         mTotalBytesWritten;  // does not include CONNECT tunnel
+     int64_t                         mContentBytesWritten;  // does not include CONNECT tunnel or TLS
+ 
+     RefPtr<nsIAsyncInputStream>   mInputOverflow;
+ 
+     PRIntervalTime                  mRtt;
+ 
++    // Whether the first non-null transaction dispatched on this connection was
++    // urgent-start or not
++    bool                            mUrgentStartPreferred;
++    // A flag to prevent reset of mUrgentStartPreferred by subsequent transactions
++    bool                            mUrgentStartPreferredKnown;
+     bool                            mConnectedTransport;
+     bool                            mKeepAlive;
+     bool                            mKeepAliveMask;
+     bool                            mDontReuse;
+     bool                            mIsReused;
+     bool                            mCompletedProxyConnect;
+     bool                            mLastTransactionExpectedNoContent;
+     bool                            mIdleMonitoring;
+diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.cpp b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
+--- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp
++++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
+@@ -1147,16 +1147,40 @@ nsHttpConnectionMgr::ProcessPendingQForE
+         LOG(("  %p", info->mTransaction.get()));
+       }
+       for (auto it = ent->mPendingTransactionTable.Iter(); !it.Done(); it.Next()) {
+         LOG(("] window id = %" PRIx64 " queue [", it.Key()));
+         for (auto info : *it.UserData()) {
+           LOG(("  %p", info->mTransaction.get()));
+         }
+       }
++      LOG(("] active urgent conns ["));
++      for (nsHttpConnection* conn : ent->mActiveConns) {
++        if (conn->IsUrgentStartPreferred()) {
++          LOG(("  %p", conn));
++        }
++      }
++      LOG(("] active regular conns ["));
++      for (nsHttpConnection* conn : ent->mActiveConns) {
++        if (!conn->IsUrgentStartPreferred()) {
++          LOG(("  %p", conn));
++        }
++      }
++      LOG(("] idle urgent conns ["));
++      for (nsHttpConnection* conn : ent->mIdleConns) {
++        if (conn->IsUrgentStartPreferred()) {
++          LOG(("  %p", conn));
++        }
++      }
++      LOG(("] idle regular conns ["));
++      for (nsHttpConnection* conn : ent->mIdleConns) {
++        if (!conn->IsUrgentStartPreferred()) {
++          LOG(("  %p", conn));
++        }
++      }
+       LOG(("]"));
+     }
+ 
+     if (!ent->mUrgentStartQ.Length() && !ent->PendingQLength()) {
+         return false;
+     }
+     ProcessSpdyPendingQ(ent);
+ 
+@@ -1340,17 +1364,18 @@ nsHttpConnectionMgr::MakeNewConnection(n
+     nsHttpTransaction *trans = pendingTransInfo->mTransaction;
+ 
+     LOG(("nsHttpConnectionMgr::MakeNewConnection %p ent=%p trans=%p",
+          this, ent, trans));
+     MOZ_ASSERT(OnSocketThread(), "not on socket thread");
+ 
+     uint32_t halfOpenLength = ent->mHalfOpens.Length();
+     for (uint32_t i = 0; i < halfOpenLength; i++) {
+-        if (ent->mHalfOpens[i]->Claim()) {
++        auto halfOpen = ent->mHalfOpens[i];
++        if (halfOpen->AcceptsTransaction(trans) && halfOpen->Claim()) {
+             // We've found a speculative connection or a connection that
+             // is free to be used in the half open list.
+             // A free to be used connection is a connection that was
+             // open for a concrete transaction, but that trunsaction
+             // ended up using another connection.
+             LOG(("nsHttpConnectionMgr::MakeNewConnection [ci = %s]\n"
+                  "Found a speculative or a free-to-use half open connection\n",
+                  ent->mConnInfo->HashKey().get()));
+@@ -1447,16 +1472,17 @@ nsHttpConnectionMgr::MakeNewConnection(n
+       outerLoopEnd:
+         ;
+     }
+ 
+     if (AtActiveConnectionLimit(ent, trans->Caps()))
+         return NS_ERROR_NOT_AVAILABLE;
+ 
+     nsresult rv = CreateTransport(ent, trans, trans->Caps(), false, false,
++                                  trans->ClassOfService() & nsIClassOfService::UrgentStart,
+                                   true, pendingTransInfo);
+     if (NS_FAILED(rv)) {
+         /* hard failure */
+         LOG(("nsHttpConnectionMgr::MakeNewConnection [ci = %s trans = %p] "
+              "CreateTransport() hard failure.\n",
+              ent->mConnInfo->HashKey().get(), trans));
+         trans->Close(rv);
+         if (rv == NS_ERROR_NOT_AVAILABLE)
+@@ -1578,45 +1604,21 @@ nsHttpConnectionMgr::TryDispatchTransact
+         if (!runNow) {
+             LOG(("   blocked due to rate pacing trans=%p\n", trans));
+             return NS_ERROR_NOT_AVAILABLE;
+         }
+     }
+ 
+     // step 2
+     // consider an idle persistent connection
++    bool idleConnsAllUrgent = false;
+     if (caps & NS_HTTP_ALLOW_KEEPALIVE) {
+-        RefPtr<nsHttpConnection> conn;
+-        while (!conn && (ent->mIdleConns.Length() > 0)) {
+-            conn = ent->mIdleConns[0];
+-            ent->mIdleConns.RemoveElementAt(0);
+-            mNumIdleConns--;
+-
+-            // we check if the connection can be reused before even checking if
+-            // it is a "matching" connection.
+-            if (!conn->CanReuse()) {
+-                LOG(("   dropping stale connection: [conn=%p]\n", conn.get()));
+-                conn->Close(NS_ERROR_ABORT);
+-                conn = nullptr;
+-            }
+-            else {
+-                LOG(("   reusing connection [conn=%p]\n", conn.get()));
+-                conn->EndIdleMonitoring();
+-            }
+-
+-            // If there are no idle connections left at all, we need to make
+-            // sure that we are not pruning dead connections anymore.
+-            ConditionallyStopPruneDeadConnectionsTimer();
+-        }
+-        if (conn) {
+-            // This will update the class of the connection to be the class of
+-            // the transaction dispatched on it.
+-            AddActiveConn(conn, ent);
+-            nsresult rv = DispatchTransaction(ent, trans, conn);
+-            NS_ENSURE_SUCCESS(rv, rv);
++        nsresult rv = TryDispatchTransactionOnIdleConn(ent, pendingTransInfo,
++                                                       true, &idleConnsAllUrgent);
++        if (NS_SUCCEEDED(rv)) {
+             LOG(("   dispatched step 2 (idle) trans=%p\n", trans));
+             return NS_OK;
+         }
+     }
+ 
+     // step 3
+     // consider pipelining scripts and revalidations
+     // h1 pipelining has been removed
+@@ -1632,16 +1634,31 @@ nsHttpConnectionMgr::TryDispatchTransact
+ 
+         if (rv != NS_ERROR_NOT_AVAILABLE) {
+             // not available return codes should try next step as they are
+             // not hard errors. Other codes should stop now
+             LOG(("   failed step 4 (%" PRIx32 ") trans=%p\n",
+                  static_cast<uint32_t>(rv), trans));
+             return rv;
+         }
++
++        // repeat step 2 when there are only idle connections and all are urgent,
++        // don't respect urgency so that non-urgent transaction will be allowed
++        // to dispatch on an urgent-start-only marked connection to avoid
++        // dispatch deadlocks
++        if (!(trans->ClassOfService() & nsIClassOfService::UrgentStart) &&
++            idleConnsAllUrgent &&
++            ent->mActiveConns.Length() < MaxPersistConnections(ent))
++        {
++            rv = TryDispatchTransactionOnIdleConn(ent, pendingTransInfo, false);
++            if (NS_SUCCEEDED(rv)) {
++                LOG(("   dispatched step 2a (idle, reuse urgent) trans=%p\n", trans));
++                return NS_OK;
++            }
++        }
+     } else if (trans->TunnelProvider() && trans->TunnelProvider()->MaybeReTunnel(trans)) {
+         LOG(("   sort of dispatched step 4a tunnel requeue trans=%p\n", trans));
+         // the tunnel provider took responsibility for making a new tunnel
+         return NS_OK;
+     }
+ 
+     // step 5
+     // previously pipelined anything here if allowed but h1 pipelining has been removed
+@@ -1654,16 +1671,82 @@ nsHttpConnectionMgr::TryDispatchTransact
+         unusedSpdyPersistentConnection->DontReuse();
+     }
+ 
+     LOG(("   not dispatched (queued) trans=%p\n", trans));
+     return NS_ERROR_NOT_AVAILABLE;                /* queue it */
+ }
+ 
+ nsresult
++nsHttpConnectionMgr::TryDispatchTransactionOnIdleConn(
++    nsConnectionEntry * ent, PendingTransactionInfo * pendingTransInfo,
++    bool respectUrgency, bool *allUrgent)
++{
++    bool onlyUrgent = !!ent->mIdleConns.Length();
++
++    nsHttpTransaction *trans = pendingTransInfo->mTransaction;
++    bool urgentTrans = trans->ClassOfService() & nsIClassOfService::UrgentStart;
++
++    LOG(("nsHttpConnectionMgr::TryDispatchTransactionOnIdleConn, ent=%p, trans=%p, urgent=%d",
++         ent, trans, urgentTrans));
++
++    RefPtr<nsHttpConnection> conn;
++    size_t index = 0;
++    while (!conn && (ent->mIdleConns.Length() > index)) {
++        conn = ent->mIdleConns[index];
++
++        // non-urgent transactions can only be dispatched on non-urgent
++        // started or used connections.
++        if (respectUrgency && conn->IsUrgentStartPreferred() && !urgentTrans) {
++            LOG(("  skipping urgent: [conn=%p]", conn.get()));
++            conn = nullptr;
++            ++index;
++            continue;
++        }
++
++        onlyUrgent = false;
++
++        ent->mIdleConns.RemoveElementAt(index);
++        mNumIdleConns--;
++
++        // we check if the connection can be reused before even checking if
++        // it is a "matching" connection.
++        if (!conn->CanReuse()) {
++            LOG(("   dropping stale connection: [conn=%p]\n", conn.get()));
++            conn->Close(NS_ERROR_ABORT);
++            conn = nullptr;
++        }
++        else {
++            LOG(("   reusing connection: [conn=%p]\n", conn.get()));
++            conn->EndIdleMonitoring();
++        }
++
++        // If there are no idle connections left at all, we need to make
++        // sure that we are not pruning dead connections anymore.
++        ConditionallyStopPruneDeadConnectionsTimer();
++    }
++
++    if (allUrgent) {
++        *allUrgent = onlyUrgent;
++    }
++
++    if (conn) {
++        // This will update the class of the connection to be the class of
++        // the transaction dispatched on it.
++        AddActiveConn(conn, ent);
++        nsresult rv = DispatchTransaction(ent, trans, conn);
++        NS_ENSURE_SUCCESS(rv, rv);
++
++        return NS_OK;
++    }
++
++    return NS_ERROR_NOT_AVAILABLE;
++}
++
++nsresult
+ nsHttpConnectionMgr::DispatchTransaction(nsConnectionEntry *ent,
+                                          nsHttpTransaction *trans,
+                                          nsHttpConnection *conn)
+ {
+     uint32_t caps = trans->Caps();
+     int32_t priority = trans->Priority();
+     nsresult rv;
+ 
+@@ -1947,26 +2030,28 @@ nsHttpConnectionMgr::ReleaseClaimedSocke
+ }
+ 
+ nsresult
+ nsHttpConnectionMgr::CreateTransport(nsConnectionEntry *ent,
+                                      nsAHttpTransaction *trans,
+                                      uint32_t caps,
+                                      bool speculative,
+                                      bool isFromPredictor,
++                                     bool urgentStart,
+                                      bool allow1918,
+                                      PendingTransactionInfo *pendingTransInfo)
+ {
+     MOZ_ASSERT(OnSocketThread(), "not on socket thread");
+     MOZ_ASSERT((speculative && !pendingTransInfo) ||
+                (!speculative && pendingTransInfo));
+ 
+     RefPtr<nsHalfOpenSocket> sock = new nsHalfOpenSocket(ent, trans, caps,
+                                                          speculative,
+-                                                         isFromPredictor);
++                                                         isFromPredictor,
++                                                         urgentStart);
+ 
+     if (speculative) {
+         sock->SetAllow1918(allow1918);
+     }
+     // The socket stream holds the reference to the half open
+     // socket - so if the stream fails to init the half open
+     // will go away.
+     nsresult rv = sock->SetupPrimaryStreams();
+@@ -3770,18 +3855,18 @@ nsHttpConnectionMgr::OnMsgSpeculativeCon
+     bool keepAlive = args->mTrans->Caps() & NS_HTTP_ALLOW_KEEPALIVE;
+     if (mNumHalfOpenConns < parallelSpeculativeConnectLimit &&
+         ((ignoreIdle && (ent->mIdleConns.Length() < parallelSpeculativeConnectLimit)) ||
+          !ent->mIdleConns.Length()) &&
+         !(keepAlive && RestrictConnections(ent)) &&
+         !AtActiveConnectionLimit(ent, args->mTrans->Caps())) {
+         DebugOnly<nsresult> rv = CreateTransport(ent, args->mTrans,
+                                                  args->mTrans->Caps(), true,
+-                                                 isFromPredictor, allow1918,
+-                                                 nullptr);
++                                                 isFromPredictor, false,
++                                                 allow1918, nullptr);
+         MOZ_ASSERT(NS_SUCCEEDED(rv));
+     } else {
+         LOG(("OnMsgSpeculativeConnect Transport "
+              "not created due to existing connection count\n"));
+     }
+ }
+ 
+ bool
+@@ -3828,21 +3913,23 @@ NS_INTERFACE_MAP_BEGIN(nsHttpConnectionM
+     } else
+ NS_INTERFACE_MAP_END
+ 
+ nsHttpConnectionMgr::
+ nsHalfOpenSocket::nsHalfOpenSocket(nsConnectionEntry *ent,
+                                    nsAHttpTransaction *trans,
+                                    uint32_t caps,
+                                    bool speculative,
+-                                   bool isFromPredictor)
++                                   bool isFromPredictor,
++                                   bool urgentStart)
+     : mTransaction(trans)
+     , mDispatchedMTransaction(false)
+     , mCaps(caps)
+     , mSpeculative(speculative)
++    , mUrgentStart(urgentStart)
+     , mIsFromPredictor(isFromPredictor)
+     , mAllow1918(true)
+     , mHasConnected(false)
+     , mPrimaryConnectedOK(false)
+     , mBackupConnectedOK(false)
+     , mFreeToUse(true)
+     , mPrimaryStreamStatus(NS_OK)
+     , mFastOpenInProgress(false)
+@@ -4628,16 +4715,25 @@ nsHalfOpenSocket::SetupConn(nsIAsyncOutp
+     if (nullTrans) {
+         conn->BootstrapTimings(nullTrans->Timings());
+     }
+ 
+     // Some capabilities are needed before a transaciton actually gets
+     // scheduled (e.g. how to negotiate false start)
+     conn->SetTransactionCaps(mTransaction->Caps());
+ 
++    if (mUrgentStart) {
++        // We deliberately leave this flag unset on the connection when
++        // this half-open was not marked urgent to let the first transaction
++        // dispatched on the connection set it.  Then we don't need to update
++        // all the speculative connect APIs to pass the urgency flag while
++        // we still get nearly (if not exactly) the same result.
++        conn->SetUrgentStartPreferred(true);
++    }
++
+     NetAddr peeraddr;
+     nsCOMPtr<nsIInterfaceRequestor> callbacks;
+     mTransaction->GetSecurityCallbacks(getter_AddRefs(callbacks));
+     nsresult rv;
+     if (out == mStreamOut) {
+         TimeDuration rtt = TimeStamp::Now() - mPrimarySynStarted;
+         rv = conn->Init(mEnt->mConnInfo,
+                         gHttpHandler->ConnMgr()->mMaxRequestDelay,
+@@ -4791,17 +4887,17 @@ nsHalfOpenSocket::SetupConn(nsIAsyncOutp
+     } else {
+         conn->SetFastOpenStatus(mFastOpenStatus);
+         mFastOpenStatus = TFO_BACKUP_CONN; // Set this to TFO_BACKUP_CONN so
+                                            // that if a backup connection is
+                                            // established we do not report
+                                            // values twice.
+     }
+ 
+-    // If this halfOpenConn was speculative, but at the ende the conn got a
++    // If this halfOpenConn was speculative, but at the end the conn got a
+     // non-null transaction than this halfOpen is not speculative anymore!
+     if (conn->Transaction() && !conn->Transaction()->IsNullTransaction()) {
+         Claim();
+     }
+ 
+     return rv;
+ }
+ 
+@@ -4957,16 +5053,24 @@ nsHttpConnectionMgr::nsHalfOpenSocket::G
+         mTransaction->GetSecurityCallbacks(getter_AddRefs(callbacks));
+         if (callbacks)
+             return callbacks->GetInterface(iid, result);
+     }
+     return NS_ERROR_NO_INTERFACE;
+ }
+ 
+ bool
++nsHttpConnectionMgr::nsHalfOpenSocket::AcceptsTransaction(nsHttpTransaction * trans)
++{
++    // When marked as urgent start, only accept urgent start marked transactions.
++    // Otherwise, accept any kind of transaction.
++    return !mUrgentStart || (trans->Caps() & nsIClassOfService::UrgentStart);
++}
++
++bool
+ nsHttpConnectionMgr::nsHalfOpenSocket::Claim()
+ {
+     if (mSpeculative) {
+         mSpeculative = false;
+         uint32_t flags;
+         if (mSocketTransport && NS_SUCCEEDED(mSocketTransport->GetConnectionFlags(&flags))) {
+             flags &= ~nsISocketTransport::DISABLE_RFC1918;
+             mSocketTransport->SetConnectionFlags(flags);
+diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.h b/netwerk/protocol/http/nsHttpConnectionMgr.h
+--- a/netwerk/protocol/http/nsHttpConnectionMgr.h
++++ b/netwerk/protocol/http/nsHttpConnectionMgr.h
+@@ -391,17 +391,18 @@ private:
+         NS_DECL_NSIINTERFACEREQUESTOR
+         NS_DECL_NSITIMERCALLBACK
+         NS_DECL_NSINAMED
+ 
+         nsHalfOpenSocket(nsConnectionEntry *ent,
+                          nsAHttpTransaction *trans,
+                          uint32_t caps,
+                          bool speculative,
+-                         bool isFromPredictor);
++                         bool isFromPredictor,
++                         bool urgentStart);
+ 
+         MOZ_MUST_USE nsresult SetupStreams(nsISocketTransport **,
+                                            nsIAsyncInputStream **,
+                                            nsIAsyncOutputStream **,
+                                            bool isBackup);
+         MOZ_MUST_USE nsresult SetupPrimaryStreams();
+         MOZ_MUST_USE nsresult SetupBackupStreams();
+         void     SetupBackupTimer();
+@@ -419,16 +420,20 @@ private:
+ 
+         bool Allow1918() { return mAllow1918; }
+         void SetAllow1918(bool val) { mAllow1918 = val; }
+ 
+         bool HasConnected() { return mHasConnected; }
+ 
+         void PrintDiagnostics(nsCString &log);
+ 
++        // Checks whether the transaction can be dispatched using this
++        // half-open's connection.  If this half-open is marked as urgent-start,
++        // it only accepts urgent start transactions.  Call only before Claim().
++        bool AcceptsTransaction(nsHttpTransaction* trans);
+         bool Claim();
+         void Unclaim();
+ 
+         bool FastOpenEnabled() override;
+         nsresult StartFastOpen() override;
+         void SetFastOpenConnected(nsresult, bool aWillRetry) override;
+         void FastOpenNotSupported() override;
+         void SetFastOpenStatus(uint8_t tfoStatus) override;
+@@ -455,16 +460,20 @@ private:
+         // SpeculativeConnect(). It is cleared when a transaction would normally
+         // start a new connection from scratch but instead finds this one in
+         // the half open list and claims it for its own use. (which due to
+         // the vagaries of scheduling from the pending queue might not actually
+         // match up - but it prevents a speculative connection from opening
+         // more connections that are needed.)
+         bool                           mSpeculative;
+ 
++        // If created with a non-null urgent transaction, remember it, so we can
++        // mark the connection as urgent rightaway it's created.
++        bool                           mUrgentStart;
++
+         // mIsFromPredictor is set if the socket originated from the network
+         // Predictor. It is used to gather data on used speculative
+         // connections from the predictor.
+         bool                           mIsFromPredictor;
+ 
+         bool                           mAllow1918;
+ 
+         TimeStamp             mPrimarySynStarted;
+@@ -577,31 +586,35 @@ private:
+     // Return |mMaxPersistConnsPerProxy| or |mMaxPersistConnsPerHost|,
+     // depending whether the proxy is used.
+     uint32_t MaxPersistConnections(nsConnectionEntry *ent) const;
+ 
+     bool     AtActiveConnectionLimit(nsConnectionEntry *, uint32_t caps);
+     MOZ_MUST_USE nsresult TryDispatchTransaction(nsConnectionEntry *ent,
+                                                  bool onlyReusedConnection,
+                                                  PendingTransactionInfo *pendingTransInfo);
++    MOZ_MUST_USE nsresult TryDispatchTransactionOnIdleConn(nsConnectionEntry *ent,
++                                                           PendingTransactionInfo *pendingTransInfo,
++                                                           bool respectUrgency,
++                                                           bool *allUrgent = nullptr);
+     MOZ_MUST_USE nsresult DispatchTransaction(nsConnectionEntry *,
+                                               nsHttpTransaction *,
+                                               nsHttpConnection *);
+     MOZ_MUST_USE nsresult DispatchAbstractTransaction(nsConnectionEntry *,
+                                                       nsAHttpTransaction *,
+                                                       uint32_t,
+                                                       nsHttpConnection *,
+                                                       int32_t);
+     bool     RestrictConnections(nsConnectionEntry *);
+     MOZ_MUST_USE nsresult ProcessNewTransaction(nsHttpTransaction *);
+     MOZ_MUST_USE nsresult EnsureSocketThreadTarget();
+     void     ClosePersistentConnections(nsConnectionEntry *ent);
+     MOZ_MUST_USE nsresult CreateTransport(nsConnectionEntry *,
+                                           nsAHttpTransaction *, uint32_t, bool,
+-                                          bool, bool,
++                                          bool, bool, bool,
+                                           PendingTransactionInfo *pendingTransInfo);
+     void     AddActiveConn(nsHttpConnection *, nsConnectionEntry *);
+     void     DecrementActiveConnCount(nsHttpConnection *);
+     void     StartedConnect();
+     void     RecvdConnect();
+ 
+     // This function will unclaim the claimed connection or set a halfOpen
+     // socket to the speculative state if the transaction claiming them ends up

+ 401 - 0
mozilla-release/patches/1416045-61a1.patch

@@ -0,0 +1,401 @@
+# HG changeset patch
+# User vinoth <cegvinoth@gmail.com>
+# Date 1521745336 -7200
+# Node ID a0a2092724797e534549cc2d80dc9c423bfaf43d
+# Parent  958cae7cd92e08ef9e8d8938560369bab0fcbff5
+Bug 1416045. r=mayhemer CLOSED TREE
+
+Reviewers: mayhemer
+
+Reviewed By: mayhemer
+
+Subscribers: freddyb, dveditz, mayhemer, ckerschb, vinoth
+
+Tags: PHID-PROJ-wkydohdk6pajyfn2llkb
+
+Bug #: 1416045
+
+Differential Revision: https://phabricator.services.mozilla.com/D675
+
+diff --git a/dom/security/test/csp/file_multipart_testserver.sjs b/dom/security/test/csp/file_multipart_testserver.sjs
+--- a/dom/security/test/csp/file_multipart_testserver.sjs
++++ b/dom/security/test/csp/file_multipart_testserver.sjs
+@@ -1,50 +1,150 @@
+ // SJS file specifically for the needs of bug
+-// Bug 1223743 - CSP: Check baseChannel for CSP when loading multipart channel
++// Bug 1416045/Bug 1223743 - CSP: Check baseChannel for CSP when loading multipart channel
+ 
+ var CSP = "script-src 'unsafe-inline', img-src 'none'";
+-var BOUNDARY = "fooboundary"
++var rootCSP = "script-src 'unsafe-inline'";
++var part1CSP = "img-src *";
++var part2CSP = "img-src 'none'";
++var BOUNDARY = "fooboundary";
+ 
+ // small red image
+ const IMG_BYTES = atob(
+   "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12" +
+   "P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==");
+ 
+ var RESPONSE = `
+   <script>
+   var myImg = new Image;
+   myImg.src = "file_multipart_testserver.sjs?img";
+   myImg.onerror = function(e) {
+-    window.parent.postMessage("img-blocked", "*");
++    window.parent.postMessage({"test": "rootCSP_test",
++                               "msg": "img-blocked"}, "*");
+   };
+   myImg.onload = function() {
+-    window.parent.postMessage("img-loaded", "*");
++    window.parent.postMessage({"test": "rootCSP_test",
++                               "msg": "img-loaded"}, "*");
+   };
+   document.body.appendChild(myImg);
+   </script>
+ `;
+ 
+-var myTimer;
++var RESPONSE1 = `
++  <body>
++  <script>
++  var triggerNextPartFrame = document.createElement('iframe');
++  var myImg = new Image;
++  myImg.src = "file_multipart_testserver.sjs?img";
++  myImg.onerror = function(e) {
++    window.parent.postMessage({"test": "part1CSP_test",
++                               "msg": "part1-img-blocked"}, "*");
++    triggerNextPartFrame.src = 'file_multipart_testserver.sjs?sendnextpart';
++  };
++  myImg.onload = function() {
++    window.parent.postMessage({"test": "part1CSP_test",
++                               "msg": "part1-img-loaded"}, "*");
++    triggerNextPartFrame.src = 'file_multipart_testserver.sjs?sendnextpart';
++  };
++  document.body.appendChild(myImg);
++  document.body.appendChild(triggerNextPartFrame);
++  </script>
++  </body>
++`;
++
++var RESPONSE2 = `
++  <body>
++  <script>
++  var myImg = new Image;
++  myImg.src = "file_multipart_testserver.sjs?img";
++  myImg.onerror = function(e) {
++    window.parent.postMessage({"test": "part2CSP_test",
++                               "msg": "part2-img-blocked"}, "*");
++  };
++  myImg.onload = function() {
++    window.parent.postMessage({"test": "part2CSP_test",
++                               "msg": "part2-img-loaded"}, "*");
++  };
++  document.body.appendChild(myImg);
++  </script>
++  </body>
++`;
++
++function setGlobalState(data, key)
++{
++  x = { data: data, QueryInterface: function(iid) { return this } };
++  x.wrappedJSObject = x;
++  setObjectState(key, x);
++}
++
++function getGlobalState(key)
++{
++  var data;
++  getObjectState(key, function(x) {
++    data = x && x.wrappedJSObject.data;
++  });
++  return data;
++}
+ 
+ function handleRequest(request, response)
+ {
+   // avoid confusing cache behaviors
+   response.setHeader("Cache-Control", "no-cache", false);
+ 
+   if (request.queryString == "doc") {
+     response.setHeader("Content-Security-Policy", CSP, false);
+     response.setHeader("Content-Type", "multipart/x-mixed-replace; boundary=" + BOUNDARY, false);
+     response.write(BOUNDARY + "\r\n");
+     response.write(RESPONSE);
+     response.write(BOUNDARY + "\r\n");
+     return;
+   }
+ 
++  if (request.queryString == "partcspdoc") {
++    response.setHeader("Content-Security-Policy", rootCSP, false);
++    response.setHeader("Content-Type",
++                       "multipart/x-mixed-replace; boundary=" + BOUNDARY, false);
++    response.setStatusLine(request.httpVersion, 200, "OK");
++    response.processAsync();
++    response.write("--"+BOUNDARY+"\r\n");
++    sendNextPart(response, 1);
++    return;
++  }
++
++  if (request.queryString == "sendnextpart") {
++    response.setStatusLine(request.httpVersion, 204, "No content");
++    var blockedResponse = getGlobalState("root-document-response");
++    if (typeof blockedResponse == "object") {
++      sendNextPart(blockedResponse, 2);
++      sendClose(blockedResponse);
++    } else {
++      dump("Couldn't find the stored response object.");
++    }
++    return;
++  }
++
+   if (request.queryString == "img") {
+     response.setHeader("Content-Type", "image/png");
+     response.write(IMG_BYTES);
+     return;
+   }
+ 
+   // we should never get here - return something unexpected
+   response.write("d'oh");
+ }
++
++function sendClose(response) {
++  response.write("--"+BOUNDARY+"--\r\n");
++  response.finish();
++}
++
++function sendNextPart(response, partNumber) {
++  response.write("Content-type: text/html" + "\r\n");
++  if (partNumber == 1) {
++    response.write("Content-Security-Policy:" + part1CSP + "\r\n");
++    response.write(RESPONSE1);
++    setGlobalState(response, "root-document-response");
++  } else {
++    response.write("Content-Security-Policy:" + part2CSP + "\r\n");
++    response.write(RESPONSE2);
++  }
++  response.write("--"+BOUNDARY+"\r\n");
++}
+diff --git a/dom/security/test/csp/test_multipartchannel.html b/dom/security/test/csp/test_multipartchannel.html
+--- a/dom/security/test/csp/test_multipartchannel.html
++++ b/dom/security/test/csp/test_multipartchannel.html
+@@ -1,34 +1,68 @@
+ <!DOCTYPE HTML>
+ <html>
+ <head>
+   <meta charset="utf-8">
+-  <title>Bug 1223743 - CSP: Check baseChannel for CSP when loading multipart channel</title>
++  <title>Bug 1416045/Bug 1223743 - CSP: Check baseChannel for CSP when loading multipart channel</title>
+   <!-- Including SimpleTest.js so we can use waitForExplicitFinish !-->
+   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+ </head>
+ <body>
+ <iframe style="width:100%;" id="testframe"></iframe>
++<iframe style="width:100%;" id="testPartCSPframe"></iframe>
+ 
+ <script class="testbody" type="text/javascript">
+ 
++var testsToRunMultipartCSP = {
++  rootCSP_test: false,
++  part1CSP_test: false,
++  part2CSP_test: false,
++};
++
+ SimpleTest.waitForExplicitFinish();
+ 
++function checkTestsCompleted() {
++  for (var prop in testsToRunMultipartCSP) {
++    // some test hasn't run yet so we're not done
++    if (!testsToRunMultipartCSP[prop]) {
++      return;
++    }
++  }
++  window.removeEventListener("message", receiveMessage);
++  SimpleTest.finish();
++}
+ /* Description of the test:
+  * We apply a CSP to a multipart channel and then try to load an image
+  * within a segment making sure the image is blocked correctly by CSP.
++ * We also provide CSP for each part and try to load an image in each
++ * part and make sure the image is loaded in first part and blocked in
++ * second part correctly based on its CSP accordingly.
+  */
+ 
+ window.addEventListener("message", receiveMessage);
+ function receiveMessage(event) {
+-  is(event.data, "img-blocked", "image should be blocked");
+-  window.removeEventListener("message", receiveMessage);
+-  SimpleTest.finish();
++  switch (event.data.test) {
++    case "rootCSP_test":
++      is(event.data.msg, "img-blocked", "image should be blocked");
++      testsToRunMultipartCSP["rootCSP_test"] = true;
++      break;
++    case "part1CSP_test":
++      is(event.data.msg, "part1-img-loaded", "Part1 image should be loaded");
++      testsToRunMultipartCSP["part1CSP_test"] = true;
++      break;
++    case "part2CSP_test":
++      is(event.data.msg, "part2-img-blocked", "Part2 image should be blocked");
++      testsToRunMultipartCSP["part2CSP_test"] = true;
++      break;
++  }
++  checkTestsCompleted();
+ }
+ 
+ // start the test
+ document.getElementById("testframe").src = "file_multipart_testserver.sjs?doc";
++document.getElementById("testPartCSPframe").src =
++                                    "file_multipart_testserver.sjs?partcspdoc";
+ 
+ </script>
+ </body>
+ </html>
+diff --git a/netwerk/streamconv/converters/nsMultiMixedConv.cpp b/netwerk/streamconv/converters/nsMultiMixedConv.cpp
+--- a/netwerk/streamconv/converters/nsMultiMixedConv.cpp
++++ b/netwerk/streamconv/converters/nsMultiMixedConv.cpp
+@@ -483,16 +483,22 @@ nsMultiMixedConv::OnStartRequest(nsIRequ
+ 
+     // ask the HTTP channel for the content-type and extract the boundary from it.
+     nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(mChannel, &rv);
+     if (NS_SUCCEEDED(rv)) {
+         rv = httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("content-type"), contentType);
+         if (NS_FAILED(rv)) {
+             return rv;
+         }
++        nsCString csp;
++        rv = httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("content-security-policy"),
++                                            csp);
++        if (NS_SUCCEEDED(rv)) {
++          mRootContentSecurityPolicy = csp;
++        }
+     } else {
+         // try asking the channel directly
+         rv = mChannel->GetContentType(contentType);
+         if (NS_FAILED(rv)) {
+             return NS_ERROR_FAILURE;
+         }
+     }
+ 
+@@ -523,16 +529,20 @@ nsMultiMixedConv::OnStartRequest(nsIRequ
+     mHeaderTokens[HEADER_CONTENT_DISPOSITION] =
+       mTokenizer.AddCustomToken("content-disposition", mTokenizer.CASE_INSENSITIVE, false);
+     mHeaderTokens[HEADER_SET_COOKIE] =
+       mTokenizer.AddCustomToken("set-cookie", mTokenizer.CASE_INSENSITIVE, false);
+     mHeaderTokens[HEADER_CONTENT_RANGE] =
+       mTokenizer.AddCustomToken("content-range", mTokenizer.CASE_INSENSITIVE, false);
+     mHeaderTokens[HEADER_RANGE] =
+       mTokenizer.AddCustomToken("range", mTokenizer.CASE_INSENSITIVE, false);
++    mHeaderTokens[HEADER_CONTENT_SECURITY_POLICY] =
++      mTokenizer.AddCustomToken("content-security-policy",
++                                mTokenizer.CASE_INSENSITIVE,
++                                false);
+ 
+     mLFToken = mTokenizer.AddCustomToken("\n", mTokenizer.CASE_SENSITIVE, false);
+     mCRLFToken = mTokenizer.AddCustomToken("\r\n", mTokenizer.CASE_SENSITIVE, false);
+ 
+     SwitchToControlParsing();
+ 
+     mBoundaryToken =
+       mTokenizer.AddCustomToken(mBoundary, mTokenizer.CASE_SENSITIVE);
+@@ -996,16 +1006,17 @@ nsMultiMixedConv::SendData()
+ }
+ 
+ void
+ nsMultiMixedConv::HeadersToDefault()
+ {
+     mContentLength = UINT64_MAX;
+     mContentType.Truncate();
+     mContentDisposition.Truncate();
++    mContentSecurityPolicy.Truncate();
+     mIsByteRangeRequest = false;
+ }
+ 
+ nsresult
+ nsMultiMixedConv::ProcessHeader()
+ {
+     mozilla::Tokenizer p(mResponseHeaderValue);
+ 
+@@ -1048,16 +1059,41 @@ nsMultiMixedConv::ProcessHeader()
+         return NS_ERROR_CORRUPTED_CONTENT;
+       }
+       mIsByteRangeRequest = true;
+       if (mContentLength == UINT64_MAX) {
+         mContentLength = uint64_t(mByteRangeEnd - mByteRangeStart + 1);
+       }
+       break;
+     }
++    case HEADER_CONTENT_SECURITY_POLICY: {
++      mContentSecurityPolicy = mResponseHeaderValue;
++      mContentSecurityPolicy.CompressWhitespace();
++      nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(mChannel);
++      if (httpChannel) {
++        nsCString resultCSP = mRootContentSecurityPolicy;
++        if (!mContentSecurityPolicy.IsEmpty()) {
++          // We are updating the root channel CSP header respectively for
++          // each part as: CSP-root + CSP-partN, where N is the part number.
++          // Here we append current part's CSP to root CSP and reset CSP
++          // header for each part.
++          if (!resultCSP.IsEmpty()) {
++            resultCSP.Append(";");
++          }
++          resultCSP.Append(mContentSecurityPolicy);
++        }
++        nsresult rv = httpChannel->SetResponseHeader(
++                        NS_LITERAL_CSTRING("Content-Security-Policy"),
++                        resultCSP, false);
++        if (NS_FAILED(rv)) {
++          return NS_ERROR_CORRUPTED_CONTENT;
++        }
++      }
++      break;
++    }
+     case HEADER_UNKNOWN:
+       // We ignore anything else...
+       break;
+     }
+ 
+     return NS_OK;
+ }
+ 
+diff --git a/netwerk/streamconv/converters/nsMultiMixedConv.h b/netwerk/streamconv/converters/nsMultiMixedConv.h
+--- a/netwerk/streamconv/converters/nsMultiMixedConv.h
++++ b/netwerk/streamconv/converters/nsMultiMixedConv.h
+@@ -146,16 +146,18 @@ protected:
+     nsCOMPtr<nsIStreamListener> mFinalListener; // this guy gets the converted data via his OnDataAvailable()
+ 
+     nsCOMPtr<nsIChannel> mChannel; // The channel as we get in in OnStartRequest call
+     RefPtr<nsPartChannel> mPartChannel;   // the channel for the given part we're processing.
+                                         // one channel per part.
+     nsCOMPtr<nsISupports> mContext;
+     nsCString           mContentType;
+     nsCString           mContentDisposition;
++    nsCString           mContentSecurityPolicy;
++    nsCString           mRootContentSecurityPolicy;
+     uint64_t            mContentLength;
+     uint64_t            mTotalSent;
+ 
+     // The following members are for tracking the byte ranges in
+     // multipart/mixed content which specified the 'Content-Range:'
+     // header...
+     int64_t             mByteRangeStart;
+     int64_t             mByteRangeEnd;
+@@ -193,16 +195,17 @@ protected:
+     enum EHeader : uint32_t {
+       HEADER_FIRST,
+       HEADER_CONTENT_TYPE = HEADER_FIRST,
+       HEADER_CONTENT_LENGTH,
+       HEADER_CONTENT_DISPOSITION,
+       HEADER_SET_COOKIE,
+       HEADER_CONTENT_RANGE,
+       HEADER_RANGE,
++      HEADER_CONTENT_SECURITY_POLICY,
+       HEADER_UNKNOWN
+     } mResponseHeader;
+     // Cumulated value of a response header.
+     nsCString mResponseHeaderValue;
+ 
+     nsCString mBoundary;
+     mozilla::IncrementalTokenizer mTokenizer;
+ 

+ 30 - 0
mozilla-release/patches/1425097-59a1.patch

@@ -0,0 +1,30 @@
+# HG changeset patch
+# User Dragana Damjanovic dd.mozilla@gmail.com
+# Date 1516165080 -7200
+# Node ID f1a74cfcfe1a4e126806a7f34335d31fabbceb57
+# Parent  4e546a4db0eebeaa19449789076cc571f593c042
+Bug 1425097 - We do not to close h2 connection in case one stream gets 425. r=mcmanus
+
+diff --git a/netwerk/protocol/http/nsHttpTransaction.cpp b/netwerk/protocol/http/nsHttpTransaction.cpp
+--- a/netwerk/protocol/http/nsHttpTransaction.cpp
++++ b/netwerk/protocol/http/nsHttpTransaction.cpp
+@@ -1642,16 +1642,19 @@ nsHttpTransaction::HandleContentStart()
+                 return NS_ERROR_NET_RESET;
+             }
+             break;
+         case 425:
+             LOG(("Too Early."));
+             if ((mEarlyDataDisposition == EARLY_425) && !mDoNotTryEarlyData) {
+                 mDoNotTryEarlyData = true;
+                 mForceRestart = true; // force restart has built in loop protection
++                if (mConnection->Version() == HTTP_VERSION_2) {
++                    mReuseOnRestart = true;
++                }
+                 return NS_ERROR_NET_RESET;
+             }
+             break;
+         }
+ 
+         if (mResponseHead->Status() == 200 &&
+             mConnection->IsProxyConnectInProgress()) {
+             // successful CONNECTs do not have response bodies

+ 52 - 0
mozilla-release/patches/1426831-60a1.patch

@@ -0,0 +1,52 @@
+# HG changeset patch
+# User Nils Ohlmeier [:drno] <drno@ohlmeier.org>
+# Date 1515547819 28800
+# Node ID 5058e3e4798eea793e935857eb84a8af0cd8487a
+# Parent  1e72d5d162ae43708dcbb0978c71b65058819f0d
+Bug 1426831: don't overwrite MaxMessageSize with default values. r=lennart.grahl+594092
+
+MozReview-Commit-ID: CiqoGUYbPR2
+
+diff --git a/netwerk/sctp/datachannel/DataChannel.cpp b/netwerk/sctp/datachannel/DataChannel.cpp
+--- a/netwerk/sctp/datachannel/DataChannel.cpp
++++ b/netwerk/sctp/datachannel/DataChannel.cpp
+@@ -438,16 +438,17 @@ DataChannelConnection::Init(unsigned sho
+                             SCTP_STREAM_RESET_EVENT,
+                             SCTP_STREAM_CHANGE_EVENT};
+   {
+     ASSERT_WEBRTC(NS_IsMainThread());
+     // MutexAutoLock lock(mLock); Not needed since we're on mainthread always
+ 
+     mSendInterleaved = false;
+     mPpidFragmentation = false;
++    mMaxMessageSizeSet = false;
+     SetMaxMessageSize(aMaxMessageSizeSet, aMaxMessageSize);
+ 
+     if (!sctp_initialized) {
+       LOG(("sctp_init"));
+ #ifdef MOZ_PEERCONNECTION
+       usrsctp_init(0,
+                    DataChannelConnection::SctpDtlsOutput,
+                    debug_printf
+@@ -609,16 +610,21 @@ error_cleanup:
+   return false;
+ }
+ 
+ void
+ DataChannelConnection::SetMaxMessageSize(bool aMaxMessageSizeSet, uint64_t aMaxMessageSize)
+ {
+   MutexAutoLock lock(mLock); // TODO: Needed?
+ 
++  if (mMaxMessageSizeSet && !aMaxMessageSizeSet) {
++    // Don't overwrite already set MMS with default values
++    return;
++  }
++
+   mMaxMessageSizeSet = aMaxMessageSizeSet;
+   mMaxMessageSize = aMaxMessageSize;
+ 
+   bool ppidFragmentationEnforced = false;
+   nsresult rv;
+   nsCOMPtr<nsIPrefService> prefs = do_GetService("@mozilla.org/preferences-service;1", &rv);
+   if (!NS_WARN_IF(NS_FAILED(rv))) {
+     nsCOMPtr<nsIPrefBranch> branch = do_QueryInterface(prefs);

+ 137 - 0
mozilla-release/patches/1430197-59a1.patch

@@ -0,0 +1,137 @@
+# HG changeset patch
+# User Honza Bambas <honzab.moz@firemni.cz>
+# Date 1515750660 -7200
+# Node ID 06dc5a5ea2238a6611c965bba2c46d1533524aa6
+# Parent  f72ef9800a0ee3277741e11ea4176b6f560db900
+Bug 1430197 - Remove the HTTP cache half-live experiment, r=michal
+
+diff --git a/netwerk/cache2/CacheObserver.cpp b/netwerk/cache2/CacheObserver.cpp
+--- a/netwerk/cache2/CacheObserver.cpp
++++ b/netwerk/cache2/CacheObserver.cpp
+@@ -18,20 +18,17 @@
+ #include <time.h>
+ #include <math.h>
+ 
+ namespace mozilla {
+ namespace net {
+ 
+ CacheObserver* CacheObserver::sSelf = nullptr;
+ 
+-static int32_t const kDefaultHalfLifeExperiment = -1; // Disabled
+-int32_t CacheObserver::sHalfLifeExperiment = kDefaultHalfLifeExperiment;
+-
+-static float const kDefaultHalfLifeHours = 1.0F; // 1 hour
++static float const kDefaultHalfLifeHours = 24.0F; // 24 hours
+ float CacheObserver::sHalfLifeHours = kDefaultHalfLifeHours;
+ 
+ static bool const kDefaultUseDiskCache = true;
+ bool CacheObserver::sUseDiskCache = kDefaultUseDiskCache;
+ 
+ static bool const kDefaultUseMemoryCache = true;
+ bool CacheObserver::sUseMemoryCache = kDefaultUseMemoryCache;
+ 
+@@ -178,62 +175,18 @@ CacheObserver::AttachToPreferences()
+   // http://mxr.mozilla.org/mozilla-central/source/netwerk/cache/nsCacheEntryDescriptor.cpp#367
+   mozilla::Preferences::AddUintVarCache(
+     &sCompressionLevel, "browser.cache.compression_level", kDefaultCompressionLevel);
+ 
+   mozilla::Preferences::GetComplex(
+     "browser.cache.disk.parent_directory", NS_GET_IID(nsIFile),
+     getter_AddRefs(mCacheParentDirectoryOverride));
+ 
+-  // First check the default value.  If it is at -1, the experient
+-  // is turned off.  If it is at 0, then use the user pref value
+-  // instead.
+-  sHalfLifeExperiment = mozilla::Preferences::GetInt(
+-    "browser.cache.frecency_experiment", kDefaultHalfLifeExperiment,
+-    PrefValueKind::Default);
+-
+-  if (sHalfLifeExperiment == 0) {
+-    // Default preferences indicate we want to run the experiment,
+-    // hence read the user value.
+-    sHalfLifeExperiment = mozilla::Preferences::GetInt(
+-      "browser.cache.frecency_experiment", sHalfLifeExperiment);
+-  }
+-
+-  if (sHalfLifeExperiment == 0) {
+-    // The experiment has not yet been initialized but is engaged, do
+-    // the initialization now.
+-    srand(time(NULL));
+-    sHalfLifeExperiment = (rand() % 4) + 1;
+-    // Store the experiemnt value, since we need it not to change between
+-    // browser sessions.
+-    mozilla::Preferences::SetInt(
+-      "browser.cache.frecency_experiment", sHalfLifeExperiment);
+-  }
+-
+-  switch (sHalfLifeExperiment) {
+-  case 1: // The experiment is engaged
+-    sHalfLifeHours = 0.083F; // ~5 mintues
+-    break;
+-  case 2:
+-    sHalfLifeHours = 0.25F; // 15 mintues
+-    break;
+-  case 3:
+-    sHalfLifeHours = 1.0F;
+-    break;
+-  case 4:
+-    sHalfLifeHours = 6.0F;
+-    break;
+-
+-  case -1:
+-  default: // The experiment is off or broken
+-    sHalfLifeExperiment = -1;
+-    sHalfLifeHours = std::max(0.01F, std::min(1440.0F, mozilla::Preferences::GetFloat(
+-      "browser.cache.frecency_half_life_hours", kDefaultHalfLifeHours)));
+-    break;
+-  }
++  sHalfLifeHours = std::max(0.01F, std::min(1440.0F, mozilla::Preferences::GetFloat(
++    "browser.cache.frecency_half_life_hours", kDefaultHalfLifeHours)));
+ 
+   mozilla::Preferences::AddBoolVarCache(
+     &sSanitizeOnShutdown, "privacy.sanitize.sanitizeOnShutdown", kDefaultSanitizeOnShutdown);
+   mozilla::Preferences::AddBoolVarCache(
+     &sClearCacheOnShutdown, "privacy.clearOnShutdown.cache", kDefaultClearCacheOnShutdown);
+ 
+   mozilla::Preferences::AddAtomicUintVarCache(
+     &sMaxShutdownIOLag, "browser.cache.max_shutdown_io_lag", kDefaultMaxShutdownIOLag);
+diff --git a/netwerk/cache2/CacheObserver.h b/netwerk/cache2/CacheObserver.h
+--- a/netwerk/cache2/CacheObserver.h
++++ b/netwerk/cache2/CacheObserver.h
+@@ -51,18 +51,16 @@ class CacheObserver : public nsIObserver
+     { return sMaxDiskEntrySize << 10; }
+   static uint32_t MaxDiskChunksMemoryUsage(bool aPriority) // result in bytes.
+     { return aPriority ? sMaxDiskPriorityChunksMemoryUsage << 10
+                        : sMaxDiskChunksMemoryUsage << 10; }
+   static uint32_t CompressionLevel()
+     { return sCompressionLevel; }
+   static uint32_t HalfLifeSeconds()
+     { return sHalfLifeHours * 60.0F * 60.0F; }
+-  static int32_t HalfLifeExperiment()
+-    { return sHalfLifeExperiment; }
+   static bool ClearCacheOnShutdown()
+     { return sSanitizeOnShutdown && sClearCacheOnShutdown; }
+   static bool CacheFSReported()
+     { return sCacheFSReported; }
+   static void SetCacheFSReported();
+   static bool HashStatsReported()
+     { return sHashStatsReported; }
+   static void SetHashStatsReported();
+@@ -96,17 +94,16 @@ private:
+   static bool sSmartCacheSizeEnabled;
+   static uint32_t sPreloadChunkCount;
+   static int32_t sMaxMemoryEntrySize;
+   static int32_t sMaxDiskEntrySize;
+   static uint32_t sMaxDiskChunksMemoryUsage;
+   static uint32_t sMaxDiskPriorityChunksMemoryUsage;
+   static uint32_t sCompressionLevel;
+   static float sHalfLifeHours;
+-  static int32_t sHalfLifeExperiment;
+   static bool sSanitizeOnShutdown;
+   static bool sClearCacheOnShutdown;
+   static bool sCacheFSReported;
+   static bool sHashStatsReported;
+   static Atomic<uint32_t, Relaxed> sMaxShutdownIOLag;
+   static Atomic<PRIntervalTime> sShutdownDemandedTime;
+ 
+   // Non static properties, accessible via sSelf

+ 108 - 0
mozilla-release/patches/1430738-60a1.patch

@@ -0,0 +1,108 @@
+# HG changeset patch
+# User Dragana Damjanovic dd.mozilla@gmail.com
+# Date 1516641000 18000
+# Node ID 07bbea0845841befecc583ea661879e7b47082a4
+# Parent  c09c2f1b86268b384d42778518b9a7c20ea65803
+Bug 1430738 - Fix the channel timing info if a halfOpenSocket is opened with a non-null httpTransaction. r=mcmanus
+
+diff --git a/netwerk/protocol/http/nsHttpConnection.cpp b/netwerk/protocol/http/nsHttpConnection.cpp
+--- a/netwerk/protocol/http/nsHttpConnection.cpp
++++ b/netwerk/protocol/http/nsHttpConnection.cpp
+@@ -85,16 +85,17 @@ nsHttpConnection::nsHttpConnection()
+     , mContentBytesWritten0RTT(0)
+     , mDid0RTTSpdy(false)
+     , mFastOpen(false)
+     , mFastOpenStatus(TFO_NOT_SET)
+     , mForceSendDuringFastOpenPending(false)
+     , mReceivedSocketWouldBlockDuringFastOpen(false)
+     , mCheckNetworkStallsWithTFO(false)
+     , mLastRequestBytesSentTime(0)
++    , mBootstrappedTimingsSet(false)
+ {
+     LOG(("Creating nsHttpConnection @%p\n", this));
+ 
+     // the default timeout is for when this connection has not yet processed a
+     // transaction
+     static const PRIntervalTime k5Sec = PR_SecondsToInterval(5);
+     mIdleTimeout =
+         (k5Sec < gHttpHandler->IdleTimeout()) ? k5Sec : gHttpHandler->IdleTimeout();
+@@ -591,20 +592,23 @@ nsHttpConnection::Activate(nsAHttpTransa
+     MOZ_ASSERT(OnSocketThread(), "not on socket thread");
+     LOG(("nsHttpConnection::Activate [this=%p trans=%p caps=%x]\n",
+          this, trans, caps));
+ 
+     if (!mExperienced && !trans->IsNullTransaction()) {
+         if (!mFastOpen) {
+             mExperienced = true;
+         }
+-        nsHttpTransaction *hTrans = trans->QueryHttpTransaction();
+-        if (hTrans) {
+-            hTrans->BootstrapTimings(mBootstrappedTimings);
+-            SetUrgentStartPreferred(hTrans->ClassOfService() & nsIClassOfService::UrgentStart);
++        if (mBootstrappedTimingsSet) {
++            mBootstrappedTimingsSet = false;
++            nsHttpTransaction *hTrans = trans->QueryHttpTransaction();
++            if (hTrans) {
++                hTrans->BootstrapTimings(mBootstrappedTimings);
++                SetUrgentStartPreferred(hTrans->ClassOfService() & nsIClassOfService::UrgentStart);
++            }
+         }
+         mBootstrappedTimings = TimingStruct();
+     }
+ 
+     mTransactionCaps = caps;
+     mPriority = pri;
+     if (mTransaction && mUsingSpdyVersion) {
+         return AddTransaction(trans, pri);
+@@ -2481,28 +2485,29 @@ nsHttpConnection::SetFastOpenStatus(uint
+             }
+         }
+     }
+ }
+ 
+ void
+ nsHttpConnection::BootstrapTimings(TimingStruct times)
+ {
++    mBootstrappedTimingsSet = true;
+     mBootstrappedTimings = times;
+ }
+ 
+ void
+ nsHttpConnection::SetEvent(nsresult aStatus)
+ {
+   switch (aStatus) {
+   case NS_NET_STATUS_RESOLVING_HOST:
+     mBootstrappedTimings.domainLookupStart = TimeStamp::Now();
+     break;
+   case NS_NET_STATUS_RESOLVED_HOST:
+-    mBootstrappedTimings.domainLookupStart = TimeStamp::Now();
++    mBootstrappedTimings.domainLookupEnd = TimeStamp::Now();
+     break;
+   case NS_NET_STATUS_CONNECTING_TO:
+     mBootstrappedTimings.connectStart = TimeStamp::Now();
+     break;
+   case NS_NET_STATUS_CONNECTED_TO:
+   {
+     TimeStamp tnow = TimeStamp::Now();
+     mBootstrappedTimings.tcpConnectEnd = tnow;
+diff --git a/netwerk/protocol/http/nsHttpConnection.h b/netwerk/protocol/http/nsHttpConnection.h
+--- a/netwerk/protocol/http/nsHttpConnection.h
++++ b/netwerk/protocol/http/nsHttpConnection.h
+@@ -413,16 +413,17 @@ private:
+     bool                           mReceivedSocketWouldBlockDuringFastOpen;
+     bool                           mCheckNetworkStallsWithTFO;
+     PRIntervalTime                 mLastRequestBytesSentTime;
+ 
+ public:
+     void BootstrapTimings(TimingStruct times);
+ private:
+     TimingStruct    mBootstrappedTimings;
++    bool            mBootstrappedTimingsSet;
+ };
+ 
+ NS_DEFINE_STATIC_IID_ACCESSOR(nsHttpConnection, NS_HTTPCONNECTION_IID)
+ 
+ } // namespace net
+ } // namespace mozilla
+ 
+ #endif // nsHttpConnection_h__

+ 44 - 0
mozilla-release/patches/1433982-60a1.patch

@@ -0,0 +1,44 @@
+# HG changeset patch
+# User Nicholas Nethercote <nnethercote@mozilla.com>
+# Date 1517353286 -39600
+# Node ID 5ada933db7e2887646d64b44525da5daf5f44b85
+# Parent  03c14ea47865f40b1da9a30191d9948ee07e49aa
+Bug 1433982 - Make nsAtomicFileOutputStream::DoOpen() fail if the file is read-only. r=glandium
+
+This means we don't leave behind prefs-<n>.js files when prefs.js is read-only.
+
+MozReview-Commit-ID: H6KKnoYGdhH
+
+diff --git a/netwerk/base/nsFileStreams.cpp b/netwerk/base/nsFileStreams.cpp
+--- a/netwerk/base/nsFileStreams.cpp
++++ b/netwerk/base/nsFileStreams.cpp
+@@ -800,21 +800,28 @@ nsAtomicFileOutputStream::DoOpen()
+ 
+         // XP_UNIX ignores SetFollowLinks(), so we have to normalize.
+         if (mTargetFileExists) {
+             tempResult->Normalize();
+         }
+     }
+ 
+     if (NS_SUCCEEDED(rv) && mTargetFileExists) {
++        // Abort if |file| is not writable; it won't work as an output stream.
++        bool isWritable;
++        if (NS_SUCCEEDED(file->IsWritable(&isWritable)) && !isWritable) {
++            return NS_ERROR_FILE_ACCESS_DENIED;
++        }
++
+         uint32_t origPerm;
+         if (NS_FAILED(file->GetPermissions(&origPerm))) {
+             NS_ERROR("Can't get permissions of target file");
+             origPerm = mOpenParams.perm;
+         }
++
+         // XXX What if |perm| is more restrictive then |origPerm|?
+         // This leaves the user supplied permissions as they were.
+         rv = tempResult->CreateUnique(nsIFile::NORMAL_FILE_TYPE, origPerm);
+     }
+     if (NS_SUCCEEDED(rv)) {
+         // nsFileOutputStream::DoOpen will work on the temporary file, so we
+         // prepare it and place it in mOpenParams.localFile.
+         mOpenParams.localFile = tempResult;
+

+ 31 - 0
mozilla-release/patches/1436134-60a1.patch

@@ -0,0 +1,31 @@
+# HG changeset patch
+# User Patrick McManus <mcmanus@ducksong.com>
+# Date 1517944563 18000
+# Node ID ddb0033c54cb2175ffa1b58d0a3554808895c54f
+# Parent  c872c592b152f2c6abc69cee24d96a50751b725a
+Bug 1436134 - disable rcwn for non-safe http methods r=valentin
+
+MozReview-Commit-ID: 3Ip1M7L3gUl
+
+diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp
+--- a/netwerk/protocol/http/nsHttpChannel.cpp
++++ b/netwerk/protocol/http/nsHttpChannel.cpp
+@@ -3624,17 +3624,17 @@ nsHttpChannel::OpenCacheEntry(bool isHtt
+         rv = cacheStorageService->PinningCacheStorage(info,
+             getter_AddRefs(cacheStorage));
+     }
+     else {
+         bool lookupAppCache = !mPostID && (mChooseApplicationCache ||
+                               (mLoadFlags & LOAD_CHECK_OFFLINE_CACHE));
+         // Try to race only if we use disk cache storage and we don't lookup
+         // app cache first
+-        maybeRCWN = !lookupAppCache;
++        maybeRCWN = (!lookupAppCache) && mRequestHead.IsSafeMethod();
+         rv = cacheStorageService->DiskCacheStorage(
+             info, lookupAppCache, getter_AddRefs(cacheStorage));
+     }
+     NS_ENSURE_SUCCESS(rv, rv);
+ 
+     if ((mClassOfService & nsIClassOfService::Leader) ||
+         (mLoadFlags & LOAD_INITIAL_DOCUMENT_URI))
+         cacheEntryOpenFlags |= nsICacheStorage::OPEN_PRIORITY;

+ 34 - 0
mozilla-release/patches/1438332-60a1.patch

@@ -0,0 +1,34 @@
+# HG changeset patch
+# User Valentin Gosu <valentin.gosu@gmail.com>
+# Date 1518823551 -3600
+# Node ID fa721c35fc3fd89c0acf8b55a625425bda70d7c7
+# Parent  dcf78d1d2428243f88ab0604ff570d9e25dc39f1
+Bug 1438332 - Change RCWN test to expect the to account for very fast code execution r=michal
+
+The test would set a timer for 200ms then expect to be called back more than 200ms later (as in 201ms or more)
+This change makes sure that we don't fail if the callback comes back exactly 200ms later.
+
+MozReview-Commit-ID: 1OCyO3juAdZ
+
+diff --git a/netwerk/test/unit/test_race_cache_with_network.js b/netwerk/test/unit/test_race_cache_with_network.js
+--- a/netwerk/test/unit/test_race_cache_with_network.js
++++ b/netwerk/test/unit/test_race_cache_with_network.js
+@@ -112,17 +112,17 @@ function *testSteps() {
+   equal(g304Counter, 1, "check number of 304 responses");
+ 
+   // Checks that delaying the response from the cache works.
+   var channel = make_channel("http://localhost:" + PORT + "/rcwn");
+   channel.QueryInterface(Ci.nsIRaceCacheWithNetwork).test_delayCacheEntryOpeningBy(200);
+   let startTime = Date.now();
+   channel.asyncOpen2(new ChannelListener(checkContent, null));
+   yield undefined;
+-  greater(Date.now() - startTime, 200, "Check that timer works properly");
++  greaterOrEqual(Date.now() - startTime, 200, "Check that timer works properly");
+   equal(gResponseCounter, 3);
+   equal(g200Counter, 1, "check number of 200 responses");
+   equal(g304Counter, 2, "check number of 304 responses");
+ 
+   // Checks that we can trigger the cache open immediately, even if the cache delay is set very high.
+   var channel = make_channel("http://localhost:" + PORT + "/rcwn");
+   channel.QueryInterface(Ci.nsIRaceCacheWithNetwork).test_delayCacheEntryOpeningBy(100000);
+   channel.asyncOpen2(new ChannelListener(checkContent, null));

+ 59 - 0
mozilla-release/patches/1439362-60a1.patch

@@ -0,0 +1,59 @@
+# HG changeset patch
+# User Nathan Froyd <froydnj@mozilla.com>
+# Date 1519054080 18000
+# Node ID 43b8d13b99614f5929174d1d1c5bb147458e738e
+# Parent  566979b34c1954fd7cb3d6c02fde2f2d6bf63bee
+Bug 1439362 - make nsBase64Encoder slightly less malloc-happy; r=valentin
+
+nsBase64Encoder::Finish currently works by calling PL_Base64Encode to
+allocate a base64-encoded string, then Assign()'ing that to the result
+string, another allocation.  mozilla::Base64Encode enables us to base64
+encode directly into the result string with a single allocation, saving
+an allocation.  (Base64Encode is also slightly more efficient, because
+we don't have to do a strlen() on the string being Assign()'d.)  Let's
+use Base64Encode instead.
+
+diff --git a/netwerk/base/nsBase64Encoder.cpp b/netwerk/base/nsBase64Encoder.cpp
+--- a/netwerk/base/nsBase64Encoder.cpp
++++ b/netwerk/base/nsBase64Encoder.cpp
+@@ -1,16 +1,15 @@
+ /* This Source Code Form is subject to the terms of the Mozilla Public
+  * License, v. 2.0. If a copy of the MPL was not distributed with this
+  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+ 
+ #include "nsBase64Encoder.h"
+ 
+-#include "plbase64.h"
+-#include "prmem.h"
++#include "mozilla/Base64.h"
+ 
+ NS_IMPL_ISUPPORTS(nsBase64Encoder, nsIOutputStream)
+ 
+ NS_IMETHODIMP
+ nsBase64Encoder::Close()
+ {
+   return NS_OK;
+ }
+@@ -50,18 +49,17 @@ nsBase64Encoder::IsNonBlocking(bool* aNo
+ {
+   *aNonBlocking = false;
+   return NS_OK;
+ }
+ 
+ nsresult
+ nsBase64Encoder::Finish(nsACString& result)
+ {
+-  char* b64 = PL_Base64Encode(mData.get(), mData.Length(), nullptr);
+-  if (!b64)
+-    return NS_ERROR_OUT_OF_MEMORY;
++  nsresult rv = mozilla::Base64Encode(mData, result);
++  if (NS_FAILED(rv)) {
++    return rv;
++  }
+ 
+-  result.Assign(b64);
+-  PR_Free(b64); // PL_Base64Encode() uses PR_MALLOC().
+   // Free unneeded memory and allow reusing the object
+   mData.Truncate();
+   return NS_OK;
+ }

+ 3 - 2
mozilla-release/patches/1496503-3-65a1.patch

@@ -2,7 +2,7 @@
 # User Mike Hommey <mh+mozilla@glandium.org>
 # Date 1542234933 0
 # Node ID 35f916cb6452aa55dd906c0c4f63b47e05dfa316
-# Parent  784282e2c083361c411036c008040b8d862ef12d
+# Parent  b5a69864923980597814be111c488a43c1d97b37
 Bug 1496503 - Change the rust panic hook to delegate to Gecko's crash code. r=froydnj
 
 The current rust panic hook keeps a string for the crash reporter, and
@@ -169,7 +169,7 @@ diff --git a/toolkit/library/rust/shared/Cargo.toml b/toolkit/library/rust/share
 diff --git a/toolkit/library/rust/shared/lib.rs b/toolkit/library/rust/shared/lib.rs
 --- a/toolkit/library/rust/shared/lib.rs
 +++ b/toolkit/library/rust/shared/lib.rs
-@@ -23,75 +23,117 @@ extern crate encoding_glue;
+@@ -23,75 +23,118 @@ extern crate encoding_glue;
  #[cfg(feature = "cubeb-remoting")]
  extern crate audioipc_client;
  #[cfg(feature = "cubeb-remoting")]
@@ -287,6 +287,7 @@ diff --git a/toolkit/library/rust/shared/lib.rs b/toolkit/library/rust/shared/li
 +                      message.as_ptr() as *const c_char);
 +    }
 +}
++
 +/// Configure a panic hook to redirect rust panics to Gecko's MOZ_CrashOOL.
  #[no_mangle]
  pub extern "C" fn install_rust_panic_hook() {

+ 30 - 0
mozilla-release/patches/1506138-65a1.patch

@@ -0,0 +1,30 @@
+# HG changeset patch
+# User Nathan Froyd <froydnj@mozilla.com>
+# Date 1542383353 18000
+# Node ID 91b2fc1a6529b25ff73b3c2a14d7add667057155
+# Parent  95c0c22616c161aff925f1ddc124f0da40561905
+Bug 1506138 - fix minidump_callback.h for aarch64 windows; r=ted.mielczarek
+
+diff --git a/toolkit/crashreporter/breakpad-client/windows/common/minidump_callback.h b/toolkit/crashreporter/breakpad-client/windows/common/minidump_callback.h
+--- a/toolkit/crashreporter/breakpad-client/windows/common/minidump_callback.h
++++ b/toolkit/crashreporter/breakpad-client/windows/common/minidump_callback.h
+@@ -44,17 +44,17 @@ typedef struct {
+   AppMemoryList::const_iterator iter;
+   AppMemoryList::const_iterator end;
+ } MinidumpCallbackContext;
+ 
+ static const size_t kExceptionAppMemoryRegions = 16;
+ 
+ #if defined(_M_IX86)
+ using RegisterValueType = DWORD;
+-#elif defined(_M_AMD64)
++#elif defined(_M_AMD64) || defined(_M_ARM64)
+ using RegisterValueType = DWORD64;
+ #else
+ #error Unsupported platform
+ #endif
+ 
+ void IncludeAppMemoryFromExceptionContext(HANDLE aProcess,
+                                           DWORD aThreadId,
+                                           AppMemoryList& aList,
+

+ 1 - 1
mozilla-release/patches/1511181-crashreporter-65a1.patch

@@ -8502,7 +8502,7 @@ diff --git a/toolkit/crashreporter/nsExceptionHandler.cpp b/toolkit/crashreporte
 -static LPTOP_LEVEL_EXCEPTION_FILTER WINAPI
 -patched_SetUnhandledExceptionFilter (LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter)
 -{
-+static LPTOP_LEVEL_EXCEPTION_FILTER WINAPI patched_SetUnhandledExceptionFilter (
++static LPTOP_LEVEL_EXCEPTION_FILTER WINAPI patched_SetUnhandledExceptionFilter(
 +    LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter) {
    if (!gBlockUnhandledExceptionFilter) {
      // don't intercept

+ 3 - 3
mozilla-release/patches/1514121-66a1.patch

@@ -2,7 +2,7 @@
 # User Mike Hommey <mh+mozilla@glandium.org>
 # Date 1544826244 0
 # Node ID ed2f754410ed822c5a1e2496a59eb1679346dda5
-# Parent  4a4c1177022605b33971dfd8375fe5a3980212e8
+# Parent  932e84dada781f0ecf8b2f3f5de4885651f9f3fb
 Bug 1514121 - Remove unused rust OOM handling variant. r=froydnj
 
 This removes the code added in bug 1458161, because the old versions of
@@ -29,9 +29,9 @@ diff --git a/toolkit/library/rust/shared/lib.rs b/toolkit/library/rust/shared/li
  extern crate mp4parse_capi;
  extern crate nsstring;
  extern crate nserror;
-@@ -126,72 +124,16 @@ fn panic_hook(info: &panic::PanicInfo) {
-     }
+@@ -127,72 +125,16 @@ fn panic_hook(info: &panic::PanicInfo) {
  }
+ 
  /// Configure a panic hook to redirect rust panics to Gecko's MOZ_CrashOOL.
  #[no_mangle]
  pub extern "C" fn install_rust_panic_hook() {

+ 32 - 0
mozilla-release/patches/1528304-67a1.patch

@@ -0,0 +1,32 @@
+# HG changeset patch
+# User David Major <dmajor@mozilla.com>
+# Date 1550257952 0
+# Node ID a1dd47617412e8932b94fb3d57f370feeb4486ed
+# Parent  e4f973a6f8a06e7a9669faee23eb1c1799f6e860
+Bug 1528304 - Update max memory recording regions. r=ted
+
+Differential Revision: https://phabricator.services.mozilla.com/D19960
+
+diff --git a/toolkit/crashreporter/breakpad-client/windows/common/minidump_callback.h b/toolkit/crashreporter/breakpad-client/windows/common/minidump_callback.h
+--- a/toolkit/crashreporter/breakpad-client/windows/common/minidump_callback.h
++++ b/toolkit/crashreporter/breakpad-client/windows/common/minidump_callback.h
+@@ -40,17 +40,17 @@ struct AppMemory {
+ typedef std::list<AppMemory> AppMemoryList;
+ 
+ // This is passed as the context to the MinidumpWriteDump callback.
+ typedef struct {
+   AppMemoryList::const_iterator iter;
+   AppMemoryList::const_iterator end;
+ } MinidumpCallbackContext;
+ 
+-static const size_t kExceptionAppMemoryRegions = 16;
++static const size_t kExceptionAppMemoryRegions = 33;
+ 
+ #if defined(_M_IX86)
+ using RegisterValueType = DWORD;
+ #elif defined(_M_AMD64) || defined(_M_ARM64)
+ using RegisterValueType = DWORD64;
+ #else
+ #error Unsupported platform
+ #endif
+

+ 47 - 0
mozilla-release/patches/1541285-68a1.patch

@@ -0,0 +1,47 @@
+# HG changeset patch
+# User Randall E. Barker <rbarker@mozilla.com>
+# Date 1554495261 0
+# Node ID 6385b4edd6153640c05ba981c19eda6e5ecad70f
+# Parent  0307afda7f5c7373055a4dac2ba721f621ac5038
+Bug 1541285 - Set CrashGenerationServer thread name for Linux and Android r=gsvelto
+
+Differential Revision: https://phabricator.services.mozilla.com/D25983
+
+diff --git a/toolkit/crashreporter/breakpad-client/linux/crash_generation/crash_generation_server.cc b/toolkit/crashreporter/breakpad-client/linux/crash_generation/crash_generation_server.cc
+--- a/toolkit/crashreporter/breakpad-client/linux/crash_generation/crash_generation_server.cc
++++ b/toolkit/crashreporter/breakpad-client/linux/crash_generation/crash_generation_server.cc
+@@ -36,16 +36,18 @@
+ #include <string.h>
+ #include <sys/socket.h>
+ #include <sys/stat.h>
+ #include <sys/types.h>
+ #include <unistd.h>
+ 
+ #include <vector>
+ 
++#include "nsThreadUtils.h"
++
+ #include "linux/crash_generation/crash_generation_server.h"
+ #include "linux/crash_generation/client_info.h"
+ #include "linux/handler/exception_handler.h"
+ #include "linux/handler/guid_generator.h"
+ #include "linux/minidump_writer/minidump_writer.h"
+ #include "common/linux/eintr_wrapper.h"
+ #include "common/linux/safe_readlink.h"
+ 
+@@ -321,13 +323,14 @@ CrashGenerationServer::MakeMinidumpFilen
+   outFilename = path;
+   return true;
+ }
+ 
+ // static
+ void*
+ CrashGenerationServer::ThreadMain(void *arg)
+ {
++  NS_SetCurrentThreadName("Breakpad Server");
+   reinterpret_cast<CrashGenerationServer*>(arg)->Run();
+   return NULL;
+ }
+ 
+ }  // namespace google_breakpad
+

+ 21 - 3
mozilla-release/patches/1850034-2only-118a1.patch

@@ -2,7 +2,7 @@
 # User Masatoshi Kimura <VYV03354@nifty.ne.jp>
 # Date 1693093498 0
 # Node ID 9ba514add5603080afc5058eebcbe34814cdaae0
-# Parent  efb8fca9f9c03035d144c451851803a10e365949
+# Parent  cda917619aacb60bc841ce5118ca01c6a2050da3
 Bug 1850034 - Remove pre-Win10-specific codepath from toolkit/crashreporter/. r=gsvelto
 
 Depends on D186809
@@ -12,7 +12,25 @@ Differential Revision: https://phabricator.services.mozilla.com/D186810
 diff --git a/toolkit/crashreporter/client/crashreporter_win.cpp b/toolkit/crashreporter/client/crashreporter_win.cpp
 --- a/toolkit/crashreporter/client/crashreporter_win.cpp
 +++ b/toolkit/crashreporter/client/crashreporter_win.cpp
-@@ -26,19 +26,16 @@
+@@ -5,17 +5,16 @@
+ 
+ #ifdef WIN32_LEAN_AND_MEAN
+ #  undef WIN32_LEAN_AND_MEAN
+ #endif
+ 
+ #include "crashreporter.h"
+ 
+ #include <windows.h>
+-#include <versionhelpers.h>
+ #include <commctrl.h>
+ #include <richedit.h>
+ #include <shellapi.h>
+ #include <shlobj.h>
+ #include <shlwapi.h>
+ #include <math.h>
+ #include <set>
+ #include <algorithm>
+@@ -26,19 +25,16 @@
  #define CRASH_REPORTER_VALUE L"Enabled"
  #define SUBMIT_REPORT_VALUE L"SubmitCrashReport"
  #define SUBMIT_REPORT_OLD L"SubmitReport"
@@ -32,7 +50,7 @@ diff --git a/toolkit/crashreporter/client/crashreporter_win.cpp b/toolkit/crashr
  
  using std::ifstream;
  using std::ios;
-@@ -1180,46 +1177,21 @@ bool UIInit() {
+@@ -1180,46 +1176,21 @@ bool UIInit() {
  
  void UIShutdown() {}
  

+ 16 - 0
mozilla-release/patches/series

@@ -8302,3 +8302,19 @@ TOP-NOBUG-revendor-25318.patch
 1439018-60a1.patch
 1428769-60a1.patch
 1440188-60a1.patch
+1367861-59a1.patch
+1430197-59a1.patch
+1425097-59a1.patch
+1405446-59a1.patch
+1430738-60a1.patch
+1426831-60a1.patch
+1397740-60a1.patch
+1433982-60a1.patch
+1436134-60a1.patch
+1344613-60a1.patch
+1439362-60a1.patch
+1438332-60a1.patch
+1416045-61a1.patch
+1506138-65a1.patch
+1528304-67a1.patch
+1541285-68a1.patch