Merge inbound to central, a=merge
authorWes Kocher <wkocher@mozilla.com>
Fri, 23 Dec 2016 14:34:55 -0800
changeset 327119 da22155a2dc30dafc93d70f38f6bb8a49248c80f
parent 327093 dd35d18c8e14751cca293db90ea2205e0a0871c7 (current diff)
parent 327118 66465b966647794ea87387babf30b2607519a569 (diff)
child 327120 de73afd1b433c8fc5d8d0653d6787fd6a6f29c8e
child 327137 a36898045139f6f6e9e6271565c4bca4516b43cd
child 327271 14d6cee6ce9d13e40a22e33c7940e25c79020e7d
push id31119
push userkwierso@gmail.com
push dateFri, 23 Dec 2016 22:34:59 +0000
treeherdermozilla-central@da22155a2dc3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone53.0a1
first release with
nightly linux32
da22155a2dc3 / 53.0a1 / 20161224030205 / files
nightly linux64
da22155a2dc3 / 53.0a1 / 20161224030205 / files
nightly mac
da22155a2dc3 / 53.0a1 / 20161224030205 / files
nightly win32
da22155a2dc3 / 53.0a1 / 20161224030205 / files
nightly win64
da22155a2dc3 / 53.0a1 / 20161224030205 / 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 central, a=merge MozReview-Commit-ID: 56QI5RIvpXC
intl/locale/mac/nsDateTimeFormatMac.cpp
intl/locale/mac/nsDateTimeFormatMac.h
intl/locale/nsDateTimeFormatCID.h
intl/locale/nsIDateTimeFormat.cpp
intl/locale/nsIDateTimeFormat.h
intl/locale/unix/nsDateTimeFormatUnix.cpp
intl/locale/unix/nsDateTimeFormatUnix.h
intl/locale/windows/nsDateTimeFormatWin.cpp
intl/locale/windows/nsDateTimeFormatWin.h
--- a/CLOBBER
+++ b/CLOBBER
@@ -17,9 +17,9 @@
 #
 # Modifying this file will now automatically clobber the buildbot machines \o/
 #
 
 # Are you updating CLOBBER because you think it's needed for your WebIDL
 # changes to stick? As of bug 928195, this shouldn't be necessary! Please
 # don't change CLOBBER for WebIDL changes any more.
 
-Bug 1309866 moving files from jar.mn to modules left duplicated files on at least Mac static analysis builds
+Bug 1142403 needs a clobber to force jemalloc to rerun configure.
--- a/build/autoconf/jemalloc.m4
+++ b/build/autoconf/jemalloc.m4
@@ -5,16 +5,19 @@ dnl file, You can obtain one at http://m
 AC_DEFUN([MOZ_SUBCONFIGURE_JEMALLOC], [
 
 if test "$MOZ_BUILD_APP" != js -o -n "$JS_STANDALONE"; then
 
   # Run jemalloc configure script
 
   if test -z "$MOZ_SYSTEM_JEMALLOC" -a "$MOZ_MEMORY" && test -n "$MOZ_JEMALLOC4" -o -n "$MOZ_REPLACE_MALLOC"; then
     ac_configure_args="--build=$build --host=$target --enable-stats --with-jemalloc-prefix=je_ --disable-valgrind"
+    if test -n "$MOZ_DEBUG"; then
+      ac_configure_args="$ac_configure_args --enable-debug"
+    fi
     # We're using memalign for _aligned_malloc in memory/build/mozmemory_wrap.c
     # on Windows, so just export memalign on all platforms.
     ac_configure_args="$ac_configure_args ac_cv_func_memalign=yes"
     if test -n "$MOZ_REPLACE_MALLOC"; then
       # When using replace_malloc, we always want valloc exported from jemalloc.
       ac_configure_args="$ac_configure_args ac_cv_func_valloc=yes"
       if test "${OS_ARCH}" = Darwin; then
         # We also need to enable pointer validation on Mac because jemalloc's
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -126,18 +126,16 @@
 #include "nsIDOMHTMLFormElement.h"
 #include "nsIRequest.h"
 #include "nsHostObjectProtocolHandler.h"
 
 #include "nsCharsetSource.h"
 #include "nsIParser.h"
 #include "nsIContentSink.h"
 
-#include "nsDateTimeFormatCID.h"
-#include "nsIDateTimeFormat.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/EventStates.h"
 #include "mozilla/InternalMutationEvent.h"
 #include "nsDOMCID.h"
 
 #include "jsapi.h"
 #include "nsIXPConnect.h"
 #include "xpcpublic.h"
--- a/dom/webidl/FontFaceSetLoadEvent.webidl
+++ b/dom/webidl/FontFaceSetLoadEvent.webidl
@@ -12,10 +12,10 @@
 
 dictionary FontFaceSetLoadEventInit : EventInit {
   sequence<FontFace> fontfaces = [];
 };
 
 [Constructor(DOMString type, optional FontFaceSetLoadEventInit eventInitDict),
  Pref="layout.css.font-loading-api.enabled"]
 interface FontFaceSetLoadEvent : Event {
-  [Cached, Constant] readonly attribute sequence<FontFace> fontfaces;
+  [Cached, Constant, Frozen] readonly attribute sequence<FontFace> fontfaces;
 };
--- a/dom/xul/templates/nsXULContentUtils.cpp
+++ b/dom/xul/templates/nsXULContentUtils.cpp
@@ -22,16 +22,17 @@
 /*
 
   A package of routines shared by the XUL content code.
 
  */
 
 #include "mozilla/ArrayUtils.h"
 
+#include "DateTimeFormat.h"
 #include "nsCOMPtr.h"
 #include "nsIContent.h"
 #include "nsIDocument.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMXULCommandDispatcher.h"
 #include "nsIDOMXULDocument.h"
 #include "nsIRDFNode.h"
 #include "nsIRDFService.h"
@@ -43,31 +44,29 @@
 #include "nsRDFCID.h"
 #include "nsString.h"
 #include "nsXPIDLString.h"
 #include "nsGkAtoms.h"
 #include "mozilla/Logging.h"
 #include "prtime.h"
 #include "rdf.h"
 #include "nsContentUtils.h"
-#include "nsIDateTimeFormat.h"
 #include "nsIScriptableDateFormat.h"
 #include "nsICollation.h"
 #include "nsCollationCID.h"
 #include "nsILocale.h"
 #include "nsILocaleService.h"
 #include "nsIConsoleService.h"
 #include "nsEscape.h"
 
 using namespace mozilla;
 
 //------------------------------------------------------------------------
 
 nsIRDFService* nsXULContentUtils::gRDF;
-nsIDateTimeFormat* nsXULContentUtils::gFormat;
 nsICollation *nsXULContentUtils::gCollation;
 
 extern LazyLogModule gXULTemplateLog;
 
 #define XUL_RESOURCE(ident, uri) nsIRDFResource* nsXULContentUtils::ident
 #define XUL_LITERAL(ident, val) nsIRDFLiteral* nsXULContentUtils::ident
 #include "nsXULResourceList.h"
 #undef XUL_RESOURCE
@@ -97,37 +96,31 @@ nsXULContentUtils::Init()
    rv = gRDF->GetLiteral(val, &(ident));                          \
    if (NS_FAILED(rv)) return rv;                                  \
   PR_END_MACRO
 
 #include "nsXULResourceList.h"
 #undef XUL_RESOURCE
 #undef XUL_LITERAL
 
-    gFormat = nsIDateTimeFormat::Create().take();
-    if (!gFormat) {
-        return NS_ERROR_FAILURE;
-    }
-
     return NS_OK;
 }
 
 
 nsresult
 nsXULContentUtils::Finish()
 {
     NS_IF_RELEASE(gRDF);
 
 #define XUL_RESOURCE(ident, uri) NS_IF_RELEASE(ident)
 #define XUL_LITERAL(ident, val) NS_IF_RELEASE(ident)
 #include "nsXULResourceList.h"
 #undef XUL_RESOURCE
 #undef XUL_LITERAL
 
-    NS_IF_RELEASE(gFormat);
     NS_IF_RELEASE(gCollation);
 
     return NS_OK;
 }
 
 nsICollation*
 nsXULContentUtils::GetCollation()
 {
@@ -209,21 +202,21 @@ nsXULContentUtils::GetTextForNode(nsIRDF
 
     nsCOMPtr<nsIRDFDate> dateLiteral = do_QueryInterface(aNode);
     if (dateLiteral) {
         PRTime value;
         rv = dateLiteral->GetValue(&value);
         if (NS_FAILED(rv)) return rv;
 
         nsAutoString str;
-        rv = gFormat->FormatPRTime(nullptr /* nsILocale* locale */,
-                                  kDateFormatShort,
-                                  kTimeFormatSeconds,
-                                  value,
-                                  str);
+        rv = DateTimeFormat::FormatPRTime(kDateFormatShort,
+                                          kTimeFormatSeconds,
+                                          value,
+                                          str);
+
         aResult.Assign(str);
 
         if (NS_FAILED(rv)) return rv;
 
         return NS_OK;
     }
 
     nsCOMPtr<nsIRDFInt> intLiteral = do_QueryInterface(aNode);
--- a/dom/xul/templates/nsXULContentUtils.h
+++ b/dom/xul/templates/nsXULContentUtils.h
@@ -16,17 +16,16 @@
 
 class nsIAtom;
 class nsIContent;
 class nsIDocument;
 class nsIRDFNode;
 class nsIRDFResource;
 class nsIRDFLiteral;
 class nsIRDFService;
-class nsIDateTimeFormat;
 class nsICollation;
 
 // errors to pass to LogTemplateError
 #define ERROR_TEMPLATE_INVALID_QUERYPROCESSOR                           \
         "querytype attribute doesn't specify a valid query processor"
 #define ERROR_TEMPLATE_INVALID_QUERYSET                                 \
         "unexpected <queryset> element"
 #define ERROR_TEMPLATE_NO_MEMBERVAR                                     \
@@ -81,17 +80,16 @@ class nsICollation;
         "the type of a query parameter is wrong"
 #define ERROR_TEMPLATE_STORAGE_QUERY_PARAMETER_NOT_BOUND                \
         "a query parameter cannot be bound to the SQL query"
 
 class nsXULContentUtils
 {
 protected:
     static nsIRDFService* gRDF;
-    static nsIDateTimeFormat* gFormat;
     static nsICollation *gCollation;
 
     static bool gDisableXULCache;
 
     static int
     DisableXULCacheChangedCallback(const char* aPrefName, void* aClosure);
 
 public:
--- a/intl/build/nsI18nModule.cpp
+++ b/intl/build/nsI18nModule.cpp
@@ -56,25 +56,22 @@ NS_DEFINE_NAMED_CID(NS_STRINGBUNDLESERVI
 NS_DEFINE_NAMED_CID(NS_STRINGBUNDLETEXTOVERRIDE_CID);
 NS_DEFINE_NAMED_CID(NS_LOCALESERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_COLLATIONFACTORY_CID);
 NS_DEFINE_NAMED_CID(NS_SCRIPTABLEDATEFORMAT_CID);
 NS_DEFINE_NAMED_CID(NS_LANGUAGEATOMSERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_PLATFORMCHARSET_CID);
 #ifdef XP_WIN
 NS_DEFINE_NAMED_CID(NS_COLLATION_CID);
-NS_DEFINE_NAMED_CID(NS_DATETIMEFORMAT_CID);
 #endif
 #ifdef USE_UNIX_LOCALE
 NS_DEFINE_NAMED_CID(NS_COLLATION_CID);
-NS_DEFINE_NAMED_CID(NS_DATETIMEFORMAT_CID);
 #endif
 #ifdef USE_MAC_LOCALE
 NS_DEFINE_NAMED_CID(NS_COLLATION_CID);
-NS_DEFINE_NAMED_CID(NS_DATETIMEFORMAT_CID);
 #endif
 
 static const mozilla::Module::CIDEntry kIntlCIDs[] = {
     { &kNS_LBRK_CID, false, nullptr, nsJISx4051LineBreakerConstructor },
     { &kNS_WBRK_CID, false, nullptr, nsSampleWordBreakerConstructor },
     { &kNS_SEMANTICUNITSCANNER_CID, false, nullptr, nsSemanticUnitScannerConstructor },
     { &kNS_UNICHARUTIL_CID, false, nullptr, nsCaseConversionImp2Constructor },
     { &kNS_UNICHARCATEGORY_CID, false, nullptr, nsCategoryImpConstructor },
@@ -85,25 +82,22 @@ static const mozilla::Module::CIDEntry k
     { &kNS_STRINGBUNDLETEXTOVERRIDE_CID, false, nullptr, nsStringBundleTextOverrideConstructor },
     { &kNS_LOCALESERVICE_CID, false, nullptr, CreateLocaleService },
     { &kNS_COLLATIONFACTORY_CID, false, nullptr, nsCollationFactoryConstructor },
     { &kNS_SCRIPTABLEDATEFORMAT_CID, false, nullptr, NS_NewScriptableDateFormat },
     { &kNS_LANGUAGEATOMSERVICE_CID, false, nullptr, nsLanguageAtomServiceConstructor },
     { &kNS_PLATFORMCHARSET_CID, false, nullptr, nsPlatformCharsetConstructor },
 #ifdef XP_WIN
     { &kNS_COLLATION_CID, false, nullptr, nsCollationWinConstructor },
-    { &kNS_DATETIMEFORMAT_CID, false, nullptr, nsDateTimeFormatWinConstructor },
 #endif
 #ifdef USE_UNIX_LOCALE
     { &kNS_COLLATION_CID, false, nullptr, nsCollationUnixConstructor },
-    { &kNS_DATETIMEFORMAT_CID, false, nullptr, nsDateTimeFormatUnixConstructor },
 #endif
 #ifdef USE_MAC_LOCALE
     { &kNS_COLLATION_CID, false, nullptr, nsCollationMacUCConstructor },
-    { &kNS_DATETIMEFORMAT_CID, false, nullptr, nsDateTimeFormatMacConstructor },
 #endif
     { nullptr }
 };
 
 static const mozilla::Module::ContractIDEntry kIntlContracts[] = {
     { NS_LBRK_CONTRACTID, &kNS_LBRK_CID },
     { NS_WBRK_CONTRACTID, &kNS_WBRK_CID },
     { NS_SEMANTICUNITSCANNER_CONTRACTID, &kNS_SEMANTICUNITSCANNER_CID },
@@ -116,25 +110,22 @@ static const mozilla::Module::ContractID
     { NS_STRINGBUNDLETEXTOVERRIDE_CONTRACTID, &kNS_STRINGBUNDLETEXTOVERRIDE_CID },
     { NS_LOCALESERVICE_CONTRACTID, &kNS_LOCALESERVICE_CID },
     { NS_COLLATIONFACTORY_CONTRACTID, &kNS_COLLATIONFACTORY_CID },
     { NS_SCRIPTABLEDATEFORMAT_CONTRACTID, &kNS_SCRIPTABLEDATEFORMAT_CID },
     { NS_LANGUAGEATOMSERVICE_CONTRACTID, &kNS_LANGUAGEATOMSERVICE_CID },
     { NS_PLATFORMCHARSET_CONTRACTID, &kNS_PLATFORMCHARSET_CID },
 #ifdef XP_WIN
     { NS_COLLATION_CONTRACTID, &kNS_COLLATION_CID },
-    { NS_DATETIMEFORMAT_CONTRACTID, &kNS_DATETIMEFORMAT_CID },
 #endif
 #ifdef USE_UNIX_LOCALE
     { NS_COLLATION_CONTRACTID, &kNS_COLLATION_CID },
-    { NS_DATETIMEFORMAT_CONTRACTID, &kNS_DATETIMEFORMAT_CID },
 #endif
 #ifdef USE_MAC_LOCALE
     { NS_COLLATION_CONTRACTID, &kNS_COLLATION_CID },
-    { NS_DATETIMEFORMAT_CONTRACTID, &kNS_DATETIMEFORMAT_CID },
 #endif
     { nullptr }
 };
 
 static const mozilla::Module kIntlModule = {
     mozilla::Module::kVersion,
     kIntlCIDs,
     kIntlContracts,
new file mode 100644
--- /dev/null
+++ b/intl/locale/DateTimeFormat.h
@@ -0,0 +1,68 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * 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 mozilla_DateTimeFormat_h
+#define mozilla_DateTimeFormat_h
+
+#include <time.h>
+#include "nsIScriptableDateFormat.h"
+#include "nsStringGlue.h"
+#include "prtime.h"
+
+#ifndef ENABLE_INTL_API
+#include "nsCOMPtr.h"
+#include "nsIUnicodeDecoder.h"
+#endif
+
+namespace mozilla {
+
+class DateTimeFormat {
+public:
+  // performs a locale sensitive date formatting operation on the time_t parameter
+  static nsresult FormatTime(const nsDateFormatSelector aDateFormatSelector,
+                             const nsTimeFormatSelector aTimeFormatSelector,
+                             const time_t aTimetTime,
+                             nsAString& aStringOut);
+
+  // performs a locale sensitive date formatting operation on the PRTime parameter
+  static nsresult FormatPRTime(const nsDateFormatSelector aDateFormatSelector,
+                               const nsTimeFormatSelector aTimeFormatSelector,
+                               const PRTime aPrTime,
+                               nsAString& aStringOut);
+
+  // performs a locale sensitive date formatting operation on the PRExplodedTime parameter
+  static nsresult FormatPRExplodedTime(const nsDateFormatSelector aDateFormatSelector,
+                                       const nsTimeFormatSelector aTimeFormatSelector,
+                                       const PRExplodedTime* aExplodedTime,
+                                       nsAString& aStringOut);
+
+  static void Shutdown();
+
+private:
+  DateTimeFormat() = delete;
+
+  static nsresult Initialize();
+
+#ifdef ENABLE_INTL_API
+  static nsCString* mLocale;
+#else
+  // performs a locale sensitive date formatting operation on the struct tm parameter
+  static nsresult FormatTMTime(const nsDateFormatSelector aDateFormatSelector,
+                               const nsTimeFormatSelector aTimeFormatSelector,
+                               const struct tm* aTmTime,
+                               nsAString& aStringOut);
+
+  static void LocalePreferred24hour();
+
+  static bool mLocalePreferred24hour;                       // true if 24 hour format is preferred by current locale
+  static bool mLocaleAMPMfirst;                             // true if AM/PM string is preferred before the time
+  static nsCOMPtr<nsIUnicodeDecoder> mDecoder;
+#endif
+};
+
+}
+
+#endif  /* mozilla_DateTimeFormat_h */
new file mode 100644
--- /dev/null
+++ b/intl/locale/DateTimeFormatICU.cpp
@@ -0,0 +1,161 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * 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 "DateTimeFormat.h"
+#include "nsCOMPtr.h"
+#include "nsIServiceManager.h"
+#include "nsILocaleService.h"
+#include "unicode/udat.h"
+
+namespace mozilla {
+
+nsCString* DateTimeFormat::mLocale = nullptr;
+
+/*static*/ nsresult
+DateTimeFormat::Initialize()
+{
+  nsAutoString localeStr;
+  nsresult rv = NS_OK;
+
+  if (!mLocale) {
+    mLocale = new nsCString();
+  } else if (!mLocale->IsEmpty()) {
+    return NS_OK;
+  }
+
+  nsCOMPtr<nsILocaleService> localeService =
+           do_GetService(NS_LOCALESERVICE_CONTRACTID, &rv);
+  if (NS_SUCCEEDED(rv)) {
+    nsCOMPtr<nsILocale> appLocale;
+    rv = localeService->GetApplicationLocale(getter_AddRefs(appLocale));
+    if (NS_SUCCEEDED(rv)) {
+      rv = appLocale->GetCategory(NS_LITERAL_STRING("NSILOCALE_TIME"), localeStr);
+      if (NS_SUCCEEDED(rv) && !localeStr.IsEmpty()) {
+        *mLocale = NS_LossyConvertUTF16toASCII(localeStr); // cache locale name
+      }
+    }
+  }
+
+  return rv;
+}
+
+// performs a locale sensitive date formatting operation on the time_t parameter
+/*static*/ nsresult
+DateTimeFormat::FormatTime(const nsDateFormatSelector aDateFormatSelector,
+                           const nsTimeFormatSelector aTimeFormatSelector,
+                           const time_t aTimetTime,
+                           nsAString& aStringOut)
+{
+  return FormatPRTime(aDateFormatSelector, aTimeFormatSelector, (aTimetTime * PR_USEC_PER_SEC), aStringOut);
+}
+
+// performs a locale sensitive date formatting operation on the PRTime parameter
+/*static*/ nsresult
+DateTimeFormat::FormatPRTime(const nsDateFormatSelector aDateFormatSelector,
+                             const nsTimeFormatSelector aTimeFormatSelector,
+                             const PRTime aPrTime,
+                             nsAString& aStringOut)
+{
+#define DATETIME_FORMAT_INITIAL_LEN 127
+  int32_t dateTimeLen = 0;
+  nsresult rv = NS_OK;
+
+  // return, nothing to format
+  if (aDateFormatSelector == kDateFormatNone && aTimeFormatSelector == kTimeFormatNone) {
+    aStringOut.Truncate();
+    return NS_OK;
+  }
+
+  // set up locale data
+  rv = Initialize();
+
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+
+  UDate timeUDate = aPrTime / PR_USEC_PER_MSEC;
+
+  // Get the date style for the formatter:
+  UDateFormatStyle dateStyle;
+  switch (aDateFormatSelector) {
+    case kDateFormatLong:
+      dateStyle = UDAT_LONG;
+      break;
+    case kDateFormatShort:
+      dateStyle = UDAT_SHORT;
+      break;
+    case kDateFormatNone:
+      dateStyle = UDAT_NONE;
+      break;
+    default:
+      NS_ERROR("Unknown nsDateFormatSelector");
+      return NS_ERROR_ILLEGAL_VALUE;
+  }
+
+  // Get the time style for the formatter:
+  UDateFormatStyle timeStyle;
+  switch (aTimeFormatSelector) {
+    case kTimeFormatSeconds:
+      timeStyle = UDAT_MEDIUM;
+      break;
+    case kTimeFormatNoSeconds:
+      timeStyle = UDAT_SHORT;
+      break;
+    case kTimeFormatNone:
+      timeStyle = UDAT_NONE;
+      break;
+    default:
+      NS_ERROR("Unknown nsTimeFormatSelector");
+      return NS_ERROR_ILLEGAL_VALUE;
+  }
+
+  // generate date/time string
+
+  UErrorCode status = U_ZERO_ERROR;
+
+  UDateFormat* dateTimeFormat = udat_open(timeStyle, dateStyle, mLocale->get(), nullptr, -1, nullptr, -1, &status);
+
+  if (U_SUCCESS(status) && dateTimeFormat) {
+    aStringOut.SetLength(DATETIME_FORMAT_INITIAL_LEN);
+    dateTimeLen = udat_format(dateTimeFormat, timeUDate, reinterpret_cast<UChar*>(aStringOut.BeginWriting()), DATETIME_FORMAT_INITIAL_LEN, nullptr, &status);
+    aStringOut.SetLength(dateTimeLen);
+
+    if (status == U_BUFFER_OVERFLOW_ERROR) {
+      status = U_ZERO_ERROR;
+      udat_format(dateTimeFormat, timeUDate, reinterpret_cast<UChar*>(aStringOut.BeginWriting()), dateTimeLen, nullptr, &status);
+    }
+  }
+
+  if (U_FAILURE(status)) {
+    rv = NS_ERROR_FAILURE;
+  }
+
+  if (dateTimeFormat) {
+    udat_close(dateTimeFormat);
+  }
+
+  return rv;
+}
+
+// performs a locale sensitive date formatting operation on the PRExplodedTime parameter
+/*static*/ nsresult
+DateTimeFormat::FormatPRExplodedTime(const nsDateFormatSelector aDateFormatSelector,
+                                     const nsTimeFormatSelector aTimeFormatSelector,
+                                     const PRExplodedTime* aExplodedTime,
+                                     nsAString& aStringOut)
+{
+  return FormatPRTime(aDateFormatSelector, aTimeFormatSelector, PR_ImplodeTime(aExplodedTime), aStringOut);
+}
+
+/*static*/ void
+DateTimeFormat::Shutdown()
+{
+  if (mLocale) {
+    delete mLocale;
+  }
+}
+
+}
rename from intl/locale/unix/nsDateTimeFormatUnix.cpp
rename to intl/locale/DateTimeFormatUnix.cpp
--- a/intl/locale/unix/nsDateTimeFormatUnix.cpp
+++ b/intl/locale/DateTimeFormatUnix.cpp
@@ -1,284 +1,239 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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 <locale.h>
+#include "DateTimeFormat.h"
 #include "plstr.h"
 #include "nsIServiceManager.h"
-#include "nsDateTimeFormatUnix.h"
-#include "nsIComponentManager.h"
 #include "nsILocaleService.h"
 #include "nsIPlatformCharset.h"
-#include "nsPosixLocale.h"
-#include "nsCRT.h"
-#include "nsReadableUtils.h"
-#include "nsUnicharUtils.h"
 #include "mozilla/dom/EncodingUtils.h"
 
 using mozilla::dom::EncodingUtils;
 
-NS_IMPL_ISUPPORTS(nsDateTimeFormatUnix, nsIDateTimeFormat)
+namespace mozilla {
 
-// init this interface to a specified locale
-nsresult nsDateTimeFormatUnix::Initialize(nsILocale* locale)
+bool DateTimeFormat::mLocalePreferred24hour;
+bool DateTimeFormat::mLocaleAMPMfirst;
+nsCOMPtr<nsIUnicodeDecoder> DateTimeFormat::mDecoder;
+
+/*static*/ nsresult
+DateTimeFormat::Initialize()
 {
   nsAutoString localeStr;
-  NS_NAMED_LITERAL_STRING(aCategory, "NSILOCALE_TIME##PLATFORM");
-  nsresult res = NS_OK;
+  nsAutoCString charset;
+  nsresult rv = NS_OK;
+
+  if (mDecoder) {
+    return NS_OK;
+  }
+
+  charset.AssignLiteral("windows-1252");
 
-  // use cached info if match with stored locale
-  if (!locale) {
-    if (!mLocale.IsEmpty() &&
-        mLocale.Equals(mAppLocale, nsCaseInsensitiveStringComparator())) {
-      return NS_OK;
+  nsCOMPtr<nsILocaleService> localeService =
+    do_GetService(NS_LOCALESERVICE_CONTRACTID, &rv);
+  if (NS_SUCCEEDED(rv)) {
+    nsCOMPtr<nsILocale> appLocale;
+    rv = localeService->GetApplicationLocale(getter_AddRefs(appLocale));
+    if (NS_SUCCEEDED(rv)) {
+      rv = appLocale->GetCategory(NS_LITERAL_STRING("NSILOCALE_TIME##PLATFORM"), localeStr);
+      NS_ASSERTION(NS_SUCCEEDED(rv), "failed to get app locale info");
     }
   }
-  else {
-    res = locale->GetCategory(aCategory, localeStr);
-    if (NS_SUCCEEDED(res) && !localeStr.IsEmpty()) {
-      if (!mLocale.IsEmpty() &&
-          mLocale.Equals(localeStr,
-                         nsCaseInsensitiveStringComparator())) {
-        return NS_OK;
+
+  if (NS_SUCCEEDED(rv) && !localeStr.IsEmpty()) {
+    nsCOMPtr<nsIPlatformCharset> platformCharset = do_GetService(NS_PLATFORMCHARSET_CONTRACTID, &rv);
+    if (NS_SUCCEEDED(rv)) {
+      nsAutoCString mappedCharset;
+      rv = platformCharset->GetDefaultCharsetForLocale(localeStr, mappedCharset);
+      if (NS_SUCCEEDED(rv)) {
+        charset = mappedCharset;
       }
     }
   }
 
-  mCharset.AssignLiteral("windows-1252");
-  mPlatformLocale.AssignLiteral("en_US");
-
-  // get locale name string, use app default if no locale specified
-  if (!locale) {
-    nsCOMPtr<nsILocaleService> localeService = 
-             do_GetService(NS_LOCALESERVICE_CONTRACTID, &res);
-    if (NS_SUCCEEDED(res)) {
-      nsCOMPtr<nsILocale> appLocale;
-      res = localeService->GetApplicationLocale(getter_AddRefs(appLocale));
-      if (NS_SUCCEEDED(res)) {
-        res = appLocale->GetCategory(aCategory, localeStr);
-        if (NS_SUCCEEDED(res) && !localeStr.IsEmpty()) {
-          NS_ASSERTION(NS_SUCCEEDED(res), "failed to get app locale info");
-          mAppLocale = localeStr; // cache app locale name
-        }
-      }
-    }
-  }
-  else {
-    res = locale->GetCategory(aCategory, localeStr);
-    NS_ASSERTION(NS_SUCCEEDED(res), "failed to get locale info");
-  }
-
-  if (NS_SUCCEEDED(res) && !localeStr.IsEmpty()) {
-    mLocale = localeStr; // cache locale name
-
-    nsPosixLocale::GetPlatformLocale(mLocale, mPlatformLocale);
-
-    nsCOMPtr <nsIPlatformCharset> platformCharset = do_GetService(NS_PLATFORMCHARSET_CONTRACTID, &res);
-    if (NS_SUCCEEDED(res)) {
-      nsAutoCString mappedCharset;
-      res = platformCharset->GetDefaultCharsetForLocale(mLocale, mappedCharset);
-      if (NS_SUCCEEDED(res)) {
-        mCharset = mappedCharset;
-      }
-    }
-  }
-
-  mDecoder = EncodingUtils::DecoderForEncoding(mCharset);
+  mDecoder = EncodingUtils::DecoderForEncoding(charset);
 
   LocalePreferred24hour();
 
-  return res;
+  return rv;
 }
 
-void nsDateTimeFormatUnix::LocalePreferred24hour()
+/*static*/ void
+DateTimeFormat::LocalePreferred24hour()
 {
   char str[100];
   time_t tt;
   struct tm *tmc;
   int i;
 
   tt = time(nullptr);
   tmc = localtime(&tt);
 
   tmc->tm_hour=22;    // put the test sample hour to 22:00 which is 10PM
   tmc->tm_min=0;      // set the min & sec other number than '2'
   tmc->tm_sec=0;
 
-  char *temp = setlocale(LC_TIME, mPlatformLocale.get());
   strftime(str, (size_t)99, "%X", (struct tm *)tmc);
 
-  (void) setlocale(LC_TIME, temp);
-
   mLocalePreferred24hour = false;
   for (i=0; str[i]; i++) {
     if (str[i] == '2') {    // if there is any '2', that locale use 0-23 time format
-        mLocalePreferred24hour = true;
-        break;
+      mLocalePreferred24hour = true;
+      break;
     }
   }
 
   mLocaleAMPMfirst = true;
   if (mLocalePreferred24hour == false) {
     if (str[0] && str[0] == '1') { // if the first character is '1' of 10:00,
 			           // AMPM string is located after 10:00
       mLocaleAMPMfirst = false;
     }
   }
 }
 
-nsresult nsDateTimeFormatUnix::FormatTime(nsILocale* locale, 
-                                      const nsDateFormatSelector  dateFormatSelector, 
-                                      const nsTimeFormatSelector timeFormatSelector, 
-                                      const time_t  timetTime, 
-                                      nsAString& stringOut) 
+/*static*/ nsresult
+DateTimeFormat::FormatTime(const nsDateFormatSelector aDateFormatSelector,
+                           const nsTimeFormatSelector aTimeFormatSelector,
+                           const time_t aTimetTime,
+                           nsAString& aStringOut)
 {
   struct tm tmTime;
-  memcpy(&tmTime, localtime(&timetTime), sizeof(struct tm));
-  return FormatTMTime(locale, dateFormatSelector, timeFormatSelector, &tmTime, stringOut);
+  memcpy(&tmTime, localtime(&aTimetTime), sizeof(struct tm));
+  return FormatTMTime(aDateFormatSelector, aTimeFormatSelector, &tmTime, aStringOut);
 }
 
 // performs a locale sensitive date formatting operation on the struct tm parameter
-nsresult nsDateTimeFormatUnix::FormatTMTime(nsILocale* locale, 
-                                        const nsDateFormatSelector  dateFormatSelector, 
-                                        const nsTimeFormatSelector timeFormatSelector, 
-                                        const struct tm*  tmTime, 
-                                        nsAString& stringOut) 
+/*static*/ nsresult
+DateTimeFormat::FormatTMTime(const nsDateFormatSelector aDateFormatSelector,
+                             const nsTimeFormatSelector aTimeFormatSelector,
+                             const struct tm* aTmTime,
+                             nsAString& aStringOut)
 {
-#define NSDATETIME_FORMAT_BUFFER_LEN  80
+#define NSDATETIME_FORMAT_BUFFER_LEN 80
   char strOut[NSDATETIME_FORMAT_BUFFER_LEN*2];  // buffer for date and time
   char fmtD[NSDATETIME_FORMAT_BUFFER_LEN], fmtT[NSDATETIME_FORMAT_BUFFER_LEN];
   nsresult rv;
 
-  
   // set up locale data
-  (void) Initialize(locale);
+  (void) Initialize();
   NS_ENSURE_TRUE(mDecoder, NS_ERROR_NOT_INITIALIZED);
 
   // set date format
-  if (dateFormatSelector == kDateFormatLong && timeFormatSelector == kTimeFormatSeconds) {
+  if (aDateFormatSelector == kDateFormatLong && aTimeFormatSelector == kTimeFormatSeconds) {
     PL_strncpy(fmtD, "%c", NSDATETIME_FORMAT_BUFFER_LEN);
-    PL_strncpy(fmtT, "", NSDATETIME_FORMAT_BUFFER_LEN); 
+    PL_strncpy(fmtT, "", NSDATETIME_FORMAT_BUFFER_LEN);
   } else {
 
-    switch (dateFormatSelector) {
+    switch (aDateFormatSelector) {
       case kDateFormatNone:
         PL_strncpy(fmtD, "", NSDATETIME_FORMAT_BUFFER_LEN);
-        break; 
+        break;
       case kDateFormatLong:
       case kDateFormatShort:
         PL_strncpy(fmtD, "%x", NSDATETIME_FORMAT_BUFFER_LEN);
-        break; 
-      case kDateFormatYearMonth:
-        PL_strncpy(fmtD, "%Y/%m", NSDATETIME_FORMAT_BUFFER_LEN);
-        break; 
-      case kDateFormatWeekday:
-        PL_strncpy(fmtD, "%a", NSDATETIME_FORMAT_BUFFER_LEN);
         break;
       default:
-        PL_strncpy(fmtD, "", NSDATETIME_FORMAT_BUFFER_LEN); 
+        PL_strncpy(fmtD, "", NSDATETIME_FORMAT_BUFFER_LEN);
     }
 
     // set time format
-    switch (timeFormatSelector) {
+    switch (aTimeFormatSelector) {
       case kTimeFormatNone:
-        PL_strncpy(fmtT, "", NSDATETIME_FORMAT_BUFFER_LEN); 
+        PL_strncpy(fmtT, "", NSDATETIME_FORMAT_BUFFER_LEN);
         break;
       case kTimeFormatSeconds:
         PL_strncpy(fmtT, "%X", NSDATETIME_FORMAT_BUFFER_LEN);
         break;
       case kTimeFormatNoSeconds:
-        PL_strncpy(fmtT, 
-                   mLocalePreferred24hour ? "%H:%M" : mLocaleAMPMfirst ? "%p %I:%M" : "%I:%M %p", 
+        PL_strncpy(fmtT,
+                   mLocalePreferred24hour ? "%H:%M" : mLocaleAMPMfirst ? "%p %I:%M" : "%I:%M %p",
                    NSDATETIME_FORMAT_BUFFER_LEN);
         break;
-      case kTimeFormatSecondsForce24Hour:
-        PL_strncpy(fmtT, "%H:%M:%S", NSDATETIME_FORMAT_BUFFER_LEN);
-        break;
-      case kTimeFormatNoSecondsForce24Hour:
-        PL_strncpy(fmtT, "%H:%M", NSDATETIME_FORMAT_BUFFER_LEN);
-        break;
       default:
-        PL_strncpy(fmtT, "", NSDATETIME_FORMAT_BUFFER_LEN); 
+        PL_strncpy(fmtT, "", NSDATETIME_FORMAT_BUFFER_LEN);
     }
   }
 
-  // generate data/time string
-  char *old_locale = setlocale(LC_TIME, nullptr);
-  (void) setlocale(LC_TIME, mPlatformLocale.get());
+  // generate date/time string
   if (strlen(fmtD) && strlen(fmtT)) {
     PL_strncat(fmtD, " ", NSDATETIME_FORMAT_BUFFER_LEN);
     PL_strncat(fmtD, fmtT, NSDATETIME_FORMAT_BUFFER_LEN);
-    strftime(strOut, NSDATETIME_FORMAT_BUFFER_LEN, fmtD, tmTime);
-  }
-  else if (strlen(fmtD) && !strlen(fmtT)) {
-    strftime(strOut, NSDATETIME_FORMAT_BUFFER_LEN, fmtD, tmTime);
-  }
-  else if (!strlen(fmtD) && strlen(fmtT)) {
-    strftime(strOut, NSDATETIME_FORMAT_BUFFER_LEN, fmtT, tmTime);
-  }
-  else {
+    strftime(strOut, NSDATETIME_FORMAT_BUFFER_LEN, fmtD, aTmTime);
+  } else if (strlen(fmtD) && !strlen(fmtT)) {
+    strftime(strOut, NSDATETIME_FORMAT_BUFFER_LEN, fmtD, aTmTime);
+  } else if (!strlen(fmtD) && strlen(fmtT)) {
+    strftime(strOut, NSDATETIME_FORMAT_BUFFER_LEN, fmtT, aTmTime);
+  } else {
     PL_strncpy(strOut, "", NSDATETIME_FORMAT_BUFFER_LEN);
   }
-  (void) setlocale(LC_TIME, old_locale);
 
   // convert result to unicode
   int32_t srcLength = (int32_t) strlen(strOut);
   int32_t unicharLength = NSDATETIME_FORMAT_BUFFER_LEN*2;
   char16_t unichars[NSDATETIME_FORMAT_BUFFER_LEN*2];   // buffer for date and time
 
   rv = mDecoder->Convert(strOut, &srcLength, unichars, &unicharLength);
-  if (NS_FAILED(rv))
+  if (NS_FAILED(rv)) {
     return rv;
-  stringOut.Assign(unichars, unicharLength);
+  }
+  aStringOut.Assign(unichars, unicharLength);
 
   return rv;
 }
 
 // performs a locale sensitive date formatting operation on the PRTime parameter
-nsresult nsDateTimeFormatUnix::FormatPRTime(nsILocale* locale, 
-                                           const nsDateFormatSelector  dateFormatSelector, 
-                                           const nsTimeFormatSelector timeFormatSelector, 
-                                           const PRTime  prTime, 
-                                           nsAString& stringOut)
+/*static*/ nsresult
+DateTimeFormat::FormatPRTime(const nsDateFormatSelector aDateFormatSelector,
+                             const nsTimeFormatSelector aTimeFormatSelector,
+                             const PRTime aPrTime,
+                             nsAString& aStringOut)
 {
   PRExplodedTime explodedTime;
-  PR_ExplodeTime(prTime, PR_LocalTimeParameters, &explodedTime);
+  PR_ExplodeTime(aPrTime, PR_LocalTimeParameters, &explodedTime);
 
-  return FormatPRExplodedTime(locale, dateFormatSelector, timeFormatSelector, &explodedTime, stringOut);
+  return FormatPRExplodedTime(aDateFormatSelector, aTimeFormatSelector, &explodedTime, aStringOut);
 }
 
 // performs a locale sensitive date formatting operation on the PRExplodedTime parameter
-nsresult nsDateTimeFormatUnix::FormatPRExplodedTime(nsILocale* locale, 
-                                                   const nsDateFormatSelector  dateFormatSelector, 
-                                                   const nsTimeFormatSelector timeFormatSelector, 
-                                                   const PRExplodedTime*  explodedTime, 
-                                                   nsAString& stringOut)
+/*static*/ nsresult
+DateTimeFormat::FormatPRExplodedTime(const nsDateFormatSelector aDateFormatSelector,
+                                     const nsTimeFormatSelector aTimeFormatSelector,
+                                     const PRExplodedTime* aExplodedTime,
+                                     nsAString& aStringOut)
 {
   struct tm  tmTime;
   /* be safe and set all members of struct tm to zero
    *
    * there are other fields in the tm struct that we aren't setting
    * (tm_isdst, tm_gmtoff, tm_zone, should we set these?) and since
    * tmTime is on the stack, it may be filled with garbage, but
    * the garbage may vary.  (this may explain why some saw bug #10412, and
    * others did not.
    *
-   * when tmTime is passed to strftime() with garbage bad things may happen. 
+   * when tmTime is passed to strftime() with garbage bad things may happen.
    * see bug #10412
    */
   memset( &tmTime, 0, sizeof(tmTime) );
 
-  tmTime.tm_yday = explodedTime->tm_yday;
-  tmTime.tm_wday = explodedTime->tm_wday;
-  tmTime.tm_year = explodedTime->tm_year;
+  tmTime.tm_yday = aExplodedTime->tm_yday;
+  tmTime.tm_wday = aExplodedTime->tm_wday;
+  tmTime.tm_year = aExplodedTime->tm_year;
   tmTime.tm_year -= 1900;
-  tmTime.tm_mon = explodedTime->tm_month;
-  tmTime.tm_mday = explodedTime->tm_mday;
-  tmTime.tm_hour = explodedTime->tm_hour;
-  tmTime.tm_min = explodedTime->tm_min;
-  tmTime.tm_sec = explodedTime->tm_sec;
+  tmTime.tm_mon = aExplodedTime->tm_month;
+  tmTime.tm_mday = aExplodedTime->tm_mday;
+  tmTime.tm_hour = aExplodedTime->tm_hour;
+  tmTime.tm_min = aExplodedTime->tm_min;
+  tmTime.tm_sec = aExplodedTime->tm_sec;
 
-  return FormatTMTime(locale, dateFormatSelector, timeFormatSelector, &tmTime, stringOut);
+  return FormatTMTime(aDateFormatSelector, aTimeFormatSelector, &tmTime, aStringOut);
 }
 
+/*static*/ void
+DateTimeFormat::Shutdown()
+{
+}
+
+}
--- a/intl/locale/mac/moz.build
+++ b/intl/locale/mac/moz.build
@@ -1,16 +1,15 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 UNIFIED_SOURCES += [
     'nsCollationMacUC.cpp',
-    'nsDateTimeFormatMac.cpp',
     'nsMacCharset.cpp',
 ]
 
 FINAL_LIBRARY = 'xul'
 LOCAL_INCLUDES += [
     '..',
 ]
deleted file mode 100644
--- a/intl/locale/mac/nsDateTimeFormatMac.cpp
+++ /dev/null
@@ -1,266 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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 <CoreFoundation/CoreFoundation.h>
-#include "nsIServiceManager.h"
-#include "nsDateTimeFormatMac.h"
-#include <CoreFoundation/CFDateFormatter.h>
-#include "nsIComponentManager.h"
-#include "nsILocaleService.h"
-#include "nsCRT.h"
-#include "plstr.h"
-#include "nsUnicharUtils.h"
-#include "nsTArray.h"
-
-
-NS_IMPL_ISUPPORTS(nsDateTimeFormatMac, nsIDateTimeFormat)
-
-nsresult nsDateTimeFormatMac::Initialize(nsILocale* locale)
-{
-  nsAutoString localeStr;
-  nsAutoString category(NS_LITERAL_STRING("NSILOCALE_TIME"));
-  nsresult res;
-
-  // use cached info if match with stored locale
-  if (nullptr == locale) {
-    if (!mLocale.IsEmpty() &&
-        mLocale.Equals(mAppLocale, nsCaseInsensitiveStringComparator())) {
-      return NS_OK;
-    }
-  }
-  else {
-    res = locale->GetCategory(category, localeStr);
-    if (NS_SUCCEEDED(res) && !localeStr.IsEmpty()) {
-      if (!mLocale.IsEmpty() &&
-          mLocale.Equals(localeStr,
-                         nsCaseInsensitiveStringComparator())) {
-        return NS_OK;
-      }
-    }
-  }
-
-  // get application locale
-  nsCOMPtr<nsILocaleService> localeService = 
-           do_GetService(NS_LOCALESERVICE_CONTRACTID, &res);
-  if (NS_SUCCEEDED(res)) {
-    nsCOMPtr<nsILocale> appLocale;
-    res = localeService->GetApplicationLocale(getter_AddRefs(appLocale));
-    if (NS_SUCCEEDED(res)) {
-      res = appLocale->GetCategory(category, localeStr);
-      if (NS_SUCCEEDED(res) && !localeStr.IsEmpty()) {
-        mAppLocale = localeStr; // cache app locale name
-      }
-    }
-  }
-  
-  // use app default if no locale specified
-  if (nullptr == locale) {
-    mUseDefaultLocale = true;
-  }
-  else {
-    mUseDefaultLocale = false;
-    res = locale->GetCategory(category, localeStr);
-  }
-    
-  if (NS_SUCCEEDED(res) && !localeStr.IsEmpty()) {
-    mLocale.Assign(localeStr); // cache locale name
-  }
-
-  return res;
-}
-
-// performs a locale sensitive date formatting operation on the time_t parameter
-nsresult nsDateTimeFormatMac::FormatTime(nsILocale* locale, 
-                                      const nsDateFormatSelector  dateFormatSelector, 
-                                      const nsTimeFormatSelector timeFormatSelector, 
-                                      const time_t  timetTime, 
-                                      nsAString& stringOut)
-{
-  struct tm tmTime;
-  return FormatTMTime(locale, dateFormatSelector, timeFormatSelector, localtime_r(&timetTime, &tmTime), stringOut);
-}
-
-// performs a locale sensitive date formatting operation on the struct tm parameter
-nsresult nsDateTimeFormatMac::FormatTMTime(nsILocale* locale, 
-                                           const nsDateFormatSelector  dateFormatSelector, 
-                                           const nsTimeFormatSelector timeFormatSelector, 
-                                           const struct tm*  tmTime, 
-                                           nsAString& stringOut)
-{
-  nsresult res = NS_OK;
-
-  // set up locale data
-  (void) Initialize(locale);
-  
-  // return, nothing to format
-  if (dateFormatSelector == kDateFormatNone && timeFormatSelector == kTimeFormatNone) {
-    stringOut.Truncate();
-    return NS_OK;
-  }
-
-  NS_ASSERTION(tmTime->tm_mon >= 0, "tm is not set correctly");
-  NS_ASSERTION(tmTime->tm_mday >= 1, "tm is not set correctly");
-  NS_ASSERTION(tmTime->tm_hour >= 0, "tm is not set correctly");
-  NS_ASSERTION(tmTime->tm_min >= 0, "tm is not set correctly");
-  NS_ASSERTION(tmTime->tm_sec >= 0, "tm is not set correctly");
-  NS_ASSERTION(tmTime->tm_wday >= 0, "tm is not set correctly");
-
-  // Got the locale for the formatter:
-  CFLocaleRef formatterLocale;
-  if (!locale) {
-    formatterLocale = CFLocaleCopyCurrent();
-  } else {
-    CFStringRef localeStr = CFStringCreateWithCharacters(nullptr,
-                                                         reinterpret_cast<const UniChar*>(mLocale.get()),
-                                                         mLocale.Length());
-    formatterLocale = CFLocaleCreate(nullptr, localeStr);
-    CFRelease(localeStr);
-  }
-
-  // Get the date style for the formatter:  
-  CFDateFormatterStyle dateStyle;
-  switch (dateFormatSelector) {
-    case kDateFormatLong:
-      dateStyle = kCFDateFormatterLongStyle;
-      break;
-    case kDateFormatShort:
-      dateStyle = kCFDateFormatterShortStyle;
-      break;
-    case kDateFormatYearMonth:
-    case kDateFormatWeekday:
-      dateStyle = kCFDateFormatterNoStyle; // formats handled below
-      break;
-    case kDateFormatNone:
-      dateStyle = kCFDateFormatterNoStyle;
-      break;
-    default:
-      NS_ERROR("Unknown nsDateFormatSelector");
-      res = NS_ERROR_FAILURE;
-      dateStyle = kCFDateFormatterNoStyle;
-  }
-  
-  // Get the time style for the formatter:
-  CFDateFormatterStyle timeStyle;
-  switch (timeFormatSelector) {
-    case kTimeFormatSeconds:
-    case kTimeFormatSecondsForce24Hour: // 24 hour part fixed below
-      timeStyle = kCFDateFormatterMediumStyle;
-      break;
-    case kTimeFormatNoSeconds:
-    case kTimeFormatNoSecondsForce24Hour: // 24 hour part fixed below
-      timeStyle = kCFDateFormatterShortStyle;
-      break;
-    case kTimeFormatNone:
-      timeStyle = kCFDateFormatterNoStyle;
-      break;
-    default:
-      NS_ERROR("Unknown nsTimeFormatSelector");
-      res = NS_ERROR_FAILURE;
-      timeStyle = kCFDateFormatterNoStyle;
-  }
-  
-  // Create the formatter and fix up its formatting as necessary:
-  CFDateFormatterRef formatter =
-    CFDateFormatterCreate(nullptr, formatterLocale, dateStyle, timeStyle);
-  
-  CFRelease(formatterLocale);
-  
-  if (dateFormatSelector == kDateFormatYearMonth ||
-      dateFormatSelector == kDateFormatWeekday) {
-    CFStringRef dateFormat =
-      dateFormatSelector == kDateFormatYearMonth ? CFSTR("yyyy/MM ") : CFSTR("EEE ");
-    
-    CFStringRef oldFormat = CFDateFormatterGetFormat(formatter);
-    CFMutableStringRef newFormat = CFStringCreateMutableCopy(nullptr, 0, oldFormat);
-    CFStringInsert(newFormat, 0, dateFormat);
-    CFDateFormatterSetFormat(formatter, newFormat);
-    CFRelease(newFormat); // note we don't own oldFormat
-  }
-  
-  if (timeFormatSelector == kTimeFormatSecondsForce24Hour ||
-      timeFormatSelector == kTimeFormatNoSecondsForce24Hour) {
-    // Replace "h" with "H", and remove "a":
-    CFStringRef oldFormat = CFDateFormatterGetFormat(formatter);
-    CFMutableStringRef newFormat = CFStringCreateMutableCopy(nullptr, 0, oldFormat);
-    CFIndex replaceCount = CFStringFindAndReplace(newFormat,
-                                                  CFSTR("h"), CFSTR("H"),
-                                                  CFRangeMake(0, CFStringGetLength(newFormat)),	
-                                                  0);
-    NS_ASSERTION(replaceCount <= 2, "Unexpected number of \"h\" occurrences");
-    replaceCount = CFStringFindAndReplace(newFormat,
-                                          CFSTR("a"), CFSTR(""),
-                                          CFRangeMake(0, CFStringGetLength(newFormat)),	
-                                          0);
-    NS_ASSERTION(replaceCount <= 1, "Unexpected number of \"a\" occurrences");
-    CFDateFormatterSetFormat(formatter, newFormat);
-    CFRelease(newFormat); // note we don't own oldFormat
-  }
-  
-  // Now get the formatted date:
-  CFGregorianDate date;
-  date.second = tmTime->tm_sec;
-  date.minute = tmTime->tm_min;
-  date.hour = tmTime->tm_hour;
-  date.day = tmTime->tm_mday;      // Mac is 1-based, tm is 1-based
-  date.month = tmTime->tm_mon + 1; // Mac is 1-based, tm is 0-based
-  date.year = tmTime->tm_year + 1900;
-
-  CFTimeZoneRef timeZone = CFTimeZoneCopySystem(); // tmTime is in local time
-  CFAbsoluteTime absTime = CFGregorianDateGetAbsoluteTime(date, timeZone);
-  CFRelease(timeZone);
-
-  CFStringRef formattedDate = CFDateFormatterCreateStringWithAbsoluteTime(nullptr,
-                                                                          formatter,
-                                                                          absTime);
-
-  CFIndex stringLen = CFStringGetLength(formattedDate);
-
-  AutoTArray<UniChar, 256> stringBuffer;
-  stringBuffer.SetLength(stringLen + 1);
-  CFStringGetCharacters(formattedDate, CFRangeMake(0, stringLen), stringBuffer.Elements());
-  stringOut.Assign(reinterpret_cast<char16_t*>(stringBuffer.Elements()), stringLen);
-
-  CFRelease(formattedDate);
-  CFRelease(formatter);
-
-  return res;
-}
-
-// performs a locale sensitive date formatting operation on the PRTime parameter
-nsresult nsDateTimeFormatMac::FormatPRTime(nsILocale* locale, 
-                                           const nsDateFormatSelector  dateFormatSelector, 
-                                           const nsTimeFormatSelector timeFormatSelector, 
-                                           const PRTime  prTime, 
-                                           nsAString& stringOut)
-{
-  PRExplodedTime explodedTime;
-  PR_ExplodeTime(prTime, PR_LocalTimeParameters, &explodedTime);
-
-  return FormatPRExplodedTime(locale, dateFormatSelector, timeFormatSelector, &explodedTime, stringOut);
-}
-
-// performs a locale sensitive date formatting operation on the PRExplodedTime parameter
-nsresult nsDateTimeFormatMac::FormatPRExplodedTime(nsILocale* locale, 
-                                                   const nsDateFormatSelector  dateFormatSelector, 
-                                                   const nsTimeFormatSelector timeFormatSelector, 
-                                                   const PRExplodedTime*  explodedTime, 
-                                                   nsAString& stringOut)
-{
-  struct tm  tmTime;
-  memset( &tmTime, 0, sizeof(tmTime) );
-
-  tmTime.tm_yday = explodedTime->tm_yday;
-  tmTime.tm_wday = explodedTime->tm_wday;
-  tmTime.tm_year = explodedTime->tm_year;
-  tmTime.tm_year -= 1900;
-  tmTime.tm_mon = explodedTime->tm_month;
-  tmTime.tm_mday = explodedTime->tm_mday;
-  tmTime.tm_hour = explodedTime->tm_hour;
-  tmTime.tm_min = explodedTime->tm_min;
-  tmTime.tm_sec = explodedTime->tm_sec;
-
-  return FormatTMTime(locale, dateFormatSelector, timeFormatSelector, &tmTime, stringOut);
-}
-
deleted file mode 100644
--- a/intl/locale/mac/nsDateTimeFormatMac.h
+++ /dev/null
@@ -1,61 +0,0 @@
-
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * 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 nsDateTimeFormatMac_h__
-#define nsDateTimeFormatMac_h__
-
-
-#include "nsCOMPtr.h"
-#include "nsIDateTimeFormat.h"
-
-
-class nsDateTimeFormatMac : public nsIDateTimeFormat {
-
-public: 
-  NS_DECL_THREADSAFE_ISUPPORTS 
-
-  // performs a locale sensitive date formatting operation on the time_t parameter
-  NS_IMETHOD FormatTime(nsILocale* locale, 
-                        const nsDateFormatSelector  dateFormatSelector, 
-                        const nsTimeFormatSelector timeFormatSelector, 
-                        const time_t  timetTime, 
-                        nsAString& stringOut) override; 
-
-  // performs a locale sensitive date formatting operation on the struct tm parameter
-  NS_IMETHOD FormatTMTime(nsILocale* locale, 
-                          const nsDateFormatSelector  dateFormatSelector, 
-                          const nsTimeFormatSelector timeFormatSelector, 
-                          const struct tm*  tmTime, 
-                          nsAString& stringOut) override; 
-  // performs a locale sensitive date formatting operation on the PRTime parameter
-  NS_IMETHOD FormatPRTime(nsILocale* locale, 
-                          const nsDateFormatSelector  dateFormatSelector, 
-                          const nsTimeFormatSelector timeFormatSelector, 
-                          const PRTime  prTime, 
-                          nsAString& stringOut) override;
-
-  // performs a locale sensitive date formatting operation on the PRExplodedTime parameter
-  NS_IMETHOD FormatPRExplodedTime(nsILocale* locale, 
-                                  const nsDateFormatSelector  dateFormatSelector, 
-                                  const nsTimeFormatSelector timeFormatSelector, 
-                                  const PRExplodedTime*  explodedTime, 
-                                  nsAString& stringOut) override; 
-
-  nsDateTimeFormatMac() {}
-
-protected:
-  virtual ~nsDateTimeFormatMac() {}
-
-private:
-  // init this interface to a specified locale
-  NS_IMETHOD Initialize(nsILocale* locale);
-
-  nsString    mLocale;
-  nsString    mAppLocale;
-  bool        mUseDefaultLocale;
-};
-
-#endif  /* nsDateTimeFormatMac_h__ */
--- a/intl/locale/moz.build
+++ b/intl/locale/moz.build
@@ -20,37 +20,44 @@ XPIDL_SOURCES += [
     'nsILocale.idl',
     'nsILocaleService.idl',
     'nsIScriptableDateFormat.idl',
 ]
 
 XPIDL_MODULE = 'locale'
 
 EXPORTS += [
+    'DateTimeFormat.h',
     'nsCollation.h',
     'nsCollationCID.h',
-    'nsDateTimeFormatCID.h',
-    'nsIDateTimeFormat.h',
     'nsILanguageAtomService.h',
     'nsIPlatformCharset.h',
     'nsPosixLocale.h',
     'nsUConvPropertySearch.h',
     'nsWin32Locale.h',
 ]
 
 UNIFIED_SOURCES += [
     'nsCollation.cpp',
-    'nsIDateTimeFormat.cpp',
     'nsLanguageAtomService.cpp',
     'nsLocale.cpp',
     'nsLocaleService.cpp',
     'nsScriptableDateFormat.cpp',
     'nsUConvPropertySearch.cpp',
 ]
 
+if CONFIG['ENABLE_INTL_API']:
+    UNIFIED_SOURCES += [
+        'DateTimeFormatICU.cpp',
+    ]
+else:
+    UNIFIED_SOURCES += [
+        'DateTimeFormatUnix.cpp',
+    ]
+
 EXTRA_JS_MODULES += [
     'PluralForm.jsm',
 ]
 
 FINAL_LIBRARY = 'xul'
 
 LOCAL_INCLUDES += [
     '/intl/uconv',
deleted file mode 100644
--- a/intl/locale/nsDateTimeFormatCID.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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 nsDateTimeFormatCID_h__
-#define nsDateTimeFormatCID_h__
-
-
-#include "nscore.h"
-#include "nsISupports.h"
-
-#define NS_DATETIMEFORMAT_CONTRACTID "@mozilla.org/intl/datetimeformat;1"
-
-// {0704E7C0-A758-11d2-9119-006008A6EDF6}
-#define NS_DATETIMEFORMAT_CID \
-{ 0x704e7c0, 0xa758, 0x11d2, \
-{ 0x91, 0x19, 0x0, 0x60, 0x8, 0xa6, 0xed, 0xf6 } }
-
-#endif  // nsDateTimeFormatCID_h__
-
deleted file mode 100644
--- a/intl/locale/nsIDateTimeFormat.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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 "nsIDateTimeFormat.h"
-#include "mozilla/RefPtr.h"
-
-#if defined(XP_MACOSX)
-#define USE_MAC_LOCALE
-#elif defined(XP_UNIX)
-#define USE_UNIX_LOCALE
-#endif
-
-#ifdef XP_WIN
-#include "windows/nsDateTimeFormatWin.h"
-#endif
-#ifdef USE_UNIX_LOCALE
-#include "unix/nsDateTimeFormatUnix.h"
-#endif
-#ifdef USE_MAC_LOCALE
-#include "mac/nsDateTimeFormatMac.h"
-#endif
-
-using mozilla::MakeAndAddRef;
-
-/*static*/ already_AddRefed<nsIDateTimeFormat>
-nsIDateTimeFormat::Create()
-{
-#ifdef XP_WIN
-  return MakeAndAddRef<nsDateTimeFormatWin>();
-#elif defined(USE_UNIX_LOCALE)
-  return MakeAndAddRef<nsDateTimeFormatUnix>();
-#elif defined(USE_MAC_LOCALE)
-  return MakeAndAddRef<nsDateTimeFormatMac>();
-#else
-  return nullptr;
-#endif
-}
deleted file mode 100644
--- a/intl/locale/nsIDateTimeFormat.h
+++ /dev/null
@@ -1,69 +0,0 @@
-
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * 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 nsIDateTimeFormat_h__
-#define nsIDateTimeFormat_h__
-
-
-#include "nsISupports.h"
-#include "nscore.h"
-#include "nsStringGlue.h"
-#include "nsILocale.h"
-#include "nsIScriptableDateFormat.h"
-#include "prtime.h"
-#include <time.h>
-
-
-// {2BBAA0B0-A591-11d2-9119-006008A6EDF6}
-#define NS_IDATETIMEFORMAT_IID \
-{ 0x2bbaa0b0, 0xa591, 0x11d2, \
-{ 0x91, 0x19, 0x0, 0x60, 0x8, 0xa6, 0xed, 0xf6 } }
-
-
-// Locale sensitive date and time format interface
-// 
-class nsIDateTimeFormat : public nsISupports {
-protected:
-  nsIDateTimeFormat() {}
-  virtual ~nsIDateTimeFormat() {}
-
-public: 
-  NS_DECLARE_STATIC_IID_ACCESSOR(NS_IDATETIMEFORMAT_IID)
-
-  static already_AddRefed<nsIDateTimeFormat> Create();
-
-  // performs a locale sensitive date formatting operation on the time_t parameter
-  NS_IMETHOD FormatTime(nsILocale* locale, 
-                        const nsDateFormatSelector  dateFormatSelector, 
-                        const nsTimeFormatSelector timeFormatSelector, 
-                        const time_t  timetTime,
-                        nsAString& stringOut) = 0; 
-
-  // performs a locale sensitive date formatting operation on the struct tm parameter
-  NS_IMETHOD FormatTMTime(nsILocale* locale, 
-                          const nsDateFormatSelector  dateFormatSelector, 
-                          const nsTimeFormatSelector timeFormatSelector, 
-                          const struct tm*  tmTime, 
-                          nsAString& stringOut) = 0; 
-
-  // performs a locale sensitive date formatting operation on the PRTime parameter
-  NS_IMETHOD FormatPRTime(nsILocale* locale, 
-                          const nsDateFormatSelector  dateFormatSelector, 
-                          const nsTimeFormatSelector timeFormatSelector, 
-                          const PRTime  prTime, 
-                          nsAString& stringOut) = 0;
-
-  // performs a locale sensitive date formatting operation on the PRExplodedTime parameter
-  NS_IMETHOD FormatPRExplodedTime(nsILocale* locale, 
-                                  const nsDateFormatSelector  dateFormatSelector, 
-                                  const nsTimeFormatSelector timeFormatSelector, 
-                                  const PRExplodedTime*  explodedTime, 
-                                  nsAString& stringOut) = 0; 
-};
-
-NS_DEFINE_STATIC_IID_ACCESSOR(nsIDateTimeFormat, NS_IDATETIMEFORMAT_IID)
-
-#endif  /* nsIDateTimeFormat_h__ */
--- a/intl/locale/nsLocaleConstructors.h
+++ b/intl/locale/nsLocaleConstructors.h
@@ -2,17 +2,16 @@
 /* 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 nsLocaleConstructors_h__
 #define nsLocaleConstructors_h__
 
 #include "nsCollationCID.h"
-#include "nsDateTimeFormatCID.h"
 #include "mozilla/ModuleUtils.h"
 #include "nsILocaleService.h"
 #include "nsIScriptableDateFormat.h"
 #include "nsIServiceManager.h"
 #include "nsLanguageAtomService.h"
 #include "nsPlatformCharset.h"
 
 #if defined(XP_MACOSX)
@@ -20,27 +19,24 @@
 #endif
 
 #if defined(XP_UNIX) && !defined(XP_MACOSX)
 #define USE_UNIX_LOCALE
 #endif
 
 #ifdef XP_WIN
 #include "windows/nsCollationWin.h"
-#include "windows/nsDateTimeFormatWin.h"
 #endif
 
 #ifdef USE_MAC_LOCALE
 #include "mac/nsCollationMacUC.h"
-#include "mac/nsDateTimeFormatMac.h"
 #endif
 
 #ifdef USE_UNIX_LOCALE
 #include "unix/nsCollationUnix.h"
-#include "unix/nsDateTimeFormatUnix.h"
 #endif
 
 #define NSLOCALE_MAKE_CTOR(ctor_, iface_, func_)          \
 static nsresult                                           \
 ctor_(nsISupports* aOuter, REFNSIID aIID, void** aResult) \
 {                                                         \
   *aResult = nullptr;                                      \
   if (aOuter)                                             \
@@ -58,22 +54,19 @@ ctor_(nsISupports* aOuter, REFNSIID aIID
 NSLOCALE_MAKE_CTOR(CreateLocaleService, nsILocaleService, NS_NewLocaleService)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsCollationFactory)
 //NS_GENERIC_FACTORY_CONSTRUCTOR(nsScriptableDateTimeFormat)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsLanguageAtomService)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPlatformCharset, Init)
 
 #ifdef XP_WIN
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsCollationWin)
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsDateTimeFormatWin)
 #endif
 
 #ifdef USE_UNIX_LOCALE
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsCollationUnix)
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsDateTimeFormatUnix)
 #endif  
 
 #ifdef USE_MAC_LOCALE
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsCollationMacUC)
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsDateTimeFormatMac)
 #endif  
 
 #endif
--- a/intl/locale/nsScriptableDateFormat.cpp
+++ b/intl/locale/nsScriptableDateFormat.cpp
@@ -1,23 +1,21 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* 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 "DateTimeFormat.h"
 #include "mozilla/Sprintf.h"
 #include "nsILocaleService.h"
-#include "nsDateTimeFormatCID.h"
-#include "nsIDateTimeFormat.h"
 #include "nsIScriptableDateFormat.h"
 #include "nsCOMPtr.h"
 #include "nsServiceManagerUtils.h"
 
 static NS_DEFINE_CID(kLocaleServiceCID, NS_LOCALESERVICE_CID);
-static NS_DEFINE_CID(kDateTimeFormatCID, NS_DATETIMEFORMAT_CID);
 
 class nsScriptableDateFormat : public nsIScriptableDateFormat {
  public: 
   NS_DECL_ISUPPORTS 
 
   NS_IMETHOD FormatDateTime(const char16_t *locale, 
                             nsDateFormatSelector dateFormatSelector, 
                             nsTimeFormatSelector timeFormatSelector, 
@@ -84,47 +82,44 @@ NS_IMETHODIMP nsScriptableDateFormat::Fo
     // get locale service
     nsCOMPtr<nsILocaleService> localeService(do_GetService(kLocaleServiceCID, &rv));
     NS_ENSURE_SUCCESS(rv, rv);
     // get locale
     rv = localeService->NewLocale(localeName, getter_AddRefs(locale));
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
-  nsCOMPtr<nsIDateTimeFormat> dateTimeFormat(do_CreateInstance(kDateTimeFormatCID, &rv));
-  NS_ENSURE_SUCCESS(rv, rv);
-
   tm tmTime;
   time_t timetTime;
 
   memset(&tmTime, 0, sizeof(tmTime));
   tmTime.tm_year = year - 1900;
   tmTime.tm_mon = month - 1;
   tmTime.tm_mday = day;
   tmTime.tm_hour = hour;
   tmTime.tm_min = minute;
   tmTime.tm_sec = second;
   tmTime.tm_yday = tmTime.tm_wday = 0;
   tmTime.tm_isdst = -1;
   timetTime = mktime(&tmTime);
 
   if ((time_t)-1 != timetTime) {
-    rv = dateTimeFormat->FormatTime(locale, dateFormatSelector, timeFormatSelector, 
-                                     timetTime, mStringOut);
+    rv = mozilla::DateTimeFormat::FormatTime(dateFormatSelector, timeFormatSelector,
+                                             timetTime, mStringOut);
   }
   else {
     // if mktime fails (e.g. year <= 1970), then try NSPR.
     PRTime prtime;
     char string[32];
     SprintfLiteral(string, "%.2d/%.2d/%d %.2d:%.2d:%.2d", month, day, year, hour, minute, second);
     if (PR_SUCCESS != PR_ParseTimeString(string, false, &prtime))
       return NS_ERROR_INVALID_ARG;
 
-    rv = dateTimeFormat->FormatPRTime(locale, dateFormatSelector, timeFormatSelector, 
-                                      prtime, mStringOut);
+    rv = mozilla::DateTimeFormat::FormatPRTime(dateFormatSelector, timeFormatSelector,
+                                               prtime, mStringOut);
   }
   if (NS_SUCCEEDED(rv))
     *dateTimeString = ToNewUnicode(mStringOut);
 
   return rv;
 }
 
 nsresult
--- a/intl/locale/unix/moz.build
+++ b/intl/locale/unix/moz.build
@@ -1,17 +1,16 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 SOURCES += [
     'nsCollationUnix.cpp',
-    'nsDateTimeFormatUnix.cpp',
     'nsPosixLocale.cpp',
 ]
 
 if CONFIG['OS_TARGET'] == 'Android':
     SOURCES += [
         'nsAndroidCharset.cpp',
     ]
 else:
deleted file mode 100644
--- a/intl/locale/unix/nsDateTimeFormatUnix.h
+++ /dev/null
@@ -1,70 +0,0 @@
-
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * 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 nsDateTimeFormatUnix_h__
-#define nsDateTimeFormatUnix_h__
-
-
-#include "nsCOMPtr.h"
-#include "nsIDateTimeFormat.h"
-#include "nsIUnicodeDecoder.h"
-
-#define kPlatformLocaleLength 64
-
-class nsDateTimeFormatUnix : public nsIDateTimeFormat {
-
-public: 
-  NS_DECL_THREADSAFE_ISUPPORTS 
-
-  // performs a locale sensitive date formatting operation on the time_t parameter
-  NS_IMETHOD FormatTime(nsILocale* locale, 
-                        const nsDateFormatSelector  dateFormatSelector, 
-                        const nsTimeFormatSelector timeFormatSelector, 
-                        const time_t  timetTime, 
-                        nsAString& stringOut) override;
-
-  // performs a locale sensitive date formatting operation on the struct tm parameter
-  NS_IMETHOD FormatTMTime(nsILocale* locale, 
-                        const nsDateFormatSelector  dateFormatSelector, 
-                        const nsTimeFormatSelector timeFormatSelector, 
-                        const struct tm*  tmTime, 
-                        nsAString& stringOut) override;
-
-  // performs a locale sensitive date formatting operation on the PRTime parameter
-  NS_IMETHOD FormatPRTime(nsILocale* locale, 
-                          const nsDateFormatSelector  dateFormatSelector, 
-                          const nsTimeFormatSelector timeFormatSelector, 
-                          const PRTime  prTime, 
-                          nsAString& stringOut) override;
-
-  // performs a locale sensitive date formatting operation on the PRExplodedTime parameter
-  NS_IMETHOD FormatPRExplodedTime(nsILocale* locale, 
-                                  const nsDateFormatSelector  dateFormatSelector, 
-                                  const nsTimeFormatSelector timeFormatSelector, 
-                                  const PRExplodedTime*  explodedTime, 
-                                  nsAString& stringOut) override;
-
-
-  nsDateTimeFormatUnix() {mLocale.Truncate();mAppLocale.Truncate();}
-
-private:
-  virtual ~nsDateTimeFormatUnix() {}
-
-  // init this interface to a specified locale
-  NS_IMETHOD Initialize(nsILocale* locale);
-
-  void LocalePreferred24hour();
-
-  nsString    mLocale;
-  nsString    mAppLocale;
-  nsCString   mCharset;        // in order to convert API result to unicode
-  nsCString   mPlatformLocale; // for setlocale
-  bool        mLocalePreferred24hour;                       // true if 24 hour format is preferred by current locale
-  bool        mLocaleAMPMfirst;                             // true if AM/PM string is preferred before the time
-  nsCOMPtr <nsIUnicodeDecoder>   mDecoder;
-};
-
-#endif  /* nsDateTimeFormatUnix_h__ */
--- a/intl/locale/windows/moz.build
+++ b/intl/locale/windows/moz.build
@@ -1,17 +1,16 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 SOURCES += [
     'nsCollationWin.cpp',
-    'nsDateTimeFormatWin.cpp',
     'nsWin32Locale.cpp',
     'nsWinCharset.cpp',
 ]
 
 FINAL_LIBRARY = 'xul'
 
 GENERATED_FILES = [
     'wincharset.properties.h',
deleted file mode 100644
--- a/intl/locale/windows/nsDateTimeFormatWin.cpp
+++ /dev/null
@@ -1,253 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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 "nsDateTimeFormatWin.h"
-#include "nsIServiceManager.h"
-#include "nsIComponentManager.h"
-#include "nsILocaleService.h"
-#include "nsWin32Locale.h"
-#include "nsUnicharUtils.h"
-#include "nsCRT.h"
-#include "nsCOMPtr.h"
-
-
-#define NSDATETIMEFORMAT_BUFFER_LEN  80
-
-NS_IMPL_ISUPPORTS(nsDateTimeFormatWin, nsIDateTimeFormat)
-
-
-// init this interface to a specified locale
-nsresult nsDateTimeFormatWin::Initialize(nsILocale* locale)
-{
-  nsAutoString localeStr;
-  nsresult res = NS_OK;
-
-  // use cached info if match with stored locale
-  if (!locale) {
-    if (!mLocale.IsEmpty() && 
-        mLocale.Equals(mAppLocale, nsCaseInsensitiveStringComparator())) {
-      return NS_OK;
-    }
-  }
-  else {
-    res = locale->GetCategory(NS_LITERAL_STRING("NSILOCALE_TIME"), localeStr);
-    if (NS_SUCCEEDED(res) && !localeStr.IsEmpty()) {
-      if (!mLocale.IsEmpty() && 
-          mLocale.Equals(localeStr, nsCaseInsensitiveStringComparator())) {
-        return NS_OK;
-      }
-    }
-  }
-
-  // default LCID (en-US)
-  mLCID = 1033;
-
-  // get locale string, use app default if no locale specified
-  if (!locale) {
-    nsCOMPtr<nsILocaleService> localeService = 
-             do_GetService(NS_LOCALESERVICE_CONTRACTID);
-    if (localeService) {
-      nsCOMPtr<nsILocale> appLocale;
-      res = localeService->GetApplicationLocale(getter_AddRefs(appLocale));
-      if (NS_SUCCEEDED(res)) {
-        res = appLocale->GetCategory(NS_LITERAL_STRING("NSILOCALE_TIME"), 
-			             localeStr);
-        if (NS_SUCCEEDED(res) && !localeStr.IsEmpty()) {
-          mAppLocale.Assign(localeStr); // cache app locale name
-        }
-      }
-    }
-  }
-  else {
-    res = locale->GetCategory(NS_LITERAL_STRING("NSILOCALE_TIME"), localeStr);
-  }
-
-  // Get LCID and charset name from locale, if available
-  if (NS_SUCCEEDED(res) && !localeStr.IsEmpty()) {
-    mLocale.Assign(localeStr); // cache locale name
-    res = nsWin32Locale::GetPlatformLocale(mLocale, (LCID *) &mLCID);
-  }
-
-  return res;
-}
-
-// performs a locale sensitive date formatting operation on the time_t parameter
-nsresult nsDateTimeFormatWin::FormatTime(nsILocale* locale, 
-                                         const nsDateFormatSelector  dateFormatSelector, 
-                                         const nsTimeFormatSelector timeFormatSelector, 
-                                         const time_t  timetTime, 
-                                         nsAString& stringOut)
-{
-  return FormatTMTime(locale, dateFormatSelector, timeFormatSelector, localtime( &timetTime ), stringOut);
-}
-
-// performs a locale sensitive date formatting operation on the struct tm parameter
-nsresult nsDateTimeFormatWin::FormatTMTime(nsILocale* locale, 
-                                           const nsDateFormatSelector  dateFormatSelector, 
-                                           const nsTimeFormatSelector timeFormatSelector, 
-                                           const struct tm*  tmTime, 
-                                           nsAString& stringOut)
-{
-  SYSTEMTIME system_time;
-  DWORD dwFlags_Date = 0, dwFlags_Time = 0;
-  int dateLen, timeLen;
-  char16_t dateBuffer[NSDATETIMEFORMAT_BUFFER_LEN], timeBuffer[NSDATETIMEFORMAT_BUFFER_LEN];
-
-  // set up locale data
-  (void) Initialize(locale);
-
-  // Map tm to SYSTEMTIME
-  system_time.wYear = 1900 + tmTime->tm_year;
-  system_time.wMonth = tmTime->tm_mon + 1;
-  system_time.wDayOfWeek = tmTime->tm_wday;
-  system_time.wDay = tmTime->tm_mday;
-  system_time.wHour = tmTime->tm_hour;
-  system_time.wMinute = tmTime->tm_min;
-  system_time.wSecond = tmTime->tm_sec;
-  system_time.wMilliseconds = 0;
-
-  // Map to WinAPI date format
-  switch (dateFormatSelector) {
-  case kDateFormatLong:
-    dwFlags_Date = DATE_LONGDATE;
-    break;
-  case kDateFormatShort:
-    dwFlags_Date = DATE_SHORTDATE;
-    break;
-  case kDateFormatWeekday:
-    dwFlags_Date = 0;
-    break;
-  case kDateFormatYearMonth:
-    dwFlags_Date = 0;     // TODO:only availabe NT5
-    break;
-  }
-
-  // Map to WinAPI time format
-  switch (timeFormatSelector) {
-  case kTimeFormatSeconds:
-    dwFlags_Time = 0;
-    break;
-  case kTimeFormatNoSeconds:
-    dwFlags_Time = TIME_NOSECONDS;
-    break;
-  case kTimeFormatSecondsForce24Hour:
-    dwFlags_Time = TIME_FORCE24HOURFORMAT;
-    break;
-  case kTimeFormatNoSecondsForce24Hour:
-    dwFlags_Time = TIME_NOSECONDS + TIME_FORCE24HOURFORMAT;
-    break;
-  }
-
-  // Call GetDateFormatW
-  if (dateFormatSelector == kDateFormatNone) {
-    dateLen = 0;
-  }
-  else {
-    if (dateFormatSelector == kDateFormatYearMonth) {
-      dateLen = nsGetDateFormatW(0, &system_time, "yyyy/MM", 
-                                 dateBuffer, NSDATETIMEFORMAT_BUFFER_LEN);
-    }
-    else if (dateFormatSelector == kDateFormatWeekday) {
-      dateLen = nsGetDateFormatW(0, &system_time, "ddd", 
-                                 dateBuffer, NSDATETIMEFORMAT_BUFFER_LEN);
-    }
-    else {
-      dateLen = nsGetDateFormatW(dwFlags_Date, &system_time, nullptr,
-                                 dateBuffer, NSDATETIMEFORMAT_BUFFER_LEN);
-    }
-    if (dateLen != 0) {
-      dateLen--;  // Since the count includes the terminating null.
-    }
-  }
-
-  // Call GetTimeFormatW
-  if (timeFormatSelector == kTimeFormatNone) {
-    timeLen = 0;
-  }
-  else {
-    timeLen = nsGetTimeFormatW(dwFlags_Time, &system_time, nullptr, 
-                               timeBuffer, NSDATETIMEFORMAT_BUFFER_LEN);
-    if (timeLen != 0) {
-      timeLen--;  // Since the count includes the terminating null.
-    }
-  }
-
-  NS_ASSERTION(NSDATETIMEFORMAT_BUFFER_LEN >= (uint32_t) (dateLen + 1), "internal date buffer is not large enough");
-  NS_ASSERTION(NSDATETIMEFORMAT_BUFFER_LEN >= (uint32_t) (timeLen + 1), "internal time buffer is not large enough");
-
-  // Copy the result
-  stringOut.Truncate();
-  if (dateLen != 0 && timeLen != 0) {
-    stringOut.Assign(dateBuffer, dateLen);
-    stringOut.Append((char16_t *)(L" "), 1);
-    stringOut.Append(timeBuffer, timeLen);
-  }
-  else if (dateLen != 0 && timeLen == 0) {
-    stringOut.Assign(dateBuffer, dateLen);
-  }
-  else if (dateLen == 0 && timeLen != 0) {
-    stringOut.Assign(timeBuffer, timeLen);
-  }
-
-  return NS_OK;
-}
-
-// performs a locale sensitive date formatting operation on the PRTime parameter
-nsresult nsDateTimeFormatWin::FormatPRTime(nsILocale* locale, 
-                                           const nsDateFormatSelector  dateFormatSelector, 
-                                           const nsTimeFormatSelector timeFormatSelector, 
-                                           const PRTime  prTime, 
-                                           nsAString& stringOut)
-{
-  PRExplodedTime explodedTime;
-  PR_ExplodeTime(prTime, PR_LocalTimeParameters, &explodedTime);
-
-  return FormatPRExplodedTime(locale, dateFormatSelector, timeFormatSelector, &explodedTime, stringOut);
-}
-
-// performs a locale sensitive date formatting operation on the PRExplodedTime parameter
-nsresult nsDateTimeFormatWin::FormatPRExplodedTime(nsILocale* locale, 
-                                                   const nsDateFormatSelector  dateFormatSelector, 
-                                                   const nsTimeFormatSelector timeFormatSelector, 
-                                                   const PRExplodedTime*  explodedTime, 
-                                                   nsAString& stringOut)
-{
-  struct tm  tmTime;
-  memset( &tmTime, 0, sizeof(tmTime) );
-
-  tmTime.tm_yday = explodedTime->tm_yday;
-  tmTime.tm_wday = explodedTime->tm_wday;
-  tmTime.tm_year = explodedTime->tm_year;
-  tmTime.tm_year -= 1900;
-  tmTime.tm_mon = explodedTime->tm_month;
-  tmTime.tm_mday = explodedTime->tm_mday;
-  tmTime.tm_hour = explodedTime->tm_hour;
-  tmTime.tm_min = explodedTime->tm_min;
-  tmTime.tm_sec = explodedTime->tm_sec;
-
-  return FormatTMTime(locale, dateFormatSelector, timeFormatSelector, &tmTime, stringOut);
-}
-
-int nsDateTimeFormatWin::nsGetTimeFormatW(DWORD dwFlags, const SYSTEMTIME *lpTime,
-                                          const char* format, char16_t *timeStr, int cchTime)
-{
-  int len = 0;
-  len = GetTimeFormatW(mLCID, dwFlags, lpTime, 
-                       format ?
-                       NS_ConvertASCIItoUTF16(format).get() :
-                       nullptr,
-                       (LPWSTR) timeStr, cchTime);
-  return len;
-}
-
-int nsDateTimeFormatWin::nsGetDateFormatW(DWORD dwFlags, const SYSTEMTIME *lpDate,
-                                          const char* format, char16_t *dateStr, int cchDate)
-{
-  int len = 0;
-  len = GetDateFormatW(mLCID, dwFlags, lpDate, 
-                       format ? NS_ConvertASCIItoUTF16(format).get() : nullptr,
-                       (LPWSTR) dateStr, cchDate);
-  return len;
-}
deleted file mode 100644
--- a/intl/locale/windows/nsDateTimeFormatWin.h
+++ /dev/null
@@ -1,71 +0,0 @@
-
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * 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 nsDateTimeFormatWin_h__
-#define nsDateTimeFormatWin_h__
-
-
-#include "nsIDateTimeFormat.h"
-#include <windows.h>
-
-
-// Locale sensitive date and time format interface
-// 
-class nsDateTimeFormatWin : public nsIDateTimeFormat {
-  virtual ~nsDateTimeFormatWin() {}
-
-public: 
-  NS_DECL_THREADSAFE_ISUPPORTS 
-
-  // performs a locale sensitive date formatting operation on the time_t parameter
-  NS_IMETHOD FormatTime(nsILocale* locale, 
-                        const nsDateFormatSelector  dateFormatSelector, 
-                        const nsTimeFormatSelector timeFormatSelector, 
-                        const time_t  timetTime, 
-                        nsAString& stringOut); 
-
-  // performs a locale sensitive date formatting operation on the struct tm parameter
-  NS_IMETHOD FormatTMTime(nsILocale* locale, 
-                          const nsDateFormatSelector  dateFormatSelector, 
-                          const nsTimeFormatSelector timeFormatSelector, 
-                          const struct tm*  tmTime, 
-                          nsAString& stringOut); 
-
-  // performs a locale sensitive date formatting operation on the PRTime parameter
-  NS_IMETHOD FormatPRTime(nsILocale* locale, 
-                          const nsDateFormatSelector  dateFormatSelector, 
-                          const nsTimeFormatSelector timeFormatSelector, 
-                          const PRTime  prTime, 
-                          nsAString& stringOut);
-
-  // performs a locale sensitive date formatting operation on the PRExplodedTime parameter
-  NS_IMETHOD FormatPRExplodedTime(nsILocale* locale, 
-                                  const nsDateFormatSelector  dateFormatSelector, 
-                                  const nsTimeFormatSelector timeFormatSelector, 
-                                  const PRExplodedTime*  explodedTime, 
-                                  nsAString& stringOut); 
-
-  nsDateTimeFormatWin() {mLocale.SetLength(0);mAppLocale.SetLength(0);}
-
-
-private:
-  // init this interface to a specified locale
-  NS_IMETHOD Initialize(nsILocale* locale);
-
-  // call GetTimeFormatW or TimeFormatA
-  int nsGetTimeFormatW(DWORD dwFlags, const SYSTEMTIME *lpTime,
-                    const char* format, char16_t *timeStr, int cchTime);
-
-  // call GetDateFormatW or GetDateFormatA
-  int nsGetDateFormatW(DWORD dwFlags, const SYSTEMTIME *lpDate,
-                       const char* format, char16_t *dateStr, int cchDate);
-
-  nsString    mLocale;
-  nsString    mAppLocale;
-  uint32_t    mLCID;             // Windows platform locale ID
-};
-
-#endif  /* nsDateTimeFormatWin_h__ */
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -4716,16 +4716,25 @@ nsCSSFrameConstructor::FindDisplayData(c
                             !aElement->IsInNativeAnonymousSubtree();
       if (!suppressScrollFrame) {
         static const FrameConstructionData sScrollableBlockData[2] =
           { FULL_CTOR_FCDATA(0, &nsCSSFrameConstructor::ConstructScrollableBlock),
             FULL_CTOR_FCDATA(kCaptionCtorFlags,
                              &nsCSSFrameConstructor::ConstructScrollableBlock) };
         return &sScrollableBlockData[caption];
       }
+
+      // If the scrollable frame would have propagated its scrolling to the
+      // viewport, we still want to construct a regular block rather than a
+      // scrollframe so that it paginates correctly, but we don't want to set
+      // the bit on the block that tells it to clip at paint time.
+      if (mPresShell->GetPresContext()->
+            ElementWouldPropagateScrollbarStyles(aElement)) {
+        suppressScrollFrame = false;
+      }
     }
 
     // Handle various non-scrollable blocks.
     static const FrameConstructionData sNonScrollableBlockData[2][2] = {
       { FULL_CTOR_FCDATA(0,
                          &nsCSSFrameConstructor::ConstructNonScrollableBlock),
         FULL_CTOR_FCDATA(kCaptionCtorFlags,
                          &nsCSSFrameConstructor::ConstructNonScrollableBlock) },
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -1360,25 +1360,16 @@ CheckOverflow(const nsStyleDisplay* aDis
   }
   return true;
 }
 
 static nsIContent*
 GetPropagatedScrollbarStylesForViewport(nsPresContext* aPresContext,
                                         ScrollbarStyles *aStyles)
 {
-  // Set default
-  *aStyles = ScrollbarStyles(NS_STYLE_OVERFLOW_AUTO, NS_STYLE_OVERFLOW_AUTO);
-
-  // We never mess with the viewport scroll state
-  // when printing or in print preview
-  if (aPresContext->IsPaginated()) {
-    return nullptr;
-  }
-
   nsIDocument* document = aPresContext->Document();
   Element* docElement = document->GetRootElement();
 
   // docElement might be null if we're doing this after removing it.
   if (!docElement) {
     return nullptr;
   }
 
@@ -1425,18 +1416,25 @@ GetPropagatedScrollbarStylesForViewport(
   }
 
   return nullptr;
 }
 
 nsIContent*
 nsPresContext::UpdateViewportScrollbarStylesOverride()
 {
-  nsIContent* propagatedFrom =
-    GetPropagatedScrollbarStylesForViewport(this, &mViewportStyleScrollbar);
+  // Start off with our default styles, and then update them as needed.
+  mViewportStyleScrollbar = ScrollbarStyles(NS_STYLE_OVERFLOW_AUTO,
+                                            NS_STYLE_OVERFLOW_AUTO);
+  nsIContent* propagatedFrom = nullptr;
+  // Don't propagate the scrollbar state in printing or print preview.
+  if (!IsPaginated()) {
+    propagatedFrom =
+      GetPropagatedScrollbarStylesForViewport(this, &mViewportStyleScrollbar);
+  }
 
   nsIDocument* document = Document();
   if (Element* fullscreenElement = document->GetFullscreenElement()) {
     // If the document is in fullscreen, but the fullscreen element is
     // not the root element, we should explicitly suppress the scrollbar
     // here. Note that, we still need to return the original element
     // the styles are from, so that the state of those elements is not
     // affected across fullscreen change.
@@ -1445,16 +1443,34 @@ nsPresContext::UpdateViewportScrollbarSt
       mViewportStyleScrollbar = ScrollbarStyles(NS_STYLE_OVERFLOW_HIDDEN,
                                                 NS_STYLE_OVERFLOW_HIDDEN);
     }
   }
 
   return propagatedFrom;
 }
 
+bool
+nsPresContext::ElementWouldPropagateScrollbarStyles(Element* aElement)
+{
+  MOZ_ASSERT(IsPaginated(), "Should only be called on paginated contexts");
+  if (aElement->GetParent() && !aElement->IsHTMLElement(nsGkAtoms::body)) {
+    // We certainly won't be propagating from this element.
+    return false;
+  }
+
+  // Go ahead and just call GetPropagatedScrollbarStylesForViewport, but update
+  // a dummy ScrollbarStyles we don't care about.  It'll do a bit of extra work,
+  // but saves us having to have more complicated code or more code duplication;
+  // in practice we will make this call quite rarely, because we checked for all
+  // the common cases above.
+  ScrollbarStyles dummy(NS_STYLE_OVERFLOW_AUTO, NS_STYLE_OVERFLOW_AUTO);
+  return GetPropagatedScrollbarStylesForViewport(this, &dummy) == aElement;
+}
+
 void
 nsPresContext::SetContainer(nsIDocShell* aDocShell)
 {
   if (aDocShell) {
     NS_ASSERTION(!(mContainer && mNeedsPrefUpdate),
                  "Should only need pref update if mContainer is null.");
     mContainer = static_cast<nsDocShell*>(aDocShell);
     if (mNeedsPrefUpdate) {
--- a/layout/base/nsPresContext.h
+++ b/layout/base/nsPresContext.h
@@ -72,16 +72,19 @@ class gfxMissingFontRecorder;
 namespace mozilla {
 class EffectCompositor;
 class EventStateManager;
 class CounterStyleManager;
 namespace layers {
 class ContainerLayer;
 class LayerManager;
 } // namespace layers
+namespace dom {
+class Element;
+} // namespace dom
 } // namespace mozilla
 
 // supported values for cached bool types
 enum nsPresContext_CachedBoolPrefType {
   kPresContext_UseDocumentFonts = 1,
   kPresContext_UnderlineLinks
 };
 
@@ -717,16 +720,22 @@ public:
    */
   nsIContent* UpdateViewportScrollbarStylesOverride();
   const ScrollbarStyles& GetViewportScrollbarStylesOverride()
   {
     return mViewportStyleScrollbar;
   }
 
   /**
+   * Check whether the given element would propagate its scrollbar styles to the
+   * viewport in non-paginated mode.  Must only be called if IsPaginated().
+   */
+  bool ElementWouldPropagateScrollbarStyles(mozilla::dom::Element* aElement);
+
+  /**
    * Set and get methods for controlling the background drawing
   */
   bool GetBackgroundImageDraw() const { return mDrawImageBackground; }
   void   SetBackgroundImageDraw(bool aCanDraw)
   {
     mDrawImageBackground = aCanDraw;
   }
 
--- a/layout/build/nsLayoutStatics.cpp
+++ b/layout/build/nsLayoutStatics.cpp
@@ -2,16 +2,17 @@
  * 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 "base/basictypes.h"
 
 #include "nsLayoutStatics.h"
 #include "nscore.h"
 
+#include "DateTimeFormat.h"
 #include "nsAttrValue.h"
 #include "nsAutoCopyListener.h"
 #include "nsColorNames.h"
 #include "nsComputedDOMStyle.h"
 #include "nsContentDLF.h"
 #include "nsContentUtils.h"
 #include "nsCSSAnonBoxes.h"
 #include "mozilla/css/ErrorReporter.h"
@@ -418,16 +419,18 @@ nsLayoutStatics::Shutdown()
 
   HTMLInputElement::DestroyUploadLastDir();
 
   nsLayoutUtils::Shutdown();
 
   nsHyphenationManager::Shutdown();
   nsDOMMutationObserver::Shutdown();
 
+  DateTimeFormat::Shutdown();
+
   ContentParent::ShutDown();
 
   DisplayItemClip::Shutdown();
 
   CustomElementRegistry::XPCOMShutdown();
 
   CacheObserver::Shutdown();
 
--- a/layout/generic/nsSimplePageSequenceFrame.cpp
+++ b/layout/generic/nsSimplePageSequenceFrame.cpp
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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 "nsSimplePageSequenceFrame.h"
 
+#include "DateTimeFormat.h"
 #include "nsCOMPtr.h"
 #include "nsDeviceContext.h"
 #include "nsPresContext.h"
 #include "gfxContext.h"
 #include "nsRenderingContext.h"
 #include "nsGkAtoms.h"
 #include "nsIPresShell.h"
 #include "nsIPrintSettings.h"
@@ -17,17 +18,16 @@
 #include "nsSubDocumentFrame.h"
 #include "nsRegion.h"
 #include "nsCSSFrameConstructor.h"
 #include "nsContentUtils.h"
 #include "nsDisplayList.h"
 #include "nsHTMLCanvasFrame.h"
 #include "mozilla/dom/HTMLCanvasElement.h"
 #include "nsICanvasRenderingContextInternal.h"
-#include "nsIDateTimeFormat.h"
 #include "nsServiceManagerUtils.h"
 #include <algorithm>
 
 #define OFFSET_NOT_SET -1
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
@@ -294,28 +294,20 @@ nsSimplePageSequenceFrame::Reflow(nsPres
     MOZ_ASSERT(e.get()->GetType() == nsGkAtoms::pageFrame,
                "only expecting nsPageFrame children. Other children will make "
                "this static_cast bogus & probably violate other assumptions");
     nsPageFrame* pf = static_cast<nsPageFrame*>(e.get());
     pf->SetPageNumInfo(pageNum, pageTot);
     pageNum++;
   }
 
-  // Create current Date/Time String
-  if (!mDateFormatter) {
-    mDateFormatter = nsIDateTimeFormat::Create();
-  }
-  if (!mDateFormatter) {
-    return;
-  }
   nsAutoString formattedDateString;
   time_t ltime;
   time( &ltime );
-  if (NS_SUCCEEDED(mDateFormatter->FormatTime(nullptr /* nsILocale* locale */,
-                                              kDateFormatShort,
+  if (NS_SUCCEEDED(DateTimeFormat::FormatTime(kDateFormatShort,
                                               kTimeFormatNoSeconds,
                                               ltime,
                                               formattedDateString))) {
     SetDateTimeStr(formattedDateString);
   }
 
   // Return our desired size
   // Adjust the reflow size by PrintPreviewScale so the scrollbars end up the
--- a/layout/generic/nsSimplePageSequenceFrame.h
+++ b/layout/generic/nsSimplePageSequenceFrame.h
@@ -5,18 +5,16 @@
 #ifndef nsSimplePageSequenceFrame_h___
 #define nsSimplePageSequenceFrame_h___
 
 #include "mozilla/Attributes.h"
 #include "nsIPageSequenceFrame.h"
 #include "nsContainerFrame.h"
 #include "nsIPrintSettings.h"
 
-class nsIDateTimeFormat;
-
 namespace mozilla {
 namespace dom {
 
 class HTMLCanvasElement;
 
 } // namespace dom
 } // namespace mozilla
 
@@ -134,19 +132,16 @@ protected:
                                  const nsMargin& aChildPhysicalMargin);
 
 
   void DetermineWhetherToPrintPage();
   nsIFrame* GetCurrentPageFrame();
 
   nsMargin mMargin;
 
-  // I18N date formatter service which we'll want to cache locally.
-  nsCOMPtr<nsIDateTimeFormat> mDateFormatter;
-
   nsSize       mSize;
   nsSharedPageData* mPageData; // data shared by all the nsPageFrames
 
   // Asynch Printing
   int32_t      mPageNum;
   int32_t      mTotalPages;
   int32_t      mPrintRangeType;
   int32_t      mFromPageNum;
--- a/layout/reftests/printing/129941-1-ref.html
+++ b/layout/reftests/printing/129941-1-ref.html
@@ -1,8 +1,10 @@
 <!DOCTYPE html>
 <html class="reftest-print" style="margin: 0; padding: 0">
   <body style="margin: 0; padding: 0">
-    <div style="height: 1.25in; border: 0.25in solid green"></div>
-    <div style="height: 1.25in; border: 0.25in solid green"></div>
-    <div style="height: 1.25in; border: 0.25in solid green; border-bottom: none"></div>
+    <div>
+      <div style="height: 1.25in; border: 0.25in solid green"></div>
+      <div style="height: 1.25in; border: 0.25in solid green"></div>
+      <div style="height: 1.25in; border: 0.25in solid green; border-bottom: none"></div>
+    </div>
   </body>
 </html>
--- a/layout/reftests/printing/129941-1a.html
+++ b/layout/reftests/printing/129941-1a.html
@@ -1,8 +1,10 @@
 <!DOCTYPE html>
 <html class="reftest-print" style="margin: 0; padding: 0;">
-  <body style="overflow: scroll; height: 5in; margin: 0; padding: 0;">
-    <div style="height: 1.25in; border: 0.25in solid green"></div>
-    <div style="height: 1.25in; border: 0.25in solid green"></div>
-    <div style="height: 1.25in; border: 0.25in solid green"></div>
+  <body style="margin: 0; padding: 0;">
+    <div style="overflow: scroll; height: 5in;">
+      <div style="height: 1.25in; border: 0.25in solid green"></div>
+      <div style="height: 1.25in; border: 0.25in solid green"></div>
+      <div style="height: 1.25in; border: 0.25in solid green"></div>
+    </div>
   </body>
 </html>
--- a/layout/reftests/printing/129941-1b.html
+++ b/layout/reftests/printing/129941-1b.html
@@ -1,8 +1,10 @@
 <!DOCTYPE html>
 <html class="reftest-print" style="margin: 0; padding: 0;">
-  <body style="overflow: -moz-hidden-unscrollable; height: 5in; margin: 0; padding: 0;">
-    <div style="height: 1.25in; border: 0.25in solid green"></div>
-    <div style="height: 1.25in; border: 0.25in solid green"></div>
-    <div style="height: 1.25in; border: 0.25in solid green"></div>
+  <body style="margin: 0; padding: 0;">
+    <div style="overflow: -moz-hidden-unscrollable; height: 5in;">
+      <div style="height: 1.25in; border: 0.25in solid green"></div>
+      <div style="height: 1.25in; border: 0.25in solid green"></div>
+      <div style="height: 1.25in; border: 0.25in solid green"></div>
+    </div>
   </body>
 </html>
copy from layout/reftests/printing/129941-1a.html
copy to layout/reftests/printing/129941-1c.html
--- a/layout/reftests/printing/129941-1a.html
+++ b/layout/reftests/printing/129941-1c.html
@@ -1,8 +1,10 @@
 <!DOCTYPE html>
-<html class="reftest-print" style="margin: 0; padding: 0;">
-  <body style="overflow: scroll; height: 5in; margin: 0; padding: 0;">
-    <div style="height: 1.25in; border: 0.25in solid green"></div>
-    <div style="height: 1.25in; border: 0.25in solid green"></div>
-    <div style="height: 1.25in; border: 0.25in solid green"></div>
+<html class="reftest-print" style="margin: 0; padding: 0; overflow: hidden">
+  <body style="margin: 0; padding: 0; overflow: scroll; height: 5in">
+    <div>
+      <div style="height: 1.25in; border: 0.25in solid green"></div>
+      <div style="height: 1.25in; border: 0.25in solid green"></div>
+      <div style="height: 1.25in; border: 0.25in solid green"></div>
+    </div>
   </body>
 </html>
copy from layout/reftests/printing/129941-1b.html
copy to layout/reftests/printing/129941-1d.html
--- a/layout/reftests/printing/129941-1b.html
+++ b/layout/reftests/printing/129941-1d.html
@@ -1,8 +1,10 @@
 <!DOCTYPE html>
-<html class="reftest-print" style="margin: 0; padding: 0;">
-  <body style="overflow: -moz-hidden-unscrollable; height: 5in; margin: 0; padding: 0;">
-    <div style="height: 1.25in; border: 0.25in solid green"></div>
-    <div style="height: 1.25in; border: 0.25in solid green"></div>
-    <div style="height: 1.25in; border: 0.25in solid green"></div>
+<html class="reftest-print" style="margin: 0; padding: 0; overflow: hidden">
+  <body style="margin: 0; padding: 0; overflow: -moz-hidden-unscrollable; height: 5in;">
+    <div>
+      <div style="height: 1.25in; border: 0.25in solid green"></div>
+      <div style="height: 1.25in; border: 0.25in solid green"></div>
+      <div style="height: 1.25in; border: 0.25in solid green"></div>
+    </div>
   </body>
 </html>
copy from layout/reftests/printing/129941-1b.html
copy to layout/reftests/printing/129941-1e.html
--- a/layout/reftests/printing/129941-1b.html
+++ b/layout/reftests/printing/129941-1e.html
@@ -1,8 +1,10 @@
 <!DOCTYPE html>
 <html class="reftest-print" style="margin: 0; padding: 0;">
-  <body style="overflow: -moz-hidden-unscrollable; height: 5in; margin: 0; padding: 0;">
-    <div style="height: 1.25in; border: 0.25in solid green"></div>
-    <div style="height: 1.25in; border: 0.25in solid green"></div>
-    <div style="height: 1.25in; border: 0.25in solid green"></div>
+  <body style="margin: 0; padding: 0; overflow: -moz-hidden-unscrollable; height: 5in;">
+    <div>
+      <div style="height: 1.25in; border: 0.25in solid green"></div>
+      <div style="height: 1.25in; border: 0.25in solid green"></div>
+      <div style="height: 1.25in; border: 0.25in solid green"></div>
+    </div>
   </body>
 </html>
copy from layout/reftests/printing/129941-1-ref.html
copy to layout/reftests/printing/1321803-1-ref.html
--- a/layout/reftests/printing/129941-1-ref.html
+++ b/layout/reftests/printing/1321803-1-ref.html
@@ -1,8 +1,10 @@
 <!DOCTYPE html>
 <html class="reftest-print" style="margin: 0; padding: 0">
   <body style="margin: 0; padding: 0">
-    <div style="height: 1.25in; border: 0.25in solid green"></div>
-    <div style="height: 1.25in; border: 0.25in solid green"></div>
-    <div style="height: 1.25in; border: 0.25in solid green; border-bottom: none"></div>
+    <div>
+      <div style="height: 1.25in; border: 0.25in solid green"></div>
+      <div style="height: 1.25in; border: 0.25in solid green"></div>
+      <div style="height: 1.25in; border: 0.25in solid green;"></div>
+    </div>
   </body>
 </html>
copy from layout/reftests/printing/129941-1a.html
copy to layout/reftests/printing/1321803-1a.html
--- a/layout/reftests/printing/129941-1a.html
+++ b/layout/reftests/printing/1321803-1a.html
@@ -1,8 +1,10 @@
 <!DOCTYPE html>
 <html class="reftest-print" style="margin: 0; padding: 0;">
-  <body style="overflow: scroll; height: 5in; margin: 0; padding: 0;">
-    <div style="height: 1.25in; border: 0.25in solid green"></div>
-    <div style="height: 1.25in; border: 0.25in solid green"></div>
-    <div style="height: 1.25in; border: 0.25in solid green"></div>
+  <body style="margin: 0; padding: 0; overflow: scroll; height: 5in">
+    <div>
+      <div style="height: 1.25in; border: 0.25in solid green"></div>
+      <div style="height: 1.25in; border: 0.25in solid green"></div>
+      <div style="height: 1.25in; border: 0.25in solid green"></div>
+    </div>
   </body>
 </html>
--- a/layout/reftests/printing/reftest.list
+++ b/layout/reftests/printing/reftest.list
@@ -4,16 +4,19 @@
 # Bugs
 == 272830-1.html 272830-1-ref.html
 == 318022-1.html 318022-1-ref.html
 == 403669-1.html 403669-1-ref.html
 == 381497-n.html 381497-f.html
 == test-async-print.html 272830-1-ref.html
 == 129941-1a.html 129941-1-ref.html
 == 129941-1b.html 129941-1-ref.html
+== 129941-1c.html 129941-1-ref.html
+== 129941-1d.html 129941-1-ref.html
+== 129941-1e.html 129941-1-ref.html
 == 609227-1.html 609227-1-ref.html
 == 609227-2a.html 609227-2-ref.html
 == 609227-2b.html 609227-2-ref.html
 == 577450-1.html 577450-1-ref.html
 == 626395-1a.html 626395-1-ref.html
 == 626395-1b.html 626395-1-ref.html
 == 626395-2a.html 626395-2-ref.html
 == 626395-2b.html 626395-2-ref.html
@@ -28,8 +31,9 @@ fuzzy-if(cocoaWidget,1,5000) == 745025-1
 == 820496-1.html 820496-1-ref.html
 
 # NOTE: These tests don't yet rigorously test what they're
 # trying to test (shrink-to-fit behavior), due to bug 967311.
 == 960822.html 960822-ref.html
 == 966419-1.html 966419-1-ref.html
 == 966419-2.html 966419-2-ref.html
 # asserts(3) HTTP(..) fails 1108104.html 1108104-ref.html # bug 1067755, 1135556
+== 1321803-1a.html 1321803-1-ref.html
--- a/layout/reftests/usercss/usercss-ref.html
+++ b/layout/reftests/usercss/usercss-ref.html
@@ -1,10 +1,12 @@
 <!DOCTYPE html>
 <html>
 <head>
 <style>p { background-color: lime; }</style>
 </head>
 <body>
 <p>This paragraph should have a green background.</p>
 <p>This paragraph should have a green background, too.</p>
+<p>@-moz-document rules should be applied.</p>
+<p>@-moz-document rules should not be applied.</p>
 </body>
 </html>
--- a/layout/reftests/usercss/usercss.html
+++ b/layout/reftests/usercss/usercss.html
@@ -1,10 +1,19 @@
 <!DOCTYPE html>
 <html class="reftest-wait">
 <head>
-<style>p { background-color: red; }</style>
+<style>
+p {
+  background-color: red;
+}
+.reftest-xdomain {
+  background: lime;
+}
+</style>
 </head>
 <body>
 <p class="reftest-usercss">This paragraph should have a green background.</p>
 <p class="reftest-userxbl">This paragraph should have a green background, too.</p>
+<p class="reftest-domain">@-moz-document rules should be applied.</p>
+<p class="reftest-xdomain">@-moz-document rules should not be applied.</p>
 </body>
 </html>
--- a/layout/tools/reftest/chrome/userContent.css
+++ b/layout/tools/reftest/chrome/userContent.css
@@ -1,6 +1,20 @@
 .reftest-usercss {
   background: lime !important;
 }
 .reftest-userxbl {
   -moz-binding: url("binding.xml#reftest-userxbl") !important;
 }
+/*
+ * file: URLs have an empty domain.
+ * Android uses special loopback-to-host address.
+ */
+@-moz-document domain(), domain(10.0.2.2) {
+  .reftest-domain {
+    background: lime !important;
+  }
+}
+@-moz-document domain(example.invalid) {
+  .reftest-xdomain {
+    background: red !important;
+  }
+}
--- a/memory/jemalloc/moz.build
+++ b/memory/jemalloc/moz.build
@@ -1,23 +1,31 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
-UNIFIED_SOURCES += [
+# When built with --enable-debug, jemalloc4 makes headers define functions that
+# are normally inlined, and that prevents unified sources from working.
+if CONFIG['MOZ_DEBUG']:
+    maybe_unified_sources = SOURCES
+else:
+    maybe_unified_sources = UNIFIED_SOURCES
+
+maybe_unified_sources += [
     'src/src/arena.c',
     'src/src/atomic.c',
     'src/src/base.c',
     'src/src/bitmap.c',
     'src/src/chunk.c',
     'src/src/chunk_dss.c',
     'src/src/chunk_mmap.c',
     'src/src/ckh.c',
+    'src/src/ctl.c',
     'src/src/extent.c',
     'src/src/hash.c',
     'src/src/huge.c',
     'src/src/jemalloc.c',
     'src/src/mb.c',
     'src/src/mutex.c',
     'src/src/nstime.c',
     'src/src/pages.c',
@@ -29,25 +37,20 @@ UNIFIED_SOURCES += [
     'src/src/stats.c',
     'src/src/tcache.c',
     'src/src/ticker.c',
     'src/src/tsd.c',
     'src/src/util.c',
     'src/src/witness.c',
 ]
 
-SOURCES += [
-    # This file cannot be built in unified mode because of symbol clash on arena_purge.
-    'src/src/ctl.c',
-]
-
 # Only OSX needs the zone allocation implementation,
 # but only if replace-malloc is not enabled.
 if CONFIG['OS_TARGET'] == 'Darwin' and not CONFIG['MOZ_REPLACE_MALLOC']:
-    UNIFIED_SOURCES += [
+    maybe_unified_sources += [
         'src/src/zone.c',
     ]
 
 if CONFIG['MOZ_JEMALLOC4']:
     FINAL_LIBRARY = 'memory'
 else:
     FINAL_LIBRARY = 'replace_jemalloc'
 
--- a/netwerk/streamconv/converters/nsIndexedToHTML.cpp
+++ b/netwerk/streamconv/converters/nsIndexedToHTML.cpp
@@ -1,29 +1,29 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* 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 "DateTimeFormat.h"
 #include "nsIndexedToHTML.h"
 #include "mozilla/dom/EncodingUtils.h"
 #include "nsNetUtil.h"
 #include "netCore.h"
 #include "nsStringStream.h"
 #include "nsIFile.h"
 #include "nsIFileURL.h"
 #include "nsEscape.h"
 #include "nsIDirIndex.h"
 #include "nsURLHelper.h"
 #include "nsIPlatformCharset.h"
 #include "nsIPrefService.h"
 #include "nsIPrefBranch.h"
 #include "nsIPrefLocalizedString.h"
 #include "nsIChromeRegistry.h"
-#include "nsIDateTimeFormat.h"
 #include "nsIStringBundle.h"
 #include "nsITextToSubURI.h"
 #include "nsXPIDLString.h"
 #include <algorithm>
 #include "nsIChannel.h"
 
 NS_IMPL_ISUPPORTS(nsIndexedToHTML,
                   nsIDirIndexListener,
@@ -64,20 +64,16 @@ nsIndexedToHTML::Create(nsISupports *aOu
 }
 
 nsresult
 nsIndexedToHTML::Init(nsIStreamListener* aListener) {
     nsresult rv = NS_OK;
 
     mListener = aListener;
 
-    mDateTime = nsIDateTimeFormat::Create();
-    if (!mDateTime)
-      return NS_ERROR_FAILURE;
-
     nsCOMPtr<nsIStringBundleService> sbs =
         do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
     if (NS_FAILED(rv)) return rv;
     rv = sbs->CreateBundle(NECKO_MSGS_URL, getter_AddRefs(mBundle));
 
     mExpectAbsLoc = false;
 
     return rv;
@@ -830,28 +826,26 @@ nsIndexedToHTML::OnIndexAvailable(nsIReq
 
     if (t == -1LL) {
         pushBuffer.AppendLiteral("></td>\n <td>");
     } else {
         pushBuffer.AppendLiteral(" sortable-data=\"");
         pushBuffer.AppendInt(static_cast<int64_t>(t));
         pushBuffer.AppendLiteral("\">");
         nsAutoString formatted;
-        mDateTime->FormatPRTime(nullptr,
-                                kDateFormatShort,
-                                kTimeFormatNone,
-                                t,
-                                formatted);
+        mozilla::DateTimeFormat::FormatPRTime(kDateFormatShort,
+                                              kTimeFormatNone,
+                                              t,
+                                              formatted);
         AppendNonAsciiToNCR(formatted, pushBuffer);
         pushBuffer.AppendLiteral("</td>\n <td>");
-        mDateTime->FormatPRTime(nullptr,
-                                kDateFormatNone,
-                                kTimeFormatSeconds,
-                                t,
-                                formatted);
+        mozilla::DateTimeFormat::FormatPRTime(kDateFormatNone,
+                                              kTimeFormatSeconds,
+                                              t,
+                                              formatted);
         // use NCR to show date in any doc charset
         AppendNonAsciiToNCR(formatted, pushBuffer);
     }
 
     pushBuffer.AppendLiteral("</td>\n</tr>");
 
     return SendToListener(aRequest, aCtxt, pushBuffer);
 }
--- a/netwerk/streamconv/converters/nsIndexedToHTML.h
+++ b/netwerk/streamconv/converters/nsIndexedToHTML.h
@@ -9,17 +9,16 @@
 #include "nsCOMPtr.h"
 #include "nsString.h"
 #include "nsIStreamConverter.h"
 #include "nsIDirIndexListener.h"
 
 #define NS_NSINDEXEDTOHTMLCONVERTER_CID \
 { 0xcf0f71fd, 0xfafd, 0x4e2b, {0x9f, 0xdc, 0x13, 0x4d, 0x97, 0x2e, 0x16, 0xe2} }
 
-class nsIDateTimeFormat;
 class nsIStringBundle;
 class nsITextToSubURI;
 
 class nsIndexedToHTML : public nsIStreamConverter,
                         public nsIDirIndexListener
 {
 public:
     NS_DECL_ISUPPORTS
@@ -42,17 +41,16 @@ protected:
     // Helper to properly implement OnStartRequest
     nsresult DoOnStartRequest(nsIRequest* request, nsISupports *aContext,
                               nsCString& aBuffer);
 
 protected:
     nsCOMPtr<nsIDirIndexParser>     mParser;
     nsCOMPtr<nsIStreamListener>     mListener; // final listener (consumer)
 
-    nsCOMPtr<nsIDateTimeFormat> mDateTime;
     nsCOMPtr<nsIStringBundle> mBundle;
 
     nsCOMPtr<nsITextToSubURI> mTextToSubURI;
 
 private:
     // Expecting absolute locations, given by 201 lines.
     bool mExpectAbsLoc;
 
--- a/security/certverifier/ExtendedValidation.cpp
+++ b/security/certverifier/ExtendedValidation.cpp
@@ -9,19 +9,16 @@
 #include "base64.h"
 #include "cert.h"
 #include "certdb.h"
 #include "hasht.h"
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/Casting.h"
 #include "mozilla/PodOperations.h"
-#ifdef ANDROID
-#include "nsPrintfCString.h"
-#endif
 #include "pk11pub.h"
 #include "pkix/pkixtypes.h"
 #include "prerror.h"
 
 extern mozilla::LazyLogModule gPIPNSSLog;
 
 #define CONST_OID static const unsigned char
 #define OI(x) { siDEROID, (unsigned char*) x, sizeof x }
@@ -1246,53 +1243,29 @@ CertIsAuthoritativeForEVPolicy(const Uni
         PodEqual(oidData->oid.data, policy.bytes, policy.numBytes)) {
       return true;
     }
   }
 
   return false;
 }
 
-#ifdef ANDROID
-static char sCrashReasonBuffer[1024];
-
-static void
-CrashWithReason(const char* messageFormat, const char* string,
-                PRErrorCode errorCode)
-{
-  nsPrintfCString assertionMessage(messageFormat, string, errorCode);
-  mozilla::PodArrayZero(sCrashReasonBuffer);
-  strncpy(sCrashReasonBuffer, assertionMessage.get(),
-          sizeof(sCrashReasonBuffer));
-  MOZ_CRASH_ANNOTATE(sCrashReasonBuffer);
-  MOZ_REALLY_CRASH();
-}
-#endif
-
 nsresult
 LoadExtendedValidationInfo()
 {
   static const char* sCABForumOIDString = "2.23.140.1.1";
   static const char* sCABForumOIDDescription = "CA/Browser Forum EV OID";
 
   mozilla::ScopedAutoSECItem cabforumOIDItem;
   if (SEC_StringToOID(nullptr, &cabforumOIDItem, sCABForumOIDString, 0)
         != SECSuccess) {
-#ifdef ANDROID
-    CrashWithReason("SEC_StringToOID failed on '%s' with error '%d'",
-                    sCABForumOIDString, PR_GetError());
-#endif
     return NS_ERROR_FAILURE;
   }
   sCABForumEVOIDTag = RegisterOID(cabforumOIDItem, sCABForumOIDDescription);
   if (sCABForumEVOIDTag == SEC_OID_UNKNOWN) {
-#ifdef ANDROID
-    CrashWithReason("RegisterOID failed on '%s' with error '%d'",
-                    sCABForumOIDDescription, PR_GetError());
-#endif
     return NS_ERROR_FAILURE;
   }
 
   for (size_t iEV = 0; iEV < mozilla::ArrayLength(myTrustedEVInfos); ++iEV) {
     nsMyTrustedEVInfo& entry = myTrustedEVInfos[iEV];
 
     SECStatus srv;
 #ifdef DEBUG
@@ -1347,28 +1320,20 @@ LoadExtendedValidationInfo()
       }
     }
 #endif
     // This is the code that actually enables these roots for EV.
     mozilla::ScopedAutoSECItem evOIDItem;
     srv = SEC_StringToOID(nullptr, &evOIDItem, entry.dotted_oid, 0);
     MOZ_ASSERT(srv == SECSuccess, "SEC_StringToOID failed");
     if (srv != SECSuccess) {
-#ifdef ANDROID
-      CrashWithReason("SEC_StringToOID failed on '%s' with error '%d'",
-                      entry.dotted_oid, PR_GetError());
-#endif
       return NS_ERROR_FAILURE;
     }
     entry.oid_tag = RegisterOID(evOIDItem, entry.oid_name);
     if (entry.oid_tag == SEC_OID_UNKNOWN) {
-#ifdef ANDROID
-      CrashWithReason("RegisterOID failed on '%s' with error '%d'",
-                      entry.oid_name, PR_GetError());
-#endif
       return NS_ERROR_FAILURE;
     }
   }
 
   return NS_OK;
 }
 
 // Helper function for GetFirstEVPolicy(): returns the first suitable policy
--- a/security/manager/ssl/TransportSecurityInfo.cpp
+++ b/security/manager/ssl/TransportSecurityInfo.cpp
@@ -1,22 +1,22 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  *
  * 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 "TransportSecurityInfo.h"
 
+#include "DateTimeFormat.h"
 #include "PSMRunnable.h"
 #include "mozilla/Casting.h"
 #include "nsComponentManagerUtils.h"
 #include "nsIArray.h"
 #include "nsICertOverrideService.h"
-#include "nsIDateTimeFormat.h"
 #include "nsIObjectInputStream.h"
 #include "nsIObjectOutputStream.h"
 #include "nsIWebProgressListener.h"
 #include "nsIX509CertValidity.h"
 #include "nsNSSCertHelper.h"
 #include "nsNSSCertificate.h"
 #include "nsNSSComponent.h"
 #include "nsReadableUtils.h"
@@ -793,24 +793,19 @@ GetDateBoundary(nsIX509Cert* ix509,
   PRTime now = PR_Now();
   if (now > notAfter) {
     timeToUse = notAfter;
   } else {
     timeToUse = notBefore;
     trueExpired_falseNotYetValid = false;
   }
 
-  nsCOMPtr<nsIDateTimeFormat> dateTimeFormat = nsIDateTimeFormat::Create();
-  if (!dateTimeFormat) {
-    return;
-  }
-
-  dateTimeFormat->FormatPRTime(nullptr, kDateFormatLong, kTimeFormatNoSeconds,
+  DateTimeFormat::FormatPRTime(kDateFormatLong, kTimeFormatNoSeconds,
                                timeToUse, formattedDate);
-  dateTimeFormat->FormatPRTime(nullptr, kDateFormatLong, kTimeFormatNoSeconds,
+  DateTimeFormat::FormatPRTime(kDateFormatLong, kTimeFormatNoSeconds,
                                now, nowDate);
 }
 
 static void
 AppendErrorTextTime(nsIX509Cert* ix509,
                     nsINSSComponent *component,
                     nsString &returnedMessage)
 {
--- a/security/manager/ssl/nsNSSCertHelper.cpp
+++ b/security/manager/ssl/nsNSSCertHelper.cpp
@@ -1,25 +1,24 @@
 /* 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 "nsNSSCertHelper.h"
 
 #include <algorithm>
 
+#include "DateTimeFormat.h"
 #include "ScopedNSSTypes.h"
 #include "mozilla/Casting.h"
 #include "mozilla/NotNull.h"
 #include "mozilla/Sprintf.h"
 #include "mozilla/UniquePtr.h"
 #include "nsCOMPtr.h"
 #include "nsComponentManagerUtils.h"
-#include "nsDateTimeFormatCID.h"
-#include "nsIDateTimeFormat.h"
 #include "nsNSSASN1Object.h"
 #include "nsNSSCertTrust.h"
 #include "nsNSSCertValidity.h"
 #include "nsNSSCertificate.h"
 #include "nsNSSComponent.h"
 #include "nsServiceManagerUtils.h"
 #include "prerror.h"
 #include "secder.h"
@@ -1609,40 +1608,35 @@ ProcessSECAlgorithmID(SECAlgorithmID *al
   sequence.forget(retSequence);
   return NS_OK;
 }
 
 static nsresult
 ProcessTime(PRTime dispTime, const char16_t* displayName,
             nsIASN1Sequence* parentSequence)
 {
-  nsCOMPtr<nsIDateTimeFormat> dateFormatter = nsIDateTimeFormat::Create();
-  if (!dateFormatter) {
-    return NS_ERROR_FAILURE;
-  }
-
   nsString text;
   nsString tempString;
 
   PRExplodedTime explodedTime;
   PR_ExplodeTime(dispTime, PR_LocalTimeParameters, &explodedTime);
 
-  dateFormatter->FormatPRExplodedTime(nullptr, kDateFormatLong,
-                                      kTimeFormatSeconds, &explodedTime,
-                                      tempString);
+  DateTimeFormat::FormatPRExplodedTime(kDateFormatLong,
+                                       kTimeFormatSeconds, &explodedTime,
+                                       tempString);
 
   text.Append(tempString);
   text.AppendLiteral("\n(");
 
   PRExplodedTime explodedTimeGMT;
   PR_ExplodeTime(dispTime, PR_GMTParameters, &explodedTimeGMT);
 
-  dateFormatter->FormatPRExplodedTime(nullptr, kDateFormatLong,
-                                      kTimeFormatSeconds, &explodedTimeGMT,
-                                      tempString);
+  DateTimeFormat::FormatPRExplodedTime(kDateFormatLong,
+                                       kTimeFormatSeconds, &explodedTimeGMT,
+                                       tempString);
 
   text.Append(tempString);
   text.AppendLiteral(" GMT)");
 
   nsCOMPtr<nsIASN1PrintableItem> printableItem = new nsNSSASN1PrintableItem();
 
   printableItem->SetDisplayValue(text);
   printableItem->SetDisplayName(nsDependentString(displayName));
--- a/security/manager/ssl/nsNSSCertValidity.cpp
+++ b/security/manager/ssl/nsNSSCertValidity.cpp
@@ -57,26 +57,21 @@ nsresult
 nsX509CertValidity::FormatTime(const PRTime& aTimeDate,
                                PRTimeParamFn aParamFn,
                                const nsTimeFormatSelector aTimeFormatSelector,
                                nsAString& aFormattedTimeDate)
 {
   if (!mTimesInitialized)
     return NS_ERROR_FAILURE;
 
-  nsCOMPtr<nsIDateTimeFormat> dateFormatter = nsIDateTimeFormat::Create();
-  if (!dateFormatter) {
-    return NS_ERROR_FAILURE;
-  }
-
   PRExplodedTime explodedTime;
   PR_ExplodeTime(const_cast<PRTime&>(aTimeDate), aParamFn, &explodedTime);
-  return dateFormatter->FormatPRExplodedTime(nullptr, kDateFormatLong,
-					     aTimeFormatSelector,
-					     &explodedTime, aFormattedTimeDate);
+  return mozilla::DateTimeFormat::FormatPRExplodedTime(kDateFormatLong,
+					                                             aTimeFormatSelector,
+					                                             &explodedTime, aFormattedTimeDate);
 }
 
 NS_IMETHODIMP
 nsX509CertValidity::GetNotBeforeLocalTime(nsAString& aNotBeforeLocalTime)
 {
   return FormatTime(mNotBefore, PR_LocalTimeParameters,
                     kTimeFormatSeconds, aNotBeforeLocalTime);
 }
--- a/security/manager/ssl/nsNSSCertValidity.h
+++ b/security/manager/ssl/nsNSSCertValidity.h
@@ -1,17 +1,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 nsNSSCertValidity_h
 #define nsNSSCertValidity_h
 
+#include "DateTimeFormat.h"
 #include "ScopedNSSTypes.h"
-#include "nsIDateTimeFormat.h"
 #include "nsIX509CertValidity.h"
 #include "nsNSSShutDown.h"
 
 class nsX509CertValidity : public nsIX509CertValidity
                          , public nsNSSShutDownObject
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
--- a/security/manager/ssl/nsNSSComponent.cpp
+++ b/security/manager/ssl/nsNSSComponent.cpp
@@ -60,16 +60,21 @@
 
 #include "windows.h" // this needs to be before the following includes
 #include "lmcons.h"
 #include "sddl.h"
 #include "wincrypt.h"
 #include "nsIWindowsRegKey.h"
 #endif
 
+#ifdef ANDROID
+#include "mozilla/PodOperations.h"
+#include "nsPrintfCString.h"
+#endif // ANDROID
+
 using namespace mozilla;
 using namespace mozilla::psm;
 
 LazyLogModule gPIPNSSLog("pipnss");
 
 int nsNSSComponent::mInstanceCount = 0;
 
 // This function can be called from chrome or content processes
@@ -1275,36 +1280,26 @@ nsNSSComponent::ConfigureInternalPKCS11T
 
 nsresult
 nsNSSComponent::InitializePIPNSSBundle()
 {
   // Called during init only, no mutex required.
 
   nsresult rv;
   nsCOMPtr<nsIStringBundleService> bundleService(do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv));
-#ifdef ANDROID
-  MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
-  MOZ_RELEASE_ASSERT(bundleService);
-#endif
   if (NS_FAILED(rv) || !bundleService)
     return NS_ERROR_FAILURE;
 
   bundleService->CreateBundle("chrome://pipnss/locale/pipnss.properties",
                               getter_AddRefs(mPIPNSSBundle));
-#ifdef ANDROID
-  MOZ_RELEASE_ASSERT(mPIPNSSBundle);
-#endif
   if (!mPIPNSSBundle)
     rv = NS_ERROR_FAILURE;
 
   bundleService->CreateBundle("chrome://pipnss/locale/nsserrors.properties",
                               getter_AddRefs(mNSSErrorsBundle));
-#ifdef ANDROID
-  MOZ_RELEASE_ASSERT(mNSSErrorsBundle);
-#endif
   if (!mNSSErrorsBundle)
     rv = NS_ERROR_FAILURE;
 
   return rv;
 }
 
 // Table of pref names and SSL cipher ID
 typedef struct {
@@ -1444,19 +1439,16 @@ StaticRefPtr<CipherSuiteChangeObserver> 
 // static
 nsresult
 CipherSuiteChangeObserver::StartObserve()
 {
   NS_ASSERTION(NS_IsMainThread(), "CipherSuiteChangeObserver::StartObserve() can only be accessed in main thread");
   if (!sObserver) {
     RefPtr<CipherSuiteChangeObserver> observer = new CipherSuiteChangeObserver();
     nsresult rv = Preferences::AddStrongObserver(observer.get(), "security.");
-#ifdef ANDROID
-    MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
-#endif
     if (NS_FAILED(rv)) {
       sObserver = nullptr;
       return rv;
     }
 
     nsCOMPtr<nsIObserverService> observerService =
       mozilla::services::GetObserverService();
     observerService->AddObserver(observer, NS_XPCOM_SHUTDOWN_OBSERVER_ID,
@@ -1682,49 +1674,47 @@ GetNSSProfilePath(nsAutoCString& aProfil
     MOZ_LOG(gPIPNSSLog, LogLevel::Error,
            ("Could not get nsILocalFileWin for profile directory.\n"));
     return NS_ERROR_FAILURE;
   }
   rv = profileFileWin->GetNativeCanonicalPath(aProfilePath);
 #else
   rv = profileFile->GetNativePath(aProfilePath);
 #endif
-#ifdef ANDROID
-  MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
-#endif
   if (NS_FAILED(rv)) {
     MOZ_LOG(gPIPNSSLog, LogLevel::Error,
            ("Could not get native path for profile directory.\n"));
     return rv;
   }
 
   MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
           ("NSS profile at '%s'\n", aProfilePath.get()));
   return NS_OK;
 }
 
+#ifdef ANDROID
+static char sCrashReasonBuffer[1024];
+#endif // ANDROID
+
 nsresult
 nsNSSComponent::InitializeNSS()
 {
   // Can be called both during init and profile change.
   // Needs mutex protection.
 
   MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("nsNSSComponent::InitializeNSS\n"));
 
   static_assert(nsINSSErrorsService::NSS_SEC_ERROR_BASE == SEC_ERROR_BASE &&
                 nsINSSErrorsService::NSS_SEC_ERROR_LIMIT == SEC_ERROR_LIMIT &&
                 nsINSSErrorsService::NSS_SSL_ERROR_BASE == SSL_ERROR_BASE &&
                 nsINSSErrorsService::NSS_SSL_ERROR_LIMIT == SSL_ERROR_LIMIT,
                 "You must update the values in nsINSSErrorsService.idl");
 
   MutexAutoLock lock(mutex);
 
-#ifdef ANDROID
-  MOZ_RELEASE_ASSERT(!mNSSInitialized);
-#endif
   if (mNSSInitialized) {
     // We should never try to initialize NSS more than once in a process.
     MOZ_ASSERT_UNREACHABLE("Trying to initialize NSS twice");
     return NS_ERROR_FAILURE;
   }
 
   MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("NSS Initialization beginning\n"));
 
@@ -1733,35 +1723,29 @@ nsNSSComponent::InitializeNSS()
   // If we could assume i18n will not change between profiles, one call per application
   // run were sufficient. As I can't predict what happens in the future, let's repeat
   // this call for every re-init of NSS.
 
   ConfigureInternalPKCS11Token();
 
   nsAutoCString profileStr;
   nsresult rv = GetNSSProfilePath(profileStr);
-#ifdef ANDROID
-  MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
-#endif
   if (NS_FAILED(rv)) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   SECStatus init_rv = SECFailure;
   bool nocertdb = Preferences::GetBool("security.nocertdb", false);
   bool inSafeMode = true;
   nsCOMPtr<nsIXULRuntime> runtime(do_GetService("@mozilla.org/xre/runtime;1"));
   // There might not be an nsIXULRuntime in embedded situations. This will
   // default to assuming we are in safe mode (as a result, no external PKCS11
   // modules will be loaded).
   if (runtime) {
     rv = runtime->GetInSafeMode(&inSafeMode);
-#ifdef ANDROID
-    MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
-#endif
     if (NS_FAILED(rv)) {
       return rv;
     }
   }
   MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("inSafeMode: %u\n", inSafeMode));
 
   if (!nocertdb && !profileStr.IsEmpty()) {
     // First try to initialize the NSS DB in read/write mode.
@@ -1777,23 +1761,28 @@ nsNSSComponent::InitializeNSS()
     }
   }
   // If we haven't succeeded in initializing the DB in our profile
   // directory or we don't have a profile at all, or the "security.nocertdb"
   // pref has been set to "true", attempt to initialize with no DB.
   if (nocertdb || init_rv != SECSuccess) {
     init_rv = NSS_NoDB_Init(nullptr);
 #ifdef ANDROID
-    MOZ_RELEASE_ASSERT(init_rv == SECSuccess);
-#endif
+    if (init_rv != SECSuccess) {
+      nsPrintfCString message("NSS_NoDB_Init failed with PRErrorCode %d",
+                              PR_GetError());
+      mozilla::PodArrayZero(sCrashReasonBuffer);
+      strncpy(sCrashReasonBuffer, message.get(),
+              sizeof(sCrashReasonBuffer) - 1);
+      MOZ_CRASH_ANNOTATE(sCrashReasonBuffer);
+      MOZ_REALLY_CRASH();
+    }
+#endif // ANDROID
   }
   if (init_rv != SECSuccess) {
-#ifdef ANDROID
-    MOZ_RELEASE_ASSERT(false);
-#endif
     MOZ_LOG(gPIPNSSLog, LogLevel::Error, ("could not initialize NSS - panicking\n"));
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   // ensure we have an initial value for the content signer root
   mContentSigningRootHash =
     Preferences::GetString("security.content.signature.root_hash");
 
@@ -1805,30 +1794,24 @@ nsNSSComponent::InitializeNSS()
 
   // Register an observer so we can inform NSS when these prefs change
   Preferences::AddStrongObserver(this, "security.");
 
   SSL_OptionSetDefault(SSL_ENABLE_SSL2, false);
   SSL_OptionSetDefault(SSL_V2_COMPATIBLE_HELLO, false);
 
   rv = setEnabledTLSVersions();
-#ifdef ANDROID
-    MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
-#endif
   if (NS_FAILED(rv)) {
     return NS_ERROR_UNEXPECTED;
   }
 
   DisableMD5();
   LoadLoadableRoots();
 
   rv = LoadExtendedValidationInfo();
-#ifdef ANDROID
-    MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
-#endif
   if (NS_FAILED(rv)) {
     MOZ_LOG(gPIPNSSLog, LogLevel::Error, ("failed to load EV info"));
     return rv;
   }
 
   MaybeEnableFamilySafetyCompatibility();
   MaybeImportEnterpriseRoots();
 
@@ -1855,72 +1838,57 @@ nsNSSComponent::InitializeNSS()
                        Preferences::GetBool("security.ssl.enable_alpn",
                                             ALPN_ENABLED_DEFAULT));
 
   SSL_OptionSetDefault(SSL_ENABLE_0RTT_DATA,
                        Preferences::GetBool("security.tls.enable_0rtt_data",
                                             ENABLED_0RTT_DATA_DEFAULT));
 
   if (NS_FAILED(InitializeCipherSuite())) {
-#ifdef ANDROID
-    MOZ_RELEASE_ASSERT(false);
-#endif
     MOZ_LOG(gPIPNSSLog, LogLevel::Error, ("Unable to initialize cipher suite settings\n"));
     return NS_ERROR_FAILURE;
   }
 
   // TLSServerSocket may be run with the session cache enabled. It is necessary
   // to call this once before that can happen. This specifies a maximum of 1000
   // cache entries (the default number of cache entries is 10000, which seems a
   // little excessive as there probably won't be that many clients connecting to
   // any TLSServerSockets the browser runs.)
   // Note that this must occur before any calls to SSL_ClearSessionCache
   // (otherwise memory will leak).
   if (SSL_ConfigServerSessionIDCache(1000, 0, 0, nullptr) != SECSuccess) {
-#ifdef ANDROID
-    MOZ_RELEASE_ASSERT(false);
-#endif
     return NS_ERROR_FAILURE;
   }
 
   // ensure the CertBlocklist is initialised
   nsCOMPtr<nsICertBlocklist> certList = do_GetService(NS_CERTBLOCKLIST_CONTRACTID);
-#ifdef ANDROID
-  MOZ_RELEASE_ASSERT(certList);
-#endif
   if (!certList) {
     return NS_ERROR_FAILURE;
   }
 
   // dynamic options from prefs
   setValidationOptions(true, lock);
 
 #ifndef MOZ_NO_SMART_CARDS
   LaunchSmartCardThreads();
 #endif
 
   mozilla::pkix::RegisterErrorTable();
 
   // Initialize the site security service
   nsCOMPtr<nsISiteSecurityService> sssService =
     do_GetService(NS_SSSERVICE_CONTRACTID);
-#ifdef ANDROID
-  MOZ_RELEASE_ASSERT(sssService);
-#endif
   if (!sssService) {
     MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("Cannot initialize site security service\n"));
     return NS_ERROR_FAILURE;
   }
 
   // Initialize the cert override service
   nsCOMPtr<nsICertOverrideService> coService =
     do_GetService(NS_CERTOVERRIDE_CONTRACTID);
-#ifdef ANDROID
-  MOZ_RELEASE_ASSERT(coService);
-#endif
   if (!coService) {
     MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("Cannot initialize cert override service\n"));
     return NS_ERROR_FAILURE;
   }
 
   if (PK11_IsFIPS()) {
     Telemetry::Accumulate(Telemetry::FIPS_ENABLED, true);
   }
@@ -1982,19 +1950,16 @@ nsNSSComponent::Init()
     return NS_ERROR_NOT_SAME_THREAD;
   }
 
   nsresult rv = NS_OK;
 
   MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("Beginning NSS initialization\n"));
 
   rv = InitializePIPNSSBundle();
-#ifdef ANDROID
-  MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
-#endif
   if (NS_FAILED(rv)) {
     MOZ_LOG(gPIPNSSLog, LogLevel::Error, ("Unable to create pipnss bundle.\n"));
     return rv;
   }
 
   // Access our string bundles now, this prevents assertions from I/O
   // - nsStandardURL not thread-safe
   // - wrong thread: 'NS_IsMainThread()' in nsIOService.cpp
@@ -2005,19 +1970,16 @@ nsNSSComponent::Init()
     mPIPNSSBundle->GetStringFromName(dummy_name.get(),
                                      getter_Copies(result));
     mNSSErrorsBundle->GetStringFromName(dummy_name.get(),
                                         getter_Copies(result));
   }
 
 
   rv = InitializeNSS();
-#ifdef ANDROID
-  MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
-#endif
   if (NS_FAILED(rv)) {
     MOZ_LOG(gPIPNSSLog, LogLevel::Error,
             ("nsNSSComponent::InitializeNSS() failed\n"));
     return rv;
   }
 
   RememberCertErrorsTable::Init();
 
@@ -2165,19 +2127,16 @@ nsresult nsNSSComponent::LogoutAuthentic
 
 nsresult
 nsNSSComponent::RegisterObservers()
 {
   // Happens once during init only, no mutex protection.
 
   nsCOMPtr<nsIObserverService> observerService(
     do_GetService("@mozilla.org/observer-service;1"));
-#ifdef ANDROID
-    MOZ_RELEASE_ASSERT(observerService);
-#endif
   if (!observerService) {
     MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
             ("nsNSSComponent: couldn't get observer service\n"));
     return NS_ERROR_FAILURE;
   }
 
   MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("nsNSSComponent: adding observers\n"));
   // Using false for the ownsweak parameter means the observer service will
@@ -2389,19 +2348,16 @@ namespace mozilla {
 namespace psm {
 
 nsresult
 InitializeCipherSuite()
 {
   NS_ASSERTION(NS_IsMainThread(), "InitializeCipherSuite() can only be accessed in main thread");
 
   if (NSS_SetDomesticPolicy() != SECSuccess) {
-#ifdef ANDROID
-    MOZ_RELEASE_ASSERT(false);
-#endif
     return NS_ERROR_FAILURE;
   }
 
   // Disable any ciphers that NSS might have enabled by default
   for (uint16_t i = 0; i < SSL_NumImplementedCiphers; ++i) {
     uint16_t cipher_id = SSL_ImplementedCiphers[i];
     SSL_CipherPrefSetDefault(cipher_id, false);
   }
--- a/security/nss/TAG-INFO
+++ b/security/nss/TAG-INFO
@@ -1,1 +1,1 @@
-5e59e858012d
+6353ce63e18f
new file mode 100644
--- /dev/null
+++ b/security/nss/automation/taskcluster/docker-fuzz/Dockerfile
@@ -0,0 +1,27 @@
+FROM ubuntu:16.04
+MAINTAINER Tim Taubert <ttaubert@mozilla.com>
+
+RUN useradd -d /home/worker -s /bin/bash -m worker
+WORKDIR /home/worker
+
+# Add build and test scripts.
+ADD bin /home/worker/bin
+RUN chmod +x /home/worker/bin/*
+
+# Install dependencies.
+ADD setup.sh /tmp/setup.sh
+RUN bash /tmp/setup.sh
+
+# Env variables.
+ENV HOME /home/worker
+ENV SHELL /bin/bash
+ENV USER worker
+ENV LOGNAME worker
+ENV HOSTNAME taskcluster-worker
+ENV LANG en_US.UTF-8
+ENV LC_ALL en_US.UTF-8
+ENV HOST localhost
+ENV DOMSUF localdomain
+
+# Set a default command for debugging.
+CMD ["/bin/bash", "--login"]
new file mode 100644
--- /dev/null
+++ b/security/nss/automation/taskcluster/docker-fuzz/bin/checkout.sh
@@ -0,0 +1,20 @@
+#!/usr/bin/env bash
+
+set -v -e -x
+
+if [ $(id -u) = 0 ]; then
+    # Drop privileges by re-running this script.
+    exec su worker $0
+fi
+
+# Default values for testing.
+REVISION=${NSS_HEAD_REVISION:-default}
+REPOSITORY=${NSS_HEAD_REPOSITORY:-https://hg.mozilla.org/projects/nss}
+
+# Clone NSS.
+for i in 0 2 5; do
+    sleep $i
+    hg clone -r $REVISION $REPOSITORY nss && exit 0
+    rm -rf nss
+done
+exit 1
new file mode 100644
--- /dev/null
+++ b/security/nss/automation/taskcluster/docker-fuzz/setup.sh
@@ -0,0 +1,54 @@
+#!/usr/bin/env bash
+
+set -v -e -x
+
+# Update packages.
+export DEBIAN_FRONTEND=noninteractive
+apt-get -y update && apt-get -y upgrade
+
+# Need this to add keys for PPAs below.
+apt-get install -y --no-install-recommends apt-utils
+
+apt_packages=()
+apt_packages+=('build-essential')
+apt_packages+=('ca-certificates')
+apt_packages+=('curl')
+apt_packages+=('git')
+apt_packages+=('gyp')
+apt_packages+=('ninja-build')
+apt_packages+=('pkg-config')
+apt_packages+=('zlib1g-dev')
+
+# ct-verif and sanitizers
+apt_packages+=('valgrind')
+
+# Latest Mercurial.
+apt_packages+=('mercurial')
+apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 41BD8711B1F0EC2B0D85B91CF59CE3A8323293EE
+echo "deb http://ppa.launchpad.net/mercurial-ppa/releases/ubuntu xenial main" > /etc/apt/sources.list.d/mercurial.list
+
+# Install packages.
+apt-get -y update
+apt-get install -y --no-install-recommends ${apt_packages[@]}
+
+# Install LLVM/clang-4.0.
+mkdir clang-tmp
+git clone -n --depth 1 https://chromium.googlesource.com/chromium/src/tools/clang clang-tmp/clang
+git -C clang-tmp/clang checkout HEAD scripts/update.py
+clang-tmp/clang/scripts/update.py
+rm -fr clang-tmp
+
+# Link to LLVM binaries.
+for b in clang clang++ llvm-symbolizer; do
+  ln -s /home/worker/third_party/llvm-build/Release+Asserts/bin/$b /usr/local/bin/$b
+done
+
+locale-gen en_US.UTF-8
+dpkg-reconfigure locales
+
+# Cleanup.
+rm -rf ~/.ccache ~/.cache
+apt-get autoremove -y
+apt-get clean
+apt-get autoclean
+rm $0
--- a/security/nss/automation/taskcluster/graph/src/extend.js
+++ b/security/nss/automation/taskcluster/graph/src/extend.js
@@ -1,16 +1,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/. */
 
 import merge from "./merge";
 import * as queue from "./queue";
 
 const LINUX_IMAGE = {name: "linux", path: "automation/taskcluster/docker"};
+const FUZZ_IMAGE = {name: "fuzz", path: "automation/taskcluster/docker-fuzz"};
 
 const WINDOWS_CHECKOUT_CMD =
   "bash -c \"hg clone -r $NSS_HEAD_REVISION $NSS_HEAD_REPOSITORY nss || " +
     "(sleep 2; hg clone -r $NSS_HEAD_REVISION $NSS_HEAD_REPOSITORY nss) || " +
     "(sleep 5; hg clone -r $NSS_HEAD_REVISION $NSS_HEAD_REPOSITORY nss)\"";
 
 /*****************************************************************************/
 
@@ -265,26 +266,26 @@ async function scheduleFuzzing() {
       UBSAN_OPTIONS: "print_stacktrace=1",
       NSS_DISABLE_ARENA_FREE_LIST: "1",
       NSS_DISABLE_UNLOAD: "1",
       CC: "clang",
       CCC: "clang++"
     },
     platform: "linux64",
     collection: "fuzz",
-    image: LINUX_IMAGE
+    image: FUZZ_IMAGE
   };
 
   // Build base definition.
   let build_base = merge({
     command: [
       "/bin/bash",
       "-c",
       "bin/checkout.sh && " +
-      "nss/automation/taskcluster/scripts/build_gyp.sh -g -v --fuzz --ubsan"
+      "nss/automation/taskcluster/scripts/build_gyp.sh -g -v --fuzz"
     ],
     artifacts: {
       public: {
         expires: 24 * 7,
         type: "directory",
         path: "/home/worker/artifacts"
       }
     },
--- a/security/nss/automation/taskcluster/windows/releng.manifest
+++ b/security/nss/automation/taskcluster/windows/releng.manifest
@@ -1,10 +1,10 @@
 [
   {
-    "version": "Visual Studio 2015 Update 2 / SDK 10.0.10586.0/212",
-    "size": 332442800,
-    "digest": "995394a4a515c7cb0f8595f26f5395361a638870dd0bbfcc22193fe1d98a0c47126057d5999cc494f3f3eac5cb49160e79757c468f83ee5797298e286ef6252c",
+    "version": "Visual Studio 2015 Update 3 14.0.25425.01 / SDK 10.0.14393.0",
+    "size": 326656969,
+    "digest": "babc414ffc0457d27f5a1ed24a8e4873afbe2f1c1a4075469a27c005e1babc3b2a788f643f825efedff95b79686664c67ec4340ed535487168a3482e68559bc7",
     "algorithm": "sha512",
-    "filename": "vs2015u2.zip",
+    "filename": "vs2015u3.zip",
     "unpack": true
   }
 ]
--- a/security/nss/automation/taskcluster/windows/setup.sh
+++ b/security/nss/automation/taskcluster/windows/setup.sh
@@ -13,18 +13,18 @@ hg_clone() {
         rm -rf "$dir"
     done
     exit 1
 }
 
 hg_clone https://hg.mozilla.org/build/tools tools default
 
 tools/scripts/tooltool/tooltool_wrapper.sh $(dirname $0)/releng.manifest https://api.pub.build.mozilla.org/tooltool/ non-existant-file.sh /c/mozilla-build/python/python.exe /c/builds/tooltool.py --authentication-file /c/builds/relengapi.tok -c /c/builds/tooltool_cache
-VSPATH="$(pwd)/vs2015u2"
+VSPATH="$(pwd)/vs2015u3"
 
 export WINDOWSSDKDIR="${VSPATH}/SDK"
 export WIN32_REDIST_DIR="${VSPATH}/VC/redist/x64/Microsoft.VC140.CRT"
 export WIN_UCRT_REDIST_DIR="${VSPATH}/SDK/Redist/ucrt/DLLs/x64"
 
 export PATH="${VSPATH}/VC/bin/amd64:${VSPATH}/VC/bin:${VSPATH}/SDK/bin/x64:${VSPATH}/VC/redist/x64/Microsoft.VC140.CRT:${VSPATH}/SDK/Redist/ucrt/DLLs/x64:${PATH}"
 
-export INCLUDE="${VSPATH}/VC/include:${VSPATH}/SDK/Include/10.0.10586.0/ucrt:${VSPATH}/SDK/Include/10.0.10586.0/shared:${VSPATH}/SDK/Include/10.0.10586.0/um"
-export LIB="${VSPATH}/VC/lib/amd64:${VSPATH}/SDK/lib/10.0.10586.0/ucrt/x64:${VSPATH}/SDK/lib/10.0.10586.0/um/x64"
+export INCLUDE="${VSPATH}/VC/include:${VSPATH}/SDK/Include/10.0.14393.0/ucrt:${VSPATH}/SDK/Include/10.0.14393.0/shared:${VSPATH}/SDK/Include/10.0.14393.0/um"
+export LIB="${VSPATH}/VC/lib/amd64:${VSPATH}/SDK/lib/10.0.14393.0/ucrt/x64:${VSPATH}/SDK/lib/10.0.14393.0/um/x64"
--- a/security/nss/build.sh
+++ b/security/nss/build.sh
@@ -1,9 +1,9 @@
-#!/bin/bash
+#!/usr/bin/env bash
 # This script builds NSS with gyp and ninja.
 #
 # This build system is still under development.  It does not yet support all
 # the features or platforms that NSS supports.
 
 set -e
 
 source $(dirname $0)/coreconf/nspr.sh
@@ -31,16 +31,17 @@ NSS build tool options:
     -m32          do a 32-bit build on a 64-bit system
     --test        ignore map files and export everything we have
     --fuzz        enable fuzzing mode. this always enables test builds
     --scan-build  run the build with scan-build (scan-build has to be in the path)
                   --scan-build=/out/path sets the output path for scan-build
     --opt|-o      do an opt build
     --asan        do an asan build
     --ubsan       do an ubsan build
+                  --ubsan=bool,shift,... sets specific UB sanitizers
     --msan        do an msan build
     --sancov      do sanitize coverage builds
                   --sancov=func sets coverage to function level for example
     --pprof       build with gperftool support
 EOF
 }
 
 if [ -n "$CCC" ] && [ -z "$CXX" ]; then
@@ -49,43 +50,60 @@ fi
 
 opt_build=0
 build_64=0
 clean=0
 rebuild_gyp=0
 target=Debug
 verbose=0
 fuzz=0
-sancov_default=edge,indirect-calls,8bit-counters
+ubsan_default=bool,signed-integer-overflow,shift,vptr
 
 # parse parameters to store in config
 params=$(echo "$*" | perl -pe 's/-c|-v|-g|-j [0-9]*|-h//g' | perl -pe 's/^\s*(.*?)\s*$/\1/')
-params=$(echo "$params $CC $CCC" | tr " " "\n" | perl -pe '/^\s*$/d')
+params=$(echo "$params $CC $CCC" | tr " " "\n" | perl -pe 's/^\s*$//')
 params=$(echo "${params[*]}" | sort)
 
 cwd=$(cd $(dirname $0); pwd -P)
 dist_dir="$cwd/../dist"
 
 # try to guess sensible defaults
 arch=$(python "$cwd/coreconf/detect_host_arch.py")
 if [ "$arch" = "x64" -o "$arch" = "aarch64" ]; then
     build_64=1
 fi
 
 gyp_params=()
 ninja_params=()
 scanbuild=()
 
+sancov_default()
+{
+    clang_version=$($CC --version | grep -oE 'clang version (3\.9\.|4\.)')
+    if [ -z "$clang_version" ]; then
+        echo "Need at least clang-3.9 (better 4.0) for sancov." 1>&2
+        exit 1
+    fi
+
+    if [ "$clang_version" = "clang version 3.9." ]; then
+        echo edge,indirect-calls,8bit-counters
+    else
+        echo trace-pc-guard
+    fi
+}
+
 enable_fuzz()
 {
     fuzz=1
     nspr_sanitizer asan
-    nspr_sanitizer sancov $sancov_default
+    nspr_sanitizer ubsan $ubsan_default
+    nspr_sanitizer sancov $(sancov_default)
     gyp_params+=(-Duse_asan=1)
-    gyp_params+=(-Duse_sancov=$sancov_default)
+    gyp_params+=(-Duse_ubsan=$ubsan_default)
+    gyp_params+=(-Duse_sancov=$(sancov_default))
 
     # Adding debug symbols even for opt builds.
     nspr_opt+=(--enable-debug-symbols)
 }
 
 # parse command line arguments
 while [ $# -gt 0 ]; do
     case $1 in
@@ -95,18 +113,19 @@ while [ $# -gt 0 ]; do
         -v) ninja_params+=(-v); verbose=1 ;;
         --test) gyp_params+=(-Dtest_build=1) ;;
         --fuzz) gyp_params+=(-Dtest_build=1 -Dfuzz=1); enable_fuzz ;;
         --scan-build) scanbuild=(scan-build) ;;
         --scan-build=?*) scanbuild=(scan-build -o "${1#*=}") ;;
         --opt|-o) opt_build=1 ;;
         -m32|--m32) build_64=0 ;;
         --asan) gyp_params+=(-Duse_asan=1); nspr_sanitizer asan ;;
-        --ubsan) gyp_params+=(-Duse_ubsan=1); nspr_sanitizer ubsan ;;
-        --sancov) gyp_params+=(-Duse_sancov=$sancov_default); nspr_sanitizer sancov $sancov_default ;;
+        --ubsan) gyp_params+=(-Duse_ubsan=$ubsan_default); nspr_sanitizer ubsan $ubsan_default ;;
+        --ubsan=?*) gyp_params+=(-Duse_ubsan="${1#*=}"); nspr_sanitizer ubsan "${1#*=}" ;;
+        --sancov) gyp_params+=(-Duse_sancov=$(sancov_default)); nspr_sanitizer sancov $(sancov_default) ;;
         --sancov=?*) gyp_params+=(-Duse_sancov="${1#*=}"); nspr_sanitizer sancov "${1#*=}" ;;
         --pprof) gyp_params+=(-Duse_pprof=1) ;;
         --msan) gyp_params+=(-Duse_msan=1); nspr_sanitizer msan ;;
         *) show_help; exit ;;
     esac
     shift
 done
 
--- a/security/nss/cmd/bltest/blapitest.c
+++ b/security/nss/cmd/bltest/blapitest.c
@@ -912,23 +912,25 @@ SECStatus
 setupIO(PLArenaPool *arena, bltestIO *input, PRFileDesc *file,
         char *str, int numBytes)
 {
     SECStatus rv = SECSuccess;
     SECItem fileData;
     SECItem *in;
     unsigned char *tok;
     unsigned int i, j;
+    PRBool needToFreeFile = PR_FALSE;
 
     if (file && (numBytes == 0 || file == PR_STDIN)) {
         /* grabbing data from a file */
         rv = SECU_FileToItem(&fileData, file);
         if (rv != SECSuccess)
             return SECFailure;
         in = &fileData;
+        needToFreeFile = PR_TRUE;
     } else if (str) {
         /* grabbing data from command line */
         fileData.data = (unsigned char *)str;
         fileData.len = PL_strlen(str);
         in = &fileData;
     } else if (file) {
         /* create nonce */
         SECITEM_AllocItem(arena, &input->buf, numBytes);
@@ -952,20 +954,17 @@ setupIO(PLArenaPool *arena, bltestIO *in
                 input->buf.data = NULL;
                 input->buf.len = 0;
                 break;
             }
             if (in->data[in->len - 1] == '\n')
                 --in->len;
             if (in->data[in->len - 1] == '\r')
                 --in->len;
-            SECITEM_CopyItem(arena, &input->buf, in);
-            if (rv != SECSuccess) {
-                return SECFailure;
-            }
+            rv = SECITEM_CopyItem(arena, &input->buf, in);
             break;
         case bltestHexSpaceDelim:
             SECITEM_AllocItem(arena, &input->buf, in->len / 5);
             for (i = 0, j = 0; i < in->len; i += 5, j++) {
                 tok = &in->data[i];
                 if (tok[0] != '0' || tok[1] != 'x' || tok[4] != ' ')
                     /* bad hex token */
                     break;
@@ -981,17 +980,17 @@ setupIO(PLArenaPool *arena, bltestIO *in
                 tok = &in->data[i];
                 rv = hex_from_2char(tok, input->buf.data + j);
                 if (rv)
                     break;
             }
             break;
     }
 
-    if (file)
+    if (needToFreeFile)
         SECITEM_FreeItem(&fileData, PR_FALSE);
     return rv;
 }
 
 SECStatus
 finishIO(bltestIO *output, PRFileDesc *file)
 {
     SECStatus rv = SECSuccess;
--- a/security/nss/cmd/certutil/certutil.c
+++ b/security/nss/cmd/certutil/certutil.c
@@ -44,17 +44,17 @@
 
 #define GEN_BREAK(e) \
     rv = e;          \
     break;
 
 char *progName;
 
 static CERTCertificateRequest *
-GetCertRequest(const SECItem *reqDER)
+GetCertRequest(const SECItem *reqDER, void *pwarg)
 {
     CERTCertificateRequest *certReq = NULL;
     CERTSignedData signedData;
     PLArenaPool *arena = NULL;
     SECStatus rv;
 
     do {
         arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
@@ -78,17 +78,17 @@ GetCertRequest(const SECItem *reqDER)
             break;
         }
         rv = SEC_ASN1DecodeItem(arena, certReq,
                                 SEC_ASN1_GET(CERT_CertificateRequestTemplate), &signedData.data);
         if (rv) {
             break;
         }
         rv = CERT_VerifySignedDataWithPublicKeyInfo(&signedData,
-                                                    &certReq->subjectPublicKeyInfo, NULL /* wincx */);
+                                                    &certReq->subjectPublicKeyInfo, pwarg);
     } while (0);
 
     if (rv) {
         SECU_PrintError(progName, "bad certificate request\n");
         if (arena) {
             PORT_FreeArena(arena, PR_FALSE);
         }
         certReq = NULL;
@@ -1995,17 +1995,17 @@ CreateCert(
     void *extHandle = NULL;
     CERTCertificate *subjectCert = NULL;
     CERTCertificateRequest *certReq = NULL;
     SECStatus rv = SECSuccess;
     CERTCertExtension **CRexts;
 
     do {
         /* Create a certrequest object from the input cert request der */
-        certReq = GetCertRequest(certReqDER);
+        certReq = GetCertRequest(certReqDER, pwarg);
         if (certReq == NULL) {
             GEN_BREAK(SECFailure)
         }
 
         subjectCert = MakeV1Cert(handle, certReq, issuerNickName, selfsign,
                                  serialNumber, warpmonths, validityMonths);
         if (subjectCert == NULL) {
             GEN_BREAK(SECFailure)
--- a/security/nss/cmd/crlutil/crlutil.c
+++ b/security/nss/cmd/crlutil/crlutil.c
@@ -61,18 +61,21 @@ FindCRL(CERTCertDBHandle *certHandle, ch
             return ((CERTSignedCrl *)NULL);
         }
 
         if (!derName.len || !derName.data) {
             SECU_PrintError(progName, "could not find certificate named '%s'", name);
             return ((CERTSignedCrl *)NULL);
         }
     } else {
-        SECITEM_CopyItem(NULL, &derName, &cert->derSubject);
+        SECStatus rv = SECITEM_CopyItem(NULL, &derName, &cert->derSubject);
         CERT_DestroyCertificate(cert);
+        if (rv != SECSuccess) {
+            return ((CERTSignedCrl *)NULL);
+        }
     }
 
     crl = SEC_FindCrlByName(certHandle, &derName, type);
     if (crl == NULL)
         SECU_PrintError(progName, "could not find %s's CRL", name);
     if (derName.data) {
         SECITEM_FreeItem(&derName, PR_FALSE);
     }
@@ -368,17 +371,17 @@ loser:
         CERT_DestroyCertificate(cert);
     return cert;
 }
 
 static CERTSignedCrl *
 CreateModifiedCRLCopy(PLArenaPool *arena, CERTCertDBHandle *certHandle,
                       CERTCertificate **cert, char *certNickName,
                       PRFileDesc *inFile, PRInt32 decodeOptions,
-                      PRInt32 importOptions)
+                      PRInt32 importOptions, secuPWData *pwdata)
 {
     SECItem crlDER = { 0, NULL, 0 };
     CERTSignedCrl *signCrl = NULL;
     CERTSignedCrl *modCrl = NULL;
     PLArenaPool *modArena = NULL;
     SECStatus rv = SECSuccess;
 
     if (!arena || !certHandle || !certNickName) {
@@ -414,17 +417,17 @@ CreateModifiedCRLCopy(PLArenaPool *arena
             /* If caCert is a v2 certificate, make sure that it
              * can be used for crl signing purpose */
             *cert = FindSigningCert(certHandle, modCrl, NULL);
             if (!*cert) {
                 goto loser;
             }
 
             rv = CERT_VerifySignedData(&modCrl->signatureWrap, *cert,
-                                       PR_Now(), NULL);
+                                       PR_Now(), pwdata);
             if (rv != SECSuccess) {
                 SECU_PrintError(progName, "fail to verify signed data\n");
                 goto loser;
             }
         }
     } else {
         modCrl = FindCRL(certHandle, certNickName, SEC_CRL_TYPE);
         if (!modCrl) {
@@ -702,17 +705,18 @@ GenerateCRL(CERTCertDBHandle *certHandle
     arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
     if (!arena) {
         SECU_PrintError(progName, "fail to allocate memory\n");
         return SECFailure;
     }
 
     if (modifyFlag == PR_TRUE) {
         signCrl = CreateModifiedCRLCopy(arena, certHandle, &cert, certNickName,
-                                        inFile, decodeOptions, importOptions);
+                                        inFile, decodeOptions, importOptions,
+                                        pwdata);
         if (signCrl == NULL) {
             rv = SECFailure;
             goto loser;
         }
     }
 
     if (!cert) {
         cert = FindSigningCert(certHandle, signCrl, certNickName);
--- a/security/nss/cmd/smimetools/cmsutil.c
+++ b/security/nss/cmd/smimetools/cmsutil.c
@@ -468,16 +468,17 @@ signed_data(struct signOptionsStr *signO
     if (signerinfo == NULL) {
         fprintf(stderr, "ERROR: cannot create CMS signerInfo object.\n");
         goto loser;
     }
     if (cms_verbose) {
         fprintf(stderr,
                 "Created CMS message, added signed data w/ signerinfo\n");
     }
+    signerinfo->cmsg->pwfn_arg = pwcb_arg;
     /* we want the cert chain included for this one */
     if (NSS_CMSSignerInfo_IncludeCerts(signerinfo, NSSCMSCM_CertChain,
                                        signOptions->options->certUsage) !=
         SECSuccess) {
         fprintf(stderr, "ERROR: cannot find cert chain.\n");
         goto loser;
     }
     if (cms_verbose) {
--- a/security/nss/coreconf/Linux.mk
+++ b/security/nss/coreconf/Linux.mk
@@ -101,26 +101,16 @@ endif
 endif
 endif
 
 
 ifneq ($(OS_TARGET),Android)
 LIBC_TAG		= _glibc
 endif
 
-ifeq ($(OS_RELEASE),2.0)
-	OS_REL_CFLAGS	+= -DLINUX2_0
-	MKSHLIB		= $(CC) -shared -Wl,-soname -Wl,$(@:$(OBJDIR)/%.so=%.so) $(RPATH)
-	ifdef MAPFILE
-		MKSHLIB += -Wl,--version-script,$(MAPFILE)
-	endif
-	PROCESS_MAP_FILE = grep -v ';-' $< | \
-         sed -e 's,;+,,' -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,;,' > $@
-endif
-
 ifdef BUILD_OPT
 ifeq (11,$(ALLOW_OPT_CODE_SIZE)$(OPT_CODE_SIZE))
 	OPTIMIZER = -Os
 else
 	OPTIMIZER = -O2
 endif
 ifdef MOZ_DEBUG_SYMBOLS
 	ifdef MOZ_DEBUG_FLAGS
@@ -134,25 +124,26 @@ endif
 ifndef COMPILER_TAG
 COMPILER_TAG := _$(CC_NAME)
 endif
 
 ifeq ($(USE_PTHREADS),1)
 OS_PTHREAD = -lpthread 
 endif
 
-OS_CFLAGS		= $(DSO_CFLAGS) $(OS_REL_CFLAGS) $(ARCHFLAG) -pipe -ffunction-sections -fdata-sections -DLINUX -Dlinux -DHAVE_STRERROR
+OS_CFLAGS		= $(DSO_CFLAGS) $(OS_REL_CFLAGS) $(ARCHFLAG) -pipe -ffunction-sections -fdata-sections -DHAVE_STRERROR
+ifeq ($(KERNEL),Linux)
+	OS_CFLAGS	+= -DLINUX -Dlinux
+endif
 OS_LIBS			= $(OS_PTHREAD) -ldl -lc
 
 ifdef USE_PTHREADS
 	DEFINES		+= -D_REENTRANT
 endif
 
-ARCH			= linux
-
 DSO_CFLAGS		= -fPIC
 DSO_LDOPTS		= -shared $(ARCHFLAG) -Wl,--gc-sections
 # The linker on Red Hat Linux 7.2 and RHEL 2.1 (GNU ld version 2.11.90.0.8)
 # incorrectly reports undefined references in the libraries we link with, so
 # we don't use -z defs there.
 # Also, -z defs conflicts with Address Sanitizer, which emits relocations
 # against the libsanitizer runtime built into the main executable.
 ZDEFS_FLAG		= -Wl,-z,defs
@@ -162,17 +153,16 @@ endif
 LDFLAGS			+= $(ARCHFLAG)
 
 # On Maemo, we need to use the -rpath-link flag for even the standard system
 # library directories.
 ifdef _SBOX_DIR
 LDFLAGS			+= -Wl,-rpath-link,/usr/lib:/lib
 endif
 
-# INCLUDES += -I/usr/include -Y/usr/include/linux
 G++INCLUDES		= -I/usr/include/g++
 
 #
 # Always set CPU_TAG on Linux.
 #
 CPU_TAG = _$(CPU_ARCH)
 
 #
@@ -197,17 +187,16 @@ ZLIB_LIBS = -lz
 ifeq ($(BUILD_SUN_PKG), 1)
 ifeq ($(USE_64), 1)
 RPATH = -Wl,-rpath,'$$ORIGIN:/opt/sun/private/lib64:/opt/sun/private/lib'
 else
 RPATH = -Wl,-rpath,'$$ORIGIN:/opt/sun/private/lib'
 endif
 endif
 
-OS_REL_CFLAGS   += -DLINUX2_1
 MKSHLIB         = $(CC) $(DSO_LDOPTS) -Wl,-soname -Wl,$(@:$(OBJDIR)/%.so=%.so) $(RPATH)
 
 ifdef MAPFILE
 	MKSHLIB += -Wl,--version-script,$(MAPFILE)
 endif
 PROCESS_MAP_FILE = grep -v ';-' $< | \
         sed -e 's,;+,,' -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,;,' > $@
 
--- a/security/nss/coreconf/arch.mk
+++ b/security/nss/coreconf/arch.mk
@@ -110,16 +110,30 @@ ifeq (,$(filter-out Linux FreeBSD IRIX,$
     OS_RELEASE := $(shell echo $(OS_RELEASE) | sed 's/-.*//')
 endif
 
 ifeq ($(OS_ARCH),Linux)
     OS_RELEASE := $(subst ., ,$(OS_RELEASE))
     ifneq ($(words $(OS_RELEASE)),1)
 	OS_RELEASE := $(word 1,$(OS_RELEASE)).$(word 2,$(OS_RELEASE))
     endif
+    KERNEL = Linux
+endif
+
+# Since all uses of OS_ARCH that follow affect only userland, we can
+# merge other Glibc systems with Linux here.
+ifeq ($(OS_ARCH),GNU)
+    OS_ARCH = Linux
+    OS_RELEASE = 2.6
+    KERNEL = GNU
+endif
+ifeq ($(OS_ARCH),GNU_kFreeBSD)
+    OS_ARCH = Linux
+    OS_RELEASE = 2.6
+    KERNEL = FreeBSD
 endif
 
 #
 # For OS/2
 #
 ifeq ($(OS_ARCH),OS_2)
     OS_ARCH = OS2
     OS_RELEASE := $(shell uname -v)
--- a/security/nss/coreconf/check_cc_clang.py
+++ b/security/nss/coreconf/check_cc_clang.py
@@ -1,20 +1,21 @@
 #!/usr/bin/env python
 
 import os
 import subprocess
 import sys
 
 def main():
     if sys.platform == 'win32':
-        print 0
+        print(0)
     else:
         cc = os.environ.get('CC', 'cc')
         try:
-            cc_is_clang = 'clang' in subprocess.check_output([cc, '--version'])
+            cc_is_clang = 'clang' in subprocess.check_output(
+              [cc, '--version'], universal_newlines=True)
         except OSError:
             # We probably just don't have CC/cc.
             cc_is_clang = False
-        print int(cc_is_clang)
+        print(int(cc_is_clang))
 
 if __name__ == '__main__':
     main()
--- a/security/nss/coreconf/config.gypi
+++ b/security/nss/coreconf/config.gypi
@@ -19,49 +19,55 @@
       'conditions': [
         ['OS=="android"', {
           'target_arch%': 'arm',
         }, {
           # Default architecture we're building for is the architecture we're
           # building on.
           'target_arch%': '<(host_arch)',
         }],
+        ['OS=="linux"', {
+          # FIPS-140 LOWHASH
+          'freebl_name': 'freeblpriv3',
+        }, {
+          'freebl_name': 'freebl3',
+        }],
+        ['OS=="mac"', {
+          'use_system_sqlite%': 1,
+        },{
+          'use_system_sqlite%': 0,
+        }],
+        ['OS=="mac" or OS=="win"', {
+          'cc_use_gnu_ld%': 0,
+        }, {
+          'cc_use_gnu_ld%': 1,
+        }],
         ['OS=="win"', {
           'use_system_zlib%': 0,
-          'nspr_libs%': ['nspr4.lib', 'plc4.lib', 'plds4.lib'],
+          'nspr_libs%': ['libnspr4.lib', 'libplc4.lib', 'libplds4.lib'],
           'zlib_libs%': [],
           #TODO
           'moz_debug_flags%': '',
           'dll_prefix': '',
           'dll_suffix': 'dll',
         }, {
+          'use_system_zlib%': 1,
           'nspr_libs%': ['-lplds4', '-lplc4', '-lnspr4'],
-          'use_system_zlib%': 1,
-        }],
-        ['OS=="linux" or OS=="android"', {
           'zlib_libs%': ['-lz'],
-          'moz_debug_flags%': '-gdwarf-2',
           'optimize_flags%': '-O2',
           'dll_prefix': 'lib',
-          'dll_suffix': 'so',
-        }],
-        ['OS=="linux"', {
-          'freebl_name': 'freeblpriv3',
-        }, {
-          'freebl_name': 'freebl3',
-        }],
-        ['OS=="mac"', {
-          'zlib_libs%': ['-lz'],
-          'use_system_sqlite%': 1,
-          'moz_debug_flags%': '-gdwarf-2 -gfull',
-          'optimize_flags%': '-O2',
-          'dll_prefix': 'lib',
-          'dll_suffix': 'dylib',
-        }, {
-          'use_system_sqlite%': 0,
+          'conditions': [
+            ['OS=="mac"', {
+              'moz_debug_flags%': '-gdwarf-2 -gfull',
+              'dll_suffix': 'dylib',
+            }, {
+              'moz_debug_flags%': '-gdwarf-2',
+              'dll_suffix': 'so',
+            }],
+          ],
         }],
         ['"<(GENERATOR)"=="ninja"', {
           'cc_is_clang%': '<!(<(python) <(DEPTH)/coreconf/check_cc_clang.py)',
         }, {
           'cc_is_clang%': '0',
         }],
       ],
     },
@@ -76,16 +82,17 @@
     'nspr_lib_dir%': '<(nspr_lib_dir)',
     'nspr_include_dir%': '<(nspr_include_dir)',
     'use_system_sqlite%': '<(use_system_sqlite)',
     'sqlite_libs%': ['-lsqlite3'],
     'dll_prefix': '<(dll_prefix)',
     'dll_suffix': '<(dll_suffix)',
     'freebl_name': '<(freebl_name)',
     'cc_is_clang%': '<(cc_is_clang)',
+    'cc_use_gnu_ld%': '<(cc_use_gnu_ld)',
     # Some defaults
     'disable_tests%': 0,
     'disable_chachapoly%': 0,
     'disable_dbm%': 0,
     'disable_libpkix%': 1,
     'disable_werror%': 0,
     'mozilla_client%': 0,
     'moz_fold_libs%': 0,
@@ -110,19 +117,23 @@
       'test_build%': 0,
     },
     'standalone_static_library': 0,
     'include_dirs': [
       '<(nspr_include_dir)',
       '<(nss_dist_dir)/private/<(module)',
     ],
     'conditions': [
+      [ 'OS!="android" and OS!="mac" and OS!="win"', {
+        'libraries': [
+          '-lpthread',
+        ],
+      }],
       [ 'OS=="linux"', {
         'libraries': [
-          '-lpthread',
           '-ldl',
           '-lc',
         ],
       }],
     ],
     'target_conditions': [
       # If we want to properly export a static library, and copy it to lib,
       # we need to mark it as a 'standalone_static_library'. Otherwise,
@@ -143,17 +154,17 @@
         ],
         'xcode_settings': {
           'OTHER_LDFLAGS': [
             '-exported_symbols_list',
             '<(INTERMEDIATE_DIR)/out.>(mapfile)',
           ],
         },
         'conditions': [
-          [ 'OS=="linux" or OS=="android"', {
+          [ 'cc_use_gnu_ld==1', {
             'ldflags': [
               '-Wl,--version-script,<(INTERMEDIATE_DIR)/out.>(mapfile)',
             ],
           }],
           [ 'OS=="win"', {
             # On Windows, .def files are used directly as sources.
             'sources': [
               '>(mapfile)',
@@ -190,21 +201,29 @@
         ],
         'library_dirs': [
           '<(nspr_lib_dir)',
         ],
       }],
       # Shared library specific settings.
       [ '_type=="shared_library"', {
         'conditions': [
-          [ 'OS=="linux" or OS=="android"', {
+          [ 'cc_use_gnu_ld==1', {
             'ldflags': [
               '-Wl,--gc-sections',
               '-Wl,-z,defs',
             ],
+            'conditions': [
+              ['OS=="dragonfly" or OS=="freebsd" or OS=="netbsd" or OS=="openbsd"', {
+                # Bug 1321317 - unix_rand.c:880: undefined reference to `environ'
+                'ldflags': [
+                  '-Wl,--warn-unresolved-symbols',
+                ],
+              }],
+            ],
           }],
         ],
         'xcode_settings': {
           'DYLIB_INSTALL_NAME_BASE': '@executable_path',
           'DYLIB_COMPATIBILITY_VERSION': '1',
           'DYLIB_CURRENT_VERSION': '1',
           'OTHER_LDFLAGS': [
             '-headerpad_max_install_names',
@@ -246,20 +265,46 @@
           ],
         },
         'conditions': [
           [ 'OS=="linux" or OS=="android"', {
             'defines': [
               'LINUX2_1',
               'LINUX',
               'linux',
+            ],
+          }],
+          [ 'OS=="dragonfly" or OS=="freebsd"', {
+            'defines': [
+              'FREEBSD',
+            ],
+          }],
+          [ 'OS=="netbsd"', {
+            'defines': [
+              'NETBSD',
+            ],
+          }],
+          [ 'OS=="openbsd"', {
+            'defines': [
+              'OPENBSD',
+            ],
+          }],
+          ['OS=="mac" or OS=="dragonfly" or OS=="freebsd" or OS=="netbsd" or OS=="openbsd"', {
+            'defines': [
+              'HAVE_BSD_FLOCK',
+            ],
+          }],
+          [ 'OS!="win"', {
+            'defines': [
               'HAVE_STRERROR',
               'XP_UNIX',
               '_REENTRANT',
             ],
+          }],
+          [ 'OS!="mac" and OS!="win"', {
             'cflags': [
               '-fPIC',
               '-pipe',
               '-ffunction-sections',
               '-fdata-sections',
             ],
             'cflags_cc': [
               '-std=c++0x',
@@ -270,38 +315,43 @@
                 'ldflags': ['-m32'],
               }],
               [ 'target_arch=="x64"', {
                 'cflags': ['-m64'],
                 'ldflags': ['-m64'],
               }],
             ],
           }],
-          [ 'use_pprof==1 and OS=="linux"', {
-            'ldflags': [ '-lprofiler' ],
-          }],
-          [ 'use_pprof==1 and OS=="mac"', {
-            'xcode_settings': {
-              'OTHER_LDFLAGS': [ '-lprofiler' ],
-            },
-            'library_dirs': [
-              '/usr/local/lib/',
+          [ 'use_pprof==1 and OS!="android" and OS!="win"', {
+            'conditions': [
+              [ 'OS=="mac"', {
+                'xcode_settings': {
+                  'OTHER_LDFLAGS': [ '-lprofiler' ],
+                },
+              }, {
+                'ldflags': [ '-lprofiler' ],
+              }],
+              [ 'OS!="linux"', {
+                'library_dirs': [
+                  '/usr/local/lib/',
+                ],
+              }],
             ],
           }],
-          [ 'disable_werror==0 and (OS=="linux" or OS=="mac")', {
+          [ 'disable_werror==0 and OS!="android" and OS!="win"', {
             'cflags': [
               '<!@(<(python) <(DEPTH)/coreconf/werror.py)',
             ],
           }],
           [ 'fuzz==1', {
             'cflags': [
               '-Wno-unused-function',
             ]
           }],
-          [ 'fuzz==1 or use_asan==1 or use_ubsan==1', {
+          [ 'fuzz==1 or use_asan==1 or use_ubsan!=0', {
             'cflags': ['-O1'],
             'xcode_settings': {
               'GCC_OPTIMIZATION_LEVEL': '1', # -O1
             }
           }],
           [ 'use_asan==1', {
             'variables': {
               'asan_flags': '<!(<(python) <(DEPTH)/coreconf/sanitizers.py asan)',
@@ -316,19 +366,19 @@
               # We want to pass -fsanitize=... to our final link call,
               # but not to libtool. OTHER_LDFLAGS is passed to both.
               # To trick GYP into doing what we want, we'll piggyback on
               # LIBRARY_SEARCH_PATHS, producing "-L/usr/lib -fsanitize=...".
               # The -L/usr/lib is redundant but innocuous: it's a default path.
               'LIBRARY_SEARCH_PATHS': ['/usr/lib <(asan_flags)'],
             },
           }],
-          [ 'use_ubsan==1', {
+          [ 'use_ubsan!=0', {
             'variables': {
-              'ubsan_flags': '<!(<(python) <(DEPTH)/coreconf/sanitizers.py ubsan)',
+              'ubsan_flags': '<!(<(python) <(DEPTH)/coreconf/sanitizers.py ubsan <(use_ubsan))',
               'no_ldflags': '<!(<(python) <(DEPTH)/coreconf/sanitizers.py ld)',
             },
             'cflags': ['<@(ubsan_flags)'],
             'ldflags': ['<@(ubsan_flags)'],
             'ldflags!': ['<@(no_ldflags)'],
             'xcode_settings': {
               'OTHER_CFLAGS': ['<@(ubsan_flags)'],
               'OTHER_LDFLAGS!': ['<@(no_ldflags)'],
@@ -371,19 +421,16 @@
               'NO_SYSINFO',
               'NO_FORK_CHECK',
               'ANDROID',
             ],
           }],
           [ 'OS=="mac"', {
             'defines': [
               'DARWIN',
-              'HAVE_STRERROR',
-              'HAVE_BSD_FLOCK',
-              'XP_UNIX',
             ],
             'conditions': [
               [ 'target_arch=="ia32"', {
                 'xcode_settings': {
                   'ARCHS': ['i386'],
                 },
               }],
               [ 'target_arch=="x64"', {
@@ -454,17 +501,17 @@
             ],
           }],
         ],
       },
       # Common settings for debug should go here.
       'Debug': {
         'inherit_from': ['Common'],
         'conditions': [
-          [ 'OS=="linux" or OS=="android"', {
+          [ 'OS!="mac" and OS!="win"', {
             'cflags': [
               '-g',
               '<(moz_debug_flags)',
             ],
           }]
         ],
         #TODO: DEBUG_$USER
         'defines': ['DEBUG'],
@@ -519,19 +566,19 @@
           'Release_x64': {
             'inherit_from': ['Release'],
           },
         }],
       ],
     },
   },
   'conditions': [
-    [ 'OS=="linux" or OS=="android"', {
+    [ 'cc_use_gnu_ld==1', {
       'variables': {
-        'process_map_file': ['/bin/sh', '-c', '/bin/grep -v ";-" >(mapfile) | sed -e "s,;+,," -e "s; DATA ;;" -e "s,;;,," -e "s,;.*,;," > >@(_outputs)'],
+        'process_map_file': ['/bin/sh', '-c', '/usr/bin/env grep -v ";-" >(mapfile) | sed -e "s,;+,," -e "s; DATA ;;" -e "s,;;,," -e "s,;.*,;," > >@(_outputs)'],
       },
     }],
     [ 'OS=="mac"', {
       'variables': {
         'process_map_file': ['/bin/sh', '-c', '/usr/bin/grep -v ";+" >(mapfile) | grep -v ";-" | sed -e "s; DATA ;;" -e "s,;;,," -e "s,;.*,," -e "s,^,_," > >@(_outputs)'],
       },
     }],
   ],
--- a/security/nss/coreconf/coreconf.dep
+++ b/security/nss/coreconf/coreconf.dep
@@ -5,9 +5,8 @@
 
 /*
  * A dummy header file that is a dependency for all the object files.
  * Used to force a full recompilation of NSS in Mozilla's Tinderbox
  * depend builds.  See comments in rules.mk.
  */
 
 #error "Do not include this header file."
-
--- a/security/nss/coreconf/nspr.sh
+++ b/security/nss/coreconf/nspr.sh
@@ -1,20 +1,25 @@
-#!/bin/bash
+#!/usr/bin/env bash
 # This script builds NSPR for NSS.
 #
 # This build system is still under development.  It does not yet support all
 # the features or platforms that the regular NSPR build supports.
 
 # variables
 nspr_opt=()
 nspr_cflags=
 nspr_cxxflags=
 nspr_ldflags=
 
+# Try to avoid bmake on OS X and BSD systems
+if hash gmake 2>/dev/null; then
+    make() { command gmake "$@"; }
+fi
+
 nspr_sanitizer()
 {
     nspr_cflags="$nspr_cflags $(python $cwd/coreconf/sanitizers.py $1 $2)"
     nspr_cxxflags="$nspr_cxxflags $(python $cwd/coreconf/sanitizers.py $1 $2)"
     nspr_ldflags="$nspr_ldflags $(python $cwd/coreconf/sanitizers.py $1 $2)"
 }
 
 verbose()
--- a/security/nss/coreconf/sanitizers.py
+++ b/security/nss/coreconf/sanitizers.py
@@ -4,17 +4,19 @@ from __future__ import print_function
 import sys
 
 def main():
     if len(sys.argv) < 2:
         raise Exception('Specify either "ld", asan", "msan", "sancov" or "ubsan" as argument.')
 
     sanitizer = sys.argv[1]
     if sanitizer == "ubsan":
-        print('-fsanitize=undefined -fno-sanitize-recover=undefined ', end='')
+        if len(sys.argv) < 3:
+            raise Exception('ubsan requires another argument.')
+        print('-fsanitize='+sys.argv[2]+' -fno-sanitize-recover=undefined ', end='')
         return
     if sanitizer == "asan":
         print('-fsanitize=address ', end='')
         print('-fno-omit-frame-pointer -fno-optimize-sibling-calls ', end='')
         return
     if sanitizer == "msan":
         print('-fsanitize=memory -fsanitize-memory-track-origins ', end='')
         print('-fno-omit-frame-pointer -fno-optimize-sibling-calls ', end='')
--- a/security/nss/coreconf/werror.py
+++ b/security/nss/coreconf/werror.py
@@ -2,17 +2,18 @@
 
 import os
 import subprocess
 
 def main():
     cc = os.environ.get('CC', 'cc')
     sink = open(os.devnull, 'wb')
     try:
-        cc_is_clang = 'clang' in subprocess.check_output([cc, '--version'], stderr=sink)
+        cc_is_clang = 'clang' in subprocess.check_output(
+          [cc, '--version'], universal_newlines=True, stderr=sink)
     except OSError:
         # We probably just don't have CC/cc.
         return
 
     def warning_supported(warning):
         return subprocess.call([cc, '-x', 'c', '-E', '-Werror',
                                 '-W%s' % warning, os.devnull], stdout=sink, stderr=sink) == 0
     def can_enable():
--- a/security/nss/gtests/ssl_gtest/libssl_internals.c
+++ b/security/nss/gtests/ssl_gtest/libssl_internals.c
@@ -340,8 +340,33 @@ PK11SymKey *SSLInt_CipherSpecToKey(PRBoo
 SSLCipherAlgorithm SSLInt_CipherSpecToAlgorithm(PRBool isServer,
                                                 ssl3CipherSpec *spec) {
   return spec->cipher_def->calg;
 }
 
 unsigned char *SSLInt_CipherSpecToIv(PRBool isServer, ssl3CipherSpec *spec) {
   return GetKeyingMaterial(isServer, spec)->write_iv;
 }
+
+SECStatus SSLInt_EnableShortHeaders(PRFileDesc *fd) {
+  sslSocket *ss;
+
+  ss = ssl_FindSocket(fd);
+  if (!ss) {
+    return SECFailure;
+  }
+
+  ss->opt.enableShortHeaders = PR_TRUE;
+  return SECSuccess;
+}
+
+SECStatus SSLInt_UsingShortHeaders(PRFileDesc *fd, PRBool *result) {
+  sslSocket *ss;
+
+  ss = ssl_FindSocket(fd);
+  if (!ss) {
+    return SECFailure;
+  }
+
+  *result = ss->ssl3.hs.shortHeaders;
+
+  return SECSuccess;
+}
--- a/security/nss/gtests/ssl_gtest/libssl_internals.h
+++ b/security/nss/gtests/ssl_gtest/libssl_internals.h
@@ -42,10 +42,12 @@ SSLKEAType SSLInt_GetKEAType(SSLNamedGro
 
 SECStatus SSLInt_SetCipherSpecChangeFunc(PRFileDesc *fd,
                                          sslCipherSpecChangedFunc func,
                                          void *arg);
 PK11SymKey *SSLInt_CipherSpecToKey(PRBool isServer, ssl3CipherSpec *spec);
 SSLCipherAlgorithm SSLInt_CipherSpecToAlgorithm(PRBool isServer,
                                                 ssl3CipherSpec *spec);
 unsigned char *SSLInt_CipherSpecToIv(PRBool isServer, ssl3CipherSpec *spec);
+SECStatus SSLInt_EnableShortHeaders(PRFileDesc *fd);
+SECStatus SSLInt_UsingShortHeaders(PRFileDesc *fd, PRBool *result);
 
 #endif  // ndef libssl_internals_h_
--- a/security/nss/gtests/ssl_gtest/ssl_gtest.gyp
+++ b/security/nss/gtests/ssl_gtest/ssl_gtest.gyp
@@ -91,13 +91,17 @@
     }
   ],
   'target_defaults': {
     'include_dirs': [
       '../../gtests/google_test/gtest/include',
       '../../gtests/common',
       '../../lib/ssl'
     ],
+    'defines': [
+      'NSS_USE_STATIC_LIBS'
+    ],
   },
   'variables': {
     'module': 'nss',
+    'use_static_libs': 1,
   }
 }
--- a/security/nss/gtests/ssl_gtest/ssl_loopback_unittest.cc
+++ b/security/nss/gtests/ssl_gtest/ssl_loopback_unittest.cc
@@ -215,16 +215,24 @@ TEST_F(TlsConnectStreamTls13, Tls13Faile
   server_->StartConnect();
   client_->Handshake();
   server_->Handshake();  // Send first flight.
   client_->adapter()->CloseWrites();
   client_->Handshake();  // This will get an error, but shouldn't crash.
   client_->CheckErrorCode(SSL_ERROR_SOCKET_WRITE_FAILURE);
 }
 
+TEST_F(TlsConnectStreamTls13, NegotiateShortHeaders) {
+  client_->SetShortHeadersEnabled();
+  server_->SetShortHeadersEnabled();
+  client_->ExpectShortHeaders();
+  server_->ExpectShortHeaders();
+  Connect();
+}
+
 INSTANTIATE_TEST_CASE_P(GenericStream, TlsConnectGeneric,
                         ::testing::Combine(TlsConnectTestBase::kTlsModesStream,
                                            TlsConnectTestBase::kTlsVAll));
 INSTANTIATE_TEST_CASE_P(
     GenericDatagram, TlsConnectGeneric,
     ::testing::Combine(TlsConnectTestBase::kTlsModesDatagram,
                        TlsConnectTestBase::kTlsV11Plus));
 
--- a/security/nss/gtests/ssl_gtest/tls_agent.cc
+++ b/security/nss/gtests/ssl_gtest/tls_agent.cc
@@ -63,17 +63,18 @@ TlsAgent::TlsAgent(const std::string& na
       auth_certificate_hook_called_(false),
       handshake_callback_called_(false),
       error_code_(0),
       send_ctr_(0),
       recv_ctr_(0),
       expect_readwrite_error_(false),
       handshake_callback_(),
       auth_certificate_callback_(),
-      sni_callback_() {
+      sni_callback_(),
+      expect_short_headers_(false) {
   memset(&info_, 0, sizeof(info_));
   memset(&csinfo_, 0, sizeof(csinfo_));
   SECStatus rv = SSL_VersionRangeGetDefault(
       mode_ == STREAM ? ssl_variant_stream : ssl_variant_datagram, &vrange_);
   EXPECT_EQ(SECSuccess, rv);
 }
 
 TlsAgent::~TlsAgent() {
@@ -360,16 +361,23 @@ void TlsAgent::SetSessionCacheEnabled(bo
 void TlsAgent::Set0RttEnabled(bool en) {
   EXPECT_TRUE(EnsureTlsSetup());
 
   SECStatus rv =
       SSL_OptionSet(ssl_fd_, SSL_ENABLE_0RTT_DATA, en ? PR_TRUE : PR_FALSE);
   EXPECT_EQ(SECSuccess, rv);
 }
 
+void TlsAgent::SetShortHeadersEnabled() {
+  EXPECT_TRUE(EnsureTlsSetup());
+
+  SECStatus rv = SSLInt_EnableShortHeaders(ssl_fd_);
+  EXPECT_EQ(SECSuccess, rv);
+}
+
 void TlsAgent::SetVersionRange(uint16_t minver, uint16_t maxver) {
   vrange_.min = minver;
   vrange_.max = maxver;
 
   if (ssl_fd_) {
     SECStatus rv = SSL_VersionRangeSet(ssl_fd_, &vrange_);
     EXPECT_EQ(SECSuccess, rv);
   }
@@ -383,16 +391,18 @@ void TlsAgent::GetVersionRange(uint16_t*
 void TlsAgent::SetExpectedVersion(uint16_t version) {
   expected_version_ = version;
 }
 
 void TlsAgent::SetServerKeyBits(uint16_t bits) { server_key_bits_ = bits; }
 
 void TlsAgent::ExpectReadWriteError() { expect_readwrite_error_ = true; }
 
+void TlsAgent::ExpectShortHeaders() { expect_short_headers_ = true; }
+
 void TlsAgent::SetSignatureSchemes(const SSLSignatureScheme* schemes,
                                    size_t count) {
   EXPECT_TRUE(EnsureTlsSetup());
   EXPECT_LE(count, SSL_SignatureMaxCount());
   EXPECT_EQ(SECSuccess,
             SSL_SignatureSchemePrefSet(ssl_fd_, schemes,
                                        static_cast<unsigned int>(count)));
   EXPECT_EQ(SECFailure, SSL_SignatureSchemePrefSet(ssl_fd_, schemes, 0))
@@ -653,16 +663,20 @@ void TlsAgent::Connected() {
     // by DTLS for retransmission.
     PRInt32 expected = ((mode_ == DGRAM) && (role_ == CLIENT)) ? 3 : 2;
     EXPECT_EQ(expected, cipherSuites);
     if (expected != cipherSuites) {
       SSLInt_PrintTls13CipherSpecs(ssl_fd_);
     }
   }
 
+  PRBool short_headers;
+  rv = SSLInt_UsingShortHeaders(ssl_fd_, &short_headers);
+  EXPECT_EQ(SECSuccess, rv);
+  EXPECT_EQ((PRBool)expect_short_headers_, short_headers);
   SetState(STATE_CONNECTED);
 }
 
 void TlsAgent::EnableExtendedMasterSecret() {
   ASSERT_TRUE(EnsureTlsSetup());
 
   SECStatus rv =
       SSL_OptionSet(ssl_fd_, SSL_ENABLE_EXTENDED_MASTER_SECRET, PR_TRUE);
--- a/security/nss/gtests/ssl_gtest/tls_agent.h
+++ b/security/nss/gtests/ssl_gtest/tls_agent.h
@@ -124,25 +124,27 @@ class TlsAgent : public PollTarget {
   void RequestClientAuth(bool requireAuth);
   bool GetClientAuthCredentials(CERTCertificate** cert,
                                 SECKEYPrivateKey** priv) const;
 
   void ConfigureSessionCache(SessionResumptionMode mode);
   void SetSessionTicketsEnabled(bool en);
   void SetSessionCacheEnabled(bool en);
   void Set0RttEnabled(bool en);
+  void SetShortHeadersEnabled();
   void SetVersionRange(uint16_t minver, uint16_t maxver);
   void GetVersionRange(uint16_t* minver, uint16_t* maxver);
   void CheckPreliminaryInfo();
   void ResetPreliminaryInfo();
   void SetExpectedVersion(uint16_t version);
   void SetServerKeyBits(uint16_t bits);
   void ExpectReadWriteError();
   void EnableFalseStart();
   void ExpectResumption();
+  void ExpectShortHeaders();
   void SetSignatureSchemes(const SSLSignatureScheme* schemes, size_t count);
   void EnableAlpn(const uint8_t* val, size_t len);
   void CheckAlpn(SSLNextProtoState expected_state,
                  const std::string& expected = "") const;
   void EnableSrtp();
   void CheckSrtp() const;
   void CheckErrorCode(int32_t expected) const;
   void WaitForErrorCode(int32_t expected, uint32_t delay) const;
@@ -364,16 +366,17 @@ class TlsAgent : public PollTarget {
   SSLVersionRange vrange_;
   PRErrorCode error_code_;
   size_t send_ctr_;
   size_t recv_ctr_;
   bool expect_readwrite_error_;
   HandshakeCallbackFunction handshake_callback_;
   AuthCertificateCallbackFunction auth_certificate_callback_;
   SniCallbackFunction sni_callback_;
+  bool expect_short_headers_;
 };
 
 inline std::ostream& operator<<(std::ostream& stream,
                                 const TlsAgent::State& state) {
   return stream << TlsAgent::state_str(state);
 }
 
 class TlsAgentTestBase : public ::testing::Test {
--- a/security/nss/lib/certhigh/certhigh.c
+++ b/security/nss/lib/certhigh/certhigh.c
@@ -1075,17 +1075,20 @@ CERT_CertChainFromCert(CERTCertificate *
         SECItem derCert;
         CERTCertificate *cCert = STAN_GetCERTCertificate(stanCert);
         if (!cCert) {
             goto loser;
         }
         derCert.len = (unsigned int)stanCert->encoding.size;
         derCert.data = (unsigned char *)stanCert->encoding.data;
         derCert.type = siBuffer;
-        SECITEM_CopyItem(arena, &chain->certs[i], &derCert);
+        if (SECITEM_CopyItem(arena, &chain->certs[i], &derCert) != SECSuccess) {
+            CERT_DestroyCertificate(cCert);
+            goto loser;
+        }
         stanCert = stanChain[++i];
         if (!stanCert && !cCert->isRoot) {
             /* reached the end of the chain, but the final cert is
              * not a root.  Don't discard it.
              */
             includeRoot = PR_TRUE;
         }
         CERT_DestroyCertificate(cCert);
--- a/security/nss/lib/certhigh/certvfy.c
+++ b/security/nss/lib/certhigh/certvfy.c
@@ -393,16 +393,152 @@ cert_AddToVerifyLog(CERTVerifyLog *log, 
     }
 
 #define LOG_ERROR(log, cert, depth, arg)                       \
     if (log != NULL) {                                         \
         cert_AddToVerifyLog(log, cert, PORT_GetError(), depth, \
                             (void *)(PRWord)arg);              \
     }
 
+/* /C=CN/O=WoSign CA Limited/CN=CA \xE6\xB2\x83\xE9\x80\x9A\xE6\xA0\xB9\xE8\xAF\x81\xE4\xB9\xA6
+ * Using a consistent naming convention, this would actually be called
+ * 'CA沃通根证书DN', but since GCC 6.2.1 apparently can't handle UTF-8
+ * identifiers, this will have to do.
+ */
+static const unsigned char CAWoSignRootDN[72] = {
+    0x30, 0x46, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+    0x43, 0x4E, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x11,
+    0x57, 0x6F, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x43, 0x41, 0x20, 0x4C, 0x69, 0x6D,
+    0x69, 0x74, 0x65, 0x64, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03,
+    0x0C, 0x12, 0x43, 0x41, 0x20, 0xE6, 0xB2, 0x83, 0xE9, 0x80, 0x9A, 0xE6, 0xA0,
+    0xB9, 0xE8, 0xAF, 0x81, 0xE4, 0xB9, 0xA6,
+};
+
+/* /C=CN/O=WoSign CA Limited/CN=CA WoSign ECC Root */
+static const unsigned char CAWoSignECCRootDN[72] = {
+    0x30, 0x46, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+    0x43, 0x4E, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x11,
+    0x57, 0x6F, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x43, 0x41, 0x20, 0x4C, 0x69, 0x6D,
+    0x69, 0x74, 0x65, 0x64, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03,
+    0x13, 0x12, 0x43, 0x41, 0x20, 0x57, 0x6F, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x45,
+    0x43, 0x43, 0x20, 0x52, 0x6F, 0x6F, 0x74,
+};
+
+/* /C=CN/O=WoSign CA Limited/CN=Certification Authority of WoSign */
+static const unsigned char CertificationAuthorityofWoSignDN[87] = {
+    0x30, 0x55, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+    0x43, 0x4E, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x11,
+    0x57, 0x6F, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x43, 0x41, 0x20, 0x4C, 0x69, 0x6D,
+    0x69, 0x74, 0x65, 0x64, 0x31, 0x2A, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, 0x03,
+    0x13, 0x21, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69,
+    0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20,
+    0x6F, 0x66, 0x20, 0x57, 0x6F, 0x53, 0x69, 0x67, 0x6E,
+};
+
+/* /C=CN/O=WoSign CA Limited/CN=Certification Authority of WoSign G2 */
+static const unsigned char CertificationAuthorityofWoSignG2DN[90] = {
+    0x30, 0x58, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+    0x43, 0x4E, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x11,
+    0x57, 0x6F, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x43, 0x41, 0x20, 0x4C, 0x69, 0x6D,
+    0x69, 0x74, 0x65, 0x64, 0x31, 0x2D, 0x30, 0x2B, 0x06, 0x03, 0x55, 0x04, 0x03,
+    0x13, 0x24, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69,
+    0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79, 0x20,
+    0x6F, 0x66, 0x20, 0x57, 0x6F, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x47, 0x32,
+};
+
+/* /C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing/CN=StartCom Certification Authority */
+static const unsigned char StartComCertificationAuthorityDN[127] = {
+    0x30, 0x7D, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+    0x49, 0x4C, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0D,
+    0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6F, 0x6D, 0x20, 0x4C, 0x74, 0x64, 0x2E,
+    0x31, 0x2B, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x22, 0x53, 0x65,
+    0x63, 0x75, 0x72, 0x65, 0x20, 0x44, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6C, 0x20,
+    0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x53,
+    0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55,
+    0x04, 0x03, 0x13, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6F, 0x6D, 0x20,
+    0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E,
+    0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79,
+};
+
+/* /C=IL/O=StartCom Ltd./CN=StartCom Certification Authority G2 */
+static const unsigned char StartComCertificationAuthorityG2DN[85] = {
+    0x30, 0x53, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+    0x49, 0x4C, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0D,
+    0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6F, 0x6D, 0x20, 0x4C, 0x74, 0x64, 0x2E,
+    0x31, 0x2C, 0x30, 0x2A, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x23, 0x53, 0x74,
+    0x61, 0x72, 0x74, 0x43, 0x6F, 0x6D, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
+    0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F,
+    0x72, 0x69, 0x74, 0x79, 0x20, 0x47, 0x32,
+};
+
+struct DataAndLength {
+    const unsigned char *data;
+    PRUint32 len;
+};
+
+static const struct DataAndLength StartComAndWoSignDNs[] = {
+    { CAWoSignRootDN,
+      sizeof(CAWoSignRootDN) },
+    { CAWoSignECCRootDN,
+      sizeof(CAWoSignECCRootDN) },
+    { CertificationAuthorityofWoSignDN,
+      sizeof(CertificationAuthorityofWoSignDN) },
+    { CertificationAuthorityofWoSignG2DN,
+      sizeof(CertificationAuthorityofWoSignG2DN) },
+    { StartComCertificationAuthorityDN,
+      sizeof(StartComCertificationAuthorityDN) },
+    { StartComCertificationAuthorityG2DN,
+      sizeof(StartComCertificationAuthorityG2DN) },
+};
+
+static PRBool
+CertIsStartComOrWoSign(const CERTCertificate *cert)
+{
+    int i;
+    const struct DataAndLength *dn = StartComAndWoSignDNs;
+
+    for (i = 0; i < sizeof(StartComAndWoSignDNs) / sizeof(struct DataAndLength); ++i, dn++) {
+        if (cert->derSubject.len == dn->len &&
+            memcmp(cert->derSubject.data, dn->data, dn->len) == 0) {
+            return PR_TRUE;
+        }
+    }
+    return PR_FALSE;
+}
+
+SECStatus
+isIssuerCertAllowedAtCertIssuanceTime(CERTCertificate *issuerCert,
+                                      CERTCertificate *referenceCert)
+{
+    if (!issuerCert || !referenceCert) {
+        PORT_SetError(SEC_ERROR_INVALID_ARGS);
+        return SECFailure;
+    }
+
+    if (CertIsStartComOrWoSign(issuerCert)) {
+        /* PRTime is microseconds since the epoch, whereas JS time is milliseconds.
+         * (new Date("2016-10-21T00:00:00Z")).getTime() * 1000
+         */
+        static const PRTime OCTOBER_21_2016 = 1477008000000000;
+
+        PRTime notBefore, notAfter;
+        SECStatus rv;
+
+        rv = CERT_GetCertTimes(referenceCert, &notBefore, &notAfter);
+        if (rv != SECSuccess)
+            return rv;
+
+        if (notBefore > OCTOBER_21_2016) {
+            return SECFailure;
+        }
+    }
+
+    return SECSuccess;
+}
+
 static SECStatus
 cert_VerifyCertChainOld(CERTCertDBHandle *handle, CERTCertificate *cert,
                         PRBool checkSig, PRBool *sigerror,
                         SECCertUsage certUsage, PRTime t, void *wincx,
                         CERTVerifyLog *log, PRBool *revoked)
 {
     SECTrustType trustType;
     CERTBasicConstraints basicConstraint;
@@ -610,16 +746,23 @@ cert_VerifyCertChainOld(CERTCertDBHandle
         rv = CERT_CompareNameSpace(issuerCert, namesList, certsList,
                                    arena, &badCert);
         if (rv != SECSuccess || badCert != NULL) {
             PORT_SetError(SEC_ERROR_CERT_NOT_IN_NAME_SPACE);
             LOG_ERROR_OR_EXIT(log, badCert, count + 1, 0);
             goto loser;
         }
 
+        rv = isIssuerCertAllowedAtCertIssuanceTime(issuerCert, cert);
+        if (rv != SECSuccess) {
+            PORT_SetError(SEC_ERROR_UNTRUSTED_ISSUER);
+            LOG_ERROR(log, issuerCert, count + 1, 0);
+            goto loser;
+        }
+
         /* XXX - the error logging may need to go down into CRL stuff at some
          * point
          */
         /* check revoked list (issuer) */
         rv = SEC_CheckCRL(handle, subjectCert, issuerCert, t, wincx);
         if (rv == SECFailure) {
             if (revoked) {
                 *revoked = PR_TRUE;
--- a/security/nss/lib/freebl/freebl.gyp
+++ b/security/nss/lib/freebl/freebl.gyp
@@ -401,16 +401,21 @@
           [ 'target_arch=="arm"', {
             'defines': [
               'MP_ASSEMBLY_MULTIPLY',
               'MP_ASSEMBLY_SQUARE',
               'MP_USE_UINT_DIGIT',
               'SHA_NO_LONG_LONG',
             ],
           }],
+          [ 'target_arch=="arm64"', {
+            'defines': [
+              'NSS_USE_64',
+            ],
+          }],
         ],
       }],
     ],
   },
   'variables': {
     'module': 'nss',
   }
 }
--- a/security/nss/lib/freebl/unix_rand.c
+++ b/security/nss/lib/freebl/unix_rand.c
@@ -155,17 +155,17 @@ RNG_kstat(PRUint32 *fed)
         PORT_Assert(0);
         rv = SECFailure;
     }
     return rv;
 }
 
 #endif
 
-#if defined(SCO) || defined(UNIXWARE) || defined(BSDI) || defined(FREEBSD) || defined(NETBSD) || defined(DARWIN) || defined(OPENBSD) || defined(NTO) || defined(__riscos__)
+#if defined(SCO) || defined(UNIXWARE) || defined(BSDI) || defined(FREEBSD) || defined(NETBSD) || defined(DARWIN) || defined(OPENBSD) || defined(NTO) || defined(__riscos__) || defined(__GNU__) || defined(__FreeBSD_kernel__) || defined(__NetBSD_kernel__)
 #include <sys/times.h>
 
 #define getdtablesize() sysconf(_SC_OPEN_MAX)
 
 static size_t
 GetHighResClock(void *buf, size_t maxbytes)
 {
     int ticks;
--- a/security/nss/lib/libpkix/include/pkix_errorstrings.h
+++ b/security/nss/lib/libpkix/include/pkix_errorstrings.h
@@ -1090,9 +1090,10 @@ PKIX_ERRORENTRY(X500NAMEGETCOMMONNAMEFAI
 PKIX_ERRORENTRY(X500NAMEGETCOUNTRYNAMEFAILED,pkix_pl_X500Name_GetCountryName failed,0),
 PKIX_ERRORENTRY(X500NAMEGETORGNAMEFAILED,pkix_pl_X500Name_GetOrgName failed,0),
 PKIX_ERRORENTRY(X500NAMEGETSECNAMEFAILED,pkix_pl_X500Name_GetSECName failed,0),
 PKIX_ERRORENTRY(X500NAMEHASHCODEFAILED,PKIX_PL_X500Name_Hashcode failed,0),
 PKIX_ERRORENTRY(X500NAMEMATCHFAILED,PKIX_PL_X500Name_Match failed,0),
 PKIX_ERRORENTRY(X500NAMETOSTRINGFAILED,PKIX_PL_X500Name_ToString failed,0),
 PKIX_ERRORENTRY(ZEROLENGTHBYTEARRAYFORCRLENCODING,Zero-length ByteArray for CRL encoding,0),
 PKIX_ERRORENTRY(INVALIDOCSPHTTPMETHOD,Unsupported HTTP Method for OCSP retrieval,0),
-PKIX_ERRORENTRY(OCSPGETREQUESTTOOBIG,OCSP request too big for HTTP GET method,0)
+PKIX_ERRORENTRY(OCSPGETREQUESTTOOBIG,OCSP request too big for HTTP GET method,0),
+PKIX_ERRORENTRY(CERTISBLACKLISTEDATISSUANCETIME,Issuer Certificate is distrusted at the time the subordinate certifiate was issued,SEC_ERROR_UNTRUSTED_ISSUER)
--- a/security/nss/lib/libpkix/pkix/top/pkix_build.c
+++ b/security/nss/lib/libpkix/pkix/top/pkix_build.c
@@ -1938,16 +1938,20 @@ pkix_PrepareForwardBuilderStateForAIA(
 {
         PORT_Assert(state->useOnlyLocal == PKIX_TRUE);
         state->useOnlyLocal = PKIX_FALSE;
         state->certStoreIndex = 0;
         state->numFanout = state->buildConstants.maxFanout;
         state->status = BUILD_TRYAIA;
 }
 
+extern SECStatus
+isIssuerCertAllowedAtCertIssuanceTime(CERTCertificate *issuerCert,
+                                      CERTCertificate *referenceCert);
+
 /*
  * FUNCTION: pkix_BuildForwardDepthFirstSearch
  * DESCRIPTION:
  *
  *  This function performs a depth first search in the "forward" direction (from
  *  the target Cert to the trust anchor). A non-NULL targetCert must be stored
  *  in the ForwardBuilderState before this function is called. It is not written
  *  recursively since execution may be suspended in in any of several places
@@ -2052,31 +2056,33 @@ pkix_BuildForwardDepthFirstSearch(
         PKIX_PL_Object *subjectName = NULL;
         PKIX_ValidateResult *valResult = NULL;
         PKIX_ForwardBuilderState *childState = NULL;
         PKIX_ForwardBuilderState *parentState = NULL;
         PKIX_PL_Object *revCheckerState = NULL;
         PKIX_ComCertSelParams *certSelParams = NULL;
         PKIX_TrustAnchor *trustAnchor = NULL;
         PKIX_PL_Cert *trustedCert = NULL;
+        PKIX_PL_Cert *targetCert = NULL;
         PKIX_VerifyNode *verifyNode = NULL;
         PKIX_Error *verifyError = NULL;
         PKIX_Error *finalError = NULL;
         void *nbio = NULL;
         PKIX_UInt32 numIterations = 0;
 
         PKIX_ENTER(BUILD, "pkix_BuildForwardDepthFirstSearch");
         PKIX_NULLCHECK_THREE(pNBIOContext, state, pValResult);
 
         nbio = *pNBIOContext;
         *pNBIOContext = NULL;
         PKIX_INCREF(state->validityDate);
         validityDate = state->validityDate;
         canBeCached = state->canBeCached;
         PKIX_DECREF(*pValResult);
+        targetCert = state->buildConstants.targetCert;
 
         /*
          * We return if successful; if we fall off the end
          * of this "while" clause our search has failed.
          */
         while (outOfOptions == PKIX_FALSE) {
             /*
              * The maximum number of iterations works around a bug that
@@ -2349,16 +2355,22 @@ pkix_BuildForwardDepthFirstSearch(
                     PKIX_DECREF(state->candidateCert);
                     PKIX_CHECK(PKIX_List_GetItem
                             (state->candidateCerts,
                             state->certIndex,
                             (PKIX_PL_Object **)&(state->candidateCert),
                             plContext),
                             PKIX_LISTGETITEMFAILED);
 
+                    if (isIssuerCertAllowedAtCertIssuanceTime(
+                          state->candidateCert->nssCert, targetCert->nssCert)
+                            != SECSuccess) {
+                        PKIX_ERROR(PKIX_CERTISBLACKLISTEDATISSUANCETIME);
+                    }
+
                     if ((state->verifyNode) != NULL) {
                             PKIX_CHECK_FATAL(pkix_VerifyNode_Create
                                     (state->candidateCert,
                                     0,
                                     NULL,
                                     &verifyNode,
                                     plContext),
                                     PKIX_VERIFYNODECREATEFAILED);
--- a/security/nss/lib/pk11wrap/pk11mech.c
+++ b/security/nss/lib/pk11wrap/pk11mech.c
@@ -607,16 +607,20 @@ PK11_GetKeyGenWithSize(CK_MECHANISM_TYPE
         case CKM_GENERIC_SECRET_KEY_GEN:
             return CKM_GENERIC_SECRET_KEY_GEN;
         case CKM_PBE_MD2_DES_CBC:
         case CKM_PBE_MD5_DES_CBC:
         case CKM_PBA_SHA1_WITH_SHA1_HMAC:
         case CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN:
         case CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN:
         case CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN:
+        case CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN:
+        case CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN:
+        case CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN:
+        case CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN:
         case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
         case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
         case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC:
         case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4:
         case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4:
         case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
         case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
         case CKM_PBE_SHA1_RC2_40_CBC:
--- a/security/nss/lib/pk11wrap/pk11pars.c
+++ b/security/nss/lib/pk11wrap/pk11pars.c
@@ -1009,16 +1009,20 @@ static char *
 secmod_getConfigDir(const char *spec, char **certPrefix, char **keyPrefix,
                     PRBool *readOnly)
 {
     char *config = NULL;
 
     *certPrefix = NULL;
     *keyPrefix = NULL;
     *readOnly = NSSUTIL_ArgHasFlag("flags", "readOnly", spec);
+    if (NSSUTIL_ArgHasFlag("flags", "nocertdb", spec) ||
+        NSSUTIL_ArgHasFlag("flags", "nokeydb", spec)) {
+        return NULL;
+    }
 
     spec = NSSUTIL_ArgStrip(spec);
     while (*spec) {
         int next;
         NSSUTIL_HANDLE_STRING_ARG(spec, config, "configdir=", ;)
         NSSUTIL_HANDLE_STRING_ARG(spec, *certPrefix, "certPrefix=", ;)
         NSSUTIL_HANDLE_STRING_ARG(spec, *keyPrefix, "keyPrefix=", ;)
         NSSUTIL_HANDLE_FINAL_ARG(spec)
@@ -1128,16 +1132,23 @@ secmod_matchPrefix(char *prefix1, char *
  * SECMODConfigLists directly, so this function breaks them out to their
  * components. */
 static PRBool
 secmod_matchConfig(char *configDir1, char *configDir2,
                    char *certPrefix1, char *certPrefix2,
                    char *keyPrefix1, char *keyPrefix2,
                    PRBool isReadOnly1, PRBool isReadOnly2)
 {
+    /* TODO: Document the answer to the question:
+     *       "Why not allow them to match if they are both NULL?"
+     * See: https://bugzilla.mozilla.org/show_bug.cgi?id=1318633#c1
+     */
+    if ((configDir1 == NULL) || (configDir2 == NULL)) {
+        return PR_FALSE;
+    }
     if (strcmp(configDir1, configDir2) != 0) {
         return PR_FALSE;
     }
     if (!secmod_matchPrefix(certPrefix1, certPrefix2)) {
         return PR_FALSE;
     }
     if (!secmod_matchPrefix(keyPrefix1, keyPrefix2)) {
         return PR_FALSE;
@@ -1164,17 +1175,16 @@ secmod_MatchConfigList(const char *spec,
     char *certPrefix;
     char *keyPrefix;
     PRBool isReadOnly;
     PRBool ret = PR_FALSE;
     int i;
 
     config = secmod_getConfigDir(spec, &certPrefix, &keyPrefix, &isReadOnly);
     if (!config) {
-        ret = PR_TRUE;
         goto done;
     }
 
     /* NOTE: we dbm isn't multiple open safe. If we open the same database
      * twice from two different locations, then we can corrupt our database
      * (the cache will be inconsistent). Protect against this by claiming
      * for comparison only that we are always openning dbm databases read only.
      */
--- a/security/nss/lib/pkcs12/p12d.c
+++ b/security/nss/lib/pkcs12/p12d.c
@@ -1330,21 +1330,33 @@ sec_pkcs12_decoder_verify_mac(SEC_PKCS12
             integrityMech = CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN;
             break;
         case SEC_OID_MD5:
             integrityMech = CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN;
             break;
         case SEC_OID_MD2:
             integrityMech = CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN;
             break;
+        case SEC_OID_SHA224:
+            integrityMech = CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN;
+            break;
+        case SEC_OID_SHA256:
+            integrityMech = CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN;
+            break;
+        case SEC_OID_SHA384:
+            integrityMech = CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN;
+            break;
+        case SEC_OID_SHA512:
+            integrityMech = CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN;
+            break;
         default:
             goto loser;
     }
 
-    symKey = PK11_KeyGen(NULL, integrityMech, params, 20, NULL);
+    symKey = PK11_KeyGen(NULL, integrityMech, params, 0, NULL);
     PK11_DestroyPBEParams(params);
     params = NULL;
     if (!symKey)
         goto loser;
     /* init hmac */
     pk11cx = PK11_CreateContextBySymKey(sec_pkcs12_algtag_to_mech(algtag),
                                         CKA_SIGN, symKey, &ignore);
     if (!pk11cx) {
--- a/security/nss/lib/smime/cmssigdata.c
+++ b/security/nss/lib/smime/cmssigdata.c
@@ -701,16 +701,17 @@ NSS_CMSSignedData_VerifyCertsOnly(NSSCMS
                                   CERTCertDBHandle *certdb,
                                   SECCertUsage usage)
 {
     CERTCertificate *cert;
     SECStatus rv = SECSuccess;
     int i;
     int count;
     PRTime now;
+    void *pwarg = NULL;
 
     if (!sigd || !certdb || !sigd->rawCerts) {
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
         return SECFailure;
     }
 
     count = NSS_CMSArray_Count((void **)sigd->rawCerts);
     now = PR_Now();
@@ -719,18 +720,21 @@ NSS_CMSSignedData_VerifyCertsOnly(NSSCMS
             cert = CERT_DupCertificate(sigd->certs[i]);
         } else {
             cert = CERT_FindCertByDERCert(certdb, sigd->rawCerts[i]);
             if (!cert) {
                 rv = SECFailure;
                 break;
             }
         }
+        if (sigd->cmsg) {
+            pwarg = sigd->cmsg->pwfn_arg;
+        }
         rv |= CERT_VerifyCert(certdb, cert, PR_TRUE, usage, now,
-                              NULL, NULL);
+                              pwarg, NULL);
         CERT_DestroyCertificate(cert);
     }
 
     return rv;
 }
 
 /*
  * NSS_CMSSignedData_HasDigests - see if we have digests in place
--- a/security/nss/lib/softoken/lowpbe.c
+++ b/security/nss/lib/softoken/lowpbe.c
@@ -403,17 +403,16 @@ loser:
         result = NULL;
     } else {
         result->len = dkLen;
     }
 
     return result;
 }
 
-#define HMAC_BUFFER 64
 #define NSSPBE_ROUNDUP(x, y) ((((x) + ((y)-1)) / (y)) * (y))
 #define NSSPBE_MIN(x, y) ((x) < (y) ? (x) : (y))
 /*
  * This is the extended PBE function defined by the final PKCS #12 spec.
  */
 static SECItem *
 nsspkcs5_PKCS12PBE(const SECHashObject *hashObject,
                    NSSPKCS5PBEParameter *pbe_param, SECItem *pwitem,
@@ -425,40 +424,44 @@ nsspkcs5_PKCS12PBE(const SECHashObject *
     unsigned char *S, *P;
     SECItem *A = NULL, B, D, I;
     SECItem *salt = &pbe_param->salt;
     unsigned int c, i = 0;
     unsigned int hashLen;
     int iter;
     unsigned char *iterBuf;
     void *hash = NULL;
+    unsigned int bufferLength;
 
     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
     if (!arena) {
         return NULL;
     }
 
     /* how many hash object lengths are needed */
     c = (bytesNeeded + (hashLength - 1)) / hashLength;
 
+    /* 64 if 0 < hashLength <= 32, 128 if 32 < hashLength <= 64 */
+    bufferLength = NSSPBE_ROUNDUP(hashLength * 2, 64);
+
     /* initialize our buffers */
-    D.len = HMAC_BUFFER;
+    D.len = bufferLength;
     /* B and D are the same length, use one alloc go get both */
     D.data = (unsigned char *)PORT_ArenaZAlloc(arena, D.len * 2);
     B.len = D.len;
     B.data = D.data + D.len;
 
     /* if all goes well, A will be returned, so don't use our temp arena */
     A = SECITEM_AllocItem(NULL, NULL, c * hashLength);
     if (A == NULL) {
         goto loser;
     }
 
-    SLen = NSSPBE_ROUNDUP(salt->len, HMAC_BUFFER);
-    PLen = NSSPBE_ROUNDUP(pwitem->len, HMAC_BUFFER);
+    SLen = NSSPBE_ROUNDUP(salt->len, bufferLength);
+    PLen = NSSPBE_ROUNDUP(pwitem->len, bufferLength);
     I.len = SLen + PLen;
     I.data = (unsigned char *)PORT_ArenaZAlloc(arena, I.len);
     if (I.data == NULL) {
         goto loser;
     }
 
     /* S & P are only used to initialize I */
     S = I.data;
--- a/security/nss/lib/softoken/pkcs11.c
+++ b/security/nss/lib/softoken/pkcs11.c
@@ -475,16 +475,20 @@ static const struct mechanismList mechan
     { CKM_PBE_SHA1_RC2_128_CBC, { 128, 128, CKF_GENERATE }, PR_TRUE },
     { CKM_PBE_SHA1_RC4_40, { 40, 40, CKF_GENERATE }, PR_TRUE },
     { CKM_PBE_SHA1_RC4_128, { 128, 128, CKF_GENERATE }, PR_TRUE },
     { CKM_PBA_SHA1_WITH_SHA1_HMAC, { 20, 20, CKF_GENERATE }, PR_TRUE },
     { CKM_PKCS5_PBKD2, { 1, 256, CKF_GENERATE }, PR_TRUE },
     { CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN, { 20, 20, CKF_GENERATE }, PR_TRUE },
     { CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN, { 16, 16, CKF_GENERATE }, PR_TRUE },
     { CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN, { 16, 16, CKF_GENERATE }, PR_TRUE },
+    { CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN, { 28, 28, CKF_GENERATE }, PR_TRUE },
+    { CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN, { 32, 32, CKF_GENERATE }, PR_TRUE },
+    { CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN, { 48, 48, CKF_GENERATE }, PR_TRUE },
+    { CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN, { 64, 64, CKF_GENERATE }, PR_TRUE },
     /* ------------------ AES Key Wrap (also encrypt)  ------------------- */
     { CKM_NETSCAPE_AES_KEY_WRAP, { 16, 32, CKF_EN_DE_WR_UN }, PR_TRUE },
     { CKM_NETSCAPE_AES_KEY_WRAP_PAD, { 16, 32, CKF_EN_DE_WR_UN }, PR_TRUE },
     /* --------------------------- J-PAKE -------------------------------- */
     { CKM_NSS_JPAKE_ROUND1_SHA1, { 0, 0, CKF_GENERATE }, PR_TRUE },
     { CKM_NSS_JPAKE_ROUND1_SHA256, { 0, 0, CKF_GENERATE }, PR_TRUE },
     { CKM_NSS_JPAKE_ROUND1_SHA384, { 0, 0, CKF_GENERATE }, PR_TRUE },
     { CKM_NSS_JPAKE_ROUND1_SHA512, { 0, 0, CKF_GENERATE }, PR_TRUE },
--- a/security/nss/lib/softoken/pkcs11c.c
+++ b/security/nss/lib/softoken/pkcs11c.c
@@ -3966,16 +3966,32 @@ nsc_SetupHMACKeyGen(CK_MECHANISM_PTR pMe
         case CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN:
             params->hashType = HASH_AlgMD5;
             params->keyLen = 16;
             break;
         case CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN:
             params->hashType = HASH_AlgMD2;
             params->keyLen = 16;
             break;
+        case CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN:
+            params->hashType = HASH_AlgSHA224;
+            params->keyLen = 28;
+            break;
+        case CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN:
+            params->hashType = HASH_AlgSHA256;
+            params->keyLen = 32;
+            break;
+        case CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN:
+            params->hashType = HASH_AlgSHA384;
+            params->keyLen = 48;
+            break;
+        case CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN:
+            params->hashType = HASH_AlgSHA512;
+            params->keyLen = 64;
+            break;
         default:
             PORT_FreeArena(arena, PR_TRUE);
             return CKR_MECHANISM_INVALID;
     }
     *pbe = params;
     return CKR_OK;
 }
 
@@ -4184,16 +4200,20 @@ NSC_GenerateKey(CK_SESSION_HANDLE hSessi
             key_type = CKK_GENERIC_SECRET;
             key_length = 48;
             key_gen_type = nsc_ssl;
             break;
         case CKM_PBA_SHA1_WITH_SHA1_HMAC:
         case CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN:
         case CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN:
         case CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN:
+        case CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN:
+        case CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN:
+        case CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN:
+        case CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN:
             key_gen_type = nsc_pbe;
             key_type = CKK_GENERIC_SECRET;
             crv = nsc_SetupHMACKeyGen(pMechanism, &pbe_param);
             break;
         case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
             faultyPBE3DES = PR_TRUE;
         /* fall through */
         case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
--- a/security/nss/lib/softoken/softoken.h
+++ b/security/nss/lib/softoken/softoken.h
@@ -178,17 +178,17 @@ extern PRBool sftk_fatalError;
  */
 
 #ifdef SOLARIS
 
 /* Solaris 8, s9 use PID checks, s10 uses pthread_atfork */
 
 #define CHECK_FORK_MIXED
 
-#elif defined(LINUX)
+#elif defined(LINUX) || defined(__GLIBC__)
 
 #define CHECK_FORK_PTHREAD
 
 #else
 
 /* Other Unix platforms use only PID checks. Even if pthread_atfork is
  * available, the behavior of dlclose isn't guaranteed by POSIX to
  * unregister the fork handler. */
--- a/security/nss/lib/ssl/ssl.gyp
+++ b/security/nss/lib/ssl/ssl.gyp
@@ -63,16 +63,21 @@
             'NSS_SSL_ENABLE_ZLIB',
           ],
         }],
         [ 'fuzz==1', {
           'defines': [
             'UNSAFE_FUZZER_MODE',
           ],
         }],
+        [ 'mozilla_client==1', {
+          'defines': [
+            'NSS_ENABLE_TLS13_SHORT_HEADERS',
+          ],
+        }],
       ],
       'dependencies': [
         '<(DEPTH)/exports.gyp:nss_exports',
         '<(DEPTH)/lib/freebl/freebl.gyp:freebl',
       ],
     },
     {
       'target_name': 'ssl3',
--- a/security/nss/lib/ssl/ssl.h
+++ b/security/nss/lib/ssl/ssl.h
@@ -223,17 +223,17 @@ SSL_IMPORT PRFileDesc *DTLS_ImportFD(PRF
  *
  * When this option is set, the server's session tickets will contain
  * a flag indicating that it accepts 0-RTT. When resuming such a
  * session, PR_Write() on the client will be allowed immediately after
  * starting the handshake and PR_Read() on the server will be allowed
  * on the server to read that data. Calls to
  * SSL_GetPreliminaryChannelInfo() and SSL_GetNextProto()
  * can be made used during this period to learn about the channel
- * parameters [TODO(ekr@rtfm.com): This hasn't landed yet].
+ * parameters.
  *
  * The transition between the 0-RTT and 1-RTT modes is marked by the
  * handshake callback.
  *
  * WARNING: 0-RTT data has different anti-replay and PFS properties than
  * the rest of the TLS data. See [draft-ietf-tls-tls13; Section 6.2.3]
  * for more details.
  */
--- a/security/nss/lib/ssl/ssl3con.c
+++ b/security/nss/lib/ssl/ssl3con.c
@@ -2572,22 +2572,34 @@ ssl3_CompressMACEncryptRecord(ssl3Cipher
 }
 
 SECStatus
 ssl_ProtectRecord(sslSocket *ss, ssl3CipherSpec *cwSpec,
                   PRBool capRecordVersion, SSL3ContentType type,
                   const SSL3Opaque *pIn, PRUint32 contentLen, sslBuffer *wrBuf)
 {
     const ssl3BulkCipherDef *cipher_def = cwSpec->cipher_def;
-    PRUint16 headerLen = IS_DTLS(ss) ? DTLS_RECORD_HEADER_LENGTH : SSL3_RECORD_HEADER_LENGTH;
-    sslBuffer protBuf = { wrBuf->buf + headerLen, 0, wrBuf->space - headerLen };
+    PRUint16 headerLen;
+    sslBuffer protBuf;
     SSL3ProtocolVersion version = cwSpec->version;
     PRBool isTLS13;
+    PRUint8 *ptr = wrBuf->buf;
     SECStatus rv;
 
+    if (ss->ssl3.hs.shortHeaders) {
+        PORT_Assert(!IS_DTLS(ss));
+        PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3);
+        headerLen = TLS13_RECORD_HEADER_LENGTH_SHORT;
+    } else {
+        headerLen = IS_DTLS(ss) ? DTLS_RECORD_HEADER_LENGTH : SSL3_RECORD_HEADER_LENGTH;
+    }
+    protBuf.buf = wrBuf->buf + headerLen;
+    protBuf.len = 0;
+    protBuf.space = wrBuf->space - headerLen;
+
     PORT_Assert(cipher_def->max_records <= RECORD_SEQ_MAX);
     if ((cwSpec->write_seq_num & RECORD_SEQ_MAX) >= cipher_def->max_records) {
         SSL_TRC(3, ("%d: SSL[-]: write sequence number at limit 0x%0llx",
                     SSL_GETPID(), cwSpec->write_seq_num));
         PORT_SetError(SSL_ERROR_TOO_MANY_RECORDS);
         return SECFailure;
     }
 
@@ -2607,39 +2619,42 @@ ssl_ProtectRecord(sslSocket *ss, ssl3Cip
 #endif
     if (rv != SECSuccess) {
         return SECFailure; /* error was set */
     }
 
     PORT_Assert(protBuf.len <= MAX_FRAGMENT_LENGTH + (isTLS13 ? 256 : 1024));
     wrBuf->len = protBuf.len + headerLen;
 
+    if (ss->ssl3.hs.shortHeaders) {
+        PORT_Assert(!IS_DTLS(ss)); /* Decoder not yet implemented. */
+        (void)ssl_EncodeUintX(0x8000 | protBuf.len, 2, ptr);
+    } else {
 #ifndef UNSAFE_FUZZER_MODE
-    if (isTLS13 && cipher_def->calg != ssl_calg_null) {
-        wrBuf->buf[0] = content_application_data;
-    } else
+        if (isTLS13 && cipher_def->calg != ssl_calg_null) {
+            *ptr++ = content_application_data;
+        } else
 #endif
-    {
-        wrBuf->buf[0] = type;
-    }
-
-    if (IS_DTLS(ss)) {
-        version = isTLS13 ? SSL_LIBRARY_VERSION_TLS_1_1 : version;
-        version = dtls_TLSVersionToDTLSVersion(version);
-
-        (void)ssl_EncodeUintX(version, 2, &wrBuf->buf[1]);
-        (void)ssl_EncodeUintX(cwSpec->write_seq_num, 8, &wrBuf->buf[3]);
-        (void)ssl_EncodeUintX(protBuf.len, 2, &wrBuf->buf[11]);
-    } else {
-        if (capRecordVersion || isTLS13) {
-            version = PR_MIN(SSL_LIBRARY_VERSION_TLS_1_0, version);
-        }
-
-        (void)ssl_EncodeUintX(version, 2, &wrBuf->buf[1]);
-        (void)ssl_EncodeUintX(protBuf.len, 2, &wrBuf->buf[3]);
+        {
+            *ptr++ = type;
+        }
+
+        if (IS_DTLS(ss)) {
+            version = isTLS13 ? SSL_LIBRARY_VERSION_TLS_1_1 : version;
+            version = dtls_TLSVersionToDTLSVersion(version);
+
+            ptr = ssl_EncodeUintX(version, 2, ptr);
+            ptr = ssl_EncodeUintX(cwSpec->write_seq_num, 8, ptr);
+        } else {
+            if (capRecordVersion || isTLS13) {
+                version = PR_MIN(SSL_LIBRARY_VERSION_TLS_1_0, version);
+            }
+            ptr = ssl_EncodeUintX(version, 2, ptr);
+        }
+        (void)ssl_EncodeUintX(protBuf.len, 2, ptr);
     }
     ++cwSpec->write_seq_num;
 
     return SECSuccess;
 }
 
 /* Process the plain text before sending it.
  * Returns the number of bytes of plaintext that were successfully sent
--- a/security/nss/lib/ssl/ssl3ext.c
+++ b/security/nss/lib/ssl/ssl3ext.c
@@ -34,16 +34,17 @@ static const ssl3ExtensionHandler client
     { ssl_signature_algorithms_xtn, &ssl3_ServerHandleSigAlgsXtn },
     { ssl_extended_master_secret_xtn, &ssl3_HandleExtendedMasterSecretXtn },
     { ssl_signed_cert_timestamp_xtn, &ssl3_ServerHandleSignedCertTimestampXtn },
     { ssl_tls13_key_share_xtn, &tls13_ServerHandleKeyShareXtn },
     { ssl_tls13_pre_shared_key_xtn, &tls13_ServerHandlePreSharedKeyXtn },
     { ssl_tls13_early_data_xtn, &tls13_ServerHandleEarlyDataXtn },
     { ssl_tls13_psk_key_exchange_modes_xtn,
       &tls13_ServerHandlePskKeyExchangeModesXtn },
+    { ssl_tls13_short_header_xtn, &tls13_HandleShortHeaderXtn },
     { -1, NULL }
 };
 
 /* These two tables are used by the client, to handle server hello
  * extensions. */
 static const ssl3ExtensionHandler serverHelloHandlersTLS[] = {
     { ssl_server_name_xtn, &ssl3_HandleServerNameXtn },
     /* TODO: add a handler for ssl_ec_point_formats_xtn */
@@ -53,16 +54,17 @@ static const ssl3ExtensionHandler server
     { ssl_app_layer_protocol_xtn, &ssl3_ClientHandleAppProtoXtn },
     { ssl_use_srtp_xtn, &ssl3_ClientHandleUseSRTPXtn },
     { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn },
     { ssl_extended_master_secret_xtn, &ssl3_HandleExtendedMasterSecretXtn },
     { ssl_signed_cert_timestamp_xtn, &ssl3_ClientHandleSignedCertTimestampXtn },
     { ssl_tls13_key_share_xtn, &tls13_ClientHandleKeyShareXtn },
     { ssl_tls13_pre_shared_key_xtn, &tls13_ClientHandlePreSharedKeyXtn },
     { ssl_tls13_early_data_xtn, &tls13_ClientHandleEarlyDataXtn },
+    { ssl_tls13_short_header_xtn, &tls13_HandleShortHeaderXtn },
     { -1, NULL }
 };
 
 static const ssl3ExtensionHandler helloRetryRequestHandlers[] = {
     { ssl_tls13_key_share_xtn, tls13_ClientHandleKeyShareXtnHrr },
     { ssl_tls13_cookie_xtn, tls13_ClientHandleHrrCookie },
     { -1, NULL }
 };
@@ -110,16 +112,17 @@ static const ssl3HelloExtensionSender cl
       { ssl_signed_cert_timestamp_xtn, &ssl3_ClientSendSignedCertTimestampXtn },
       { ssl_tls13_key_share_xtn, &tls13_ClientSendKeyShareXtn },
       { ssl_tls13_early_data_xtn, &tls13_ClientSendEarlyDataXtn },
       /* Some servers (e.g. WebSphere Application Server 7.0 and Tomcat) will
        * time out or terminate the connection if the last extension in the
        * client hello is empty. They are not intolerant of TLS 1.2, so list
        * signature_algorithms at the end. See bug 1243641. */
       { ssl_tls13_supported_versions_xtn, &tls13_ClientSendSupportedVersionsXtn },
+      { ssl_tls13_short_header_xtn, &tls13_SendShortHeaderXtn },
       { ssl_signature_algorithms_xtn, &ssl3_ClientSendSigAlgsXtn },
       { ssl_tls13_cookie_xtn, &tls13_ClientSendHrrCookieXtn },
       { ssl_tls13_psk_key_exchange_modes_xtn,
         &tls13_ClientSendPskKeyExchangeModesXtn },
       /* The pre_shared_key extension MUST be last. */
       { ssl_tls13_pre_shared_key_xtn, &tls13_ClientSendPreSharedKeyXtn },
       /* any extra entries will appear as { 0, NULL }    */
     };
--- a/security/nss/lib/ssl/ssl3gthr.c
+++ b/security/nss/lib/ssl/ssl3gthr.c
@@ -92,17 +92,17 @@ ssl3_GatherData(sslSocket *ss, sslGather
     int nb;
     int err;
     int rv = 1;
     PRUint8 v2HdrLength = 0;
 
     PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
     if (gs->state == GS_INIT) {
         gs->state = GS_HEADER;
-        gs->remainder = 5;
+        gs->remainder = ss->ssl3.hs.shortHeaders ? 2 : 5;
         gs->offset = 0;
         gs->writeOffset = 0;
         gs->readOffset = 0;
         gs->inbuf.len = 0;
     }
 
     lbp = gs->inbuf.buf;
     for (;;) {
@@ -144,20 +144,32 @@ ssl3_GatherData(sslSocket *ss, sslGather
         }
 
         /* have received entire record header, or entire record. */
         switch (gs->state) {
             case GS_HEADER:
                 /* Check for SSLv2 handshakes. Always assume SSLv3 on clients,
                  * support SSLv2 handshakes only when ssl2gs != NULL. */
                 if (!ssl2gs || ssl3_isLikelyV3Hello(gs->hdr)) {
-                    /* Should have an SSLv3 record header in gs->hdr. Extract
+                    /* Should have a non-SSLv2 record header in gs->hdr. Extract
                      * the length of the following encrypted data, and then
-                     * read in the rest of the SSL3 record into gs->inbuf. */
-                    gs->remainder = (gs->hdr[3] << 8) | gs->hdr[4];
+                     * read in the rest of the record into gs->inbuf. */
+                    if (ss->ssl3.hs.shortHeaders) {
+                        PRUint16 len = (gs->hdr[0] << 8) | gs->hdr[1];
+                        if (!(len & 0x8000)) {
+                            SSL_DBG(("%d: SSL3[%d]: incorrectly formatted header"));
+                            SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
+                            gs->state = GS_INIT;
+                            PORT_SetError(SSL_ERROR_BAD_MAC_READ);
+                            return SECFailure;
+                        }
+                        gs->remainder = len & ~0x8000;
+                    } else {
+                        gs->remainder = (gs->hdr[3] << 8) | gs->hdr[4];
+                    }
                 } else {
                     /* Probably an SSLv2 record header. No need to handle any
                      * security escapes (gs->hdr[0] & 0x40) as we wouldn't get
                      * here if one was set. See ssl3_isLikelyV3Hello(). */
                     gs->remainder = ((gs->hdr[0] & 0x7f) << 8) | gs->hdr[1];
                     ssl2gs->isV2 = PR_TRUE;
                     v2HdrLength = 2;
 
@@ -453,18 +465,23 @@ ssl3_GatherCompleteHandshake(sslSocket *
                     return rv;
                 }
             } else {
                 /* decipher it, and handle it if it's a handshake.
                  * If it's application data, ss->gs.buf will not be empty upon return.
                  * If it's a change cipher spec, alert, or handshake message,
                  * ss->gs.buf.len will be 0 when ssl3_HandleRecord returns SECSuccess.
                  */
-                cText.type = (SSL3ContentType)ss->gs.hdr[0];
-                cText.version = (ss->gs.hdr[1] << 8) | ss->gs.hdr[2];
+                if (ss->ssl3.hs.shortHeaders) {
+                    cText.type = content_application_data;
+                    cText.version = SSL_LIBRARY_VERSION_TLS_1_0;
+                } else {
+                    cText.type = (SSL3ContentType)ss->gs.hdr[0];
+                    cText.version = (ss->gs.hdr[1] << 8) | ss->gs.hdr[2];
+                }
 
                 if (IS_DTLS(ss)) {
                     sslSequenceNumber seq_num;
 
                     cText.version = dtls_DTLSVersionToTLSVersion(cText.version);
                     /* DTLS sequence number */
                     PORT_Memcpy(&seq_num, &ss->gs.hdr[3], sizeof(seq_num));
                     cText.seq_num = PR_ntohll(seq_num);
--- a/security/nss/lib/ssl/ssl3prot.h
+++ b/security/nss/lib/ssl/ssl3prot.h
@@ -27,16 +27,17 @@ typedef PRUint16 ssl3CipherSuite;
 #define MAX_COMPRESSION_METHODS 10
 #define MAX_MAC_LENGTH 64
 #define MAX_PADDING_LENGTH 64
 #define MAX_KEY_LENGTH 64
 #define EXPORT_KEY_LENGTH 5
 #define SSL3_RANDOM_LENGTH 32
 
 #define SSL3_RECORD_HEADER_LENGTH 5
+#define TLS13_RECORD_HEADER_LENGTH_SHORT 2
 
 /* SSL3_RECORD_HEADER_LENGTH + epoch/sequence_number */
 #define DTLS_RECORD_HEADER_LENGTH 13
 
 #define MAX_FRAGMENT_LENGTH 16384
 
 typedef enum {
     content_change_cipher_spec = 20,
--- a/security/nss/lib/ssl/sslimpl.h
+++ b/security/nss/lib/ssl/sslimpl.h
@@ -291,16 +291,17 @@ typedef struct sslOptionsStr {
     unsigned int enableALPN : 1;
     unsigned int reuseServerECDHEKey : 1;
     unsigned int enableFallbackSCSV : 1;
     unsigned int enableServerDhe : 1;
     unsigned int enableExtendedMS : 1;
     unsigned int enableSignedCertTimestamps : 1;
     unsigned int requireDHENamedGroups : 1;
     unsigned int enable0RttData : 1;
+    unsigned int enableShortHeaders : 1;
 } sslOptions;
 
 typedef enum { sslHandshakingUndetermined = 0,
                sslHandshakingAsClient,
                sslHandshakingAsServer
 } sslHandshakingType;
 
 #define SSL_LOCK_RANK_SPEC 255
@@ -869,16 +870,17 @@ typedef struct SSL3HandshakeStateStr {
     sslZeroRttIgnore zeroRttIgnore; /* Are we ignoring 0-RTT? */
     ssl3CipherSuite zeroRttSuite;   /* The cipher suite we used for 0-RTT. */
     PRCList bufferedEarlyData;      /* Buffered TLS 1.3 early data
                                      * on server.*/
     PRBool helloRetry;              /* True if HelloRetryRequest has been sent
                                      * or received. */
     ssl3KEADef kea_def_mutable;     /* Used to hold the writable kea_def
                                      * we use for TLS 1.3 */
+    PRBool shortHeaders;            /* Assigned if we are doing short headers. */
 } SSL3HandshakeState;
 
 /*
 ** This is the "ssl3" struct, as in "ss->ssl3".
 ** note:
 ** usually,   crSpec == cwSpec and prSpec == pwSpec.
 ** Sometimes, crSpec == pwSpec and prSpec == cwSpec.
 ** But there are never more than 2 actual specs.
--- a/security/nss/lib/ssl/sslinfo.c
+++ b/security/nss/lib/ssl/sslinfo.c
@@ -135,16 +135,19 @@ SSL_GetPreliminaryChannelInfo(PRFileDesc
     }
 
     memset(&inf, 0, sizeof(inf));
     inf.length = PR_MIN(sizeof(inf), len);
 
     inf.valuesSet = ss->ssl3.hs.preliminaryInfo;
     inf.protocolVersion = ss->version;
     inf.cipherSuite = ss->ssl3.hs.cipher_suite;
+    inf.canSendEarlyData = !ss->sec.isServer &&
+                           (ss->ssl3.hs.zeroRttState == ssl_0rtt_sent) &&
+                           !ss->firstHsDone;
 
     memcpy(info, &inf, inf.length);
     return SECSuccess;
 }
 
 /* name */
 #define CS_(x) x, #x
 #define CS(x) CS_(TLS_##x)
--- a/security/nss/lib/ssl/sslmutex.c
+++ b/security/nss/lib/ssl/sslmutex.c
@@ -55,17 +55,18 @@ single_process_sslMutex_Lock(sslMutex* p
     if (!pMutex->u.sslLock) {
         PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
         return SECFailure;
     }
     PR_Lock(pMutex->u.sslLock);
     return SECSuccess;
 }
 
-#if defined(LINUX) || defined(AIX) || defined(BEOS) || defined(BSDI) || (defined(NETBSD) && __NetBSD_Version__ < 500000000) || defined(OPENBSD)
+#if defined(LINUX) || defined(AIX) || defined(BEOS) || defined(BSDI) || \
+    (defined(NETBSD) && __NetBSD_Version__ < 500000000) || defined(OPENBSD) || defined(__GLIBC__)
 
 #include <unistd.h>
 #include <fcntl.h>
 #include <string.h>
 #include <errno.h>
 #include "unix_err.h"
 #include "pratom.h"
 
--- a/security/nss/lib/ssl/sslmutex.h
+++ b/security/nss/lib/ssl/sslmutex.h
@@ -44,17 +44,18 @@ typedef struct {
 #endif
         PRLock *sslLock;
         HANDLE sslMutx;
     } u;
 } sslMutex;
 
 typedef int sslPID;
 
-#elif defined(LINUX) || defined(AIX) || defined(BEOS) || defined(BSDI) || (defined(NETBSD) && __NetBSD_Version__ < 500000000) || defined(OPENBSD)
+#elif defined(LINUX) || defined(AIX) || defined(BEOS) || defined(BSDI) || \
+    (defined(NETBSD) && __NetBSD_Version__ < 500000000) || defined(OPENBSD) || defined(__GLIBC__)
 
 #include <sys/types.h>
 #include "prtypes.h"
 
 typedef struct {
     PRBool isMultiProcess;
     union {
         PRLock *sslLock;
--- a/security/nss/lib/ssl/sslsock.c
+++ b/security/nss/lib/ssl/sslsock.c
@@ -73,17 +73,22 @@ static sslOptions ssl_defaults = {
     PR_FALSE,              /* enableNPN          */
     PR_TRUE,               /* enableALPN         */
     PR_TRUE,               /* reuseServerECDHEKey */
     PR_FALSE,              /* enableFallbackSCSV */
     PR_TRUE,               /* enableServerDhe */
     PR_FALSE,              /* enableExtendedMS    */
     PR_FALSE,              /* enableSignedCertTimestamps */
     PR_FALSE,              /* requireDHENamedGroups */
-    PR_FALSE               /* enable0RttData */
+    PR_FALSE,              /* enable0RttData */
+#ifdef NSS_ENABLE_TLS13_SHORT_HEADERS
+    PR_TRUE /* enableShortHeaders */
+#else
+    PR_FALSE /* enableShortHeaders */
+#endif
 };
 
 /*
  * default range of enabled SSL/TLS protocols
  */
 static SSLVersionRange versions_defaults_stream = {
     SSL_LIBRARY_VERSION_TLS_1_0,
     SSL_LIBRARY_VERSION_TLS_1_2
--- a/security/nss/lib/ssl/sslt.h
+++ b/security/nss/lib/ssl/sslt.h
@@ -293,16 +293,22 @@ typedef struct SSLPreliminaryChannelInfo
     /* A bitfield over SSLPreliminaryValueSet that describes which
      * preliminary values are set (see ssl_preinfo_*). */
     PRUint32 valuesSet;
     /* Protocol version: test (valuesSet & ssl_preinfo_version) */
     PRUint16 protocolVersion;
     /* Cipher suite: test (valuesSet & ssl_preinfo_cipher_suite) */
     PRUint16 cipherSuite;
 
+    /* The following fields were added in NSS 3.29. */
+    /* |canSendEarlyData| is true when a 0-RTT is enabled. This can only be
+     * true after sending the ClientHello and before the handshake completes.
+     */
+    PRBool canSendEarlyData;
+
     /* When adding new fields to this structure, please document the
      * NSS version in which they were added. */
 } SSLPreliminaryChannelInfo;
 
 typedef struct SSLCipherSuiteInfoStr {
     /* On return, SSL_GetCipherSuitelInfo sets |length| to the smaller of
      * the |len| argument and the length of the struct used by NSS.
      * Callers must ensure the application uses a version of NSS that
@@ -383,27 +389,28 @@ typedef enum {
     ssl_tls13_key_share_xtn = 40,
     ssl_tls13_pre_shared_key_xtn = 41,
     ssl_tls13_early_data_xtn = 42,
     ssl_tls13_supported_versions_xtn = 43,
     ssl_tls13_cookie_xtn = 44,
     ssl_tls13_psk_key_exchange_modes_xtn = 45,
     ssl_tls13_ticket_early_data_info_xtn = 46,
     ssl_next_proto_nego_xtn = 13172,
-    ssl_renegotiation_info_xtn = 0xff01
+    ssl_renegotiation_info_xtn = 0xff01,
+    ssl_tls13_short_header_xtn = 0xff03
 } SSLExtensionType;
 
 /* This is the old name for the supported_groups extensions. */
 #define ssl_elliptic_curves_xtn ssl_supported_groups_xtn
 
 /* SSL_MAX_EXTENSIONS doesn't include ssl_padding_xtn.  It includes the maximum
  * number of extensions that are supported for any single message type.  That
  * is, a ClientHello; ServerHello and TLS 1.3 NewSessionTicket and
  * HelloRetryRequest extensions are smaller. */
-#define SSL_MAX_EXTENSIONS 18
+#define SSL_MAX_EXTENSIONS 19
 
 /* Deprecated */
 typedef enum {
     ssl_dhe_group_none = 0,
     ssl_ff_dhe_2048_group = 1,
     ssl_ff_dhe_3072_group = 2,
     ssl_ff_dhe_4096_group = 3,
     ssl_ff_dhe_6144_group = 4,
--- a/security/nss/lib/ssl/tls13con.c
+++ b/security/nss/lib/ssl/tls13con.c
@@ -1445,16 +1445,17 @@ tls13_HandleClientHelloPart2(sslSocket *
                                 kHkdfLabelEarlyTrafficSecret,
                                 NULL, /* Current running hash. */
                                 &ss->ssl3.hs.clientEarlyTrafficSecret);
         if (rv != SECSuccess) {
             FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
             return SECFailure;
         }
     }
+
     ssl_GetXmitBufLock(ss);
     rv = tls13_SendServerHelloSequence(ss);
     ssl_ReleaseXmitBufLock(ss);
     if (rv != SECSuccess) {
         FATAL_ERROR(ss, PORT_GetError(), handshake_failure);
         return SECFailure;
     }
 
@@ -1855,16 +1856,19 @@ tls13_SendEncryptedServerSequence(sslSoc
 
     rv = tls13_SetCipherSpec(ss, TrafficKeyHandshake,
                              CipherSpecWrite, PR_FALSE);
     if (rv != SECSuccess) {
         LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE);
         return SECFailure;
     }
 
+    ss->ssl3.hs.shortHeaders = ssl3_ExtensionNegotiated(
+        ss, ssl_tls13_short_header_xtn);
+
     if (ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted) {
         rv = ssl3_RegisterExtensionSender(ss, &ss->xtnData, ssl_tls13_early_data_xtn,
                                           tls13_ServerSendEarlyDataXtn);
         if (rv != SECSuccess) {
             return SECFailure; /* Error code set already. */
         }
     }
 
@@ -2061,16 +2065,19 @@ tls13_HandleServerHelloPart2(sslSocket *
     if (rv != SECSuccess) {
         return SECFailure;
     }
     rv = tls13_ComputeHandshakeSecrets(ss);
     if (rv != SECSuccess) {
         return SECFailure; /* error code is set. */
     }
 
+    ss->ssl3.hs.shortHeaders = ssl3_ExtensionNegotiated(
+        ss, ssl_tls13_short_header_xtn);
+
     rv = tls13_SetCipherSpec(ss, TrafficKeyHandshake,
                              CipherSpecRead, PR_FALSE);
     if (rv != SECSuccess) {
         FATAL_ERROR(ss, SSL_ERROR_INIT_CIPHER_SUITE_FAILURE, internal_error);
         return SECFailure;
     }
     TLS13_SET_HS_STATE(ss, wait_encrypted_extensions);
 
@@ -4020,17 +4027,18 @@ static const struct {
     { ssl_tls13_key_share_xtn, ExtensionSendClearOrHrr },
     { ssl_tls13_pre_shared_key_xtn, ExtensionSendClear },
     { ssl_tls13_early_data_xtn, ExtensionSendEncrypted },
     { ssl_next_proto_nego_xtn, ExtensionNotUsed },
     { ssl_renegotiation_info_xtn, ExtensionNotUsed },
     { ssl_signed_cert_timestamp_xtn, ExtensionSendCertificate },
     { ssl_cert_status_xtn, ExtensionSendCertificate },
     { ssl_tls13_ticket_early_data_info_xtn, ExtensionNewSessionTicket },
-    { ssl_tls13_cookie_xtn, ExtensionSendHrr }
+    { ssl_tls13_cookie_xtn, ExtensionSendHrr },
+    { ssl_tls13_short_header_xtn, ExtensionSendClear }
 };
 
 PRBool
 tls13_ExtensionAllowed(PRUint16 extension, SSL3HandshakeType message)
 {
     unsigned int i;
 
     PORT_Assert((message == client_hello) ||
@@ -4292,16 +4300,17 @@ tls13_MaybeDo0RTTHandshake(sslSocket *ss
 {
     SECStatus rv;
 
     /* Don't do anything if there is no early_data xtn, which means we're
      * not doing early data. */
     if (!ssl3_ClientExtensionAdvertised(ss, ssl_tls13_early_data_xtn)) {
         return SECSuccess;
     }
+
     ss->ssl3.hs.zeroRttState = ssl_0rtt_sent;
     ss->ssl3.hs.zeroRttSuite = ss->ssl3.hs.cipher_suite;
 
     SSL_TRC(3, ("%d: TLS13[%d]: in 0-RTT mode", SSL_GETPID(), ss->fd));
 
     /* Set the ALPN data as if it was negotiated. We check in the ServerHello
      * handler that the server negotiates the same value. */
     if (ss->sec.ci.sid->u.ssl3.alpnSelection.len) {
@@ -4314,18 +4323,17 @@ tls13_MaybeDo0RTTHandshake(sslSocket *ss
 
     /* Null spec... */
     ssl_GetSpecReadLock(ss);
     ss->ssl3.hs.nullSpec = ss->ssl3.cwSpec;
     tls13_CipherSpecAddRef(ss->ssl3.hs.nullSpec);
     ssl_ReleaseSpecReadLock(ss);
 
     /* Cipher suite already set in tls13_SetupClientHello. */
-    ss->ssl3.hs.preliminaryInfo = 0; /* TODO(ekr@rtfm.com) Fill this in.
-                                      * bug 1281255. */
+    ss->ssl3.hs.preliminaryInfo = 0;
 
     rv = tls13_DeriveSecret(ss, ss->ssl3.hs.currentSecret,
                             kHkdfLabelClient,
                             kHkdfLabelEarlyTrafficSecret,
                             NULL,
                             &ss->ssl3.hs.clientEarlyTrafficSecret);
     if (rv != SECSuccess)
         return SECFailure;
--- a/security/nss/lib/ssl/tls13exthandle.c
+++ b/security/nss/lib/ssl/tls13exthandle.c
@@ -1066,8 +1066,106 @@ tls13_ServerHandlePskKeyExchangeModesXtn
         return SECFailure;
     }
 
     /* Keep track of negotiated extensions. */
     xtnData->negotiated[xtnData->numNegotiated++] = ex_type;
 
     return SECSuccess;
 }
+
+PRInt32
+tls13_SendShortHeaderXtn(const sslSocket *ss,
+                         TLSExtensionData *xtnData,
+                         PRBool append, PRUint32 maxBytes)
+{
+    PRUint32 extension_len = 2 + 2; /* Type + length (0). */
+
+    if (!ss->opt.enableShortHeaders) {
+        return 0;
+    }
+
+    /* Presently this is incompatible with 0-RTT. We will fix if
+     * it becomes more than an experiment. */
+    if (ss->opt.enable0RttData) {
+        return 0;
+    }
+
+    if (IS_DTLS(ss)) {
+        return 0;
+    }
+
+    SSL_TRC(3, ("%d: TLS13[%d]: send short_header extension",
+                SSL_GETPID(), ss->fd));
+
+    if (maxBytes < extension_len) {
+        PORT_Assert(0);
+        return 0;
+    }
+
+    if (append) {
+        SECStatus rv;
+
+        rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_tls13_short_header_xtn, 2);
+        if (rv != SECSuccess)
+            return -1;
+
+        rv = ssl3_ExtAppendHandshakeNumber(ss, 0, 2);
+        if (rv != SECSuccess)
+            return -1;
+
+        xtnData->advertised[xtnData->numAdvertised++] =
+            ssl_tls13_short_header_xtn;
+    }
+
+    return extension_len;
+}
+
+SECStatus
+tls13_HandleShortHeaderXtn(
+    const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type,
+    SECItem *data)
+{
+    SSL_TRC(3, ("%d: TLS13[%d]: handle early_data extension",
+                SSL_GETPID(), ss->fd));
+
+    /* If we are doing < TLS 1.3, then ignore this. */
+    if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
+        return SECSuccess;
+    }
+
+    /* Presently this is incompatible with 0-RTT. We will fix if
+     * it becomes more than an experiment. */
+    if (ss->opt.enable0RttData) {
+        return SECSuccess;
+    }
+
+    if (IS_DTLS(ss)) {
+        PORT_SetError(SSL_ERROR_EXTENSION_DISALLOWED_FOR_VERSION);
+        return SECFailure;
+    }
+
+    if (data->len) {
+        PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE);
+        return SECFailure;
+    }
+
+    if (!ss->opt.enableShortHeaders) {
+        /* Ignore. */
+        return SECSuccess;
+    }
+
+    /* Keep track of negotiated extensions. */
+    xtnData->negotiated[xtnData->numNegotiated++] = ex_type;
+
+    if (ss->sec.isServer) {
+        SECStatus rv;
+
+        rv = ssl3_RegisterExtensionSender(ss, xtnData,
+                                          ssl_tls13_short_header_xtn,
+                                          tls13_SendShortHeaderXtn);
+        if (rv != SECSuccess) {
+            return SECFailure;
+        }
+    }
+
+    return SECSuccess;
+}
--- a/security/nss/lib/ssl/tls13exthandle.h
+++ b/security/nss/lib/ssl/tls13exthandle.h
@@ -59,10 +59,16 @@ PRInt32 tls13_ClientSendHrrCookieXtn(con
                                      PRBool append,
                                      PRUint32 maxBytes);
 PRInt32 tls13_ClientSendPskKeyExchangeModesXtn(const sslSocket *ss,
                                                TLSExtensionData *xtnData,
                                                PRBool append, PRUint32 maxBytes);
 SECStatus tls13_ServerHandlePskKeyExchangeModesXtn(const sslSocket *ss,
                                                    TLSExtensionData *xtnData,
                                                    PRUint16 ex_type, SECItem *data);
+PRInt32 tls13_SendShortHeaderXtn(const sslSocket *ss,
+                                 TLSExtensionData *xtnData,
+                                 PRBool append, PRUint32 maxBytes);
+SECStatus tls13_HandleShortHeaderXtn(
+    const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type,
+    SECItem *data);
 
 #endif
--- a/security/nss/lib/util/pkcs11n.h
+++ b/security/nss/lib/util/pkcs11n.h
@@ -217,16 +217,22 @@
 
 /* TLS extended master secret derivation */
 #define CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE (CKM_NSS + 25)
 #define CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH (CKM_NSS + 26)
 
 #define CKM_NSS_CHACHA20_KEY_GEN (CKM_NSS + 27)
 #define CKM_NSS_CHACHA20_POLY1305 (CKM_NSS + 28)
 
+/* Additional PKCS #12 PBE algorithms defined in v1.1 */
+#define CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN (CKM_NSS + 29)
+#define CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN (CKM_NSS + 30)
+#define CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN (CKM_NSS + 31)
+#define CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN (CKM_NSS + 32)
+
 /*
  * HISTORICAL:
  * Do not attempt to use these. They are only used by NETSCAPE's internal
  * PKCS #11 interface. Most of these are place holders for other mechanism
  * and will change in the future.
  */
 #define CKM_NETSCAPE_PBE_SHA1_DES_CBC 0x80000002UL
 #define CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC 0x80000003UL
--- a/security/nss/lib/util/utilmod.c
+++ b/security/nss/lib/util/utilmod.c
@@ -227,20 +227,25 @@ nssutil_ReadSecmodDB(const char *appName
      * the following loop takes line separated config lines and collapses
      * the lines to a single string, escaping and quoting as necessary.
      */
     /* loop state variables */
     moduleString = NULL;   /* current concatenated string */
     internal = PR_FALSE;   /* is this an internal module */
     skipParams = PR_FALSE; /* did we find an override parameter block*/
     paramsValue = NULL;    /* the current parameter block value */
-    while (fgets(line, sizeof(line), fd) != NULL) {
-        int len = PORT_Strlen(line);
+    do {
+        int len;
+
+        if (fgets(line, sizeof(line), fd) == NULL) {
+            goto endloop;
+        }
 
         /* remove the ending newline */
+        len = PORT_Strlen(line);
         if (len && line[len - 1] == '\n') {
             len--;
             line[len] = 0;
         }
         if (*line == '#') {
             continue;
         }
         if (*line != 0) {
@@ -339,16 +344,17 @@ nssutil_ReadSecmodDB(const char *appName
                 }
             }
             continue;
         }
         if ((moduleString == NULL) || (*moduleString == 0)) {
             continue;
         }
 
+    endloop:
         /*
          * if we are here, we have found a complete stanza. Now write out
          * any param section we may have found.
          */
         if (paramsValue) {
             /* we had an override */
             if (!skipParams) {
                 moduleString = nssutil_DupnCat(moduleString, " parameters=", 12);
@@ -374,17 +380,17 @@ nssutil_ReadSecmodDB(const char *appName
             moduleList[0] = moduleString;
         } else {
             moduleList[moduleCount] = moduleString;
             moduleCount++;
         }
         moduleString = NULL;
         internal = PR_FALSE;
         skipParams = PR_FALSE;
-    }
+    } while (!feof(fd));
 
     if (moduleString) {
         PORT_Free(moduleString);
         moduleString = NULL;
     }
 done:
     /* if we couldn't open a pkcs11 database, look for the old one */
     if (fd == NULL) {
index a826a1da252f02cf2d1612d88b5e85356cce7810..d71fbb5016b2ac180a61303d2aa2732910aa7a4b
GIT binary patch
literal 1376
zc$_n6VvR9qVsTl(%*4pVB*1j*!`#KcY~J;Vq_QlrJ*IEK%f_kI=F#?@mywa1mBFCE
zklTQhjX9KsO_(V(*ih6!7{uWc=5fhP&vZ^LDpByvOE#1=5C;i!3k#H&m+PefrILYC
zddc~@hWZA&ASq^HHMovo4@V;fkIeK81;^sz(xSw?<Wz;=)S|M~A_Zqh137VCLo-7|
z0}}%<hyrpgfLudEBQV#X7S%<<27(|ChcK6OVoqjSeo<a#qM@JxKS+>Wm?JnbPr)m{
zI2Fm|0g06Xi8(qThwB+i8Aw1}E(j4;2q?-=DNQcP%+G@v%`D7SkXTuem;>^UK@+1A
zau_kPGB7tW@-qO%xtN+585vI16-T)q%WMh?<+)!TxxHFWc=5KLH20f)pNl<q{B!ZE
z%kN^Erkro#vEW$L#HP&~4?f{43;&%_`oZd2$uXO4M@udgUhBUyOY4q!?+)hVtN+9u
zxm}x1S1h$Ka4<aCVD`>n`e)^|mcydQT;$6Se7fADUiMHmy5cXl;DVdUMOSWi%BBWB
zD)eTlEE37hTbd;r<;nl&@V7d@hsV8h{X|)KZhhfC>!`>6e9y956=yu3mb7kRT(v)Q
zf1G$uq(r;w-O9FE?s}iX85q-JUM1gl%)By7;jfP=TU79W<BIT(RT;7zDWdmV>IFT*
zoc<|ixp9f5m7UyJ*B&gF$6x-Fae<)CLndZM2FArrjE{jKa^FB67=W_MED{D{4I+UV
z|0k?xVlTBhb2Bw1X_3&5$RcY4S&#xg7BLo)&l6NqpPH*aWeQJyqy1HD&LsxL6$YXp
zX+ah~1D+=2NZ<nr^D{F3XJKJxVqE|+MU_R&K!lA$n~jl`m7SRp&SEks1xd@Z<Qe1`
zm@F__V9=(QQBqQ1rLUh{lw*vNT=k1H5{+~-5_OBg=}|Y`R1c^IQ<n)bx_m&^DzLa3
zI2)L=aVE5RFt+{8VPrJWGSGlIj)_rB24re6&{*`WqwgFLY{0?Bmfpw%%&7*A%`i=j
zj4b5_r3NZ6z5!#K1k`Ey$;AaIh8Xz5RWY?W!aR@&k}gKI4VFDYxf7H*;dv91HJu%S
zekw8G0r^Q76!J_43}}S~GbsHl?%p&zyXNcsWp4js+um<0pEaGwsXLB0_T!b?uibte
z5Yb7n>YS_B=VI$JuYba--TS{qi#$;mQOcZa^Ox64<DmDG=e{E6zMRnzl4P8(7N4^#
zVNYGw?o(4sr#$+4sv~nt*t}_9f1a^lwbP{O?1p`Z)!U0hJZ9YZp?_5JVOkJJ6z~7L
zf;a2tKCv%*70~H3wO9CZ*7Jq-;gekS_BtH=6E^Qi`AnwUk8kwX+gUGbWBVOpHnUsC
z=ayn<W7Z^9S(BF&4mkDqcD;0;rq?&&)$G)>D?Pq1legQK{M~KSsVDEdzZfLBn!dex
il#jFb`lZ<WY;$k**RxM@{h%k;WAQU%y=m8(m#qL5@YweN
--- a/security/nss/tests/ssl/ssl.sh
+++ b/security/nss/tests/ssl/ssl.sh
@@ -1001,17 +1001,17 @@ ssl_cleanup()
 # local shell function to run coverage, authentication and stress tests
 ########################################################################
 ssl_run()
 {
     for SSL_RUN in ${NSS_SSL_RUN}
     do
         case "${SSL_RUN}" in
         "stapling")
-            if [ -nz "$NSS_DISABLE_LIBPKIX" ]; then
+            if [ -z "$NSS_DISABLE_LIBPKIX" ]; then
               ssl_stapling
             fi
             ;;
         "signed_cert_timestamps")
             ssl_signed_cert_timestamps
             ;;
         "cov")
             ssl_cov
--- a/taskcluster/ci/android-stuff/kind.yml
+++ b/taskcluster/ci/android-stuff/kind.yml
@@ -36,18 +36,16 @@ jobs:
                 MH_CUSTOM_BUILD_VARIANT_CFG: "api-15-gradle-dependencies"
                 MOZHARNESS_ACTIONS: "get-secrets build multi-l10n update"
                 MOZHARNESS_CONFIG: >
                     builds/releng_base_android_64_builds.py
                     disable_signing.py
                     platform_supports_post_upload_to_latest.py
                 MOZHARNESS_SCRIPT: "mozharness/scripts/fx_desktop_build.py"
                 TOOLTOOL_CACHE: "/home/worker/tooltool-cache"
-                TOOLTOOL_REPO: "https://github.com/mozilla/build-tooltool"
-                TOOLTOOL_REV: "master"
             artifacts:
               - name: public/build
                 path: /home/worker/artifacts/
                 type: directory
             caches:
               - name: tooltool-cache
                 mount-point: /home/worker/tooltool-cache
                 type: persistent
@@ -86,18 +84,16 @@ jobs:
                 MH_BUILD_POOL: "taskcluster"
                 MH_CUSTOM_BUILD_VARIANT_CFG: "android-test"
                 MOZHARNESS_ACTIONS: "get-secrets build multi-l10n update"
                 MOZHARNESS_CONFIG: >
                     builds/releng_base_android_64_builds.py
                     disable_signing.py
                     platform_supports_post_upload_to_latest.py
                 MOZHARNESS_SCRIPT: "mozharness/scripts/fx_desktop_build.py"
-                TOOLTOOL_REPO: "https://github.com/mozilla/build-tooltool"
-                TOOLTOOL_REV: "master"
             artifacts:
               - name: public/android/unittest
                 path: /home/worker/workspace/build/src/obj-firefox/gradle/build/mobile/android/app/reports/tests
                 type: directory
               - name: public/build
                 path: /home/worker/artifacts/
                 type: directory
             caches:
@@ -137,18 +133,16 @@ jobs:
                 MH_BUILD_POOL: "taskcluster"
                 MH_CUSTOM_BUILD_VARIANT_CFG: "android-lint"
                 MOZHARNESS_ACTIONS: "get-secrets build multi-l10n update"
                 MOZHARNESS_CONFIG: >
                     builds/releng_base_android_64_builds.py
                     disable_signing.py
                     platform_supports_post_upload_to_latest.py
                 MOZHARNESS_SCRIPT: "mozharness/scripts/fx_desktop_build.py"
-                TOOLTOOL_REPO: "https://github.com/mozilla/build-tooltool"
-                TOOLTOOL_REV: "master"
             artifacts:
               - name: public/android/lint/lint-results-automationDebug.html
                 path: /home/worker/workspace/build/src/obj-firefox/gradle/build/mobile/android/app/outputs/lint-results-automationDebug.html
                 type: file
               - name: public/android/lint/lint-results-automationDebug.xml
                 path: /home/worker/workspace/build/src/obj-firefox/gradle/build/mobile/android/app/outputs/lint-results-automationDebug.xml
                 type: file
               - name: public/android/lint/lint-results-automationDebug_files
@@ -199,18 +193,16 @@ jobs:
                 MH_BUILD_POOL: "taskcluster"
                 MH_CUSTOM_BUILD_VARIANT_CFG: "android-checkstyle"
                 MOZHARNESS_ACTIONS: "get-secrets build multi-l10n update"
                 MOZHARNESS_CONFIG: >
                     builds/releng_base_android_64_builds.py
                     disable_signing.py
                     platform_supports_post_upload_to_latest.py
                 MOZHARNESS_SCRIPT: "mozharness/scripts/fx_desktop_build.py"
-                TOOLTOOL_REPO: "https://github.com/mozilla/build-tooltool"
-                TOOLTOOL_REV: "master"
             artifacts:
               - name: public/android/checkstyle/checkstyle.xml
                 path: /home/worker/workspace/build/src/obj-firefox/gradle/build/mobile/android/app/reports/checkstyle/checkstyle.xml
                 type: file
               - name: public/build
                 path: /home/worker/artifacts/
                 type: directory
             caches:
@@ -251,18 +243,16 @@ jobs:
                 MH_BUILD_POOL: "taskcluster"
                 MH_CUSTOM_BUILD_VARIANT_CFG: "android-findbugs"
                 MOZHARNESS_ACTIONS: "get-secrets build multi-l10n update"
                 MOZHARNESS_CONFIG: >
                     builds/releng_base_android_64_builds.py
                     disable_signing.py
                     platform_supports_post_upload_to_latest.py
                 MOZHARNESS_SCRIPT: "mozharness/scripts/fx_desktop_build.py"
-                TOOLTOOL_REPO: "https://github.com/mozilla/build-tooltool"
-                TOOLTOOL_REV: "master"
             artifacts:
               - name: public/android/findbugs/findbugs-report.html
                 path: /home/worker/workspace/build/src/obj-firefox/gradle/build/mobile/android/app/outputs/findbugs/findbugs-automationDebug-output.html
                 type: file
               - name: public/build
                 path: /home/worker/artifacts/
                 type: directory
             caches:
--- a/taskcluster/ci/marionette-harness/kind.yml
+++ b/taskcluster/ci/marionette-harness/kind.yml
@@ -27,18 +27,16 @@ jobs:
         worker-type: aws-provisioner-v1/gecko-t-linux-xlarge
         worker:
             implementation: docker-worker
             docker-image: {in-tree: desktop-build}  # NOTE: better to use the lint image
             env:
                 JOB_SCRIPT: "taskcluster/scripts/tester/harness-test-linux.sh"
                 MOZHARNESS_SCRIPT: "testing/mozharness/scripts/marionette_harness_tests.py"
                 TOOLS_DISABLE: "true"
-                TOOLTOOL_REPO: "https://github.com/mozilla/build-tooltool"
-                TOOLTOOL_REV: "master"
             artifacts:
               - name: public/logs/
                 path: /home/worker/workspace/mozharness_workspace/upload/logs/
                 type: directory
             command:
               - "bash"
               - "/home/worker/bin/build.sh"
               - "--tests=testing/marionette/harness/marionette_harness/tests/harness_unit"
--- a/taskcluster/scripts/misc/build-clang32-windows.sh
+++ b/taskcluster/scripts/misc/build-clang32-windows.sh
@@ -1,28 +1,26 @@
 #!/bin/bash
 
 set -x -e -v
 
 # This script is for building clang-cl on Windows.
 
-# Fetch our toolchain from tooltool.
-wget -O tooltool.py ${TOOLTOOL_REPO}/raw/${TOOLTOOL_REV}/tooltool.py
-chmod +x tooltool.py
+chmod +x build/src/taskcluster/docker/recipes/tooltool.py
 : TOOLTOOL_CACHE                ${TOOLTOOL_CACHE:=/home/worker/tooltool-cache}
 export TOOLTOOL_CACHE
 
 TOOLTOOL_AUTH_FILE=/c/builds/relengapi.tok
 if [ ! -e ${TOOLTOOL_AUTH_FILE} ]; then
     echo cannot find ${TOOLTOOL_AUTH_FILE}
     exit 1
 fi
 
 TOOLTOOL_MANIFEST=build/src/browser/config/tooltool-manifests/win32/build-clang-cl.manifest
-./tooltool.py --authentication-file="${TOOLTOOL_AUTH_FILE}" -m "${TOOLTOOL_MANIFEST}" fetch
+./build/src/taskcluster/docker/recipes/tooltool.py --authentication-file="${TOOLTOOL_AUTH_FILE}" -m "${TOOLTOOL_MANIFEST}" fetch
 
 # Set up all the Visual Studio paths.
 MSVC_DIR=vs2015u3
 VSWINPATH="$(cd ${MSVC_DIR} && pwd)"
 
 echo vswinpath ${VSWINPATH}
 
 export WINDOWSSDKDIR="${VSWINPATH}/SDK"
--- a/taskcluster/scripts/misc/build-clang64-windows.sh
+++ b/taskcluster/scripts/misc/build-clang64-windows.sh
@@ -1,28 +1,26 @@
 #!/bin/bash
 
 set -x -e -v
 
 # This script is for building clang-cl on Windows.
 
-# Fetch our toolchain from tooltool.
-wget -O tooltool.py ${TOOLTOOL_REPO}/raw/${TOOLTOOL_REV}/tooltool.py
-chmod +x tooltool.py
+chmod +x build/src/taskcluster/docker/recipes/tooltool.py
 : TOOLTOOL_CACHE                ${TOOLTOOL_CACHE:=/home/worker/tooltool-cache}
 export TOOLTOOL_CACHE
 
 TOOLTOOL_AUTH_FILE=/c/builds/relengapi.tok
 if [ ! -e ${TOOLTOOL_AUTH_FILE} ]; then
     echo cannot find ${TOOLTOOL_AUTH_FILE}
     exit 1
 fi
 
 TOOLTOOL_MANIFEST=build/src/browser/config/tooltool-manifests/win32/build-clang-cl.manifest
-./tooltool.py --authentication-file="${TOOLTOOL_AUTH_FILE}" -m "${TOOLTOOL_MANIFEST}" fetch
+./build/src/taskcluster/docker/recipes/tooltool.py --authentication-file="${TOOLTOOL_AUTH_FILE}" -m "${TOOLTOOL_MANIFEST}" fetch
 
 # Set up all the Visual Studio paths.
 MSVC_DIR=vs2015u3
 VSWINPATH="$(cd ${MSVC_DIR} && pwd)"
 
 echo vswinpath ${VSWINPATH}
 
 export WINDOWSSDKDIR="${VSWINPATH}/SDK"
--- a/taskcluster/taskgraph/transforms/job/hazard.py
+++ b/taskcluster/taskgraph/transforms/job/hazard.py
@@ -69,18 +69,16 @@ def docker_worker_hazard(config, job, ta
         'name': 'tooltool-cache',
         'mount-point': '/home/worker/tooltool-cache',
     })
     worker['relengapi-proxy'] = True
     taskdesc['scopes'].extend([
         'docker-worker:relengapi-proxy:tooltool.download.public',
     ])
     env['TOOLTOOL_CACHE'] = '/home/worker/tooltool-cache'
-    env['TOOLTOOL_REPO'] = 'https://github.com/mozilla/build-tooltool'
-    env['TOOLTOOL_REV'] = 'master'
 
     # build-haz-linux.sh needs this otherwise it assumes the checkout is in
     # the workspace.
     env['GECKO_DIR'] = '/home/worker/checkouts/gecko'
 
     worker['command'] = [
         '/home/worker/bin/run-task',
         '--chown-recursive', '/home/worker/tooltool-cache',
--- a/taskcluster/taskgraph/transforms/job/mozharness.py
+++ b/taskcluster/taskgraph/transforms/job/mozharness.py
@@ -137,18 +137,16 @@ def mozharness_on_docker_worker_setup(co
         })
         taskdesc['scopes'].extend([
             'docker-worker:relengapi-proxy:tooltool.download.public',
         ])
         if run['tooltool-downloads'] == 'internal':
             taskdesc['scopes'].append(
                 'docker-worker:relengapi-proxy:tooltool.download.internal')
         env['TOOLTOOL_CACHE'] = '/home/worker/tooltool-cache'
-        env['TOOLTOOL_REPO'] = 'https://github.com/mozilla/build-tooltool'
-        env['TOOLTOOL_REV'] = 'master'
 
     # Retry if mozharness returns TBPL_RETRY
     worker['retry-exit-status'] = 4
 
     docker_worker_setup_secrets(config, job, taskdesc)
 
     command = [
         '/home/worker/bin/run-task',
@@ -193,18 +191,16 @@ def mozharness_on_windows(config, job, t
     }]
 
     docker_worker_add_gecko_vcs_env_vars(config, job, taskdesc)
 
     env = worker['env']
     env.update({
         'MOZ_BUILD_DATE': config.params['moz_build_date'],
         'MOZ_SCM_LEVEL': config.params['level'],
-        'TOOLTOOL_REPO': 'https://github.com/mozilla/build-tooltool',
-        'TOOLTOOL_REV': 'master',
     })
 
     mh_command = [r'c:\mozilla-build\python\python.exe']
     mh_command.append('\\'.join([r'.\build\src\testing', run['script'].replace('/', '\\')]))
     for cfg in run['config']:
         mh_command.append('--config ' + cfg.replace('/', '\\'))
     mh_command.append('--branch ' + config.params['project'])
     mh_command.append(r'--skip-buildbot-actions --work-dir %cd:Z:=z:%\build')
--- a/taskcluster/taskgraph/transforms/job/toolchain.py
+++ b/taskcluster/taskgraph/transforms/job/toolchain.py
@@ -50,18 +50,16 @@ def docker_worker_toolchain(config, job,
     # tooltool downloads; note that this downloads using the API endpoint directly,
     # rather than via relengapi-proxy
     worker['caches'].append({
         'type': 'persistent',
         'name': 'tooltool-cache',
         'mount-point': '/home/worker/tooltool-cache',
     })
     env['TOOLTOOL_CACHE'] = '/home/worker/tooltool-cache'
-    env['TOOLTOOL_REPO'] = 'https://github.com/mozilla/build-tooltool'
-    env['TOOLTOOL_REV'] = 'master'
 
     command = ' && '.join([
         "cd /home/worker/",
         "./bin/checkout-sources.sh",
         "./workspace/build/src/taskcluster/scripts/misc/" + run['script'],
     ])
     worker['command'] = ["/bin/bash", "-c", command]
 
@@ -88,18 +86,16 @@ def windows_toolchain(config, job, taskd
     taskdesc['scopes'].extend([
         'generic-worker:cache:' + svn_cache,
     ])
 
     env = worker['env']
     env.update({
         'MOZ_BUILD_DATE': config.params['moz_build_date'],
         'MOZ_SCM_LEVEL': config.params['level'],
-        'TOOLTOOL_REPO': 'https://github.com/mozilla/build-tooltool',
-        'TOOLTOOL_REV': 'master',
     })
 
     hg = r'c:\Program Files\Mercurial\hg.exe'
     hg_command = ['"{}"'.format(hg)]
     hg_command.append('robustcheckout')
     hg_command.extend(['--sharebase', 'y:\\hg-shared'])
     hg_command.append('--purge')
     hg_command.extend(['--upstream', 'https://hg.mozilla.org/mozilla-unified'])
--- a/toolkit/components/filepicker/nsFileView.cpp
+++ b/toolkit/components/filepicker/nsFileView.cpp
@@ -1,25 +1,25 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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 "DateTimeFormat.h"
 #include "nsIFileView.h"
 #include "nsITreeView.h"
 #include "mozilla/ModuleUtils.h"
 #include "nsITreeSelection.h"
 #include "nsITreeColumns.h"
 #include "nsITreeBoxObject.h"
 #include "nsIFile.h"
 #include "nsString.h"
 #include "nsReadableUtils.h"
 #include "nsCRT.h"
 #include "nsPrintfCString.h"
-#include "nsIDateTimeFormat.h"
 #include "nsQuickSort.h"
 #include "nsIAtom.h"
 #include "nsIAutoCompleteResult.h"
 #include "nsIAutoCompleteSearch.h"
 #include "nsISimpleEnumerator.h"
 #include "nsAutoPtr.h"
 #include "nsIMutableArray.h"
 #include "nsTArray.h"
@@ -229,17 +229,16 @@ protected:
 
   nsTArray<nsCOMPtr<nsIFile> > mFileList;
   nsTArray<nsCOMPtr<nsIFile> > mDirList;
   nsTArray<nsCOMPtr<nsIFile> > mFilteredFiles;
 
   nsCOMPtr<nsIFile> mDirectoryPath;
   nsCOMPtr<nsITreeBoxObject> mTree;
   nsCOMPtr<nsITreeSelection> mSelection;
-  nsCOMPtr<nsIDateTimeFormat> mDateFormatter;
 
   int16_t mSortType;
   int32_t mTotalRows;
 
   nsTArray<char16_t*> mCurrentFilters;
 
   bool mShowHiddenFiles;
   bool mDirectoryFilter;
@@ -286,20 +285,16 @@ nsFileView::~nsFileView()
   uint32_t count = mCurrentFilters.Length();
   for (uint32_t i = 0; i < count; ++i)
     free(mCurrentFilters[i]);
 }
 
 nsresult
 nsFileView::Init()
 {
-  mDateFormatter = nsIDateTimeFormat::Create();
-  if (!mDateFormatter)
-    return NS_ERROR_OUT_OF_MEMORY;
-
   return NS_OK;
 }
 
 // nsISupports implementation
 
 NS_IMPL_ISUPPORTS(nsFileView, nsITreeView, nsIFileView)
 
 // nsIFileView implementation
@@ -725,18 +720,18 @@ nsFileView::GetCellText(int32_t aRow, ns
   aCol->GetIdConst(&colID);
   if (NS_LITERAL_STRING("FilenameColumn").Equals(colID)) {
     curFile->GetLeafName(aCellText);
   } else if (NS_LITERAL_STRING("LastModifiedColumn").Equals(colID)) {
     PRTime lastModTime;
     curFile->GetLastModifiedTime(&lastModTime);
     // XXX FormatPRTime could take an nsAString&
     nsAutoString temp;
-    mDateFormatter->FormatPRTime(nullptr, kDateFormatShort, kTimeFormatSeconds,
-                                 lastModTime * 1000, temp);
+    mozilla::DateTimeFormat::FormatPRTime(kDateFormatShort, kTimeFormatSeconds,
+                                          lastModTime * 1000, temp);
     aCellText = temp;
   } else {
     // file size
     if (isDirectory)
       aCellText.SetCapacity(0);
     else {
       int64_t fileSize;
       curFile->GetFileSize(&fileSize);
--- a/toolkit/moz.configure
+++ b/toolkit/moz.configure
@@ -804,21 +804,23 @@ def skia_gpu(value, skia, target):
     if skia and value:
         return True
 
 set_config('MOZ_ENABLE_SKIA_GPU', skia_gpu)
 set_define('USE_SKIA_GPU', skia_gpu)
 
 option('--enable-skia-pdf', help='Enable Skia PDF')
 
-@depends('--enable-skia-pdf', skia)
-def skia_pdf(value, skia):
+@depends('--enable-skia-pdf', skia, milestone)
+def skia_pdf(value, skia, milestone):
     if value.origin == 'default':
         if not skia:
             return None
+        if milestone.is_nightly:
+            return True
     elif value and not skia:
         die('Cannot enable Skia PDF without enabling Skia')
     if skia and value:
         return True
 
 set_config('MOZ_ENABLE_SKIA_PDF', skia_pdf)
 set_define('MOZ_ENABLE_SKIA_PDF', skia_pdf)