Merge inbound to mozilla-central. a=merge
authorNoemi Erli <nerli@mozilla.com>
Sat, 07 Apr 2018 00:55:15 +0300
changeset 412168 ee6283795f41d97faeaccbe8bd051a36bbe30c64
parent 412146 0e0ec6c01e25afb67e04cbb4c2539f42e63f6c9b (current diff)
parent 412167 95342072369b1f23a7c2ac207ab78626793d99cb (diff)
child 412210 42c91891fad0b9383a2931aa64838dd469e00d01
child 412232 e8f1530940a5c38f01955f8fcb886496ae6ca1ae
push id33785
push usernerli@mozilla.com
push dateFri, 06 Apr 2018 21:55:43 +0000
treeherdermozilla-central@ee6283795f41 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone61.0a1
first release with
nightly linux32
ee6283795f41 / 61.0a1 / 20180406220121 / files
nightly linux64
ee6283795f41 / 61.0a1 / 20180406220121 / files
nightly mac
ee6283795f41 / 61.0a1 / 20180406220121 / files
nightly win32
ee6283795f41 / 61.0a1 / 20180406220121 / files
nightly win64
ee6283795f41 / 61.0a1 / 20180406220121 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge inbound to mozilla-central. a=merge
js/src/frontend/LanguageExtensions.h
layout/style/nsCSSRules.h
toolkit/components/telemetry/Histograms.json
toolkit/themes/linux/global/toolbar/spring.png
toolkit/themes/osx/global/10pct_transparent_grey.png
toolkit/themes/osx/global/arrow/arrow-rit.gif
toolkit/themes/osx/global/icons/tabprompts-bgtexture.png
toolkit/themes/osx/global/toolbar/spring.png
toolkit/themes/osx/global/toolbar/toolbar-separator.png
toolkit/themes/windows/global/icons/tabprompts-bgtexture.png
toolkit/themes/windows/global/toolbar/spring.png
--- a/accessible/html/HTMLTableAccessible.cpp
+++ b/accessible/html/HTMLTableAccessible.cpp
@@ -1058,16 +1058,21 @@ HTMLTableAccessible::IsProbablyLayoutTab
   uint32_t childCount = ChildCount();
   nscolor rowColor = 0;
   nscolor prevRowColor;
   for (uint32_t childIdx = 0; childIdx < childCount; childIdx++) {
     Accessible* child = GetChildAt(childIdx);
     if (child->Role() == roles::ROW) {
       prevRowColor = rowColor;
       nsIFrame* rowFrame = child->GetFrame();
+      MOZ_ASSERT(rowFrame, "Table hierarchy got screwed up");
+      if (!rowFrame) {
+        RETURN_LAYOUT_ANSWER(false, "Unexpected table hierarchy");
+      }
+
       rowColor = rowFrame->StyleBackground()->BackgroundColor(rowFrame);
 
       if (childIdx > 0 && prevRowColor != rowColor)
         RETURN_LAYOUT_ANSWER(false, "2 styles of row background color, non-bordered");
     }
   }
 
   // Check for many rows
--- a/browser/base/content/content.js
+++ b/browser/base/content/content.js
@@ -83,16 +83,17 @@ const SEC_ERROR_EXPIRED_ISSUER_CERTIFICA
 const SEC_ERROR_CA_CERT_INVALID                    = SEC_ERROR_BASE + 36;
 const SEC_ERROR_OCSP_FUTURE_RESPONSE               = SEC_ERROR_BASE + 131;
 const SEC_ERROR_OCSP_OLD_RESPONSE                  = SEC_ERROR_BASE + 132;
 const SEC_ERROR_REUSED_ISSUER_AND_SERIAL           = SEC_ERROR_BASE + 138;
 const SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED  = SEC_ERROR_BASE + 176;
 const MOZILLA_PKIX_ERROR_NOT_YET_VALID_CERTIFICATE = MOZILLA_PKIX_ERROR_BASE + 5;
 const MOZILLA_PKIX_ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE = MOZILLA_PKIX_ERROR_BASE + 6;
 const MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT          = MOZILLA_PKIX_ERROR_BASE + 14;
+const MOZILLA_PKIX_ERROR_MITM_DETECTED             = MOZILLA_PKIX_ERROR_BASE + 15;
 
 
 const SSL_ERROR_BASE = Ci.nsINSSErrorsService.NSS_SSL_ERROR_BASE;
 const SSL_ERROR_SSL_DISABLED  = SSL_ERROR_BASE + 20;
 const SSL_ERROR_SSL2_DISABLED  = SSL_ERROR_BASE + 14;
 
 const PREF_SERVICES_SETTINGS_CLOCK_SKEW_SECONDS = "services.settings.clock_skew_seconds";
 const PREF_SERVICES_SETTINGS_LAST_FETCHED       = "services.settings.last_update_seconds";
@@ -313,16 +314,18 @@ var AboutNetAndCertErrorListener = {
     }
 
     let msg1 = gPipNSSBundle.formatStringFromName("certErrorIntro",
                                                   [hostString], 1);
     msg1 += "\n\n";
 
     if (input.data.certIsUntrusted) {
       switch (input.data.code) {
+        // We only want to measure MitM rates for now. Treat it as unkown issuer.
+        case MOZILLA_PKIX_ERROR_MITM_DETECTED:
         case SEC_ERROR_UNKNOWN_ISSUER:
           msg1 += gPipNSSBundle.GetStringFromName("certErrorTrust_UnknownIssuer") + "\n";
           msg1 += gPipNSSBundle.GetStringFromName("certErrorTrust_UnknownIssuer2") + "\n";
           msg1 += gPipNSSBundle.GetStringFromName("certErrorTrust_UnknownIssuer3") + "\n";
           break;
         case SEC_ERROR_CA_CERT_INVALID:
           msg1 += gPipNSSBundle.GetStringFromName("certErrorTrust_CaInvalid") + "\n";
           break;
@@ -481,16 +484,17 @@ var AboutNetAndCertErrorListener = {
     let div = doc.getElementById("certificateErrorText");
     div.textContent = msg.data.info;
     this._setTechDetails(msg, doc);
     let learnMoreLink = doc.getElementById("learnMoreLink");
     let baseURL = Services.urlFormatter.formatURLPref("app.support.baseURL");
 
     switch (msg.data.code) {
       case SEC_ERROR_UNKNOWN_ISSUER:
+      case MOZILLA_PKIX_ERROR_MITM_DETECTED:
       case MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT:
         learnMoreLink.href = baseURL + "security-error";
         break;
 
       // In case the certificate expired we make sure the system clock
       // matches the remote-settings service (blocklist via Kinto) ping time
       // and is not before the build date.
       case SEC_ERROR_EXPIRED_CERTIFICATE:
--- a/browser/base/content/pageinfo/pageInfo.js
+++ b/browser/base/content/pageinfo/pageInfo.js
@@ -466,31 +466,16 @@ function loadTab(args) {
   var initialTab = (args && args.initialTab) || "generalTab";
   var radioGroup = document.getElementById("viewGroup");
   initialTab = document.getElementById(initialTab) || document.getElementById("generalTab");
   radioGroup.selectedItem = initialTab;
   radioGroup.selectedItem.doCommand();
   radioGroup.focus();
 }
 
-function toggleGroupbox(id) {
-  var elt = document.getElementById(id);
-  if (elt.hasAttribute("closed")) {
-    elt.removeAttribute("closed");
-    if (elt.flexWhenOpened)
-      elt.flex = elt.flexWhenOpened;
-  } else {
-    elt.setAttribute("closed", "true");
-    if (elt.flex) {
-      elt.flexWhenOpened = elt.flex;
-      elt.flex = 0;
-    }
-  }
-}
-
 function openCacheEntry(key, cb) {
   var checkCacheListener = {
     onCacheEntryCheck(entry, appCache) {
       return Ci.nsICacheEntryOpenCallback.ENTRY_WANTED;
     },
     onCacheEntryAvailable(entry, isNew, appCache, status) {
       cb(entry);
     }
@@ -518,30 +503,30 @@ function makeGeneralTab(metaViewRows, do
   // get the document characterset
   var encoding = docInfo.characterSet;
   document.getElementById("encodingtext").value = encoding;
 
   let length = metaViewRows.length;
 
   var metaGroup = document.getElementById("metaTags");
   if (!length)
-    metaGroup.collapsed = true;
+    metaGroup.style.visibility = "hidden";
   else {
     var metaTagsCaption = document.getElementById("metaTagsCaption");
     if (length == 1)
-      metaTagsCaption.label = gBundle.getString("generalMetaTag");
+      metaTagsCaption.value = gBundle.getString("generalMetaTag");
     else
-      metaTagsCaption.label = gBundle.getFormattedString("generalMetaTags", [length]);
+      metaTagsCaption.value = gBundle.getFormattedString("generalMetaTags", [length]);
     var metaTree = document.getElementById("metatree");
     metaTree.view = gMetaView;
 
     // Add the metaViewRows onto the general tab's meta info tree.
     gMetaView.addRows(metaViewRows);
 
-    metaGroup.collapsed = false;
+    metaGroup.style.removeProperty("visibility");
   }
 
   // get the date of last modification
   var modifiedText = formatDate(docInfo.lastModified, gStrings.notSet);
   document.getElementById("modifiedtext").value = modifiedText;
 
   // get cache info
   var cacheKey = url.replace(/#.*$/, "");
--- a/browser/base/content/pageinfo/pageInfo.xul
+++ b/browser/base/content/pageinfo/pageInfo.xul
@@ -137,31 +137,31 @@
           <row id="generalModifiedRow">
             <label control="modifiedtext" value="&generalModified;"/>
             <separator/>
             <textbox readonly="true" id="modifiedtext"/>
           </row>
         </rows>
       </grid>
       <separator class="thin"/>
-      <groupbox id="metaTags" flex="1" class="collapsable treebox">
-        <caption id="metaTagsCaption" onclick="toggleGroupbox('metaTags');"/>
+      <vbox id="metaTags" flex="1">
+        <label control="metatree" id="metaTagsCaption" class="header"/>
         <tree id="metatree" flex="1" hidecolumnpicker="true" contextmenu="picontext">
           <treecols>
             <treecol id="meta-name"    label="&generalMetaName;"
                      persist="width" flex="1"
                      onclick="gMetaView.onPageMediaSort('meta-name');"/>
             <splitter class="tree-splitter"/>
             <treecol id="meta-content" label="&generalMetaContent;"
                      persist="width" flex="4"
                      onclick="gMetaView.onPageMediaSort('meta-content');"/>
           </treecols>
           <treechildren id="metatreechildren" flex="1"/>
         </tree>        
-      </groupbox>
+      </vbox>
       <hbox pack="end">
         <button command="cmd_help" label="&helpButton.label;" dlgtype="help"/>
       </hbox>
     </vbox>
 
     <!-- Media information -->
     <vbox id="mediaPanel">
       <tree id="imagetree" onselect="onImageSelect();" contextmenu="picontext"
--- a/browser/themes/linux/pageInfo.css
+++ b/browser/themes/linux/pageInfo.css
@@ -93,45 +93,16 @@ textbox[disabled] {
   font-style: italic;
 }
 
 /* General Tab */
 #generalPanel > #titletext {
   margin-inline-start: 5px;
 }
 
-groupbox.collapsable caption .caption-icon {
-  width: 9px;
-  height: 9px;
-  background-repeat: no-repeat;
-  background-position: center;
-  margin-inline-start: 1px;
-  margin-inline-end: 3px;
-  background-image: url("chrome://global/skin/tree/twisty-open.png");
-}
-
-groupbox.collapsable[closed="true"] {
-  border: none;
-}
-
-groupbox.collapsable[closed="true"] caption .caption-icon {
-  background-image: url("chrome://global/skin/tree/twisty-clsd.png");
-}
-
-groupbox tree {
-  margin: 0;
-  border: none;
-}
-
-groupbox.treebox .groupbox-body {
-  margin-inline-start: 5px;
-  margin-inline-end: 1px;
-  padding-top: 0;
-}
-
 #securityBox description {
   margin-inline-start: 10px;
 }
 
 #general-security-identity {
   white-space: pre-wrap;
   line-height: 2em;
 }
--- a/browser/themes/osx/pageInfo.css
+++ b/browser/themes/osx/pageInfo.css
@@ -67,37 +67,16 @@ textbox.header {
   border: 1px solid ThreeDLightShadow;
 }
 
 textbox[disabled] {
   font-style: italic;
 }
 
 /* General Tab */
-groupbox.collapsable caption .caption-icon {
-  width: 11px;
-  height: 11px;
-  background-repeat: no-repeat;
-  background-position: center;
-  margin-inline-end: 2px;
-  background-image: url("chrome://global/skin/arrow/arrow-dn.gif");
-}
-
-groupbox.collapsable[closed="true"] caption .caption-icon {
-  background-image: url("chrome://global/skin/arrow/arrow-rit.gif");
-}
-
-groupbox tree {
-  margin: 0;
-  border: none;
-}
-
-groupbox.treebox .groupbox-body {
-  padding: 0;
-}
 
 #securityBox description {
   margin-inline-start: 10px;
 }
 
 #general-security-identity {
   white-space: pre-wrap;
   line-height: 2em;
--- a/browser/themes/windows/pageInfo.css
+++ b/browser/themes/windows/pageInfo.css
@@ -117,40 +117,16 @@ textbox.header {
   border: 1px solid ThreeDLightShadow;
 }
 
 textbox[disabled] {
   font-style: italic;
 }
 
 /* General Tab */
-groupbox.collapsable caption .caption-icon {
-  width: 9px;
-  height: 9px;
-  background-repeat: no-repeat;
-  background-position: center;
-  margin-inline-start: 2px;
-  margin-inline-end: 2px;
-  background-image: url("chrome://global/skin/tree/twisty.svg#open");
-}
-
-groupbox.collapsable[closed="true"] {
-  border: none;
-  margin-bottom: 9px;
-  -moz-appearance: none;
-}
-
-groupbox.collapsable[closed="true"] caption .caption-icon {
-  background-image: url("chrome://global/skin/tree/twisty.svg#clsd");
-}
-
-groupbox tree {
-  margin: 0 3px;
-  border: none;
-}
 
 #securityBox description {
   margin-inline-start: 10px;
 }
 
 #general-security-identity {
   white-space: pre-wrap;
   line-height: 2em;
--- a/dom/base/test/mochitest.ini
+++ b/dom/base/test/mochitest.ini
@@ -658,16 +658,17 @@ skip-if = (toolkit == 'android') # Andro
 [test_gsp-quirks.html]
 [test_gsp-standards.html]
 [test_history_document_open.html]
 [test_history_state_null.html]
 [test_html_colors_quirks.html]
 [test_html_colors_standards.html]
 [test_htmlcopyencoder.html]
 [test_htmlcopyencoder.xhtml]
+[test_iframe_event_listener_leaks.html]
 [test_iframe_referrer.html]
 [test_iframe_referrer_changing.html]
 [test_iframe_referrer_invalid.html]
 [test_Image_constructor.html]
 [test_img_referrer.html]
 [test_innersize_scrollport.html]
 [test_integer_attr_with_leading_zero.html]
 [test_intersectionobservers.html]
new file mode 100644
--- /dev/null
+++ b/dom/base/test/test_iframe_event_listener_leaks.html
@@ -0,0 +1,41 @@
+<!--
+  Any copyright is dedicated to the Public Domain.
+  http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Bug 1451426 - Test iframe event listener leak conditions</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="/tests/dom/events/test/event_leak_utils.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<script class="testbody" type="text/javascript">
+// Manipulate iframe.  Its important here that we create a
+// listener callback from the DOM objects back to the frame's global
+// in order to exercise the leak condition.
+async function useIFrame(contentWindow) {
+  let f = contentWindow.document.createElement("iframe");
+  contentWindow.document.body.appendChild(f);
+  f.onload = _ => {
+    contentWindow.loadCount += 1;
+  };
+}
+
+async function runTest() {
+  try {
+    await checkForEventListenerLeaks("IFrame", useIFrame);
+  } catch (e) {
+    ok(false, e);
+  } finally {
+    SimpleTest.finish();
+  }
+}
+
+SimpleTest.waitForExplicitFinish();
+addEventListener("load", runTest, { once: true });
+</script>
+</pre>
+</body>
+</html>
--- a/dom/plugins/ipc/FunctionHook.cpp
+++ b/dom/plugins/ipc/FunctionHook.cpp
@@ -291,26 +291,33 @@ CreateFileWHookFn(LPCWSTR aFname, DWORD 
     return replacement;
   }
   return sCreateFileWStub(aFname, aAccess, aShare, aSecurity, aCreation, aFlags,
                           aFTemplate);
 }
 
 void FunctionHook::HookProtectedMode()
 {
+  // Make sure we only do this once.
+  static bool sRunOnce = false;
+  if (sRunOnce) {
+    return;
+  }
+  sRunOnce = true;
+
   // Legacy code.  Uses the nsWindowsDLLInterceptor directly instead of
   // using the FunctionHook
+  sKernel32Intercept.Init("kernel32.dll");
   MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Plugin);
-  WindowsDllInterceptor k32Intercept("kernel32.dll");
-  k32Intercept.AddHook("CreateFileW",
-                       reinterpret_cast<intptr_t>(CreateFileWHookFn),
-                       (void**) &sCreateFileWStub);
-  k32Intercept.AddHook("CreateFileA",
-                       reinterpret_cast<intptr_t>(CreateFileAHookFn),
-                       (void**) &sCreateFileAStub);
+  sKernel32Intercept.AddHook("CreateFileW",
+                             reinterpret_cast<intptr_t>(CreateFileWHookFn),
+                             (void**) &sCreateFileWStub);
+  sKernel32Intercept.AddHook("CreateFileA",
+                             reinterpret_cast<intptr_t>(CreateFileAHookFn),
+                             (void**) &sCreateFileAStub);
 }
 
 #endif // defined(XP_WIN)
 
 #define FUN_HOOK(x) static_cast<FunctionHook*>(x)
 
 void
 FunctionHook::AddFunctionHooks(FunctionHookArray& aHooks)
--- a/dom/security/nsContentSecurityManager.cpp
+++ b/dom/security/nsContentSecurityManager.cpp
@@ -154,42 +154,43 @@ nsContentSecurityManager::AllowInsecureR
                                   NS_LITERAL_CSTRING("DATA_URI_BLOCKED"),
                                   doc,
                                   nsContentUtils::eSECURITY_PROPERTIES,
                                   "BlockSubresourceRedirectToData",
                                   params, ArrayLength(params));
   return false;
 }
 
-/* static */ bool
-nsContentSecurityManager::AllowFTPSubresourceLoad(nsIChannel* aChannel)
+/* static */ nsresult
+nsContentSecurityManager::CheckFTPSubresourceLoad(nsIChannel* aChannel)
 {
   // We dissallow using FTP resources as a subresource everywhere.
   // The only valid way to use FTP resources is loading it as
   // a top level document.
 
   nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo();
   if (!loadInfo) {
-    return true;
+    return NS_OK;
   }
 
   nsContentPolicyType type = loadInfo->GetExternalContentPolicyType();
   if (type == nsIContentPolicy::TYPE_DOCUMENT) {
-    return true;
+    return NS_OK;
   }
 
   nsCOMPtr<nsIURI> uri;
   nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
-  if (NS_FAILED(rv) || !uri) {
-    return true;
+  NS_ENSURE_SUCCESS(rv, rv);
+  if (!uri) {
+    return NS_OK;
   }
 
   bool isFtpURI = (NS_SUCCEEDED(uri->SchemeIs("ftp", &isFtpURI)) && isFtpURI);
   if (!isFtpURI) {
-    return true;
+    return NS_OK;
   }
 
   nsCOMPtr<nsIDocument> doc;
   if (nsINode* node = loadInfo->LoadingNode()) {
     doc = node->OwnerDoc();
   }
 
   nsAutoCString spec;
@@ -199,17 +200,17 @@ nsContentSecurityManager::AllowFTPSubres
 
   nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
                                   NS_LITERAL_CSTRING("FTP_URI_BLOCKED"),
                                   doc,
                                   nsContentUtils::eSECURITY_PROPERTIES,
                                   "BlockSubresourceFTP",
                                   params, ArrayLength(params));
 
-  return false;
+  return NS_ERROR_CONTENT_BLOCKED;
 }
 
 static nsresult
 ValidateSecurityFlags(nsILoadInfo* aLoadInfo)
 {
   nsSecurityFlags securityMode = aLoadInfo->GetSecurityMode();
 
   // We should never perform a security check on a loadInfo that uses the flag
@@ -649,16 +650,20 @@ nsContentSecurityManager::doContentSecur
 
   rv = CheckChannel(aChannel);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Perform all ContentPolicy checks (MixedContent, CSP, ...)
   rv = DoContentSecurityChecks(aChannel, loadInfo);
   NS_ENSURE_SUCCESS(rv, rv);
 
+  // Apply this after CSP to match Chrome.
+  rv = CheckFTPSubresourceLoad(aChannel);
+  NS_ENSURE_SUCCESS(rv, rv);
+
   // now lets set the initalSecurityFlag for subsequent calls
   loadInfo->SetInitialSecurityCheckDone(true);
 
   // all security checks passed - lets allow the load
   return NS_OK;
 }
 
 NS_IMETHODIMP
@@ -666,16 +671,19 @@ nsContentSecurityManager::AsyncOnChannel
                                                  nsIChannel* aNewChannel,
                                                  uint32_t aRedirFlags,
                                                  nsIAsyncVerifyRedirectCallback *aCb)
 {
   nsCOMPtr<nsILoadInfo> loadInfo = aOldChannel->GetLoadInfo();
   // Are we enforcing security using LoadInfo?
   if (loadInfo && loadInfo->GetEnforceSecurity()) {
     nsresult rv = CheckChannel(aNewChannel);
+    if (NS_SUCCEEDED(rv)) {
+      rv = CheckFTPSubresourceLoad(aNewChannel);
+    }
     if (NS_FAILED(rv)) {
       aOldChannel->Cancel(rv);
       return rv;
     }
   }
 
   // Also verify that the redirecting server is allowed to redirect to the
   // given URI
@@ -801,20 +809,16 @@ nsContentSecurityManager::CheckChannel(n
     // within the loadInfo, then then CheckLoadURIWithPrincipal is performed
     // within nsCorsListenerProxy
     rv = DoCheckLoadURIChecks(uri, loadInfo);
     NS_ENSURE_SUCCESS(rv, rv);
     // TODO: Bug 1371237
     // consider calling SetBlockedRequest in nsContentSecurityManager::CheckChannel
   }
 
-  if (!AllowFTPSubresourceLoad(aChannel)) {
-    return NS_ERROR_CONTENT_BLOCKED;
-  }
-
   return NS_OK;
 }
 
 // ==== nsIContentSecurityManager implementation =====
 
 NS_IMETHODIMP
 nsContentSecurityManager::PerformSecurityCheck(nsIChannel* aChannel,
                                                nsIStreamListener* aStreamListener,
--- a/dom/security/nsContentSecurityManager.h
+++ b/dom/security/nsContentSecurityManager.h
@@ -31,18 +31,17 @@ public:
   nsContentSecurityManager() {}
 
   static nsresult doContentSecurityCheck(nsIChannel* aChannel,
                                          nsCOMPtr<nsIStreamListener>& aInAndOutListener);
 
   static bool AllowTopLevelNavigationToDataURI(nsIChannel* aChannel);
   static bool AllowInsecureRedirectToDataURI(nsIChannel* aNewChannel);
 
-  static bool AllowFTPSubresourceLoad(nsIChannel* aChannel);
-
 private:
   static nsresult CheckChannel(nsIChannel* aChannel);
+  static nsresult CheckFTPSubresourceLoad(nsIChannel* aChannel);
 
   virtual ~nsContentSecurityManager() {}
 
 };
 
 #endif /* nsContentSecurityManager_h___ */
--- a/dom/webidl/XULElement.webidl
+++ b/dom/webidl/XULElement.webidl
@@ -11,18 +11,16 @@ interface XULElement : Element {
   // Layout properties
   [SetterThrows]
   attribute DOMString align;
   [SetterThrows]
   attribute DOMString dir;
   [SetterThrows]
   attribute DOMString flex;
   [SetterThrows]
-  attribute DOMString flexGroup;
-  [SetterThrows]
   attribute DOMString ordinal;
   [SetterThrows]
   attribute DOMString orient;
   [SetterThrows]
   attribute DOMString pack;
 
   // Properties for hiding elements.
   attribute boolean hidden;
@@ -49,33 +47,27 @@ interface XULElement : Element {
   attribute DOMString minWidth;
   [SetterThrows]
   attribute DOMString minHeight;
   [SetterThrows]
   attribute DOMString maxWidth;
   [SetterThrows]
   attribute DOMString maxHeight;
 
-  // Persistence
-  [SetterThrows]
-  attribute DOMString persist;
-
   // Position properties for
   // * popups - these are screen coordinates
   // * other elements - these are client coordinates relative to parent stack.
   [SetterThrows]
   attribute DOMString left;
   [SetterThrows]
   attribute DOMString top;
 
-  // Tooltip and status info
+  // Tooltip
   [SetterThrows]
   attribute DOMString tooltipText;
-  [SetterThrows]
-  attribute DOMString statusText;
 
   // Properties for images
   [SetterThrows]
   attribute DOMString src;
 
   attribute boolean allowEvents;
 
   [Throws, ChromeOnly]
--- a/dom/xul/nsXULElement.h
+++ b/dom/xul/nsXULElement.h
@@ -450,24 +450,16 @@ public:
     void GetFlex(DOMString& aValue) const
     {
         GetXULAttr(nsGkAtoms::flex, aValue);
     }
     void SetFlex(const nsAString& aValue, mozilla::ErrorResult& rv)
     {
         SetXULAttr(nsGkAtoms::flex, aValue, rv);
     }
-    void GetFlexGroup(DOMString& aValue) const
-    {
-        GetXULAttr(nsGkAtoms::flexgroup, aValue);
-    }
-    void SetFlexGroup(const nsAString& aValue, mozilla::ErrorResult& rv)
-    {
-        SetXULAttr(nsGkAtoms::flexgroup, aValue, rv);
-    }
     void GetOrdinal(DOMString& aValue) const
     {
         GetXULAttr(nsGkAtoms::ordinal, aValue);
     }
     void SetOrdinal(const nsAString& aValue, mozilla::ErrorResult& rv)
     {
         SetXULAttr(nsGkAtoms::ordinal, aValue, rv);
     }
@@ -578,24 +570,16 @@ public:
     void GetMaxHeight(DOMString& aValue) const
     {
         GetXULAttr(nsGkAtoms::maxheight, aValue);
     }
     void SetMaxHeight(const nsAString& aValue, mozilla::ErrorResult& rv)
     {
         SetXULAttr(nsGkAtoms::maxheight, aValue, rv);
     }
-    void GetPersist(DOMString& aValue) const
-    {
-        GetXULAttr(nsGkAtoms::persist, aValue);
-    }
-    void SetPersist(const nsAString& aValue, mozilla::ErrorResult& rv)
-    {
-        SetXULAttr(nsGkAtoms::persist, aValue, rv);
-    }
     void GetLeft(DOMString& aValue) const
     {
         GetXULAttr(nsGkAtoms::left, aValue);
     }
     void SetLeft(const nsAString& aValue, mozilla::ErrorResult& rv)
     {
         SetXULAttr(nsGkAtoms::left, aValue, rv);
     }
@@ -610,24 +594,16 @@ public:
     void GetTooltipText(DOMString& aValue) const
     {
         GetXULAttr(nsGkAtoms::tooltiptext, aValue);
     }
     void SetTooltipText(const nsAString& aValue, mozilla::ErrorResult& rv)
     {
         SetXULAttr(nsGkAtoms::tooltiptext, aValue, rv);
     }
-    void GetStatusText(DOMString& aValue) const
-    {
-        GetXULAttr(nsGkAtoms::statustext, aValue);
-    }
-    void SetStatusText(const nsAString& aValue, mozilla::ErrorResult& rv)
-    {
-        SetXULAttr(nsGkAtoms::statustext, aValue, rv);
-    }
     void GetSrc(DOMString& aValue) const
     {
         GetXULAttr(nsGkAtoms::src, aValue);
     }
     void SetSrc(const nsAString& aValue, mozilla::ErrorResult& rv)
     {
         SetXULAttr(nsGkAtoms::src, aValue, rv);
     }
--- a/gfx/gl/GLTextureImage.cpp
+++ b/gfx/gl/GLTextureImage.cpp
@@ -144,16 +144,19 @@ BasicTextureImage::DirectUpdate(gfx::Dat
         UploadSurfaceToTexture(mGLContext,
                                aSurf,
                                region,
                                mTexture,
                                mSize,
                                &uploadSize,
                                needInit,
                                aFrom);
+    if (mTextureFormat == SurfaceFormat::UNKNOWN) {
+        return false;
+    }
 
     if (uploadSize > 0) {
         UpdateUploadSize(uploadSize);
     }
     mTextureState = Valid;
     return true;
 }
 
--- a/gfx/gl/GLUploadHelpers.cpp
+++ b/gfx/gl/GLUploadHelpers.cpp
@@ -22,16 +22,33 @@ namespace gl {
 static unsigned int
 DataOffset(const IntPoint& aPoint, int32_t aStride, SurfaceFormat aFormat)
 {
   unsigned int data = aPoint.y * aStride;
   data += aPoint.x * BytesPerPixel(aFormat);
   return data;
 }
 
+static bool
+CheckUploadBounds(const IntSize& aDst, const IntSize& aSrc, const IntPoint& aOffset)
+{
+  if (aOffset.x < 0 || aOffset.y < 0 ||
+      aOffset.x >= aSrc.width ||
+      aOffset.y >= aSrc.height) {
+    MOZ_ASSERT_UNREACHABLE("Offset outside source bounds");
+    return false;
+  }
+  if (aDst.width > (aSrc.width - aOffset.x) ||
+      aDst.height > (aSrc.height - aOffset.y)) {
+    MOZ_ASSERT_UNREACHABLE("Source has insufficient data");
+    return false;
+  }
+  return true;
+}
+
 static GLint GetAddressAlignment(ptrdiff_t aAddress)
 {
     if (!(aAddress & 0x7)) {
        return 8;
     } else if (!(aAddress & 0x3)) {
         return 4;
     } else if (!(aAddress & 0x1)) {
         return 2;
@@ -370,16 +387,17 @@ TexImage2DHelper(GLContext* gl,
         gl->fPixelStorei(LOCAL_GL_UNPACK_ROW_LENGTH, 0);
         gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 4);
     }
 }
 
 SurfaceFormat
 UploadImageDataToTexture(GLContext* gl,
                          unsigned char* aData,
+                         const gfx::IntSize& aDataSize,
                          int32_t aStride,
                          SurfaceFormat aFormat,
                          const nsIntRegion& aDstRegion,
                          GLuint aTexture,
                          const gfx::IntSize& aSize,
                          size_t* aOutUploadSize,
                          bool aNeedInit,
                          GLenum aTextureUnit,
@@ -501,16 +519,20 @@ UploadImageDataToTexture(GLContext* gl,
             uint32_t texelSize = GetBytesPerTexel(internalFormat, type);
             size_t numTexels = size_t(aSize.width) * size_t(aSize.height);
             *aOutUploadSize += texelSize * numTexels;
         }
     } else {
         // Upload each rect in the region to the texture
         for (auto iter = aDstRegion.RectIter(); !iter.Done(); iter.Next()) {
             const IntRect& rect = iter.Get();
+            if (!CheckUploadBounds(rect.Size(), aDataSize, rect.TopLeft())) {
+                return SurfaceFormat::UNKNOWN;
+            }
+
             const unsigned char* rectData =
                 aData + DataOffset(rect.TopLeft(), aStride, aFormat);
 
             TexSubImage2DHelper(gl,
                                 aTextureTarget,
                                 0,
                                 rect.X(),
                                 rect.Y(),
@@ -537,20 +559,27 @@ UploadSurfaceToTexture(GLContext* gl,
                        bool aNeedInit,
                        const gfx::IntPoint& aSrcPoint,
                        GLenum aTextureUnit,
                        GLenum aTextureTarget)
 {
     DataSourceSurface::ScopedMap map(aSurface, DataSourceSurface::READ);
     int32_t stride = map.GetStride();
     SurfaceFormat format = aSurface->GetFormat();
+    gfx::IntSize size = aSurface->GetSize();
+    if (!CheckUploadBounds(aSize, size, aSrcPoint)) {
+        return SurfaceFormat::UNKNOWN;
+    }
+
     unsigned char* data = map.GetData() +
         DataOffset(aSrcPoint, stride, format);
+    size.width -= aSrcPoint.x;
+    size.height -= aSrcPoint.y;
 
-    return UploadImageDataToTexture(gl, data, stride, format,
+    return UploadImageDataToTexture(gl, data, size, stride, format,
                                     aDstRegion, aTexture, aSize,
                                     aOutUploadSize, aNeedInit,
                                     aTextureUnit, aTextureTarget);
 }
 
 bool
 CanUploadNonPowerOfTwo(GLContext* gl)
 {
--- a/gfx/gl/GLUploadHelpers.h
+++ b/gfx/gl/GLUploadHelpers.h
@@ -23,16 +23,17 @@ class GLContext;
 
 /**
  * Uploads image data to an OpenGL texture, initializing the texture
  * first if necessary.
  *
  * \param gl The GL Context to use.
  * \param aData Start of image data of surface to upload.
  *              Corresponds to the first pixel of the texture.
+ * \param aDataSize The image data's size.
  * \param aStride The image data's stride.
  * \param aFormat The image data's format.
  * \param aDstRegion Region of the texture to upload.
  * \param aTexture The OpenGL texture to use. Must refer to a valid texture.
  * \param aSize The full size of the texture.
  * \param aOutUploadSize If set, the number of bytes the texture requires will
  *                       be returned here.
  * \param aNeedInit Indicates whether a new texture must be allocated.
@@ -41,16 +42,17 @@ class GLContext;
  *                     the aTexture being bound to aTextureUnit after this call,
  *                     or even on aTextureUnit being active.
  * \param aTextureTarget The texture target to use.
  * \return Surface format of this texture.
  */
 gfx::SurfaceFormat
 UploadImageDataToTexture(GLContext* gl,
                          unsigned char* aData,
+                         const gfx::IntSize& aDataSize,
                          int32_t aStride,
                          gfx::SurfaceFormat aFormat,
                          const nsIntRegion& aDstRegion,
                          GLuint aTexture,
                          const gfx::IntSize& aSize,
                          size_t* aOutUploadSize = nullptr,
                          bool aNeedInit = false,
                          GLenum aTextureUnit = LOCAL_GL_TEXTURE0,
--- a/gfx/gl/TextureImageEGL.cpp
+++ b/gfx/gl/TextureImageEGL.cpp
@@ -114,16 +114,20 @@ TextureImageEGL::DirectUpdate(gfx::DataS
       UploadSurfaceToTexture(mGLContext,
                              aSurf,
                              region,
                              mTexture,
                              mSize,
                              &uploadSize,
                              needInit,
                              aFrom);
+    if (mTextureFormat == SurfaceFormat::UNKNOWN) {
+        return false;
+    }
+
     if (uploadSize > 0) {
         UpdateUploadSize(uploadSize);
     }
 
     mTextureState = Valid;
     return true;
 }
 
--- a/gfx/layers/composite/TextureHost.cpp
+++ b/gfx/layers/composite/TextureHost.cpp
@@ -1007,18 +1007,17 @@ BufferTextureHost::Upload(nsIntRegion *a
         ImageDataSerializer::DataSourceSurfaceFromYCbCrDescriptor(buf, mDescriptor.get_YCbCrDescriptor());
       if (NS_WARN_IF(!surf)) {
         return false;
       }
       if (!mFirstSource) {
         mFirstSource = mProvider->CreateDataTextureSource(mFlags|TextureFlags::RGB_FROM_YCBCR);
         mFirstSource->SetOwner(this);
       }
-      mFirstSource->Update(surf, aRegion);
-      return true;
+      return mFirstSource->Update(surf, aRegion);
     }
 
     RefPtr<DataTextureSource> srcY;
     RefPtr<DataTextureSource> srcU;
     RefPtr<DataTextureSource> srcV;
     if (!mFirstSource) {
       // We don't support BigImages for YCbCr compositing.
       srcY = mProvider->CreateDataTextureSource(mFlags|TextureFlags::DISALLOW_BIGIMAGE);
--- a/gfx/layers/opengl/TextureHostOGL.cpp
+++ b/gfx/layers/opengl/TextureHostOGL.cpp
@@ -163,19 +163,17 @@ TextureImageTextureSourceOGL::Update(gfx
       // UpdateFromDataSource will ignore our specified aDestRegion since the texture
       // hasn't been allocated with glTexImage2D yet. Call Resize() to force the
       // allocation (full size, but no upload), and then we'll only upload the pixels
       // we care about below.
       mTexImage->Resize(size);
     }
   }
 
-  mTexImage->UpdateFromDataSource(aSurface, aDestRegion, aSrcOffset);
-
-  return true;
+  return mTexImage->UpdateFromDataSource(aSurface, aDestRegion, aSrcOffset);
 }
 
 void
 TextureImageTextureSourceOGL::EnsureBuffer(const IntSize& aSize,
                                            gfxContentType aContentType)
 {
   if (!mTexImage ||
       mTexImage->GetSize() != aSize ||
--- a/gfx/thebes/gfxDWriteCommon.cpp
+++ b/gfx/thebes/gfxDWriteCommon.cpp
@@ -5,18 +5,20 @@
 
 #include "gfxDWriteCommon.h"
 
 #include <unordered_map>
 
 #include "mozilla/Atomics.h"
 #include "mozilla/gfx/Logging.h"
 
+class gfxDWriteFontFileStream;
+
 static mozilla::Atomic<uint64_t> sNextFontFileKey;
-static std::unordered_map<uint64_t, IDWriteFontFileStream*> sFontFileStreams;
+static std::unordered_map<uint64_t, gfxDWriteFontFileStream*> sFontFileStreams;
 
 IDWriteFontFileLoader* gfxDWriteFontFileLoader::mInstance = nullptr;
 
 class gfxDWriteFontFileStream final : public IDWriteFontFileStream
 {
 public:
   /**
   * Used by the FontFileLoader to create a new font stream,
@@ -72,16 +74,24 @@ public:
                                                      OUT void** fragmentContext);
 
   virtual void STDMETHODCALLTYPE ReleaseFileFragment(void* fragmentContext);
 
   virtual HRESULT STDMETHODCALLTYPE GetFileSize(OUT UINT64* fileSize);
 
   virtual HRESULT STDMETHODCALLTYPE GetLastWriteTime(OUT UINT64* lastWriteTime);
 
+  size_t SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
+    return mData.ShallowSizeOfExcludingThis(mallocSizeOf);
+  }
+
+  size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
+    return mallocSizeOf(this) + SizeOfExcludingThis(mallocSizeOf);
+  }
+
 private:
   FallibleTArray<uint8_t> mData;
   nsAutoRefCnt mRefCnt;
   uint64_t mFontFileKey;
 };
 
 gfxDWriteFontFileStream::gfxDWriteFontFileStream(const uint8_t* aData,
                                                  uint32_t aLength,
@@ -167,24 +177,39 @@ gfxDWriteFontFileLoader::CreateCustomFon
 
   RefPtr<IDWriteFactory> factory = mozilla::gfx::Factory::GetDWriteFactory();
   if (!factory) {
     gfxCriticalError() << "Failed to get DWrite Factory in CreateCustomFontFile.";
     return E_FAIL;
   }
 
   uint64_t fontFileKey = sNextFontFileKey++;
-  RefPtr<IDWriteFontFileStream> ffsRef =
+  RefPtr<gfxDWriteFontFileStream> ffsRef =
       new gfxDWriteFontFileStream(aFontData, aLength, fontFileKey);
   sFontFileStreams[fontFileKey] = ffsRef;
 
   RefPtr<IDWriteFontFile> fontFile;
   HRESULT hr = factory->CreateCustomFontFileReference(&fontFileKey, sizeof(fontFileKey), Instance(), getter_AddRefs(fontFile));
   if (FAILED(hr)) {
     NS_WARNING("Failed to load font file from data!");
     return hr;
   }
 
   fontFile.forget(aFontFile);
   ffsRef.forget(aFontFileStream);
 
   return S_OK;
 }
+
+size_t
+gfxDWriteFontFileLoader::SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const
+{
+  size_t sizes = mallocSizeOf(this);
+
+  // We are a singleton type that is effective owner of sFontFileStreams.
+  MOZ_ASSERT(this == mInstance);
+  for (const auto& entry : sFontFileStreams) {
+    gfxDWriteFontFileStream* fileStream = entry.second;
+    sizes += fileStream->SizeOfIncludingThis(mallocSizeOf);
+  }
+
+  return sizes;
+}
--- a/gfx/thebes/gfxDWriteCommon.h
+++ b/gfx/thebes/gfxDWriteCommon.h
@@ -2,16 +2,17 @@
  * 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/. */
 
 #ifndef GFX_DWRITECOMMON_H
 #define GFX_DWRITECOMMON_H
 
 // Mozilla includes
+#include "mozilla/MemoryReporting.h"
 #include "nscore.h"
 #include "nsIServiceManager.h"
 #include "nsCOMPtr.h"
 #include "cairo-features.h"
 #include "gfxFontConstants.h"
 #include "nsTArray.h"
 #include "gfxWindowsPlatform.h"
 #include "nsIUUIDGenerator.h"
@@ -68,22 +69,16 @@ FontStretchFromDWriteStretch(DWRITE_FONT
             return NS_FONT_STRETCH_EXTRA_EXPANDED;
         case DWRITE_FONT_STRETCH_ULTRA_EXPANDED:
             return NS_FONT_STRETCH_ULTRA_EXPANDED;
         default:
             return NS_FONT_STRETCH_NORMAL;
     }
 }
 
-struct ffReferenceKey
-{
-    FallibleTArray<uint8_t> *mArray;
-    nsID mGUID;
-};
-
 class gfxDWriteFontFileLoader : public IDWriteFontFileLoader
 {
 public:
     gfxDWriteFontFileLoader()
     {
     }
 
     // IUnknown interface
@@ -144,13 +139,15 @@ public:
      * @param aFontFileStream out param for the corresponding stream
      * @return HRESULT of internal calls
      */
     static HRESULT CreateCustomFontFile(const uint8_t* aFontData,
                                         uint32_t aLength,
                                         IDWriteFontFile** aFontFile,
                                         IDWriteFontFileStream** aFontFileStream);
 
+    size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
+
 private:
     static IDWriteFontFileLoader* mInstance;
 }; 
 
 #endif /* GFX_DWRITECOMMON_H */
--- a/gfx/thebes/gfxDWriteFontList.cpp
+++ b/gfx/thebes/gfxDWriteFontList.cpp
@@ -1445,16 +1445,22 @@ gfxDWriteFontList::FindAndAddFamilies(co
 }
 
 void
 gfxDWriteFontList::AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
                                           FontListSizes* aSizes) const
 {
     gfxPlatformFontList::AddSizeOfExcludingThis(aMallocSizeOf, aSizes);
 
+    // We are a singleton, so include the font loader singleton's memory.
+    MOZ_ASSERT(static_cast<const gfxPlatformFontList*>(this) == gfxPlatformFontList::PlatformFontList());
+    gfxDWriteFontFileLoader* loader =
+      static_cast<gfxDWriteFontFileLoader*>(gfxDWriteFontFileLoader::Instance());
+    aSizes->mLoaderSize += loader->SizeOfIncludingThis(aMallocSizeOf);
+
     aSizes->mFontListSize +=
         SizeOfFontFamilyTableExcludingThis(mFontSubstitutes, aMallocSizeOf);
 
     aSizes->mFontListSize +=
         mNonExistingFonts.ShallowSizeOfExcludingThis(aMallocSizeOf);
     for (uint32_t i = 0; i < mNonExistingFonts.Length(); ++i) {
         aSizes->mFontListSize +=
             mNonExistingFonts[i].SizeOfExcludingThisIfUnshared(aMallocSizeOf);
--- a/gfx/thebes/gfxMacFont.cpp
+++ b/gfx/thebes/gfxMacFont.cpp
@@ -452,16 +452,26 @@ gfxMacFont::CreateCTFontFromCGFontWithVa
                                                 aFontDesc);
     }
     return ctFont;
 }
 
 int32_t
 gfxMacFont::GetGlyphWidth(DrawTarget& aDrawTarget, uint16_t aGID)
 {
+    if (mVariationFont) {
+        // Avoid a potential Core Text crash (bug 1450209) by using
+        // CoreGraphics glyph advance API. This is inferior for 'sbix'
+        // fonts, but those won't have variations, so it's OK.
+        int cgAdvance;
+        if (::CGFontGetGlyphAdvances(mCGFont, &aGID, 1, &cgAdvance)) {
+            return cgAdvance * mFUnitsConvFactor * 0x10000;
+        }
+    }
+
     if (!mCTFont) {
         mCTFont = CreateCTFontFromCGFontWithVariations(mCGFont, mAdjustedSize);
         if (!mCTFont) { // shouldn't happen, but let's be safe
             NS_WARNING("failed to create CTFontRef to measure glyph width");
             return 0;
         }
     }
 
--- a/gfx/thebes/gfxPlatformFontList.cpp
+++ b/gfx/thebes/gfxPlatformFontList.cpp
@@ -156,16 +156,17 @@ NS_IMPL_ISUPPORTS(gfxPlatformFontList::M
 NS_IMETHODIMP
 gfxPlatformFontList::MemoryReporter::CollectReports(
     nsIHandleReportCallback* aHandleReport, nsISupports* aData, bool aAnonymize)
 {
     FontListSizes sizes;
     sizes.mFontListSize = 0;
     sizes.mFontTableCacheSize = 0;
     sizes.mCharMapsSize = 0;
+    sizes.mLoaderSize = 0;
 
     gfxPlatformFontList::PlatformFontList()->AddSizeOfIncludingThis(&FontListMallocSizeOf,
                                                                     &sizes);
 
     MOZ_COLLECT_REPORT(
         "explicit/gfx/font-list", KIND_HEAP, UNITS_BYTES,
         sizes.mFontListSize,
         "Memory used to manage the list of font families and faces.");
@@ -177,16 +178,23 @@ gfxPlatformFontList::MemoryReporter::Col
 
     if (sizes.mFontTableCacheSize) {
         MOZ_COLLECT_REPORT(
             "explicit/gfx/font-tables", KIND_HEAP, UNITS_BYTES,
             sizes.mFontTableCacheSize,
             "Memory used for cached font metrics and layout tables.");
     }
 
+    if (sizes.mLoaderSize) {
+        MOZ_COLLECT_REPORT(
+            "explicit/gfx/font-loader", KIND_HEAP, UNITS_BYTES,
+            sizes.mLoaderSize,
+            "Memory used for (platform-specific) font loader.");
+    }
+
     return NS_OK;
 }
 
 gfxPlatformFontList::gfxPlatformFontList(bool aNeedFullnamePostscriptNames)
     : mFontFamiliesMutex("gfxPlatformFontList::mFontFamiliesMutex"), mFontFamilies(64),
       mOtherFamilyNames(16), mBadUnderlineFamilyNames(8), mSharedCmaps(8),
       mStartIndex(0), mNumFamilies(0), mFontlistInitCount(0),
       mFontFamilyWhitelistActive(false)
--- a/gfx/thebes/gfxPlatformFontList.h
+++ b/gfx/thebes/gfxPlatformFontList.h
@@ -82,16 +82,17 @@ protected:
 // Much of this is based on the old gfxQuartzFontCache, but adapted for use on all platforms.
 
 struct FontListSizes {
     uint32_t mFontListSize; // size of the font list and dependent objects
                             // (font family and face names, etc), but NOT
                             // including the font table cache and the cmaps
     uint32_t mFontTableCacheSize; // memory used for the gfxFontEntry table caches
     uint32_t mCharMapsSize; // memory used for cmap coverage info
+    uint32_t mLoaderSize;   // memory used for (platform-specific) loader
 };
 
 class gfxUserFontSet;
 
 class gfxPlatformFontList : public gfxFontInfoLoader
 {
     friend class InitOtherFamilyNamesRunnable;
 
deleted file mode 100644
--- a/js/src/frontend/LanguageExtensions.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sts=4 et sw=4 tw=99:
- * 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/. */
-
-/* Code related to various SpiderMonkey-specific language syntax extensions. */
-
-#ifndef frontend_LanguageExtensions_h
-#define frontend_LanguageExtensions_h
-
-namespace js {
-
-/**
- * Numeric identifiers for various deprecated language extensions.
- *
- * The initializer numbers are directly used in telemetry, so while it's okay
- * to *remove* values as language extensions are removed from SpiderMonkey,
- * it's *not* okay to compact or reorder them.  When an initializer falls into
- * disuse, remove it without reassigning its value to a new or existing
- * initializer.  The *only* initializer whose value should ever change is
- * DeprecatedLanguageExtension::Count.
- */
-enum class DeprecatedLanguageExtension
-{
-    // NO LONGER USING 0
-    // NO LONGER USING 1
-    // NO LONGER USING 2
-    ExpressionClosure = 3, // Added in JS 1.8
-    // NO LONGER USING 4
-    // NO LONGER USING 5
-    // NO LONGER USING 6
-    // NO LONGER USING 7
-    // NO LONGER USING 8
-    // NO LONGER USING 9
-    // NO LONGER USING 10
-
-    // Sentinel value.  MAY change as extension initializers are added (only to
-    // the end) above.
-    Count
-};
-
-} // namespace js
-
-#endif /* frontend_LanguageExtensions_h */
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -9987,24 +9987,16 @@ GeneralParser<ParseHandler, CharT>::expr
                                                  YieldHandling yieldHandling,
                                                  TripledotHandling tripledotHandling,
                                                  PossibleError* possibleError /* = nullptr */)
 {
     MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Lp));
     return expr(inHandling, yieldHandling, tripledotHandling, possibleError, PredictInvoked);
 }
 
-void
-ParserBase::addTelemetry(DeprecatedLanguageExtension e)
-{
-    if (context->helperThread())
-        return;
-    context->compartment()->addTelemetry(getFilename(), e);
-}
-
 template class PerHandlerParser<FullParseHandler>;
 template class PerHandlerParser<SyntaxParseHandler>;
 template class GeneralParser<FullParseHandler, char16_t>;
 template class GeneralParser<SyntaxParseHandler, char16_t>;
 template class Parser<FullParseHandler, char16_t>;
 template class Parser<SyntaxParseHandler, char16_t>;
 
 } /* namespace frontend */
--- a/js/src/frontend/Parser.h
+++ b/js/src/frontend/Parser.h
@@ -168,17 +168,16 @@
 #include "mozilla/Maybe.h"
 #include "mozilla/TypeTraits.h"
 
 #include "jspubtd.h"
 
 #include "ds/Nestable.h"
 #include "frontend/BytecodeCompiler.h"
 #include "frontend/FullParseHandler.h"
-#include "frontend/LanguageExtensions.h"
 #include "frontend/NameAnalysisTypes.h"
 #include "frontend/NameCollections.h"
 #include "frontend/ParseContext.h"
 #include "frontend/SharedContext.h"
 #include "frontend/SyntaxParseHandler.h"
 #include "frontend/TokenStream.h"
 #include "vm/Iteration.h"
 
@@ -329,18 +328,16 @@ class ParserBase
 
     bool isUnexpectedEOF() const { return isUnexpectedEOF_; }
 
     MOZ_MUST_USE bool warningNoOffset(unsigned errorNumber, ...);
     void errorNoOffset(unsigned errorNumber, ...);
 
     bool isValidStrictBinding(PropertyName* name);
 
-    void addTelemetry(DeprecatedLanguageExtension e);
-
     bool hasValidSimpleStrictParameterNames();
 
     /*
      * Create a new function object given a name (which is optional if this is
      * a function expression).
      */
     JSFunction* newFunction(HandleAtom atom, FunctionSyntaxKind kind,
                             GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
--- a/js/src/jsfriendapi.h
+++ b/js/src/jsfriendapi.h
@@ -153,17 +153,16 @@ enum {
     JS_TELEMETRY_GC_NON_INCREMENTAL_REASON,
     JS_TELEMETRY_GC_SCC_SWEEP_TOTAL_MS,
     JS_TELEMETRY_GC_SCC_SWEEP_MAX_PAUSE_MS,
     JS_TELEMETRY_GC_MINOR_REASON,
     JS_TELEMETRY_GC_MINOR_REASON_LONG,
     JS_TELEMETRY_GC_MINOR_US,
     JS_TELEMETRY_GC_NURSERY_BYTES,
     JS_TELEMETRY_GC_PRETENURE_COUNT,
-    JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT,
     JS_TELEMETRY_PRIVILEGED_PARSER_COMPILE_LAZY_AFTER_MS,
     JS_TELEMETRY_WEB_PARSER_COMPILE_LAZY_AFTER_MS,
     JS_TELEMETRY_END
 };
 
 typedef void
 (*JSAccumulateTelemetryDataCallback)(int id, uint32_t sample, const char* key);
 
--- a/js/src/vm/JSCompartment.cpp
+++ b/js/src/vm/JSCompartment.cpp
@@ -86,26 +86,23 @@ JSCompartment::JSCompartment(Zone* zone,
     scheduledForDestruction(false),
     maybeAlive(true),
     jitCompartment_(nullptr),
     mappedArgumentsTemplate_(nullptr),
     unmappedArgumentsTemplate_(nullptr),
     iterResultTemplate_(nullptr),
     lcovOutput()
 {
-    PodArrayZero(sawDeprecatedLanguageExtension);
     runtime_->numCompartments++;
     MOZ_ASSERT_IF(creationOptions_.mergeable(),
                   creationOptions_.invisibleToDebugger());
 }
 
 JSCompartment::~JSCompartment()
 {
-    reportTelemetry();
-
     // Write the code coverage information in a file.
     JSRuntime* rt = runtimeFromActiveCooperatingThread();
     if (rt->lcovOutput().isEnabled())
         rt->lcovOutput().writeLCovResult(lcovOutput);
 
     js_delete(jitCompartment_);
     js_delete(scriptCountsMap);
     js_delete(scriptNameMap);
@@ -1332,45 +1329,16 @@ JSCompartment::addSizeOfIncludingThis(mo
     if (scriptCountsMap) {
         *scriptCountsMapArg += scriptCountsMap->sizeOfIncludingThis(mallocSizeOf);
         for (auto r = scriptCountsMap->all(); !r.empty(); r.popFront()) {
             *scriptCountsMapArg += r.front().value()->sizeOfIncludingThis(mallocSizeOf);
         }
     }
 }
 
-void
-JSCompartment::reportTelemetry()
-{
-    // Only report telemetry for web content, not chrome JS.
-    if (isSystem_)
-        return;
-
-    // Hazard analysis can't tell that the telemetry callbacks don't GC.
-    JS::AutoSuppressGCAnalysis nogc;
-
-    // Call back into Firefox's Telemetry reporter.
-    for (size_t i = 0; i < size_t(DeprecatedLanguageExtension::Count); i++) {
-        if (sawDeprecatedLanguageExtension[i])
-            runtime_->addTelemetry(JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT, i);
-    }
-}
-
-void
-JSCompartment::addTelemetry(const char* filename, DeprecatedLanguageExtension e)
-{
-    // Only report telemetry for web content, not chrome JS.
-    if (isSystem_)
-        return;
-    if (!filename || strncmp(filename, "http", 4) != 0)
-        return;
-
-    sawDeprecatedLanguageExtension[size_t(e)] = true;
-}
-
 HashNumber
 JSCompartment::randomHashCode()
 {
     ensureRandomNumberGenerator();
     return HashNumber(randomNumberGenerator.ref().next());
 }
 
 mozilla::HashCodeScrambler
--- a/js/src/vm/JSCompartment.h
+++ b/js/src/vm/JSCompartment.h
@@ -11,17 +11,16 @@
 #include "mozilla/Maybe.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/Tuple.h"
 #include "mozilla/Variant.h"
 #include "mozilla/XorShift128PlusRNG.h"
 
 #include <stddef.h>
 
-#include "frontend/LanguageExtensions.h"
 #include "gc/Barrier.h"
 #include "gc/NurseryAwareHashMap.h"
 #include "gc/Zone.h"
 #include "vm/ArrayBufferObject.h"
 #include "vm/GlobalObject.h"
 #include "vm/ReceiverGuard.h"
 #include "vm/RegExpShared.h"
 #include "vm/SavedStacks.h"
@@ -1181,26 +1180,16 @@ struct JSCompartment
     js::ArgumentsObject* getOrCreateArgumentsTemplateObject(JSContext* cx, bool mapped);
 
     js::ArgumentsObject* maybeArgumentsTemplateObject(bool mapped) const;
 
     static const size_t IterResultObjectValueSlot = 0;
     static const size_t IterResultObjectDoneSlot = 1;
     js::NativeObject* getOrCreateIterResultTemplateObject(JSContext* cx);
 
-  private:
-    // Used for collecting telemetry on SpiderMonkey's deprecated language extensions.
-    bool sawDeprecatedLanguageExtension[size_t(js::DeprecatedLanguageExtension::Count)];
-
-    void reportTelemetry();
-
-  public:
-    void addTelemetry(const char* filename, js::DeprecatedLanguageExtension e);
-
-  public:
     // Aggregated output used to collect JSScript hit counts when code coverage
     // is enabled.
     js::coverage::LCovCompartment lcovOutput;
 
     bool addMapWithNurseryMemory(js::MapObject* obj) {
         MOZ_ASSERT_IF(!mapsWithNurseryMemory.empty(),
                       mapsWithNurseryMemory.back() != obj);
         return mapsWithNurseryMemory.append(obj);
--- a/js/src/wasm/WasmBuiltins.cpp
+++ b/js/src/wasm/WasmBuiltins.cpp
@@ -497,18 +497,18 @@ FuncCast(F* funcPtr, ABIFunctionType abi
 {
     void* pf = JS_FUNC_TO_DATA_PTR(void*, funcPtr);
 #ifdef JS_SIMULATOR
     pf = Simulator::RedirectNativeFunction(pf, abiType);
 #endif
     return pf;
 }
 
-void*
-wasm::AddressOf(SymbolicAddress imm, ABIFunctionType* abiType)
+static void*
+AddressOf(SymbolicAddress imm, ABIFunctionType* abiType)
 {
     switch (imm) {
       case SymbolicAddress::HandleDebugTrap:
         *abiType = Args_General0;
         return FuncCast(WasmHandleDebugTrap, *abiType);
       case SymbolicAddress::HandleThrow:
         *abiType = Args_General0;
         return FuncCast(WasmHandleThrow, *abiType);
--- a/js/src/wasm/WasmBuiltins.h
+++ b/js/src/wasm/WasmBuiltins.h
@@ -21,19 +21,16 @@
 
 #include "wasm/WasmTypes.h"
 
 namespace js {
 namespace wasm {
 
 class WasmFrameIter;
 
-void*
-AddressOf(SymbolicAddress sym, jit::ABIFunctionType* abiType);
-
 // A SymbolicAddress that NeedsBuiltinThunk() will call through a thunk to the
 // C++ function. This will be true for all normal calls from normal wasm
 // function code. Only calls to C++ from other exits/thunks do not need a thunk.
 
 bool
 NeedsBuiltinThunk(SymbolicAddress sym);
 
 // This function queries whether pc is in one of the process's builtin thunks
--- a/js/src/wasm/WasmStubs.cpp
+++ b/js/src/wasm/WasmStubs.cpp
@@ -466,19 +466,18 @@ static const ValueOperand ScratchValIonE
 #else
 static const ValueOperand ScratchValIonEntry = ValueOperand(ABINonArgReg0, ABINonArgReg1);
 #endif
 static const Register ScratchIonEntry = ABINonArgReg2;
 
 static void
 CallSymbolicAddress(MacroAssembler& masm, bool isAbsolute, SymbolicAddress sym)
 {
-    ABIFunctionType _;
     if (isAbsolute)
-        masm.call(ImmPtr(AddressOf(sym, &_), ImmPtr::NoCheckToken()));
+        masm.call(ImmPtr(SymbolicAddressTarget(sym), ImmPtr::NoCheckToken()));
     else
         masm.call(sym);
 }
 
 // Load instance's TLS from the callee.
 static void
 GenerateJitEntryLoadTls(MacroAssembler& masm, unsigned frameSize)
 {
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -2560,19 +2560,16 @@ AccumulateTelemetryCallback(int id, uint
         Telemetry::Accumulate(Telemetry::GC_MINOR_US, sample);
         break;
       case JS_TELEMETRY_GC_NURSERY_BYTES:
         Telemetry::Accumulate(Telemetry::GC_NURSERY_BYTES, sample);
         break;
       case JS_TELEMETRY_GC_PRETENURE_COUNT:
         Telemetry::Accumulate(Telemetry::GC_PRETENURE_COUNT, sample);
         break;
-      case JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT:
-        Telemetry::Accumulate(Telemetry::JS_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT, sample);
-        break;
       case JS_TELEMETRY_PRIVILEGED_PARSER_COMPILE_LAZY_AFTER_MS:
         Telemetry::Accumulate(Telemetry::JS_PRIVILEGED_PARSER_COMPILE_LAZY_AFTER_MS, sample);
         break;
       case JS_TELEMETRY_WEB_PARSER_COMPILE_LAZY_AFTER_MS:
         Telemetry::Accumulate(Telemetry::JS_WEB_PARSER_COMPILE_LAZY_AFTER_MS, sample);
         break;
       default:
         MOZ_ASSERT_UNREACHABLE("Unexpected JS_TELEMETRY id");
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -1782,18 +1782,20 @@ nsPresContext::ThemeChangedInternal()
     // in bug 940625 we decided theme changes are rare enough not to bother.)
     image::SurfaceCacheUtils::DiscardAll();
   }
 
   RefreshSystemMetrics();
 
   // Recursively notify all remote leaf descendants that the
   // system theme has changed.
-  nsContentUtils::CallOnAllRemoteChildren(mDocument->GetWindow(),
-                                          NotifyThemeChanged, nullptr);
+  if (nsPIDOMWindowOuter* window = mDocument->GetWindow()) {
+    nsContentUtils::CallOnAllRemoteChildren(window,
+                                            NotifyThemeChanged, nullptr);
+  }
 }
 
 void
 nsPresContext::SysColorChanged()
 {
   if (!mPendingSysColorChanged) {
     sLookAndFeelChanged = true;
     nsCOMPtr<nsIRunnable> ev =
@@ -2113,19 +2115,21 @@ NotifyTabSizeModeChanged(TabParent* aTab
   nsSizeMode* sizeMode = static_cast<nsSizeMode*>(aArg);
   aTab->SizeModeChanged(*sizeMode);
   return false;
 }
 
 void
 nsPresContext::SizeModeChanged(nsSizeMode aSizeMode)
 {
-  nsContentUtils::CallOnAllRemoteChildren(mDocument->GetWindow(),
-                                          NotifyTabSizeModeChanged,
-                                          &aSizeMode);
+  if (nsPIDOMWindowOuter* window = mDocument->GetWindow()) {
+    nsContentUtils::CallOnAllRemoteChildren(window,
+                                            NotifyTabSizeModeChanged,
+                                            &aSizeMode);
+  }
   MediaFeatureValuesChangedAllDocuments({ MediaFeatureChangeReason::SizeModeChange });
 }
 
 nsCompatibility
 nsPresContext::CompatibilityMode() const
 {
   return Document()->GetCompatibilityMode();
 }
--- a/layout/style/ServoUtils.h
+++ b/layout/style/ServoUtils.h
@@ -36,46 +36,26 @@ inline bool IsInServoTraversal()
 } // namespace mozilla
 
 #define MOZ_DECL_STYLO_CONVERT_METHODS_SERVO(servotype_) \
   inline servotype_* AsServo();                         \
   inline const servotype_* AsServo() const;             \
   inline servotype_* GetAsServo();                      \
   inline const servotype_* GetAsServo() const;
 
-#define MOZ_DECL_STYLO_CONVERT_METHODS_GECKO(geckotype_) \
-  inline geckotype_* AsGecko();                         \
-  inline const geckotype_* AsGecko() const;             \
-  inline geckotype_* GetAsGecko();                      \
-  inline const geckotype_* GetAsGecko() const;
-
 #define MOZ_DECL_STYLO_CONVERT_METHODS(geckotype_, servotype_) \
   MOZ_DECL_STYLO_CONVERT_METHODS_SERVO(servotype_)
 
 /**
  * Macro used in a base class of |geckotype_| and |servotype_|.
  * The class should define |StyleBackendType mType;| itself.
  */
 #define MOZ_DECL_STYLO_METHODS(geckotype_, servotype_)  \
   MOZ_DECL_STYLO_CONVERT_METHODS(geckotype_, servotype_)
 
-#define MOZ_DEFINE_STYLO_METHODS_GECKO(type_, geckotype_) \
-  geckotype_* type_::AsGecko() {                                \
-    return static_cast<geckotype_*>(this);                      \
-  }                                                             \
-  const geckotype_* type_::AsGecko() const {                    \
-    return static_cast<const geckotype_*>(this);                \
-  }                                                             \
-  geckotype_* type_::GetAsGecko() {                             \
-    return nullptr;                                             \
-  }                                                             \
-  const geckotype_* type_::GetAsGecko() const {                 \
-    return nullptr;                                             \
-  }
-
 #define MOZ_DEFINE_STYLO_METHODS_SERVO(type_, servotype_) \
   servotype_* type_::AsServo() {                                \
     return static_cast<servotype_*>(this);                      \
   }                                                             \
   const servotype_* type_::AsServo() const {                    \
     return static_cast<const servotype_*>(this);                \
   }                                                             \
   servotype_* type_::GetAsServo() {                             \
@@ -90,17 +70,16 @@ inline bool IsInServoTraversal()
  * Macro used in inline header of class |type_| with its Gecko and Servo
  * subclasses named |geckotype_| and |servotype_| correspondingly for
  * implementing the inline methods defined by MOZ_DECL_STYLO_METHODS.
  */
 #define MOZ_DEFINE_STYLO_METHODS(type_, geckotype_, servotype_) \
   MOZ_DEFINE_STYLO_METHODS_SERVO(type_, servotype_)
 
 #define MOZ_STYLO_THIS_TYPE  mozilla::RemovePointer<decltype(this)>::Type
-#define MOZ_STYLO_GECKO_TYPE mozilla::RemovePointer<decltype(AsGecko())>::Type
 #define MOZ_STYLO_SERVO_TYPE mozilla::RemovePointer<decltype(AsServo())>::Type
 
 /**
  * Macro used to forward a method call to the concrete method defined by
  * the Servo or Gecko implementation. The class of the method using it
  * should use MOZ_DECL_STYLO_METHODS to define basic stylo methods.
  */
 #define MOZ_STYLO_FORWARD_CONCRETE(method_, geckoargs_, servoargs_)         \
deleted file mode 100644
--- a/layout/style/nsCSSRules.h
+++ /dev/null
@@ -1,429 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* 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/. */
-
-/* rules in a CSS stylesheet other than style rules (e.g., @import rules) */
-
-#ifndef nsCSSRules_h_
-#define nsCSSRules_h_
-
-#include "Declaration.h"
-#include "StyleRule.h"
-#include "gfxFontFeatures.h"
-#include "mozilla/Attributes.h"
-#include "mozilla/MemoryReporting.h"
-#include "mozilla/Move.h"
-#include "mozilla/SheetType.h"
-#include "mozilla/css/GroupRule.h"
-#include "mozilla/css/URLMatchingFunction.h"
-#include "mozilla/dom/CSSFontFeatureValuesRule.h"
-#include "mozilla/dom/CSSKeyframeRule.h"
-#include "mozilla/dom/CSSKeyframesRule.h"
-#include "mozilla/dom/CSSMediaRule.h"
-#include "mozilla/dom/CSSPageRule.h"
-#include "mozilla/dom/CSSSupportsRule.h"
-#include "mozilla/dom/CSSMozDocumentRule.h"
-#include "nsAutoPtr.h"
-#include "nsCSSPropertyID.h"
-#include "nsCSSValue.h"
-#include "nsDOMCSSDeclaration.h"
-#include "nsTArray.h"
-
-class nsMediaList;
-
-namespace mozilla {
-
-class ErrorResult;
-
-namespace dom {
-class DocGroup;
-class MediaList;
-}
-
-namespace css {
-
-class MediaRule final : public dom::CSSMediaRule
-{
-public:
-  MediaRule(uint32_t aLineNumber, uint32_t aColumnNumber);
-private:
-  MediaRule(const MediaRule& aCopy);
-  ~MediaRule();
-public:
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MediaRule, dom::CSSMediaRule)
-
-  // Rule methods
-#ifdef DEBUG
-  virtual void List(FILE* out = stdout, int32_t aIndent = 0) const override;
-#endif
-  virtual void SetStyleSheet(mozilla::StyleSheet* aSheet) override; //override GroupRule
-  mozilla::CSSStyleSheet* GetStyleSheet() const
-  {
-    mozilla::StyleSheet* sheet = GroupRule::GetStyleSheet();
-    return sheet ? sheet->AsGecko() : nullptr;
-  }
-  virtual already_AddRefed<Rule> Clone() const override;
-
-  // rest of GroupRule
-  virtual bool UseForPresentation(nsPresContext* aPresContext,
-                                    nsMediaQueryResultCacheKey& aKey) override;
-
-  // @media rule methods
-  nsresult SetMedia(nsMediaList* aMedia);
-
-  // WebIDL interface
-  void GetCssText(nsAString& aCssText) const final;
-  void GetConditionText(nsAString& aConditionText) final;
-  void SetConditionText(const nsAString& aConditionText,
-                        ErrorResult& aRv) final;
-  dom::MediaList* Media() final;
-
-  virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)
-    const override MOZ_MUST_OVERRIDE;
-
-protected:
-  void AppendConditionText(nsAString& aOutput) const;
-
-  RefPtr<nsMediaList> mMedia;
-};
-
-class DocumentRule final : public dom::CSSMozDocumentRule
-{
-public:
-  DocumentRule(uint32_t aLineNumber, uint32_t aColumnNumber);
-private:
-  DocumentRule(const DocumentRule& aCopy);
-  ~DocumentRule();
-public:
-
-  NS_INLINE_DECL_REFCOUNTING_INHERITED(DocumentRule,
-                                       dom::CSSMozDocumentRule)
-
-  // Rule methods
-#ifdef DEBUG
-  virtual void List(FILE* out = stdout, int32_t aIndent = 0) const override;
-#endif
-  virtual already_AddRefed<Rule> Clone() const override;
-
-  // rest of GroupRule
-  virtual bool UseForPresentation(nsPresContext* aPresContext,
-                                  nsMediaQueryResultCacheKey& aKey) override;
-
-  bool UseForPresentation(nsPresContext* aPresContext);
-
-  struct URL {
-    URLMatchingFunction func;
-    nsCString url;
-    URL *next;
-
-    URL() : next(nullptr) {}
-    URL(const URL& aOther)
-      : func(aOther.func)
-      , url(aOther.url)
-      , next(aOther.next ? new URL(*aOther.next) : nullptr)
-    {
-    }
-    ~URL();
-  };
-
-  void SetURLs(URL *aURLs) { mURLs = aURLs; }
-
-  // WebIDL interface
-  void GetCssText(nsAString& aCssText) const final;
-  void GetConditionText(nsAString& aConditionText) final;
-  void SetConditionText(const nsAString& aConditionText,
-                        ErrorResult& aRv) final;
-
-  virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)
-    const override MOZ_MUST_OVERRIDE;
-
-protected:
-  void AppendConditionText(nsAString& aOutput) const;
-
-  nsAutoPtr<URL> mURLs; // linked list of |struct URL| above.
-};
-
-} // namespace css
-
-} // namespace mozilla
-
-class nsCSSFontFeatureValuesRule final : public mozilla::dom::CSSFontFeatureValuesRule
-{
-public:
-  nsCSSFontFeatureValuesRule(uint32_t aLineNumber, uint32_t aColumnNumber)
-    : mozilla::dom::CSSFontFeatureValuesRule(aLineNumber, aColumnNumber)
-  {
-  }
-
-  nsCSSFontFeatureValuesRule(const nsCSSFontFeatureValuesRule& aCopy)
-    // copy everything except our reference count
-    : mozilla::dom::CSSFontFeatureValuesRule(aCopy),
-      mFamilyList(aCopy.mFamilyList),
-      mFeatureValues(aCopy.mFeatureValues)
-  {
-  }
-
-#ifdef DEBUG
-  void List(FILE* out = stdout, int32_t aIndent = 0) const final;
-#endif
-  already_AddRefed<mozilla::css::Rule> Clone() const final;
-
-  // WebIDL interface
-  void GetCssText(nsAString& aCssText) const final;
-  void GetFontFamily(nsAString& aFamily) final;
-  void SetFontFamily(const nsAString& aFamily, mozilla::ErrorResult& aRv) final;
-  void GetValueText(nsAString& aValueText) final;
-  void SetValueText(const nsAString& aValueText, mozilla::ErrorResult& aRv) final;
-
-  mozilla::SharedFontList* GetFamilyList() const { return mFamilyList; }
-  void SetFamilyList(mozilla::SharedFontList* aFamilyList)
-  {
-    mFamilyList = aFamilyList;
-  }
-
-  void AddValueList(int32_t aVariantAlternate,
-                    nsTArray<gfxFontFeatureValueSet::ValueList>& aValueList);
-
-  const nsTArray<gfxFontFeatureValueSet::FeatureValues>& GetFeatureValues()
-  {
-    return mFeatureValues;
-  }
-
-  size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const final;
-
-protected:
-  ~nsCSSFontFeatureValuesRule() {}
-
-  RefPtr<mozilla::SharedFontList> mFamilyList;
-  nsTArray<gfxFontFeatureValueSet::FeatureValues> mFeatureValues;
-};
-
-class nsCSSKeyframeRule;
-
-class nsCSSKeyframeStyleDeclaration final : public nsDOMCSSDeclaration
-{
-public:
-  explicit nsCSSKeyframeStyleDeclaration(nsCSSKeyframeRule *aRule);
-
-  mozilla::css::Rule* GetParentRule() override;
-  void DropReference() { mRule = nullptr; }
-  virtual mozilla::DeclarationBlock* GetCSSDeclaration(Operation aOperation) override;
-  virtual nsresult SetCSSDeclaration(mozilla::DeclarationBlock* aDecl) override;
-  virtual void GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv,
-                                        nsIPrincipal* aSubjectPrincipal) override;
-  nsDOMCSSDeclaration::ServoCSSParsingEnvironment
-  GetServoCSSParsingEnvironment(nsIPrincipal* aSubjectPrincipal) const final;
-  virtual nsIDocument* DocToUpdate() override;
-
-  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsCSSKeyframeStyleDeclaration,
-                                                         nsICSSDeclaration)
-
-  virtual nsINode* GetParentObject() override;
-
-protected:
-  virtual ~nsCSSKeyframeStyleDeclaration();
-
-  // This reference is not reference-counted. The rule object tells us
-  // when it's about to go away.
-  nsCSSKeyframeRule* MOZ_NON_OWNING_REF mRule;
-};
-
-class nsCSSKeyframeRule final : public mozilla::dom::CSSKeyframeRule
-{
-public:
-  // Steals the contents of aKeys, and takes the reference in Declaration
-  nsCSSKeyframeRule(InfallibleTArray<float>&& aKeys,
-                    already_AddRefed<mozilla::css::Declaration>&& aDeclaration,
-                    uint32_t aLineNumber, uint32_t aColumnNumber)
-    : mozilla::dom::CSSKeyframeRule(aLineNumber, aColumnNumber)
-    , mKeys(mozilla::Move(aKeys))
-    , mDeclaration(mozilla::Move(aDeclaration))
-  {
-    mDeclaration->SetOwningRule(this);
-  }
-private:
-  nsCSSKeyframeRule(const nsCSSKeyframeRule& aCopy);
-  ~nsCSSKeyframeRule();
-public:
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsCSSKeyframeRule,
-                                           mozilla::dom::CSSKeyframeRule)
-  virtual bool IsCCLeaf() const override;
-
-#ifdef DEBUG
-  virtual void List(FILE* out = stdout, int32_t aIndent = 0) const override;
-#endif
-  virtual already_AddRefed<mozilla::css::Rule> Clone() const override;
-
-  // WebIDL interface
-  void GetCssText(nsAString& aCssText) const final;
-  void GetKeyText(nsAString& aKeyText) final;
-  void SetKeyText(const nsAString& aKeyText) final;
-  nsICSSDeclaration* Style() final;
-
-  const nsTArray<float>& GetKeys() const     { return mKeys; }
-  mozilla::css::Declaration* Declaration()   { return mDeclaration; }
-
-  void ChangeDeclaration(mozilla::css::Declaration* aDeclaration);
-
-  virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
-
-  void DoGetKeyText(nsAString &aKeyText) const;
-
-private:
-  nsTArray<float>                            mKeys;
-  RefPtr<mozilla::css::Declaration>          mDeclaration;
-  // lazily created when needed:
-  RefPtr<nsCSSKeyframeStyleDeclaration>    mDOMDeclaration;
-};
-
-class nsCSSKeyframesRule final : public mozilla::dom::CSSKeyframesRule
-{
-public:
-  nsCSSKeyframesRule(already_AddRefed<nsAtom> aName,
-                     uint32_t aLineNumber, uint32_t aColumnNumber)
-    : mozilla::dom::CSSKeyframesRule(aLineNumber, aColumnNumber)
-    , mName(aName)
-  {
-  }
-private:
-  nsCSSKeyframesRule(const nsCSSKeyframesRule& aCopy);
-  ~nsCSSKeyframesRule();
-public:
-  // Rule methods
-#ifdef DEBUG
-  virtual void List(FILE* out = stdout, int32_t aIndent = 0) const override;
-#endif
-  virtual already_AddRefed<mozilla::css::Rule> Clone() const override;
-
-  // WebIDL interface
-  void GetCssText(nsAString& aCssText) const final;
-  void GetName(nsAString& aName) const final;
-  void SetName(const nsAString& aName) final;
-  mozilla::dom::CSSRuleList* CssRules() final { return GroupRule::CssRules(); }
-  void AppendRule(const nsAString& aRule) final;
-  void DeleteRule(const nsAString& aKey) final;
-  nsCSSKeyframeRule* FindRule(const nsAString& aKey) final;
-
-  const nsAtom* GetName() const { return mName; }
-
-  virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
-
-private:
-  uint32_t FindRuleIndexForKey(const nsAString& aKey);
-
-  RefPtr<nsAtom> mName;
-};
-
-class nsCSSPageRule;
-
-class nsCSSPageStyleDeclaration final : public nsDOMCSSDeclaration
-{
-public:
-  explicit nsCSSPageStyleDeclaration(nsCSSPageRule *aRule);
-
-  mozilla::css::Rule* GetParentRule() override;
-  void DropReference() { mRule = nullptr; }
-  virtual mozilla::DeclarationBlock* GetCSSDeclaration(Operation aOperation) override;
-  virtual nsresult SetCSSDeclaration(mozilla::DeclarationBlock* aDecl) override;
-  virtual void GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv,
-                                        nsIPrincipal* aSubjectPrincipal) override;
-  nsDOMCSSDeclaration::ServoCSSParsingEnvironment
-  GetServoCSSParsingEnvironment(nsIPrincipal* aSubjectPrincipal) const final;
-  virtual nsIDocument* DocToUpdate() override;
-
-  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsCSSPageStyleDeclaration,
-                                                         nsICSSDeclaration)
-
-  virtual nsINode *GetParentObject() override;
-
-protected:
-  virtual ~nsCSSPageStyleDeclaration();
-
-  // This reference is not reference-counted. The rule object tells us
-  // when it's about to go away.
-  nsCSSPageRule* MOZ_NON_OWNING_REF mRule;
-};
-
-class nsCSSPageRule final : public mozilla::dom::CSSPageRule
-{
-public:
-  nsCSSPageRule(mozilla::css::Declaration* aDeclaration,
-                uint32_t aLineNumber, uint32_t aColumnNumber)
-    : mozilla::dom::CSSPageRule(aLineNumber, aColumnNumber)
-    , mDeclaration(aDeclaration)
-  {
-    mDeclaration->SetOwningRule(this);
-  }
-private:
-  nsCSSPageRule(const nsCSSPageRule& aCopy);
-  ~nsCSSPageRule();
-public:
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsCSSPageRule, mozilla::dom::CSSPageRule)
-  virtual bool IsCCLeaf() const override;
-
-#ifdef DEBUG
-  virtual void List(FILE* out = stdout, int32_t aIndent = 0) const override;
-#endif
-  virtual already_AddRefed<mozilla::css::Rule> Clone() const override;
-
-  // WebIDL interfaces
-  virtual void GetCssText(nsAString& aCssText) const override;
-  virtual nsICSSDeclaration* Style() override;
-
-  mozilla::css::Declaration* Declaration()   { return mDeclaration; }
-
-  void ChangeDeclaration(mozilla::css::Declaration* aDeclaration);
-
-  virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
-
-private:
-  RefPtr<mozilla::css::Declaration>     mDeclaration;
-  // lazily created when needed:
-  RefPtr<nsCSSPageStyleDeclaration>     mDOMDeclaration;
-};
-
-namespace mozilla {
-
-class CSSSupportsRule final : public dom::CSSSupportsRule
-{
-public:
-  CSSSupportsRule(bool aConditionMet, const nsString& aCondition,
-                  uint32_t aLineNumber, uint32_t aColumnNumber);
-  CSSSupportsRule(const CSSSupportsRule& aCopy);
-
-  // Rule methods
-#ifdef DEBUG
-  virtual void List(FILE* out = stdout, int32_t aIndent = 0) const override;
-#endif
-  virtual already_AddRefed<mozilla::css::Rule> Clone() const override;
-  virtual bool UseForPresentation(nsPresContext* aPresContext,
-                                  nsMediaQueryResultCacheKey& aKey) override;
-
-  NS_INLINE_DECL_REFCOUNTING_INHERITED(CSSSupportsRule,
-                                       dom::CSSSupportsRule)
-
-  // WebIDL interface
-  void GetCssText(nsAString& aCssText) const final;
-  void GetConditionText(nsAString& aConditionText) final;
-  void SetConditionText(const nsAString& aConditionText,
-                        ErrorResult& aRv) final;
-
-  virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
-
-protected:
-  virtual ~CSSSupportsRule();
-
-  bool mUseGroup;
-  nsString mCondition;
-};
-
-} // namespace mozilla
-
-#endif /* !defined(nsCSSRules_h_) */
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/GlobalSession.java
+++ b/mobile/android/services/src/main/java/org/mozilla/gecko/sync/GlobalSession.java
@@ -278,16 +278,29 @@ public class GlobalSession implements Ht
   public void advance() {
     // If we have a backoff, request a backoff and don't advance to next stage.
     long existingBackoff = largestBackoffObserved.get();
     if (existingBackoff > 0) {
       this.abort(new BackoffException(), "Aborting sync because of backoff of " + existingBackoff + " milliseconds.");
       return;
     }
 
+    // Bug 1442248. The right fix for this is to figure out why we're reaching
+    // `session.advance()` in `ServerSyncStage.onSynchronizeFailed(_, _, _)` after
+    // the session has been cleaned up. It might be that we're cleaning up/aborting when
+    // we shouldn't -- e.g., line 685 of `ServerSyncStage.java` is where we should bail
+    // out if we've aborted, and that's not the case.
+    //
+    // In the absence of someone with the time and tools to figure this out, let's just
+    // bail out here.
+    if (this.stages == null) {
+      Logger.info(LOG_TAG, "Not advancing: stages cleaned up.");
+      return;
+    }
+
     this.callback.handleStageCompleted(this.currentState, this);
     Stage next = nextStage(this.currentState);
     GlobalSyncStage nextStage;
     try {
       nextStage = this.getSyncStageByName(next);
     } catch (NoSuchStageException e) {
       this.abort(e, "No such stage " + next);
       return;
--- a/security/certverifier/CertVerifier.cpp
+++ b/security/certverifier/CertVerifier.cpp
@@ -929,16 +929,34 @@ CertVerifier::VerifySSLServerCert(const 
                          ctInfo);
   if (rv != Success) {
     if (rv == Result::ERROR_UNKNOWN_ISSUER &&
         CertIsSelfSigned(peerCert, pinarg)) {
       // In this case we didn't find any issuer for the certificate and the
       // certificate is self-signed.
       return Result::ERROR_SELF_SIGNED_CERT;
     }
+    if (rv == Result::ERROR_UNKNOWN_ISSUER) {
+      // In this case we didn't get any valid path for the cert. Let's see if
+      // the issuer is the same as the issuer for our canary probe. If yes, this
+      // connection is connecting via a misconfigured proxy.
+      // Note: The MitM canary might not be set. In this case we consider this
+      // an unknown issuer error.
+      nsCOMPtr<nsINSSComponent> component(
+        do_GetService(PSM_COMPONENT_CONTRACTID));
+      if (!component) {
+        return Result::FATAL_ERROR_LIBRARY_FAILURE;
+      }
+      // IssuerMatchesMitmCanary succeeds if the issuer matches the canary and
+      // the feature is enabled.
+      nsresult rv = component->IssuerMatchesMitmCanary(peerCert->issuerName);
+      if (NS_SUCCEEDED(rv)) {
+        return Result::ERROR_MITM_DETECTED;
+      }
+    }
     return rv;
   }
 
   Input peerCertInput;
   rv = peerCertInput.Init(peerCert->derCert.data, peerCert->derCert.len);
   if (rv != Success) {
     return rv;
   }
--- a/security/manager/locales/en-US/chrome/pipnss/nsserrors.properties
+++ b/security/manager/locales/en-US/chrome/pipnss/nsserrors.properties
@@ -324,8 +324,9 @@ MOZILLA_PKIX_ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE=A certificate that is not yet valid was used to issue the server’s certificate.
 MOZILLA_PKIX_ERROR_SIGNATURE_ALGORITHM_MISMATCH=The signature algorithm in the signature field of the certificate does not match the algorithm in its signatureAlgorithm field.
 MOZILLA_PKIX_ERROR_OCSP_RESPONSE_FOR_CERT_MISSING=The OCSP response does not include a status for the certificate being verified.
 MOZILLA_PKIX_ERROR_VALIDITY_TOO_LONG=The server presented a certificate that is valid for too long.
 MOZILLA_PKIX_ERROR_REQUIRED_TLS_FEATURE_MISSING=A required TLS feature is missing.
 MOZILLA_PKIX_ERROR_INVALID_INTEGER_ENCODING=The server presented a certificate that contains an invalid encoding of an integer. Common causes include negative serial numbers, negative RSA moduli, and encodings that are longer than necessary.
 MOZILLA_PKIX_ERROR_EMPTY_ISSUER_NAME=The server presented a certificate with an empty issuer distinguished name.
 MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED=An additional policy constraint failed when validating this certificate.
 MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT=The certificate is not trusted because it is self-signed.
+MOZILLA_PKIX_ERROR_MITM_DETECTED=Your connection is being intercepted by a TLS proxy. Uninstall it if possible or configure Firefox to trust its root certificate.
--- a/security/manager/ssl/NSSErrorsService.cpp
+++ b/security/manager/ssl/NSSErrorsService.cpp
@@ -145,16 +145,17 @@ ErrorIsOverridable(PRErrorCode code)
 {
   switch (code)
   {
     // Overridable errors.
     case mozilla::pkix::MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED:
     case mozilla::pkix::MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY:
     case mozilla::pkix::MOZILLA_PKIX_ERROR_EMPTY_ISSUER_NAME:
     case mozilla::pkix::MOZILLA_PKIX_ERROR_INADEQUATE_KEY_SIZE:
+    case mozilla::pkix::MOZILLA_PKIX_ERROR_MITM_DETECTED:
     case mozilla::pkix::MOZILLA_PKIX_ERROR_NOT_YET_VALID_CERTIFICATE:
     case mozilla::pkix::MOZILLA_PKIX_ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE:
     case mozilla::pkix::MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT:
     case mozilla::pkix::MOZILLA_PKIX_ERROR_V1_CERT_USED_AS_CA:
     case SEC_ERROR_CA_CERT_INVALID:
     case SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED:
     case SEC_ERROR_EXPIRED_CERTIFICATE:
     case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
--- a/security/manager/ssl/SSLServerCertVerification.cpp
+++ b/security/manager/ssl/SSLServerCertVerification.cpp
@@ -285,16 +285,17 @@ MapOverridableErrorToProbeValue(PRErrorC
     case mozilla::pkix::MOZILLA_PKIX_ERROR_NOT_YET_VALID_CERTIFICATE: return 14;
     case mozilla::pkix::MOZILLA_PKIX_ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE:
       return 15;
     case SEC_ERROR_INVALID_TIME: return 16;
     case mozilla::pkix::MOZILLA_PKIX_ERROR_EMPTY_ISSUER_NAME: return 17;
     case mozilla::pkix::MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED:
       return 18;
     case mozilla::pkix::MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT: return 19;
+    case mozilla::pkix::MOZILLA_PKIX_ERROR_MITM_DETECTED: return 20;
   }
   NS_WARNING("Unknown certificate error code. Does MapOverridableErrorToProbeValue "
              "handle everything in DetermineCertOverrideErrors?");
   return 0;
 }
 
 static uint32_t
 MapCertErrorToProbeValue(PRErrorCode errorCode)
@@ -346,16 +347,17 @@ DetermineCertOverrideErrors(const Unique
     case SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED:
     case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
     case SEC_ERROR_UNKNOWN_ISSUER:
     case SEC_ERROR_CA_CERT_INVALID:
     case mozilla::pkix::MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED:
     case mozilla::pkix::MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY:
     case mozilla::pkix::MOZILLA_PKIX_ERROR_EMPTY_ISSUER_NAME:
     case mozilla::pkix::MOZILLA_PKIX_ERROR_INADEQUATE_KEY_SIZE:
+    case mozilla::pkix::MOZILLA_PKIX_ERROR_MITM_DETECTED:
     case mozilla::pkix::MOZILLA_PKIX_ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE:
     case mozilla::pkix::MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT:
     case mozilla::pkix::MOZILLA_PKIX_ERROR_V1_CERT_USED_AS_CA:
     {
       collectedErrors = nsICertOverrideService::ERROR_UNTRUSTED;
       errorCodeTrust = defaultErrorCodeToReport;
 
       SECCertTimeValidity validity = CERT_CheckCertValidTimes(cert.get(), now,
--- a/security/manager/ssl/nsNSSComponent.cpp
+++ b/security/manager/ssl/nsNSSComponent.cpp
@@ -2196,16 +2196,22 @@ nsNSSComponent::InitializeNSS()
     mTestBuiltInRootHash.Truncate();
     Preferences::GetString("security.test.built_in_root_hash",
                            mTestBuiltInRootHash);
 #endif
     mContentSigningRootHash.Truncate();
     Preferences::GetString("security.content.signature.root_hash",
                            mContentSigningRootHash);
 
+    mMitmCanaryIssuer.Truncate();
+    Preferences::GetString("security.pki.mitm_canary_issuer",
+                           mMitmCanaryIssuer);
+    mMitmDetecionEnabled =
+      Preferences::GetBool("security.pki.mitm_canary_issuer.enabled", true);
+
     mNSSInitialized = true;
   }
 
   RefPtr<LoadLoadableRootsTask> loadLoadableRootsTask(
     new LoadLoadableRootsTask(this));
   return loadLoadableRootsTask->Dispatch();
 }
 
@@ -2362,16 +2368,26 @@ nsNSSComponent::Observe(nsISupports* aSu
       MaybeEnableFamilySafetyCompatibility();
     } else if (prefName.EqualsLiteral("security.content.signature.root_hash")) {
       MutexAutoLock lock(mMutex);
       mContentSigningRootHash.Truncate();
       Preferences::GetString("security.content.signature.root_hash",
                              mContentSigningRootHash);
     } else if (prefName.Equals(kEnterpriseRootModePref)) {
       MaybeImportEnterpriseRoots();
+    } else if (prefName.EqualsLiteral("security.pki.mitm_canary_issuer")) {
+      MutexAutoLock lock(mMutex);
+      mMitmCanaryIssuer.Truncate();
+      Preferences::GetString("security.pki.mitm_canary_issuer",
+                             mMitmCanaryIssuer);
+    } else if (prefName.EqualsLiteral(
+                 "security.pki.mitm_canary_issuer.enabled")) {
+      MutexAutoLock lock(mMutex);
+      mMitmDetecionEnabled =
+        Preferences::GetBool("security.pki.mitm_canary_issuer.enabled", true);
     } else {
       clearSessionCache = false;
     }
     if (clearSessionCache)
       SSL_ClearSessionCache();
   }
 
   return NS_OK;
@@ -2490,16 +2506,30 @@ nsNSSComponent::IsCertContentSigningRoot
     MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("mContentSigningRootHash is empty"));
     return NS_ERROR_FAILURE;
   }
 
   result = mContentSigningRootHash.Equals(certHash);
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsNSSComponent::IssuerMatchesMitmCanary(const char* aCertIssuer)
+{
+  MutexAutoLock lock(mMutex);
+  if (mMitmDetecionEnabled && !mMitmCanaryIssuer.IsEmpty()) {
+    nsString certIssuer = NS_ConvertUTF8toUTF16(aCertIssuer);
+    if (mMitmCanaryIssuer.Equals(certIssuer)) {
+      return NS_OK;
+    }
+  }
+
+  return NS_ERROR_FAILURE;
+}
+
 SharedCertVerifier::~SharedCertVerifier() { }
 
 already_AddRefed<SharedCertVerifier>
 nsNSSComponent::GetDefaultCertVerifier()
 {
   MutexAutoLock lock(mMutex);
   MOZ_ASSERT(mNSSInitialized);
   RefPtr<SharedCertVerifier> certVerifier(mDefaultCertVerifier);
--- a/security/manager/ssl/nsNSSComponent.h
+++ b/security/manager/ssl/nsNSSComponent.h
@@ -74,16 +74,20 @@ public:
   NS_IMETHOD IsCertContentSigningRoot(CERTCertificate* cert, bool& result) = 0;
 
 #ifdef XP_WIN
   NS_IMETHOD GetEnterpriseRoots(nsIX509CertList** enterpriseRoots) = 0;
 #endif
 
   NS_IMETHOD BlockUntilLoadableRootsLoaded() = 0;
   NS_IMETHOD CheckForSmartCardChanges() = 0;
+  // IssuerMatchesMitmCanary succeeds if aCertIssuer matches the canary and
+  // the feature is enabled. It returns an error if the strings don't match,
+  // the canary is not set, or the feature is disabled.
+  NS_IMETHOD IssuerMatchesMitmCanary(const char* aCertIssuer) = 0;
 
   // Main thread only
   NS_IMETHOD HasActiveSmartCards(bool& result) = 0;
   NS_IMETHOD HasUserCertsInstalled(bool& result) = 0;
 
   virtual ::already_AddRefed<mozilla::psm::SharedCertVerifier>
     GetDefaultCertVerifier() = 0;
 };
@@ -126,16 +130,17 @@ public:
   NS_IMETHOD IsCertContentSigningRoot(CERTCertificate* cert, bool& result) override;
 
 #ifdef XP_WIN
   NS_IMETHOD GetEnterpriseRoots(nsIX509CertList** enterpriseRoots) override;
 #endif
 
   NS_IMETHOD BlockUntilLoadableRootsLoaded() override;
   NS_IMETHOD CheckForSmartCardChanges() override;
+  NS_IMETHOD IssuerMatchesMitmCanary(const char* aCertIssuer) override;
 
   // Main thread only
   NS_IMETHOD HasActiveSmartCards(bool& result) override;
   NS_IMETHOD HasUserCertsInstalled(bool& result) override;
 
   ::already_AddRefed<mozilla::psm::SharedCertVerifier>
     GetDefaultCertVerifier() override;
 
@@ -187,16 +192,18 @@ private:
   nsCOMPtr<nsIStringBundle> mPIPNSSBundle;
   nsCOMPtr<nsIStringBundle> mNSSErrorsBundle;
   bool mNSSInitialized;
 #ifdef DEBUG
   nsString mTestBuiltInRootHash;
 #endif
   nsString mContentSigningRootHash;
   RefPtr<mozilla::psm::SharedCertVerifier> mDefaultCertVerifier;
+  nsString mMitmCanaryIssuer;
+  bool mMitmDetecionEnabled;
 #ifdef XP_WIN
   mozilla::UniqueCERTCertificate mFamilySafetyRoot;
   mozilla::UniqueCERTCertList mEnterpriseRoots;
 #endif // XP_WIN
 
   // The following members are accessed only on the main thread:
   static int mInstanceCount;
 };
--- a/security/manager/ssl/security-prefs.js
+++ b/security/manager/ssl/security-prefs.js
@@ -131,8 +131,15 @@ pref("security.ssl.errorReporting.automa
 pref("security.cert_pinning.max_max_age_seconds", 5184000);
 
 // security.pki.distrust_ca_policy controls what root program distrust policies
 // are enforced at this time:
 // 0: No distrust policies enforced
 // 1: Symantec root distrust policy enforced
 // See https://wiki.mozilla.org/CA/Upcoming_Distrust_Actions for more details.
 pref("security.pki.distrust_ca_policy", 1);
+
+// Issuer we use to detect MitM proxies. Set to the issuer of the cert of the
+// Firefox update service. The string format is whatever NSS uses to print a DN.
+// This value is set and cleared automatically.
+pref("security.pki.mitm_canary_issuer", "");
+// Pref to disable the MitM proxy checks.
+pref("security.pki.mitm_canary_issuer.enabled", true);
new file mode 100644
--- /dev/null
+++ b/security/manager/ssl/tests/unit/bad_certs/mitm.pem
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIC+jCCAeKgAwIBAgIUEeg5ETFB4yT6lPxRZ18k9rDVmqowDQYJKoZIhvcNAQEL
+BQAwGTEXMBUGA1UEAwwOVGVzdCBNSVRNIFJvb3QwIhgPMjAxNjExMjcwMDAwMDBa
+GA8yMDE5MDIwNTAwMDAwMFowMDEuMCwGA1UEAwwlVGVzdCBlbmQtZW50aXR5IGlz
+c3VlZCBmcm9tIE1JVE0gUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
+ggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAab
+bhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmts
+Du0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhI
+H6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8
+rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kX
+Mbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMfMB0wGwYDVR0RBBQwEoIQbWl0bS5l
+eGFtcGxlLmNvbTANBgkqhkiG9w0BAQsFAAOCAQEAHDyyXCBKd2xYyHOw25cei6gU
+MAXeyHZyC6+8h62U61eGL7KWnO+xjVuSK1KlvQjo1G1R0ypkmZzBcNjO/GEfqr06
+xkkGKlTUJcDNyzCFpOm4GDvp3Ojm6SOZT2YeilMjpRU8ONLhFn5s3YvhF2WWp9Al
+1qooxIE6XGJ7TSrA76iEgr1k6+XGg2UULpAONIJZ5K8eS21VWC1r0QKbPWmQ1O1y
+ltEtiC0DluBLeEQf6x5POCNbNaERf1tTVmiNZe2waavvR/gCz+XpxY5k6dnLq8Gf
+cJ4Id3UlcZ5A5W7urNIlMeI2wWhevboRTIx2tKNOQ+3tgsYdf3vGJ2OEqjg5cA==
+-----END CERTIFICATE-----
new file mode 100644
--- /dev/null
+++ b/security/manager/ssl/tests/unit/bad_certs/mitm.pem.certspec
@@ -0,0 +1,3 @@
+issuer:Test MITM Root
+subject:Test end-entity issued from MITM Root
+extension:subjectAlternativeName:mitm.example.com
--- a/security/manager/ssl/tests/unit/bad_certs/moz.build
+++ b/security/manager/ssl/tests/unit/bad_certs/moz.build
@@ -31,16 +31,17 @@
 #    'md5signature-expired.pem',
 #    'md5signature.pem',
 #    'mismatch-expired.pem',
 #    'mismatch-notYetValid.pem',
 #    'mismatch-untrusted-expired.pem',
 #    'mismatch-untrusted.pem',
 #    'mismatch.pem',
 #    'mismatchCN.pem',
+#    'mitm.pem',
 #    'noValidNames.pem',
 #    'notYetValid.pem',
 #    'notYetValidINT.pem',
 #    'notYetValidIssuer.pem',
 #    'nsCertTypeCritical.pem',
 #    'nsCertTypeCriticalWithExtKeyUsage.pem',
 #    'nsCertTypeNotCritical.pem',
 #    'other-issuer-ee.pem',
--- a/security/manager/ssl/tests/unit/head_psm.js
+++ b/security/manager/ssl/tests/unit/head_psm.js
@@ -79,16 +79,17 @@ const MOZILLA_PKIX_ERROR_INADEQUATE_KEY_
 const MOZILLA_PKIX_ERROR_V1_CERT_USED_AS_CA             = MOZILLA_PKIX_ERROR_BASE + 3;
 const MOZILLA_PKIX_ERROR_NOT_YET_VALID_CERTIFICATE      = MOZILLA_PKIX_ERROR_BASE + 5;
 const MOZILLA_PKIX_ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE = MOZILLA_PKIX_ERROR_BASE + 6;
 const MOZILLA_PKIX_ERROR_OCSP_RESPONSE_FOR_CERT_MISSING = MOZILLA_PKIX_ERROR_BASE + 8;
 const MOZILLA_PKIX_ERROR_REQUIRED_TLS_FEATURE_MISSING   = MOZILLA_PKIX_ERROR_BASE + 10;
 const MOZILLA_PKIX_ERROR_EMPTY_ISSUER_NAME              = MOZILLA_PKIX_ERROR_BASE + 12;
 const MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED = MOZILLA_PKIX_ERROR_BASE + 13;
 const MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT               = MOZILLA_PKIX_ERROR_BASE + 14;
+const MOZILLA_PKIX_ERROR_MITM_DETECTED                  = MOZILLA_PKIX_ERROR_BASE + 15;
 
 // Supported Certificate Usages
 const certificateUsageSSLClient              = 0x0001;
 const certificateUsageSSLServer              = 0x0002;
 const certificateUsageSSLCA                  = 0x0008;
 const certificateUsageEmailSigner            = 0x0010;
 const certificateUsageEmailRecipient         = 0x0020;
 
--- a/security/manager/ssl/tests/unit/test_cert_overrides.js
+++ b/security/manager/ssl/tests/unit/test_cert_overrides.js
@@ -13,17 +13,17 @@
 
 do_get_profile();
 
 function check_telemetry() {
   let histogram = Services.telemetry
                     .getHistogramById("SSL_CERT_ERROR_OVERRIDES")
                     .snapshot();
   equal(histogram.counts[0], 0, "Should have 0 unclassified counts");
-  equal(histogram.counts[2], 6,
+  equal(histogram.counts[2], 9,
         "Actual and expected SEC_ERROR_UNKNOWN_ISSUER counts should match");
   equal(histogram.counts[3], 1,
         "Actual and expected SEC_ERROR_CA_CERT_INVALID counts should match");
   equal(histogram.counts[4], 0,
         "Actual and expected SEC_ERROR_UNTRUSTED_ISSUER counts should match");
   equal(histogram.counts[5], 1,
         "Actual and expected SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE counts should match");
   equal(histogram.counts[6], 0,
@@ -47,27 +47,29 @@ function check_telemetry() {
   equal(histogram.counts[15], 1,
         "Actual and expected MOZILLA_PKIX_ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE counts should match");
   equal(histogram.counts[16], 2,
         "Actual and expected SEC_ERROR_INVALID_TIME counts should match");
   equal(histogram.counts[17], 1,
         "Actual and expected MOZILLA_PKIX_ERROR_EMPTY_ISSUER_NAME counts should match");
   equal(histogram.counts[19], 3,
         "Actual and expected MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT counts should match");
+  equal(histogram.counts[20], 1,
+        "Actual and expected MOZILLA_PKIX_ERROR_MITM_DETECTED counts should match");
 
   let keySizeHistogram = Services.telemetry
                            .getHistogramById("CERT_CHAIN_KEY_SIZE_STATUS")
                            .snapshot();
   equal(keySizeHistogram.counts[0], 0,
         "Actual and expected unchecked key size counts should match");
   equal(keySizeHistogram.counts[1], 16,
         "Actual and expected successful verifications of 2048-bit keys should match");
   equal(keySizeHistogram.counts[2], 0,
         "Actual and expected successful verifications of 1024-bit keys should match");
-  equal(keySizeHistogram.counts[3], 60,
+  equal(keySizeHistogram.counts[3], 68,
         "Actual and expected verification failures unrelated to key size should match");
 
   run_next_test();
 }
 
 // Internally, specifying "port" -1 is the same as port 443. This tests that.
 function run_port_equivalency_test(inPort, outPort) {
   Assert.ok((inPort == 443 && outPort == -1) || (inPort == -1 && outPort == 443),
@@ -171,16 +173,63 @@ function add_simple_tests() {
   add_cert_override_test("selfsigned-inadequateEKU.example.com",
                          Ci.nsICertOverrideService.ERROR_UNTRUSTED,
                          MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT);
 
   add_prevented_cert_override_test("inadequatekeyusage.example.com",
                                    Ci.nsICertOverrideService.ERROR_UNTRUSTED,
                                    SEC_ERROR_INADEQUATE_KEY_USAGE);
 
+  // Test triggering the MitM detection. We don't set-up a proxy here. Just
+  // set the pref. Without the pref set we expect an unkown issuer error.
+  add_cert_override_test("mitm.example.com",
+                         Ci.nsICertOverrideService.ERROR_UNTRUSTED,
+                         SEC_ERROR_UNKNOWN_ISSUER);
+  add_test(function() {
+    Services.prefs.setStringPref("security.pki.mitm_canary_issuer",
+                                 "CN=Test MITM Root");
+    let certOverrideService = Cc["@mozilla.org/security/certoverride;1"]
+                                .getService(Ci.nsICertOverrideService);
+    certOverrideService.clearValidityOverride("mitm.example.com", 8443);
+    run_next_test();
+  });
+  add_cert_override_test("mitm.example.com",
+                         Ci.nsICertOverrideService.ERROR_UNTRUSTED,
+                         MOZILLA_PKIX_ERROR_MITM_DETECTED);
+  add_test(function() {
+    Services.prefs.setStringPref("security.pki.mitm_canary_issuer",
+                                 "CN=Other MITM Root");
+    let certOverrideService = Cc["@mozilla.org/security/certoverride;1"]
+                                .getService(Ci.nsICertOverrideService);
+    certOverrideService.clearValidityOverride("mitm.example.com", 8443);
+    run_next_test();
+  });
+  // If the canary issuer doesn't match the one we see, we exepct and unknown
+  // issuer error.
+  add_cert_override_test("mitm.example.com",
+                         Ci.nsICertOverrideService.ERROR_UNTRUSTED,
+                         SEC_ERROR_UNKNOWN_ISSUER);
+  // If security.pki.mitm_canary_issuer.enabled is false, there should always
+  // be an unknown issuer error.
+  add_test(function() {
+    Services.prefs.setBoolPref("security.pki.mitm_canary_issuer.enabled",
+                               false);
+    let certOverrideService = Cc["@mozilla.org/security/certoverride;1"]
+                                .getService(Ci.nsICertOverrideService);
+    certOverrideService.clearValidityOverride("mitm.example.com", 8443);
+    run_next_test();
+  });
+  add_cert_override_test("mitm.example.com",
+                         Ci.nsICertOverrideService.ERROR_UNTRUSTED,
+                         SEC_ERROR_UNKNOWN_ISSUER);
+  add_test(function() {
+    Services.prefs.clearUserPref("security.pki.mitm_canary_issuer");
+    run_next_test();
+  });
+
   // This is intended to test the case where a verification has failed for one
   // overridable reason (e.g. unknown issuer) but then, in the process of
   // reporting that error, a non-overridable error is encountered. The
   // non-overridable error should be prioritized.
   add_test(function() {
     let rootCert = constructCertFromFile("bad_certs/test-ca.pem");
     setCertTrust(rootCert, ",,");
     run_next_test();
--- a/security/manager/ssl/tests/unit/tlsserver/cmd/BadCertServer.cpp
+++ b/security/manager/ssl/tests/unit/tlsserver/cmd/BadCertServer.cpp
@@ -29,16 +29,17 @@ const BadCertHost sBadCertHosts[] =
 {
   { "expired.example.com", "expired-ee" },
   { "notyetvalid.example.com", "notYetValid" },
   { "before-epoch.example.com", "beforeEpoch" },
   { "selfsigned.example.com", "selfsigned" },
   { "unknownissuer.example.com", "unknownissuer" },
   { "mismatch.example.com", "mismatch" },
   { "mismatch-CN.example.com", "mismatchCN" },
+  { "mitm.example.com", "mitm" },
   { "expiredissuer.example.com", "expiredissuer" },
   { "notyetvalidissuer.example.com", "notYetValidIssuer" },
   { "before-epoch-issuer.example.com", "beforeEpochIssuer" },
   { "md5signature.example.com", "md5signature" },
   { "untrusted.example.com", "default-ee" },
   { "untrustedissuer.example.com", "untrustedissuer" },
   { "mismatch-expired.example.com", "mismatch-expired" },
   { "mismatch-notYetValid.example.com", "mismatch-notYetValid" },
--- a/security/pkix/include/pkix/Result.h
+++ b/security/pkix/include/pkix/Result.h
@@ -190,16 +190,18 @@ static const unsigned int FATAL_ERROR_FL
     MOZILLA_PKIX_MAP(ERROR_INVALID_INTEGER_ENCODING, 52, \
                      MOZILLA_PKIX_ERROR_INVALID_INTEGER_ENCODING) \
     MOZILLA_PKIX_MAP(ERROR_EMPTY_ISSUER_NAME, 53, \
                      MOZILLA_PKIX_ERROR_EMPTY_ISSUER_NAME) \
     MOZILLA_PKIX_MAP(ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED, 54, \
                      MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED) \
     MOZILLA_PKIX_MAP(ERROR_SELF_SIGNED_CERT, 55, \
                      MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT) \
+    MOZILLA_PKIX_MAP(ERROR_MITM_DETECTED, 56, \
+                     MOZILLA_PKIX_ERROR_MITM_DETECTED) \
     MOZILLA_PKIX_MAP(FATAL_ERROR_INVALID_ARGS, FATAL_ERROR_FLAG | 1, \
                      SEC_ERROR_INVALID_ARGS) \
     MOZILLA_PKIX_MAP(FATAL_ERROR_INVALID_STATE, FATAL_ERROR_FLAG | 2, \
                      PR_INVALID_STATE_ERROR) \
     MOZILLA_PKIX_MAP(FATAL_ERROR_LIBRARY_FAILURE, FATAL_ERROR_FLAG | 3, \
                      SEC_ERROR_LIBRARY_FAILURE) \
     MOZILLA_PKIX_MAP(FATAL_ERROR_NO_MEMORY, FATAL_ERROR_FLAG | 4, \
                      SEC_ERROR_NO_MEMORY) \
--- a/security/pkix/include/pkix/pkixnss.h
+++ b/security/pkix/include/pkix/pkixnss.h
@@ -84,16 +84,17 @@ enum ErrorCode
   MOZILLA_PKIX_ERROR_SIGNATURE_ALGORITHM_MISMATCH = ERROR_BASE + 7,
   MOZILLA_PKIX_ERROR_OCSP_RESPONSE_FOR_CERT_MISSING = ERROR_BASE + 8,
   MOZILLA_PKIX_ERROR_VALIDITY_TOO_LONG = ERROR_BASE + 9,
   MOZILLA_PKIX_ERROR_REQUIRED_TLS_FEATURE_MISSING = ERROR_BASE + 10,
   MOZILLA_PKIX_ERROR_INVALID_INTEGER_ENCODING = ERROR_BASE + 11,
   MOZILLA_PKIX_ERROR_EMPTY_ISSUER_NAME = ERROR_BASE + 12,
   MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED = ERROR_BASE + 13,
   MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT = ERROR_BASE + 14,
+  MOZILLA_PKIX_ERROR_MITM_DETECTED = ERROR_BASE + 15,
   END_OF_LIST
 };
 
 void RegisterErrorTable();
 
 inline SECItem UnsafeMapInputToSECItem(Input input)
 {
   SECItem result = {
--- a/security/pkix/lib/pkixnss.cpp
+++ b/security/pkix/lib/pkixnss.cpp
@@ -211,16 +211,19 @@ RegisterErrorTable()
     { "MOZILLA_PKIX_ERROR_EMPTY_ISSUER_NAME",
       "The server presented a certificate with an empty issuer distinguished "
       "name." },
     { "MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED",
       "An additional policy constraint failed when validating this "
       "certificate." },
     { "MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT",
       "The certificate is not trusted because it is self-signed." },
+    { "MOZILLA_PKIX_ERROR_MITM_DETECTED",
+      "Your connection is being intercepted by a TLS proxy. Uninstall it if "
+      "possible or configure Firefox to trust its root certificate." },
   };
   // Note that these error strings are not localizable.
   // When these strings change, update the localization information too.
 
   static const PRErrorTable ErrorTable = {
     ErrorTableText,
     "pkixerrors",
     ERROR_BASE,
--- a/testing/web-platform/tests/content-security-policy/reporting/multiple-report-policies.html
+++ b/testing/web-platform/tests/content-security-policy/reporting/multiple-report-policies.html
@@ -6,14 +6,14 @@
     <title>When multiple report-uri endpoints for multiple policies are specified, each gets a report</title>
     <!-- CSP headers
 Content-Security-Policy-Report-Only: img-src http://* https://*; default-src 'self'; script-src 'self' 'unsafe-inline'; report-uri ../support/report.py?op=put&reportID={{$id}}
 
 Content-Security-Policy-Report-Only: img-src http://*; default-src 'self'; script-src 'self' 'unsafe-inline'; report-uri ../support/report.py?op=put&reportID={{$id}}
 -->
 </head>
 <body>
-    <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAEElEQVR42mNgaGD4D8YwBgAw9AX9Y9zBwwAAAABJRU5ErkJggg==" />
+    <img src="ftp://blah.test" />
 
     <script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=img-src%20http%3A%2F%2F%2A%20https%3A%2F%2F%2A&testName=1-Violation%20report%20status%20OK'></script>
     <script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=img-src%20http%3A%2F%2F%2A&reportCookieName=multiple-report-policies-2&testName=2-Violation%20report%20status%20OK'></script>
 </body>
 </html>
--- a/testing/web-platform/tests/content-security-policy/reporting/report-uri-multiple-reversed.html
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-uri-multiple-reversed.html
@@ -5,12 +5,12 @@
     <script src="/resources/testharnessreport.js"></script>
     <title>Content-Security-Policy-Report-Only violation report is sent even when resource is blocked by actual policy.</title>
     <!-- CSP headers
          Content-Security-Policy-Report-Only: img-src http://*; report-uri ../support/report.py?op=put&reportID={{$id}}
          Content-Security-Policy: img-src http://*
          -->
 </head>
 <body>
-    <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAEElEQVR42mNgaGD4D8YwBgAw9AX9Y9zBwwAAAABJRU5ErkJggg==" />
+    <img src="ftp://blah.test" />
     <script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=img-src%20http%3A%2F%2F%2A'></script>
 </body>
 </html>
--- a/testing/web-platform/tests/content-security-policy/reporting/report-uri-multiple.html
+++ b/testing/web-platform/tests/content-security-policy/reporting/report-uri-multiple.html
@@ -5,12 +5,12 @@
     <script src="/resources/testharnessreport.js"></script>
     <title>Content-Security-Policy-Report-Only violation report is sent even when resource is blocked by actual policy.</title>
     <!-- CSP headers
          Content-Security-Policy: img-src http://*
          Content-Security-Policy-Report-Only: img-src http://*; report-uri ../support/report.py?op=put&reportID={{$id}}
       -->
 </head>
 <body>
-    <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAEElEQVR42mNgaGD4D8YwBgAw9AX9Y9zBwwAAAABJRU5ErkJggg==" />
+    <img src="ftp://blah.test" />
     <script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=img-src%20http%3A%2F%2F%2A'></script>
 </body>
 </html>
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -953,24 +953,16 @@
     "alert_emails": ["cpearce@mozilla.com", "gsquelart@mozilla.com"],
     "expires_in_version": "60",
     "bug_numbers": [1338011],
     "kind": "enumerated",
     "releaseChannelCollection": "opt-out",
     "n_values":  10,
     "description": "Count how often we use different fallbacks when the GPU process crashes: None=0, GPUProcessDecodingDisabled=1, GPUProcessDisabled=2"
   },
-  "JS_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT": {
-    "record_in_processes": ["main", "content"],
-    "alert_emails": ["jdemooij@mozilla.com"],
-    "expires_in_version": "never",
-    "kind": "enumerated",
-    "n_values": 10,
-    "description": "Use of SpiderMonkey's deprecated language extensions in web content: ForEach=0 (obsolete), DestructuringForIn=1 (obsolete), LegacyGenerator=2 (obsolete), ExpressionClosure=3, LetBlock=4 (obsolete), LetExpression=5 (obsolete), NoSuchMethod=6 (obsolete), FlagsArgument=7 (obsolete), RegExpSourceProp=8 (obsolete), RestoredRegExpStatics=9 (obsolete), BlockScopeFunRedecl=10 (obsolete)"
-  },
   "JS_PRIVILEGED_PARSER_COMPILE_LAZY_AFTER_MS": {
     "record_in_processes": ["main", "content"],
     "alert_emails": ["dteller@mozilla.com"],
     "expires_in_version": "70",
     "bug_numbers": [1343483],
     "kind": "exponential",
     "low": 10,
     "high": 10000,
--- a/toolkit/components/telemetry/histogram-whitelists.json
+++ b/toolkit/components/telemetry/histogram-whitelists.json
@@ -869,17 +869,16 @@
     "IMAGE_DECODE_SPEED_GIF",
     "IMAGE_DECODE_SPEED_JPEG",
     "IMAGE_DECODE_SPEED_PNG",
     "IMAGE_DECODE_TIME",
     "INNERWINDOWS_WITH_MUTATION_LISTENERS",
     "IPC_SAME_PROCESS_MESSAGE_COPY_OOM_KB",
     "IPC_TRANSACTION_CANCEL",
     "IPV4_AND_IPV6_ADDRESS_CONNECTIVITY",
-    "JS_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT",
     "LOCALDOMSTORAGE_CLEAR_BLOCKING_MS",
     "LOCALDOMSTORAGE_GETALLKEYS_BLOCKING_MS",
     "LOCALDOMSTORAGE_GETKEY_BLOCKING_MS",
     "LOCALDOMSTORAGE_GETLENGTH_BLOCKING_MS",
     "LOCALDOMSTORAGE_GETVALUE_BLOCKING_MS",
     "LOCALDOMSTORAGE_PRELOAD_PENDING_ON_FIRST_ACCESS",
     "LOCALDOMSTORAGE_REMOVEKEY_BLOCKING_MS",
     "LOCALDOMSTORAGE_SESSIONONLY_PRELOAD_BLOCKING_MS",
--- a/toolkit/mozapps/update/nsUpdateService.js
+++ b/toolkit/mozapps/update/nsUpdateService.js
@@ -3076,16 +3076,17 @@ Checker.prototype = {
 
   /**
    * The XMLHttpRequest succeeded and the document was loaded.
    * @param   event
    *          The nsIDOMEvent for the load
    */
   onLoad: function UC_onLoad(event) {
     LOG("Checker:onLoad - request completed downloading document");
+    Services.prefs.clearUserPref("security.pki.mitm_canary_issuer");
 
     try {
       // Analyze the resulting DOM and determine the set of updates.
       var updates = this._updates;
       LOG("Checker:onLoad - number of updates available: " + updates.length);
 
       if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_BACKGROUNDERRORS)) {
         Services.prefs.clearUserPref(PREF_APP_UPDATE_BACKGROUNDERRORS);
@@ -3119,16 +3120,29 @@ Checker.prototype = {
    * @param   event
    *          The nsIDOMEvent for the error
    */
   onError: function UC_onError(event) {
     var request = event.target;
     var status = this._getChannelStatus(request);
     LOG("Checker:onError - request.status: " + status);
 
+    // Set MitM pref.
+    try {
+      var sslStatus = request.channel.QueryInterface(Ci.nsIRequest)
+                        .securityInfo.QueryInterface(Ci.nsISSLStatusProvider)
+                        .SSLStatus.QueryInterface(Ci.nsISSLStatus);
+      if (sslStatus && sslStatus.serverCert && sslStatus.serverCert.issuerName) {
+        Services.prefs.setStringPref("security.pki.mitm_canary_issuer",
+                                     sslStatus.serverCert.issuerName);
+      }
+    } catch (e) {
+      LOG("Checker:onError - Getting sslStatus failed.");
+    }
+
     // If we can't find an error string specific to this status code,
     // just use the 200 message from above, which means everything
     // "looks" fine but there was probably an XML error or a bogus file.
     var update = new Update(null);
     update.errorCode = status;
     update.statusText = getStatusTextFromCode(status, 200);
 
     if (status == Cr.NS_ERROR_OFFLINE) {
--- a/toolkit/themes/linux/global/jar.mn
+++ b/toolkit/themes/linux/global/jar.mn
@@ -40,11 +40,10 @@ toolkit.jar:
    skin/classic/global/icons/Close.gif                         (icons/Close.gif)
    skin/classic/global/icons/Minimize.gif                      (icons/Minimize.gif)
    skin/classic/global/icons/resizer.png                       (icons/resizer.png)
    skin/classic/global/icons/Restore.gif                       (icons/Restore.gif)
    skin/classic/global/icons/sslWarning.png                    (icons/sslWarning.png)
 
 *  skin/classic/global/in-content/common.css                   (in-content/common.css)
 *  skin/classic/global/in-content/info-pages.css               (in-content/info-pages.css)
-   skin/classic/global/toolbar/spring.png                      (toolbar/spring.png)
    skin/classic/global/tree/twisty-clsd.png                    (tree/twisty-clsd.png)
    skin/classic/global/tree/twisty-open.png                    (tree/twisty-open.png)
--- a/toolkit/themes/linux/global/toolbar.css
+++ b/toolkit/themes/linux/global/toolbar.css
@@ -49,50 +49,16 @@ toolbarspacer {
 }
 
 /* ::::: toolbarpaletteitem ::::: */
 
 toolbarpaletteitem {
   cursor: grab;
 }
 
-.toolbarpaletteitem-box[type="spacer"],
-.toolbarpaletteitem-box[type="spring"] {
-  border: 1px solid #808080;
-  background-color: #FFF !important;
-}
-
-toolbarpaletteitem[place="toolbar"] > toolbarspacer {
-  width: 11px;
-}
-
-.toolbarpaletteitem-box[type="spacer"][place="toolbar"],
-.toolbarpaletteitem-box[type="spring"][place="toolbar"] {
-  margin-top: 2px;
-  margin-bottom: 2px;
-  margin-inline-start: 0px;
-  margin-inline-end: 2px;
-}
-
-.toolbarpaletteitem-box[type="separator"][place="palette"] {
-  width: 2px;
-  height: 50px;
-}
-
-.toolbarpaletteitem-box[type="spacer"][place="palette"],
-.toolbarpaletteitem-box[type="spring"][place="palette"] {
-  margin-bottom: 2px;
-  width: 50px;
-  height: 50px;
-}
-
-.toolbarpaletteitem-box[type="spring"][place="palette"] {
-  background: url("chrome://global/skin/toolbar/spring.png") no-repeat center;
-}
-
 /* ..... drag and drop feedback ..... */
 
 toolbarpaletteitem[place="toolbar"] {
   margin-left: -2px;
   margin-right: -2px;
   border-left: 2px solid transparent;
   border-right: 2px solid transparent;
 }
deleted file mode 100644
index 4130ff62ff11bc4142deecba12a8453a2dd59c3d..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index c4928b0734a97c049c0ff928540de87f843451c2..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index dce39aecc1887e897d4b23e7272bf7f977b6064a..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 8f75b2c5d0f6eda7bdb5e2f556f4825bf2676443..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
--- a/toolkit/themes/osx/global/jar.mn
+++ b/toolkit/themes/osx/global/jar.mn
@@ -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 ../../shared/jar.inc.mn
 
 toolkit.jar:
-  skin/classic/global/10pct_transparent_grey.png
   skin/classic/global/autocomplete.css
   skin/classic/global/button.css
   skin/classic/global/checkbox.css
   skin/classic/global/colorpicker.css
   skin/classic/global/commonDialog.css
   skin/classic/global/dialog.css
   skin/classic/global/dropmarker.css
   skin/classic/global/filefield.css
@@ -43,17 +42,16 @@ toolkit.jar:
   skin/classic/global/arrow/arrow-dn-dis.png                         (arrow/arrow-dn-dis.png)
   skin/classic/global/arrow/arrow-dn-sharp.gif                       (arrow/arrow-dn-sharp.gif)
   skin/classic/global/arrow/arrow-dn.gif                             (arrow/arrow-dn.gif)
   skin/classic/global/arrow/arrow-dn.png                             (arrow/arrow-dn.png)
   skin/classic/global/arrow/arrow-lft-dis.gif                        (arrow/arrow-lft-dis.gif)
   skin/classic/global/arrow/arrow-lft-sharp.gif                      (arrow/arrow-lft-sharp.gif)
   skin/classic/global/arrow/arrow-rit-dis.gif                        (arrow/arrow-rit-dis.gif)
   skin/classic/global/arrow/arrow-rit-sharp.gif                      (arrow/arrow-rit-sharp.gif)
-  skin/classic/global/arrow/arrow-rit.gif                            (arrow/arrow-rit.gif)
   skin/classic/global/arrow/arrow-up-dis.gif                         (arrow/arrow-up-dis.gif)
   skin/classic/global/arrow/arrow-up-sharp.gif                       (arrow/arrow-up-sharp.gif)
   skin/classic/global/arrow/arrow-up.gif                             (arrow/arrow-up.gif)
   skin/classic/global/arrow/panelarrow-horizontal.svg                (arrow/panelarrow-horizontal.svg)
   skin/classic/global/arrow/panelarrow-vertical.svg                  (arrow/panelarrow-vertical.svg)
   skin/classic/global/checkbox/cbox-check.gif                        (checkbox/cbox-check.gif)
   skin/classic/global/checkbox/cbox-check-dis.gif                    (checkbox/cbox-check-dis.gif)
   skin/classic/global/dirListing/dirListing.css                      (dirListing/dirListing.css)
@@ -65,30 +63,27 @@ toolkit.jar:
   skin/classic/global/icons/glyph-dropdown@2x.png                    (icons/glyph-dropdown@2x.png)
   skin/classic/global/icons/panel-dropmarker.png                     (icons/panel-dropmarker.png)
   skin/classic/global/icons/resizer.png                              (icons/resizer.png)
   skin/classic/global/icons/resizer@2x.png                           (icons/resizer@2x.png)
   skin/classic/global/icons/resizer-rtl.png                          (icons/resizer-rtl.png)
   skin/classic/global/icons/resizer-rtl@2x.png                       (icons/resizer-rtl@2x.png)
   skin/classic/global/icons/search-textbox.svg                       (icons/search-textbox.svg)
   skin/classic/global/icons/searchfield-cancel.svg                   (icons/searchfield-cancel.svg)
-  skin/classic/global/icons/tabprompts-bgtexture.png                 (icons/tabprompts-bgtexture.png)
   skin/classic/global/icons/warning-16.png                           (icons/warning-16.png)
   skin/classic/global/icons/warning-64.png                           (icons/warning-64.png)
   skin/classic/global/icons/warning-large.png                        (icons/warning-large.png)
   skin/classic/global/icons/error-16.png                             (icons/error-16.png)
   skin/classic/global/icons/error-64.png                             (icons/error-64.png)
   skin/classic/global/icons/question-16.png                          (icons/question-16.png)
   skin/classic/global/icons/question-32.png                          (icons/question-32.png)
   skin/classic/global/icons/question-64.png                          (icons/question-64.png)
   skin/classic/global/icons/sslWarning.png                           (icons/sslWarning.png)
 * skin/classic/global/in-content/common.css                          (in-content/common.css)
 * skin/classic/global/in-content/info-pages.css                      (in-content/info-pages.css)
-  skin/classic/global/toolbar/spring.png                             (toolbar/spring.png)
-  skin/classic/global/toolbar/toolbar-separator.png                  (toolbar/toolbar-separator.png)
   skin/classic/global/tree/arrow-disclosure.svg                      (tree/arrow-disclosure.svg)
   skin/classic/global/tree/columnpicker.gif                          (tree/columnpicker.gif)
   skin/classic/global/tree/folder.png                                (tree/folder.png)
   skin/classic/global/tree/folder@2x.png                             (tree/folder@2x.png)
 
 #if MOZ_BUILD_APP == browser
 [browser/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}] chrome.jar:
 #elif MOZ_SEPARATE_MANIFEST_FOR_THEME_OVERRIDES
--- a/toolkit/themes/osx/global/tabprompts.css
+++ b/toolkit/themes/osx/global/tabprompts.css
@@ -1,15 +1,14 @@
 /* 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/. */
 
 /* Tab Modal Prompt boxes */
 tabmodalprompt {
-  background-image: url(chrome://global/skin/icons/tabprompts-bgtexture.png);
   background-color: hsla(0,0%,10%,.5);
   font-family: sans-serif; /* use content font not system UI font */
   font-size: 110%;
 }
 
 .mainContainer {
   color: black;
   background-color: hsla(0,0%,100%,.95);
--- a/toolkit/themes/osx/global/toolbar.css
+++ b/toolkit/themes/osx/global/toolbar.css
@@ -20,73 +20,31 @@ toolbar:-moz-lwtheme {
 menubar {
   -moz-appearance: dialog; /* For content menubars, "toolbar" is too dark, so we use "dialog". */
   min-width: 1px;
 }
 
 toolbarseparator {
   -moz-appearance: none;
   margin: 3px 4px;
-  background: url("chrome://global/skin/toolbar/toolbar-separator.png") transparent repeat-y;
+  background-color: ThreeDShadow;
   padding: 0;
   width: 1px !important;
 }
 
 /* ::::: toolbarpaletteitem ::::: */
 
 toolbarpaletteitem {
   cursor: grab;
 }
 
-toolbarpaletteitem[type="spacer"],
 toolbarspacer {
   min-width: 24px !important;
 }
 
-.toolbarpaletteitem-box[type="spacer"] {
-  border: 1px solid #A3A3A3;
-  background: url("chrome://global/skin/10pct_transparent_grey.png") repeat;
-  width: 32px;
-  margin-top: 18px;
-}
-
-.toolbarpaletteitem-box[type="spring"] {
-  border: 1px solid #A3A3A3;
-  background: url("chrome://global/skin/toolbar/spring.png") #FFFFFF no-repeat;
-  width: 32px;
-  margin-top: 18px;
-}
-
-.toolbarpaletteitem-box[type="spring"][place="toolbar"] {
-  background: url("chrome://global/skin/10pct_transparent_grey.png") repeat;
-}
-
-.toolbarpaletteitem-box[type="spacer"][place="toolbar"],
-.toolbarpaletteitem-box[type="spring"][place="toolbar"] {
-  margin: 2px;
-}
-
-.toolbarpaletteitem-box[type="separator"][place="palette"] {
-  width: 2px;
-  height: 50px;
-}
-
-.toolbarpaletteitem-box[type="spacer"][place="palette"],
-.toolbarpaletteitem-box[type="spring"][place="palette"] {
-  margin-top: 0;
-  margin-bottom: 2px;
-  height: 32px;
-}
-
-.toolbarpaletteitem-box[type="spring"][place="palette"] {
-  background-position: center;
-  margin-left: 8px;
-  margin-right: 8px;
-}
-
 /* ..... drag and drop feedback ..... */
 
 toolbarpaletteitem[place="toolbar"] {
   margin-left: -2px;
   margin-right: -2px;
   border-left: 2px solid transparent;
   border-right: 2px solid transparent;
 }
deleted file mode 100644
index 675fa539e1d5f00178a8714b38f58e6b43b489c2..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 3c549ecdb1dfd99d4b5056d3f188193459c131be..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
--- a/toolkit/themes/shared/non-mac.jar.inc.mn
+++ b/toolkit/themes/shared/non-mac.jar.inc.mn
@@ -25,17 +25,16 @@
   skin/classic/global/arrow/panelarrow-vertical.svg        (../../windows/global/arrow/panelarrow-vertical.svg)
 
 * skin/classic/global/dirListing/dirListing.css            (../../windows/global/dirListing/dirListing.css)
   skin/classic/global/icons/error-16.png                   (../../windows/global/icons/error-16.png)
   skin/classic/global/icons/question-16.png                (../../windows/global/icons/question-16.png)
   skin/classic/global/icons/question-64.png                (../../windows/global/icons/question-64.png)
   skin/classic/global/icons/resizer-rtl.png                (../../windows/global/icons/resizer-rtl.png)
   skin/classic/global/icons/search-textbox.svg             (../../windows/global/icons/search-textbox.svg)
-  skin/classic/global/icons/tabprompts-bgtexture.png       (../../windows/global/icons/tabprompts-bgtexture.png)
   skin/classic/global/icons/warning-16.png                 (../../windows/global/icons/warning-16.png)
   skin/classic/global/icons/warning-64.png                 (../../windows/global/icons/warning-64.png)
   skin/classic/global/tree/columnpicker.gif                (../../windows/global/tree/columnpicker.gif)
   skin/classic/global/tree/sort-asc.png                    (../../windows/global/tree/sort-asc.png)
   skin/classic/global/tree/sort-dsc.png                    (../../windows/global/tree/sort-dsc.png)
   skin/classic/global/tree/sort-asc-classic.png            (../../windows/global/tree/sort-asc-classic.png)
   skin/classic/global/tree/sort-dsc-classic.png            (../../windows/global/tree/sort-dsc-classic.png)
 
deleted file mode 100644
index 2725eb5fbf30af06b71458a44c51b1a34b756bd9..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
--- a/toolkit/themes/windows/global/jar.mn
+++ b/toolkit/themes/windows/global/jar.mn
@@ -53,17 +53,16 @@ toolkit.jar:
   skin/classic/global/icons/Question.png                   (icons/Question.png)
   skin/classic/global/icons/resizer.png                    (icons/resizer.png)
   skin/classic/global/icons/sslWarning.png                 (icons/sslWarning.png)
   skin/classic/global/icons/Warning.png                    (icons/Warning.png)
   skin/classic/global/icons/warning-large.png              (icons/warning-large.png)
   skin/classic/global/icons/windowControls.png             (icons/windowControls.png)
 * skin/classic/global/in-content/common.css                (in-content/common.css)
 * skin/classic/global/in-content/info-pages.css            (in-content/info-pages.css)
-  skin/classic/global/toolbar/spring.png                   (toolbar/spring.png)
   skin/classic/global/tree/twisty.svg                      (tree/twisty.svg)
   skin/classic/global/tree/twisty-preWin10.svg             (tree/twisty-preWin10.svg)
 
 #if MOZ_BUILD_APP == browser
 [browser/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}] chrome.jar:
 #elif MOZ_SEPARATE_MANIFEST_FOR_THEME_OVERRIDES
 [extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}] chrome.jar:
 #endif
--- a/toolkit/themes/windows/global/tabprompts.css
+++ b/toolkit/themes/windows/global/tabprompts.css
@@ -1,15 +1,14 @@
 /* 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/. */
 
 /* Tab Modal Prompt boxes */
 tabmodalprompt {
-  background-image: url(chrome://global/skin/icons/tabprompts-bgtexture.png);
   background-color: hsla(0,0%,10%,.5);
   font-family: sans-serif; /* use content font not system UI font */
 }
 
 .mainContainer {
   color: -moz-fieldText;
   background-color: -moz-field;
   border-radius: 2px;
--- a/toolkit/themes/windows/global/toolbar.css
+++ b/toolkit/themes/windows/global/toolbar.css
@@ -42,50 +42,16 @@ toolbarspacer {
 }
 
 /* ::::: toolbarpaletteitem ::::: */
 
 toolbarpaletteitem {
   cursor: grab;
 }
 
-.toolbarpaletteitem-box[type="spacer"],
-.toolbarpaletteitem-box[type="spring"] {
-  border: 1px solid #808080;
-  background-color: #FFF !important;
-}
-
-toolbarpaletteitem[place="toolbar"] > toolbarspacer {
-  width: 11px;
-}
-
-.toolbarpaletteitem-box[type="spacer"][place="toolbar"],
-.toolbarpaletteitem-box[type="spring"][place="toolbar"] {
-  margin-top: 2px;
-  margin-bottom: 2px;
-  margin-inline-start: 0px;
-  margin-inline-end: 2px;
-}
-
-.toolbarpaletteitem-box[type="separator"][place="palette"] {
-  width: 2px;
-  height: 50px;
-}
-
-.toolbarpaletteitem-box[type="spacer"][place="palette"],
-.toolbarpaletteitem-box[type="spring"][place="palette"] {
-  margin-bottom: 2px;
-  width: 50px;
-  height: 50px;
-}
-
-.toolbarpaletteitem-box[type="spring"][place="palette"] {
-  background: url("chrome://global/skin/toolbar/spring.png") no-repeat center;
-}
-
 /* ..... drag and drop feedback ..... */
 
 toolbarpaletteitem[place="toolbar"] {
   margin-left: -2px;
   margin-right: -2px;
   border-left: 2px solid transparent;
   border-right: 2px solid transparent;
 }
deleted file mode 100644
index 60d88e6d3942430d3d289699caa8f4e35799f0ac..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
--- a/widget/windows/GfxInfo.cpp
+++ b/widget/windows/GfxInfo.cpp
@@ -1383,20 +1383,20 @@ GfxInfo::GetGfxDriverInfo()
     // bug 1359416
     APPEND_TO_DRIVER_BLOCKLIST2(OperatingSystem::Windows,
       (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorIntel),
       (GfxDeviceFamily*) GfxDriverInfo::GetDeviceFamily(IntelHDGraphicsToSandyBridge),
       nsIGfxInfo::FEATURE_D3D11_KEYED_MUTEX, nsIGfxInfo::FEATURE_BLOCKED_DEVICE,
       DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions, "FEATURE_FAILURE_BUG_1359416");
 
     // bug 1419264
-    APPEND_TO_DRIVER_BLOCKLIST(OperatingSystem::Windows7,
+    APPEND_TO_DRIVER_BLOCKLIST_RANGE(OperatingSystem::Windows7,
       (nsAString&) GfxDriverInfo::GetDeviceVendor(VendorNVIDIA), GfxDriverInfo::allDevices,
       nsIGfxInfo::FEATURE_ADVANCED_LAYERS, nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION,
-      DRIVER_GREATER_THAN_OR_EQUAL, V(23,21,13,8813),
+      DRIVER_BETWEEN_INCLUSIVE, V(23,21,13,8569), V(23,21,13,9135),
       "FEATURE_FAILURE_BUG_1419264", "Windows 10");
   }
   return *mDriverInfo;
 }
 
 nsresult
 GfxInfo::GetFeatureStatusImpl(int32_t aFeature,
                               int32_t *aStatus,
--- a/xpcom/ds/nsGkAtomList.h
+++ b/xpcom/ds/nsGkAtomList.h
@@ -459,17 +459,16 @@ GK_ATOM(field, "field")
 GK_ATOM(fieldset, "fieldset")
 GK_ATOM(file, "file")
 GK_ATOM(figcaption, "figcaption")
 GK_ATOM(figure, "figure")
 GK_ATOM(findbar, "findbar")
 GK_ATOM(fixed, "fixed")
 GK_ATOM(flags, "flags")
 GK_ATOM(flex, "flex")
-GK_ATOM(flexgroup, "flexgroup")
 GK_ATOM(flip, "flip")
 GK_ATOM(floating, "floating")
 GK_ATOM(floor, "floor")
 GK_ATOM(flowlength, "flowlength")
 GK_ATOM(focus, "focus")
 GK_ATOM(focused, "focused")
 GK_ATOM(followanchor, "followanchor")
 GK_ATOM(following, "following")