Bug 1119980 - Use 'snprintf' instead of 'sprintf' to avoid a warning on Lollipop-based builds. r=froydnj
☠☠ backed out by c8053cb8ac32 ☠ ☠
authorBotond Ballo <botond@mozilla.com>
Mon, 25 May 2015 20:45:17 -0400
changeset 277925 bdb8d05f8870425176e12885c16f339439e2d3b0
parent 277924 a68a18840492b3899badfd98c13369779da5ab4b
child 277926 12ce98475c6e15c4eada2807bb7ec7003711ab9f
push id897
push userjlund@mozilla.com
push dateMon, 14 Sep 2015 18:56:12 +0000
treeherdermozilla-release@9411e2d2b214 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1119980
milestone41.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1119980 - Use 'snprintf' instead of 'sprintf' to avoid a warning on Lollipop-based builds. r=froydnj
dom/ipc/CrashReporterParent.cpp
dom/media/AudioStream.cpp
dom/wifi/WifiHotspotUtils.cpp
extensions/auth/nsHttpNegotiateAuth.cpp
gfx/thebes/gfxFontUtils.cpp
gfx/thebes/gfxHarfBuzzShaper.cpp
gfx/thebes/gfxTextRun.cpp
intl/locale/nsScriptableDateFormat.cpp
ipc/netd/Netd.cpp
layout/base/nsPresShell.cpp
layout/generic/nsAbsoluteContainingBlock.cpp
layout/generic/nsFrame.cpp
layout/style/FontFaceSet.cpp
media/gmp-clearkey/0.1/openaes/oaes_lib.c
mfbt/JSONWriter.h
mfbt/Snprintf.h
mfbt/moz.build
mfbt/tests/TestIntegerPrintfMacros.cpp
netwerk/cache/nsDiskCacheMap.cpp
netwerk/protocol/rtsp/rtsp/ASessionDescription.cpp
netwerk/test/PropertiesTest.cpp
toolkit/crashreporter/nsExceptionHandler.cpp
toolkit/profile/nsToolkitProfileService.cpp
tools/profiler/LulDwarf.cpp
tools/profiler/LulMain.cpp
widget/nsBaseWidget.cpp
xpcom/base/CodeAddressService.h
xpcom/ds/TimeStamp_posix.cpp
xpcom/glue/nsCRTGlue.cpp
--- a/dom/ipc/CrashReporterParent.cpp
+++ b/dom/ipc/CrashReporterParent.cpp
@@ -1,14 +1,15 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set sw=4 ts=8 et tw=80 : 
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #include "CrashReporterParent.h"
+#include "mozilla/Snprintf.h"
 #include "mozilla/dom/ContentParent.h"
 #include "nsXULAppAPI.h"
 #include <time.h>
 
 #include "mozilla/Telemetry.h"
 
 #ifdef MOZ_CRASHREPORTER
 #include "nsExceptionHandler.h"
@@ -121,17 +122,17 @@ CrashReporterParent::GenerateChildData(c
             break;
         default:
             NS_ERROR("unknown process type");
             break;
     }
     mNotes.Put(NS_LITERAL_CSTRING("ProcessType"), type);
 
     char startTime[32];
-    sprintf(startTime, "%lld", static_cast<long long>(mStartTime));
+    snprintf_literal(startTime, "%lld", static_cast<long long>(mStartTime));
     mNotes.Put(NS_LITERAL_CSTRING("StartupTime"), nsDependentCString(startTime));
 
     if (!mAppNotes.IsEmpty())
         mNotes.Put(NS_LITERAL_CSTRING("Notes"), mAppNotes);
 
     bool ret = CrashReporter::AppendExtraData(mChildDumpID, mNotes);
     if (ret && processNotes)
         ret = CrashReporter::AppendExtraData(mChildDumpID, *processNotes);
--- a/dom/media/AudioStream.cpp
+++ b/dom/media/AudioStream.cpp
@@ -7,16 +7,17 @@
 #include <math.h>
 #include <string.h>
 #include "mozilla/Logging.h"
 #include "prdtoa.h"
 #include "AudioStream.h"
 #include "VideoUtils.h"
 #include "mozilla/Monitor.h"
 #include "mozilla/Mutex.h"
+#include "mozilla/Snprintf.h"
 #include <algorithm>
 #include "mozilla/Telemetry.h"
 #include "soundtouch/SoundTouch.h"
 #include "Latency.h"
 #include "CubebUtils.h"
 #include "nsPrintfCString.h"
 #ifdef XP_MACOSX
 #include <sys/sysctl.h>
@@ -259,17 +260,17 @@ static void SetUint32LE(uint8_t* aDest, 
 }
 
 static FILE*
 OpenDumpFile(AudioStream* aStream)
 {
   if (!getenv("MOZ_DUMP_AUDIO"))
     return nullptr;
   char buf[100];
-  sprintf(buf, "dumped-audio-%d.wav", gDumpedAudioCount);
+  snprintf_literal(buf, "dumped-audio-%d.wav", gDumpedAudioCount);
   FILE* f = fopen(buf, "wb");
   if (!f)
     return nullptr;
   ++gDumpedAudioCount;
 
   uint8_t header[] = {
     // RIFF header
     0x52, 0x49, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x57, 0x41, 0x56, 0x45,
--- a/dom/wifi/WifiHotspotUtils.cpp
+++ b/dom/wifi/WifiHotspotUtils.cpp
@@ -9,16 +9,17 @@
 #include <errno.h>
 #include <string.h>
 #include <dirent.h>
 #include <stdlib.h>
 #include <cutils/properties.h>
 
 #include "prinit.h"
 #include "mozilla/Assertions.h"
+#include "mozilla/Snprintf.h"
 #include "nsDebug.h"
 #include "nsPrintfCString.h"
 
 static void* sWifiHotspotUtilsLib;
 static PRCallOnceType sInitWifiHotspotUtilsLib;
 // Socket pair used to exit from a blocking read.
 static struct wpa_ctrl* ctrl_conn;
 static const char *ctrl_iface_dir = "/data/misc/wifi/hostapd";
@@ -172,16 +173,16 @@ int32_t WifiHotspotUtils::do_wifi_hostap
   int stations = 0;
   size_t addrLen = sizeof(addr);
 
   if (sendCommand(ctrl_conn, "STA-FIRST", addr, &addrLen)) {
     return 0;
   }
   stations++;
 
-  sprintf(cmd, "STA-NEXT %s", addr);
+  snprintf_literal(cmd, "STA-NEXT %s", addr);
   while (sendCommand(ctrl_conn, cmd, addr, &addrLen) == 0) {
     stations++;
-    sprintf(cmd, "STA-NEXT %s", addr);
+    snprintf_literal(cmd, "STA-NEXT %s", addr);
   }
 
   return stations;
 }
--- a/extensions/auth/nsHttpNegotiateAuth.cpp
+++ b/extensions/auth/nsHttpNegotiateAuth.cpp
@@ -32,16 +32,17 @@
 #include "nsNetCID.h"
 #include "plbase64.h"
 #include "plstr.h"
 #include "prprf.h"
 #include "mozilla/Logging.h"
 #include "prmem.h"
 #include "prnetdb.h"
 #include "mozilla/Likely.h"
+#include "mozilla/Snprintf.h"
 
 //-----------------------------------------------------------------------------
 
 static const char kNegotiate[] = "Negotiate";
 static const char kNegotiateAuthTrustedURIs[] = "network.negotiate-auth.trusted-uris";
 static const char kNegotiateAuthDelegationURIs[] = "network.negotiate-auth.delegation-uris";
 static const char kNegotiateAuthAllowProxies[] = "network.negotiate-auth.allow-proxies";
 static const char kNegotiateAuthAllowNonFqdn[] = "network.negotiate-auth.allow-non-fqdn";
@@ -271,21 +272,22 @@ nsHttpNegotiateAuth::GenerateCredentials
     free(outToken);
 
     if (!encoded_token)
         return NS_ERROR_OUT_OF_MEMORY;
 
     LOG(("  Sending a token of length %d\n", outTokenLen));
 
     // allocate a buffer sizeof("Negotiate" + " " + b64output_token + "\0")
-    *creds = (char *) moz_xmalloc(kNegotiateLen + 1 + strlen(encoded_token) + 1);
+    const int bufsize = kNegotiateLen + 1 + strlen(encoded_token) + 1;
+    *creds = (char *) moz_xmalloc(bufsize);
     if (MOZ_UNLIKELY(!*creds))
         rv = NS_ERROR_OUT_OF_MEMORY;
     else
-        sprintf(*creds, "%s %s", kNegotiate, encoded_token);
+        snprintf(*creds, bufsize, "%s %s", kNegotiate, encoded_token);
 
     PR_Free(encoded_token);
     return rv;
 }
 
 bool
 nsHttpNegotiateAuth::TestBoolPref(const char *pref)
 {
--- a/gfx/thebes/gfxFontUtils.cpp
+++ b/gfx/thebes/gfxFontUtils.cpp
@@ -10,16 +10,17 @@
 #include "gfxColor.h"
 
 #include "nsServiceManagerUtils.h"
 
 #include "mozilla/dom/EncodingUtils.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
 #include "mozilla/BinarySearch.h"
+#include "mozilla/Snprintf.h"
 
 #include "nsCOMPtr.h"
 #include "nsIUUIDGenerator.h"
 #include "nsIUnicodeDecoder.h"
 
 #include "harfbuzz/hb.h"
 
 #include "plbase64.h"
@@ -63,31 +64,32 @@ void
 gfxSparseBitSet::Dump(const char* aPrefix, eGfxLog aWhichLog) const
 {
     NS_ASSERTION(mBlocks.DebugGetHeader(), "mHdr is null, this is bad");
     uint32_t b, numBlocks = mBlocks.Length();
 
     for (b = 0; b < numBlocks; b++) {
         Block *block = mBlocks[b];
         if (!block) continue;
-        char outStr[256];
+        const int BUFSIZE = 256;
+        char outStr[BUFSIZE];
         int index = 0;
-        index += sprintf(&outStr[index], "%s u+%6.6x [", aPrefix, (b << BLOCK_INDEX_SHIFT));
+        index += snprintf(&outStr[index], BUFSIZE - index, "%s u+%6.6x [", aPrefix, (b << BLOCK_INDEX_SHIFT));
         for (int i = 0; i < 32; i += 4) {
             for (int j = i; j < i + 4; j++) {
                 uint8_t bits = block->mBits[j];
                 uint8_t flip1 = ((bits & 0xaa) >> 1) | ((bits & 0x55) << 1);
                 uint8_t flip2 = ((flip1 & 0xcc) >> 2) | ((flip1 & 0x33) << 2);
                 uint8_t flipped = ((flip2 & 0xf0) >> 4) | ((flip2 & 0x0f) << 4);
 
-                index += sprintf(&outStr[index], "%2.2x", flipped);
+                index += snprintf(&outStr[index], BUFSIZE - index, "%2.2x", flipped);
             }
-            if (i + 4 != 32) index += sprintf(&outStr[index], " ");
+            if (i + 4 != 32) index += snprintf(&outStr[index], BUFSIZE - index, " ");
         }
-        index += sprintf(&outStr[index], "]");
+        index += snprintf(&outStr[index], BUFSIZE - index, "]");
         LOG(aWhichLog, ("%s", outStr));
     }
 }
 
 nsresult
 gfxFontUtils::ReadCMAPTableFormat10(const uint8_t *aBuf, uint32_t aLength,
                                     gfxSparseBitSet& aCharacterMap)
 {
@@ -1405,18 +1407,18 @@ gfxFontUtils::DecodeFontName(const char 
     const char *csName = GetCharsetForFontName(aPlatformCode, aScriptCode, aLangCode);
 
     if (!csName) {
         // nullptr -> unknown charset
 #ifdef DEBUG
         char warnBuf[128];
         if (aByteLen > 64)
             aByteLen = 64;
-        sprintf(warnBuf, "skipping font name, unknown charset %d:%d:%d for <%.*s>",
-                aPlatformCode, aScriptCode, aLangCode, aByteLen, aNameData);
+        snprintf_literal(warnBuf, "skipping font name, unknown charset %d:%d:%d for <%.*s>",
+                         aPlatformCode, aScriptCode, aLangCode, aByteLen, aNameData);
         NS_WARNING(warnBuf);
 #endif
         return false;
     }
 
     if (csName[0] == 0) {
         // empty charset name: data is utf16be, no need to instantiate a converter
         uint32_t strLen = aByteLen / 2;
--- a/gfx/thebes/gfxHarfBuzzShaper.cpp
+++ b/gfx/thebes/gfxHarfBuzzShaper.cpp
@@ -4,16 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsString.h"
 #include "gfxContext.h"
 #include "gfxFontConstants.h"
 #include "gfxHarfBuzzShaper.h"
 #include "gfxFontUtils.h"
 #include "gfxTextRun.h"
+#include "mozilla/Snprintf.h"
 #include "nsUnicodeProperties.h"
 #include "nsUnicodeScriptCodes.h"
 #include "nsUnicodeNormalizer.h"
 
 #include "harfbuzz/hb.h"
 #include "harfbuzz/hb-ot.h"
 
 #if ENABLE_INTL_API // ICU is available: we'll use it for Unicode composition
@@ -896,20 +897,20 @@ gfxHarfBuzzShaper::GetHKerning(uint16_t 
                                  (coverage & KERN0_COVERAGE_MINIMUM) != 0);
                 break;
             default:
                 // TODO: implement support for other formats,
                 // if they're ever used in practice
 #if DEBUG
                 {
                     char buf[1024];
-                    sprintf(buf, "unknown kern subtable in %s: "
-                                 "ver 0 format %d\n",
-                            NS_ConvertUTF16toUTF8(mFont->GetName()).get(),
-                            format);
+                    snprintf_literal(buf, "unknown kern subtable in %s: "
+                                          "ver 0 format %d\n",
+                                     NS_ConvertUTF16toUTF8(mFont->GetName()).get(),
+                                     format);
                     NS_WARNING(buf);
                 }
 #endif
                 break;
             }
         }
     } else {
         // It wasn't a "version 0" table; check if it is Apple version 1.0
@@ -958,20 +959,20 @@ gfxHarfBuzzShaper::GetHKerning(uint16_t 
                 default:
                     // TODO: implement support for other formats.
                     // Note that format 1 cannot be supported here,
                     // as it requires the full glyph array to run the FSM,
                     // not just the current glyph pair.
 #if DEBUG
                     {
                         char buf[1024];
-                        sprintf(buf, "unknown kern subtable in %s: "
-                                     "ver 0 format %d\n",
-                                NS_ConvertUTF16toUTF8(mFont->GetName()).get(),
-                                format);
+                        snprintf_literal(buf, "unknown kern subtable in %s: "
+                                              "ver 0 format %d\n",
+                                         NS_ConvertUTF16toUTF8(mFont->GetName()).get(),
+                                         format);
                         NS_WARNING(buf);
                     }
 #endif
                     break;
                 }
             }
         }
     }
--- a/gfx/thebes/gfxTextRun.cpp
+++ b/gfx/thebes/gfxTextRun.cpp
@@ -4,16 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "gfxTextRun.h"
 #include "gfxGlyphExtents.h"
 #include "gfxPlatformFontList.h"
 #include "gfxUserFontSet.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/PathHelpers.h"
+#include "mozilla/Snprintf.h"
 #include "nsGkAtoms.h"
 #include "nsILanguageAtomService.h"
 #include "nsServiceManagerUtils.h"
 
 #include "gfxContext.h"
 #include "gfxFontConstants.h"
 #include "gfxFontMissingGlyphs.h"
 #include "gfxScriptItemizer.h"
@@ -1897,18 +1898,18 @@ gfxFontGroup::GetDefaultFont()
     }
 
     if (!mDefaultFont) {
         // an empty font list at this point is fatal; we're not going to
         // be able to do even the most basic layout operations
         char msg[256]; // CHECK buffer length if revising message below
         nsAutoString families;
         mFamilyList.ToString(families);
-        sprintf(msg, "unable to find a usable font (%.220s)",
-                NS_ConvertUTF16toUTF8(families).get());
+        snprintf_literal(msg, "unable to find a usable font (%.220s)",
+                         NS_ConvertUTF16toUTF8(families).get());
         NS_RUNTIMEABORT(msg);
     }
 
     return mDefaultFont.get();
 }
 
 
 gfxFont*
--- a/intl/locale/nsScriptableDateFormat.cpp
+++ b/intl/locale/nsScriptableDateFormat.cpp
@@ -1,13 +1,14 @@
 /* -*- 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 "mozilla/Snprintf.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);
@@ -108,17 +109,17 @@ NS_IMETHODIMP nsScriptableDateFormat::Fo
   if ((time_t)-1 != timetTime) {
     rv = dateTimeFormat->FormatTime(locale, dateFormatSelector, timeFormatSelector, 
                                      timetTime, mStringOut);
   }
   else {
     // if mktime fails (e.g. year <= 1970), then try NSPR.
     PRTime prtime;
     char string[32];
-    sprintf(string, "%.2d/%.2d/%d %.2d:%.2d:%.2d", month, day, year, hour, minute, second);
+    snprintf_literal(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);
   }
   if (NS_SUCCEEDED(rv))
     *dateTimeString = ToNewUnicode(mStringOut);
--- a/ipc/netd/Netd.cpp
+++ b/ipc/netd/Netd.cpp
@@ -12,16 +12,17 @@
 #include "android/log.h"
 
 #include "nsWhitespaceTokenizer.h"
 #include "nsXULAppAPI.h"
 #include "nsAutoPtr.h"
 #include "nsString.h"
 #include "nsThreadUtils.h"
 #include "mozilla/RefPtr.h"
+#include "mozilla/Snprintf.h"
 
 #define NETD_LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "Gonk", args)
 #define ICS_SYS_USB_RNDIS_MAC "/sys/class/android_usb/android0/f_rndis/ethaddr"
 #define INVALID_SOCKET -1
 #define MAX_RECONNECT_TIMES 10
 
 namespace {
 
@@ -62,19 +63,19 @@ InitRndisAddress()
   memset(address, 0, sizeof(address));
   // First byte is 0x02 to signify a locally administered address.
   address[0] = 0x02;
   length = strlen(serialno);
   for (i = 0; i < length; i++) {
     address[i % (kEthernetAddressLength - 1) + 1] ^= serialno[i];
   }
 
-  sprintf(mac, "%02x:%02x:%02x:%02x:%02x:%02x",
-          address[0], address[1], address[2],
-          address[3], address[4], address[5]);
+  snprintf_literal(mac, "%02x:%02x:%02x:%02x:%02x:%02x",
+                   address[0], address[1], address[2],
+                   address[3], address[4], address[5]);
   length = strlen(mac);
   ret = write(fd.get(), mac, length);
   if (ret != length) {
     NETD_LOG("Fail to write file %s.", ICS_SYS_USB_RNDIS_MAC);
     return false;
   }
   return true;
 }
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -25,16 +25,17 @@
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/EventStateManager.h"
 #include "mozilla/EventStates.h"
 #include "mozilla/IMEStateManager.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/dom/TabChild.h"
 #include "mozilla/Likely.h"
 #include "mozilla/MouseEvents.h"
+#include "mozilla/Snprintf.h"
 #include "mozilla/TextEvents.h"
 #include "mozilla/TouchEvents.h"
 #include "mozilla/UniquePtr.h"
 #include <algorithm>
 
 #ifdef XP_WIN
 #include "winuser.h"
 #endif
@@ -1007,24 +1008,24 @@ LogTextPerfStats(gfxTextPerfMetrics* aTe
   if (!PR_LOG_TEST(tpLog, logLevel)) {
     return;
   }
 
   char prefix[256];
 
   switch (aLogType) {
     case eLog_reflow:
-      sprintf(prefix, "(textperf-reflow) %p time-ms: %7.0f", aPresShell, aTime);
+      snprintf_literal(prefix, "(textperf-reflow) %p time-ms: %7.0f", aPresShell, aTime);
       break;
     case eLog_loaddone:
-      sprintf(prefix, "(textperf-loaddone) %p time-ms: %7.0f", aPresShell, aTime);
+      snprintf_literal(prefix, "(textperf-loaddone) %p time-ms: %7.0f", aPresShell, aTime);
       break;
     default:
       MOZ_ASSERT(aLogType == eLog_totals, "unknown textperf log type");
-      sprintf(prefix, "(textperf-totals) %p", aPresShell);
+      snprintf_literal(prefix, "(textperf-totals) %p", aPresShell);
   }
 
   double hitRatio = 0.0;
   uint32_t lookups = aCounts.wordCacheHit + aCounts.wordCacheMiss;
   if (lookups) {
     hitRatio = double(aCounts.wordCacheHit) / double(lookups);
   }
 
@@ -10369,17 +10370,17 @@ void ReflowCountMgr::Add(const char * aN
     }
     counter->Add();
   }
 
   if ((mDumpFrameByFrameCounts || mPaintFrameByFrameCounts) &&
       nullptr != mIndiFrameCounts &&
       aFrame != nullptr) {
     char key[KEY_BUF_SIZE_FOR_PTR];
-    sprintf(key, "%p", (void*)aFrame);
+    snprintf_literal(key, "%p", (void*)aFrame);
     IndiReflowCounter * counter = (IndiReflowCounter *)PL_HashTableLookup(mIndiFrameCounts, key);
     if (counter == nullptr) {
       counter = new IndiReflowCounter(this);
       counter->mFrame = aFrame;
       counter->mName.AssignASCII(aName);
       PL_HashTableAdd(mIndiFrameCounts, NS_strdup(key), counter);
     }
     // this eliminates extra counts from super classes
@@ -10397,17 +10398,17 @@ void ReflowCountMgr::PaintCount(const ch
                                 nsIFrame*       aFrame,
                                 const nsPoint&  aOffset,
                                 uint32_t        aColor)
 {
   if (mPaintFrameByFrameCounts &&
       nullptr != mIndiFrameCounts &&
       aFrame != nullptr) {
     char key[KEY_BUF_SIZE_FOR_PTR];
-    sprintf(key, "%p", (void*)aFrame);
+    snprintf_literal(key, "%p", (void*)aFrame);
     IndiReflowCounter * counter =
       (IndiReflowCounter *)PL_HashTableLookup(mIndiFrameCounts, key);
     if (counter != nullptr && counter->mName.EqualsASCII(aName)) {
       DrawTarget* drawTarget = aRenderingContext->GetDrawTarget();
       int32_t appUnitsPerDevPixel = aPresContext->AppUnitsPerDevPixel();
 
       aRenderingContext->ThebesContext()->Save();
       gfxPoint devPixelOffset =
@@ -10421,17 +10422,17 @@ void ReflowCountMgr::PaintCount(const ch
                   NS_FONT_WEIGHT_NORMAL, NS_FONT_STRETCH_NORMAL, 0,
                   nsPresContext::CSSPixelsToAppUnits(11));
       nsRefPtr<nsFontMetrics> fm;
       aPresContext->DeviceContext()->GetMetricsFor(font,
         nsGkAtoms::x_western, false, gfxFont::eHorizontal, nullptr,
         aPresContext->GetTextPerfMetrics(), *getter_AddRefs(fm));
 
       char buf[16];
-      int len = sprintf(buf, "%d", counter->mCount);
+      int len = snprintf_literal(buf, "%d", counter->mCount);
       nscoord x = 0, y = fm->MaxAscent();
       nscoord width, height = fm->MaxHeight();
       fm->SetTextRunRTL(false);
       width = fm->GetWidth(buf, len, aRenderingContext);;
 
       uint32_t color;
       uint32_t color2;
       if (aColor != 0) {
@@ -10542,17 +10543,17 @@ static void RecurseIndiTotals(nsPresCont
                               nsIFrame *      aParentFrame,
                               int32_t         aLevel)
 {
   if (aParentFrame == nullptr) {
     return;
   }
 
   char key[KEY_BUF_SIZE_FOR_PTR];
-  sprintf(key, "%p", (void*)aParentFrame);
+  snprintf_literal(key, "%p", (void*)aParentFrame);
   IndiReflowCounter * counter = (IndiReflowCounter *)PL_HashTableLookup(aHT, key);
   if (counter) {
     counter->mHasBeenOutput = true;
     char * name = ToNewCString(counter->mName);
     for (int32_t i=0;i<aLevel;i++) printf(" ");
     printf("%s - %p   [%d][", name, (void*)aParentFrame, counter->mCount);
     printf("%d", counter->mCounter.GetTotal());
     printf("]\n");
--- a/layout/generic/nsAbsoluteContainingBlock.cpp
+++ b/layout/generic/nsAbsoluteContainingBlock.cpp
@@ -13,28 +13,30 @@
 #include "nsContainerFrame.h"
 #include "nsGkAtoms.h"
 #include "nsIPresShell.h"
 #include "nsHTMLReflowState.h"
 #include "nsPresContext.h"
 #include "nsCSSFrameConstructor.h"
 #include "nsGridContainerFrame.h"
 
+#include "mozilla/Snprintf.h"
+
 #ifdef DEBUG
 #include "nsBlockFrame.h"
 
-static void PrettyUC(nscoord aSize, char* aBuf)
+static void PrettyUC(nscoord aSize, char* aBuf, int aBufSize)
 {
   if (NS_UNCONSTRAINEDSIZE == aSize) {
     strcpy(aBuf, "UC");
   } else {
     if((int32_t)0xdeadbeef == aSize) {
       strcpy(aBuf, "deadbeef");
     } else {
-      sprintf(aBuf, "%d", aSize);
+      snprintf(aBuf, aBufSize, "%d", aSize);
     }
   }
 }
 #endif
 
 using namespace mozilla;
 
 void
@@ -365,21 +367,21 @@ nsAbsoluteContainingBlock::ReflowAbsolut
     if (aKidFrame) {
       nsAutoString name;
       aKidFrame->GetFrameName(name);
       printf("%s ", NS_LossyConvertUTF16toASCII(name).get());
     }
 
     char width[16];
     char height[16];
-    PrettyUC(aReflowState.AvailableWidth(), width);
-    PrettyUC(aReflowState.AvailableHeight(), height);
+    PrettyUC(aReflowState.AvailableWidth(), width, 16);
+    PrettyUC(aReflowState.AvailableHeight(), height, 16);
     printf(" a=%s,%s ", width, height);
-    PrettyUC(aReflowState.ComputedWidth(), width);
-    PrettyUC(aReflowState.ComputedHeight(), height);
+    PrettyUC(aReflowState.ComputedWidth(), width, 16);
+    PrettyUC(aReflowState.ComputedHeight(), height, 16);
     printf("c=%s,%s \n", width, height);
   }
   AutoNoisyIndenter indent(nsBlockFrame::gNoisy);
 #endif // DEBUG
 
   WritingMode wm = aKidFrame->GetWritingMode();
   nscoord availISize = LogicalSize(wm, aContainingBlock.Size()).ISize(wm);
   if (availISize == -1) {
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -6,22 +6,23 @@
 
 /* base class of all rendering objects */
 
 #include "nsFrame.h"
 
 #include <stdarg.h>
 #include <algorithm>
 
+#include "gfx2DGlue.h"
 #include "gfxUtils.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/DebugOnly.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/PathHelpers.h"
-#include "gfx2DGlue.h"
+#include "mozilla/Snprintf.h"
 
 #include "nsCOMPtr.h"
 #include "nsFrameList.h"
 #include "nsPlaceholderFrame.h"
 #include "nsIContent.h"
 #include "nsContentUtils.h"
 #include "nsIAtom.h"
 #include "nsString.h"
@@ -9148,17 +9149,18 @@ struct DR_State
   DR_Rule* ParseRule(FILE* aFile);
   void ParseRulesFile();
   void AddRule(nsTArray<DR_Rule*>& aRules,
                DR_Rule&            aRule);
   bool IsWhiteSpace(int c);
   bool GetNumber(char*    aBuf, 
                  int32_t&  aNumber);
   void PrettyUC(nscoord aSize,
-                char*   aBuf);
+                char*   aBuf,
+                int     aBufSize);
   void PrintMargin(const char* tag, const nsMargin* aMargin);
   void DisplayFrameTypeInfo(nsIFrame* aFrame,
                             int32_t   aIndent);
   void DeleteTreeNode(DR_FrameTreeNode& aNode);
 
   bool        mInited;
   bool        mActive;
   int32_t     mCount;
@@ -9641,40 +9643,41 @@ DR_FrameTreeNode* DR_State::CreateTreeNo
   }
   mFrameTreeLeaves.AppendElement(newNode);
   mCount++;
 
   return newNode;
 }
 
 void DR_State::PrettyUC(nscoord aSize,
-                        char*   aBuf)
+                        char*   aBuf,
+                        int     aBufSize)
 {
   if (NS_UNCONSTRAINEDSIZE == aSize) {
     strcpy(aBuf, "UC");
   }
   else {
     if ((nscoord)0xdeadbeefU == aSize)
     {
       strcpy(aBuf, "deadbeef");
     }
     else {
-      sprintf(aBuf, "%d", aSize);
+      snprintf(aBuf, aBufSize, "%d", aSize);
     }
   }
 }
 
 void DR_State::PrintMargin(const char *tag, const nsMargin* aMargin)
 {
   if (aMargin) {
     char t[16], r[16], b[16], l[16];
-    PrettyUC(aMargin->top, t);
-    PrettyUC(aMargin->right, r);
-    PrettyUC(aMargin->bottom, b);
-    PrettyUC(aMargin->left, l);
+    PrettyUC(aMargin->top, t, 16);
+    PrettyUC(aMargin->right, r, 16);
+    PrettyUC(aMargin->bottom, b, 16);
+    PrettyUC(aMargin->left, l, 16);
     printf(" %s=%s,%s,%s,%s", tag, t, r, b, l);
   } else {
     // use %p here for consistency with other null-pointer printouts
     printf(" %s=%p", tag, (void*)aMargin);
   }
 }
 
 void DR_State::DeleteTreeNode(DR_FrameTreeNode& aNode)
@@ -9710,22 +9713,22 @@ static void DisplayReflowEnterPrint(nsPr
                                     bool                     aChanged)
 {
   if (aTreeNode.mDisplay) {
     DR_state->DisplayFrameTypeInfo(aFrame, aTreeNode.mIndent);
 
     char width[16];
     char height[16];
 
-    DR_state->PrettyUC(aReflowState.AvailableWidth(), width);
-    DR_state->PrettyUC(aReflowState.AvailableHeight(), height);
+    DR_state->PrettyUC(aReflowState.AvailableWidth(), width, 16);
+    DR_state->PrettyUC(aReflowState.AvailableHeight(), height, 16);
     printf("Reflow a=%s,%s ", width, height);
 
-    DR_state->PrettyUC(aReflowState.ComputedWidth(), width);
-    DR_state->PrettyUC(aReflowState.ComputedHeight(), height);
+    DR_state->PrettyUC(aReflowState.ComputedWidth(), width, 16);
+    DR_state->PrettyUC(aReflowState.ComputedHeight(), height, 16);
     printf("c=%s,%s ", width, height);
 
     if (aFrame->GetStateBits() & NS_FRAME_IS_DIRTY)
       printf("dirty ");
 
     if (aFrame->GetStateBits() & NS_FRAME_HAS_DIRTY_CHILDREN)
       printf("dirty-children ");
 
@@ -9837,48 +9840,48 @@ void nsFrame::DisplayReflowExit(nsPresCo
   DR_FrameTreeNode* treeNode = (DR_FrameTreeNode*)aFrameTreeNode;
   if (treeNode->mDisplay) {
     DR_state->DisplayFrameTypeInfo(aFrame, treeNode->mIndent);
 
     char width[16];
     char height[16];
     char x[16];
     char y[16];
-    DR_state->PrettyUC(aMetrics.Width(), width);
-    DR_state->PrettyUC(aMetrics.Height(), height);
+    DR_state->PrettyUC(aMetrics.Width(), width, 16);
+    DR_state->PrettyUC(aMetrics.Height(), height, 16);
     printf("Reflow d=%s,%s", width, height);
 
     if (!NS_FRAME_IS_FULLY_COMPLETE(aStatus)) {
       printf(" status=0x%x", aStatus);
     }
     if (aFrame->HasOverflowAreas()) {
-      DR_state->PrettyUC(aMetrics.VisualOverflow().x, x);
-      DR_state->PrettyUC(aMetrics.VisualOverflow().y, y);
-      DR_state->PrettyUC(aMetrics.VisualOverflow().width, width);
-      DR_state->PrettyUC(aMetrics.VisualOverflow().height, height);
+      DR_state->PrettyUC(aMetrics.VisualOverflow().x, x, 16);
+      DR_state->PrettyUC(aMetrics.VisualOverflow().y, y, 16);
+      DR_state->PrettyUC(aMetrics.VisualOverflow().width, width, 16);
+      DR_state->PrettyUC(aMetrics.VisualOverflow().height, height, 16);
       printf(" vis-o=(%s,%s) %s x %s", x, y, width, height);
 
       nsRect storedOverflow = aFrame->GetVisualOverflowRect();
-      DR_state->PrettyUC(storedOverflow.x, x);
-      DR_state->PrettyUC(storedOverflow.y, y);
-      DR_state->PrettyUC(storedOverflow.width, width);
-      DR_state->PrettyUC(storedOverflow.height, height);
+      DR_state->PrettyUC(storedOverflow.x, x, 16);
+      DR_state->PrettyUC(storedOverflow.y, y, 16);
+      DR_state->PrettyUC(storedOverflow.width, width, 16);
+      DR_state->PrettyUC(storedOverflow.height, height, 16);
       printf(" vis-sto=(%s,%s) %s x %s", x, y, width, height);
 
-      DR_state->PrettyUC(aMetrics.ScrollableOverflow().x, x);
-      DR_state->PrettyUC(aMetrics.ScrollableOverflow().y, y);
-      DR_state->PrettyUC(aMetrics.ScrollableOverflow().width, width);
-      DR_state->PrettyUC(aMetrics.ScrollableOverflow().height, height);
+      DR_state->PrettyUC(aMetrics.ScrollableOverflow().x, x, 16);
+      DR_state->PrettyUC(aMetrics.ScrollableOverflow().y, y, 16);
+      DR_state->PrettyUC(aMetrics.ScrollableOverflow().width, width, 16);
+      DR_state->PrettyUC(aMetrics.ScrollableOverflow().height, height, 16);
       printf(" scr-o=(%s,%s) %s x %s", x, y, width, height);
 
       storedOverflow = aFrame->GetScrollableOverflowRect();
-      DR_state->PrettyUC(storedOverflow.x, x);
-      DR_state->PrettyUC(storedOverflow.y, y);
-      DR_state->PrettyUC(storedOverflow.width, width);
-      DR_state->PrettyUC(storedOverflow.height, height);
+      DR_state->PrettyUC(storedOverflow.x, x, 16);
+      DR_state->PrettyUC(storedOverflow.y, y, 16);
+      DR_state->PrettyUC(storedOverflow.width, width, 16);
+      DR_state->PrettyUC(storedOverflow.height, height, 16);
       printf(" scr-sto=(%s,%s) %s x %s", x, y, width, height);
     }
     printf("\n");
     if (DR_state->mDisplayPixelErrors) {
       int32_t p2t = aPresContext->AppUnitsPerDevPixel();
       CheckPixelError(aMetrics.Width(), p2t);
       CheckPixelError(aMetrics.Height(), p2t);
     }
@@ -9912,17 +9915,17 @@ void nsFrame::DisplayIntrinsicISizeExit(
 
   NS_ASSERTION(aFrame, "non-null frame required");
   if (!aFrameTreeNode) return;
 
   DR_FrameTreeNode* treeNode = (DR_FrameTreeNode*)aFrameTreeNode;
   if (treeNode->mDisplay) {
     DR_state->DisplayFrameTypeInfo(aFrame, treeNode->mIndent);
     char width[16];
-    DR_state->PrettyUC(aResult, width);
+    DR_state->PrettyUC(aResult, width, 16);
     printf("Get%sWidth=%s\n", aType, width);
   }
   DR_state->DeleteTreeNode(*treeNode);
 }
 
 void nsFrame::DisplayIntrinsicSizeExit(nsIFrame*            aFrame,
                                        const char*          aType,
                                        nsSize               aResult,
@@ -9934,18 +9937,18 @@ void nsFrame::DisplayIntrinsicSizeExit(n
   if (!aFrameTreeNode) return;
 
   DR_FrameTreeNode* treeNode = (DR_FrameTreeNode*)aFrameTreeNode;
   if (treeNode->mDisplay) {
     DR_state->DisplayFrameTypeInfo(aFrame, treeNode->mIndent);
 
     char width[16];
     char height[16];
-    DR_state->PrettyUC(aResult.width, width);
-    DR_state->PrettyUC(aResult.height, height);
+    DR_state->PrettyUC(aResult.width, width, 16);
+    DR_state->PrettyUC(aResult.height, height, 16);
     printf("Get%sSize=%s,%s\n", aType, width, height);
   }
   DR_state->DeleteTreeNode(*treeNode);
 }
 
 /* static */ void
 nsFrame::DisplayReflowStartup()
 {
@@ -9986,22 +9989,22 @@ nsHTMLReflowState::DisplayInitConstraint
     DR_state->DisplayFrameTypeInfo(aFrame, treeNode->mIndent);
 
     printf("InitConstraints parent=%p",
            (void*)aState->parentReflowState);
 
     char width[16];
     char height[16];
 
-    DR_state->PrettyUC(aContainingBlockWidth, width);
-    DR_state->PrettyUC(aContainingBlockHeight, height);
+    DR_state->PrettyUC(aContainingBlockWidth, width, 16);
+    DR_state->PrettyUC(aContainingBlockHeight, height, 16);
     printf(" cb=%s,%s", width, height);
 
-    DR_state->PrettyUC(aState->AvailableWidth(), width);
-    DR_state->PrettyUC(aState->AvailableHeight(), height);
+    DR_state->PrettyUC(aState->AvailableWidth(), width, 16);
+    DR_state->PrettyUC(aState->AvailableHeight(), height, 16);
     printf(" as=%s,%s", width, height);
 
     DR_state->PrintMargin("b", aBorder);
     DR_state->PrintMargin("p", aPadding);
     putchar('\n');
   }
   return treeNode;
 }
@@ -10016,22 +10019,22 @@ nsHTMLReflowState::DisplayInitConstraint
 
   if (!DR_state->mActive) return;
   if (!aValue) return;
 
   DR_FrameTreeNode* treeNode = (DR_FrameTreeNode*)aValue;
   if (treeNode->mDisplay) {
     DR_state->DisplayFrameTypeInfo(aFrame, treeNode->mIndent);
     char cmiw[16], cw[16], cmxw[16], cmih[16], ch[16], cmxh[16];
-    DR_state->PrettyUC(aState->ComputedMinWidth(), cmiw);
-    DR_state->PrettyUC(aState->ComputedWidth(), cw);
-    DR_state->PrettyUC(aState->ComputedMaxWidth(), cmxw);
-    DR_state->PrettyUC(aState->ComputedMinHeight(), cmih);
-    DR_state->PrettyUC(aState->ComputedHeight(), ch);
-    DR_state->PrettyUC(aState->ComputedMaxHeight(), cmxh);
+    DR_state->PrettyUC(aState->ComputedMinWidth(), cmiw, 16);
+    DR_state->PrettyUC(aState->ComputedWidth(), cw, 16);
+    DR_state->PrettyUC(aState->ComputedMaxWidth(), cmxw, 16);
+    DR_state->PrettyUC(aState->ComputedMinHeight(), cmih, 16);
+    DR_state->PrettyUC(aState->ComputedHeight(), ch, 16);
+    DR_state->PrettyUC(aState->ComputedMaxHeight(), cmxh, 16);
     printf("InitConstraints= cw=(%s <= %s <= %s) ch=(%s <= %s <= %s)",
            cmiw, cw, cmxw, cmih, ch, cmxh);
     DR_state->PrintMargin("co", &aState->ComputedPhysicalOffsets());
     putchar('\n');
   }
   DR_state->DeleteTreeNode(*treeNode);
 }
 
@@ -10052,18 +10055,18 @@ nsCSSOffsetState::DisplayInitOffsetsEnte
 
   // aState is not necessarily a nsHTMLReflowState
   DR_FrameTreeNode* treeNode = DR_state->CreateTreeNode(aFrame, nullptr);
   if (treeNode && treeNode->mDisplay) {
     DR_state->DisplayFrameTypeInfo(aFrame, treeNode->mIndent);
 
     char horizPctBasisStr[16];
     char vertPctBasisStr[16];
-    DR_state->PrettyUC(aHorizontalPercentBasis, horizPctBasisStr);
-    DR_state->PrettyUC(aVerticalPercentBasis,   vertPctBasisStr);
+    DR_state->PrettyUC(aHorizontalPercentBasis, horizPctBasisStr, 16);
+    DR_state->PrettyUC(aVerticalPercentBasis,   vertPctBasisStr, 16);
     printf("InitOffsets pct_basis=%s,%s", horizPctBasisStr, vertPctBasisStr);
 
     DR_state->PrintMargin("b", aBorder);
     DR_state->PrintMargin("p", aPadding);
     putchar('\n');
   }
   return treeNode;
 }
--- a/layout/style/FontFaceSet.cpp
+++ b/layout/style/FontFaceSet.cpp
@@ -11,16 +11,17 @@
 #include "mozilla/css/Loader.h"
 #include "mozilla/dom/CSSFontFaceLoadEvent.h"
 #include "mozilla/dom/CSSFontFaceLoadEventBinding.h"
 #include "mozilla/dom/FontFaceSetBinding.h"
 #include "mozilla/dom/FontFaceSetIterator.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/AsyncEventDispatcher.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/Snprintf.h"
 #include "nsCORSListenerProxy.h"
 #include "nsFontFaceLoader.h"
 #include "nsIConsoleService.h"
 #include "nsIContentPolicy.h"
 #include "nsIContentSecurityPolicy.h"
 #include "nsIDocShell.h"
 #include "nsIDocument.h"
 #include "nsINetworkPredictor.h"
@@ -1076,17 +1077,17 @@ FontFaceSet::LogMessage(gfxUserFontEntry
   char weightKeywordBuf[8]; // plenty to sprintf() a uint16_t
   const char* weightKeyword;
   const nsAFlatCString& weightKeywordString =
     nsCSSProps::ValueToKeyword(aUserFontEntry->Weight(),
                                nsCSSProps::kFontWeightKTable);
   if (weightKeywordString.Length() > 0) {
     weightKeyword = weightKeywordString.get();
   } else {
-    sprintf(weightKeywordBuf, "%u", aUserFontEntry->Weight());
+    snprintf_literal(weightKeywordBuf, "%u", aUserFontEntry->Weight());
     weightKeyword = weightKeywordBuf;
   }
 
   nsPrintfCString message
        ("downloadable font: %s "
         "(font-family: \"%s\" style:%s weight:%s stretch:%s src index:%d)",
         aMessage,
         familyName.get(),
--- a/media/gmp-clearkey/0.1/openaes/oaes_lib.c
+++ b/media/gmp-clearkey/0.1/openaes/oaes_lib.c
@@ -28,16 +28,18 @@
  * ---------------------------------------------------------------------------
  */
 
 #include <stdlib.h>
 #include <stddef.h>
 #include <time.h> 
 #include <string.h>
 
+#include "mozilla/Snprintf.h"
+
 #ifdef WIN32
 #include <process.h>
 #endif
 
 #include "oaes_config.h"
 #include "oaes_lib.h"
 
 #ifdef OAES_HAVE_ISAAC
@@ -448,17 +450,17 @@ OAES_RET oaes_sprintf(
 
 	if( NULL == data )
 		return OAES_RET_ARG3;
 
 	strcpy( buf, "" );
 	
 	for( _i = 0; _i < data_len; _i++ )
 	{
-		sprintf( _temp, "%02x ", data[_i] );
+		snprintf( _temp, sizeof(_temp), "%02x ", data[_i] );
 		strcat( buf, _temp );
 		if( _i && 0 == ( _i + 1 ) % OAES_BLOCK_SIZE )
 			strcat( buf, "\n" );
 	}
 	
 	return OAES_RET_SUCCESS;
 }
 
--- a/mfbt/JSONWriter.h
+++ b/mfbt/JSONWriter.h
@@ -90,16 +90,17 @@
 // readability.
 
 #ifndef mozilla_JSONWriter_h
 #define mozilla_JSONWriter_h
 
 #include "mozilla/double-conversion.h"
 #include "mozilla/IntegerPrintfMacros.h"
 #include "mozilla/PodOperations.h"
+#include "mozilla/Snprintf.h"
 #include "mozilla/UniquePtr.h"
 #include "mozilla/Vector.h"
 
 #include <stdio.h>
 
 namespace mozilla {
 
 // A quasi-functor for JSONWriter. We don't use a true functor because that
@@ -383,17 +384,17 @@ public:
 
   // Prints: <aBool>
   void BoolElement(bool aBool) { BoolProperty(nullptr, aBool); }
 
   // Prints: "<aName>": <aInt>
   void IntProperty(const char* aName, int64_t aInt)
   {
     char buf[64];
-    sprintf(buf, "%" PRId64, aInt);
+    snprintf_literal(buf, "%" PRId64, aInt);
     Scalar(aName, buf);
   }
 
   // Prints: <aInt>
   void IntElement(int64_t aInt) { IntProperty(nullptr, aInt); }
 
   // Prints: "<aName>": <aDouble>
   void DoubleProperty(const char* aName, double aDouble)
new file mode 100644
--- /dev/null
+++ b/mfbt/Snprintf.h
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* Polyfills snprintf() on platforms that don't provide it, and provides
+ * related utilities. */
+
+#ifndef mozilla_Snprintf_h_
+#define mozilla_Snprintf_h_
+
+#include <stddef.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+// Older MSVC versions do not provide snprintf(), but they do provide
+// vsnprintf(), which has the same semantics except that if the number of
+// characters written equals the buffer size, it does not write a null
+// terminator, so we wrap it to do so.
+#if defined(_MSC_VER) && _MSC_VER < 1900
+#include "mozilla/Attributes.h"
+MOZ_ALWAYS_INLINE int snprintf(char* buffer, size_t n, const char* format, ...)
+{
+  va_list args;
+  va_start(args, format);
+  int result = vsnprintf(buffer, n, format, args);
+  va_end(args);
+  buffer[n - 1] = '\0';
+  return result;
+}
+#endif
+
+// In addition, in C++ code, on all platforms, provide an snprintf_literal()
+// function which uses template argument deduction to deduce the size of the
+// buffer, avoiding the need for the user to pass it in explicitly.
+#ifdef __cplusplus
+template <size_t N>
+int snprintf_literal(char (&buffer)[N], const char* format, ...)
+{
+  va_list args;
+  va_start(args, format);
+  int result = vsnprintf(buffer, N, format, args);
+  va_end(args);
+  buffer[N - 1] = '\0';
+  return result;
+}
+#endif
+
+#endif  /* mozilla_Snprintf_h_ */
--- a/mfbt/moz.build
+++ b/mfbt/moz.build
@@ -65,16 +65,17 @@ EXPORTS.mozilla = [
     'ReentrancyGuard.h',
     'RefPtr.h',
     'ReverseIterator.h',
     'RollingMean.h',
     'Scoped.h',
     'SegmentedVector.h',
     'SHA1.h',
     'SizePrintfMacros.h',
+    'Snprintf.h',
     'SplayTree.h',
     'TaggedAnonymousMemory.h',
     'TemplateLib.h',
     'ThreadLocal.h',
     'ToString.h',
     'Tuple.h',
     'TypedEnumBits.h',
     'Types.h',
--- a/mfbt/tests/TestIntegerPrintfMacros.cpp
+++ b/mfbt/tests/TestIntegerPrintfMacros.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/Assertions.h"
 #include "mozilla/IntegerPrintfMacros.h" // this must pick up <stdint.h>
+#include "mozilla/Snprintf.h"
 
 #include <stddef.h>
 #include <stdio.h>
 #include <string.h>
 
 /* Output array and poisoning method shared by all tests. */
 static char gOutput[32];
 
@@ -28,204 +29,204 @@ PoisonOutput()
  *
  * In these names N is the width of the type as described in C99 7.18.1.
  */
 
 static void
 TestPrintSigned8()
 {
   PoisonOutput();
-  sprintf(gOutput, "%" PRId8, int8_t(-17));
+  snprintf_literal(gOutput, "%" PRId8, int8_t(-17));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "-17"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIi8, int8_t(42));
+  snprintf_literal(gOutput, "%" PRIi8, int8_t(42));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "42"));
 }
 
 static void
 TestPrintSigned16()
 {
   PoisonOutput();
-  sprintf(gOutput, "%" PRId16, int16_t(-289));
+  snprintf_literal(gOutput, "%" PRId16, int16_t(-289));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "-289"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIi16, int16_t(728));
+  snprintf_literal(gOutput, "%" PRIi16, int16_t(728));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "728"));
 }
 
 static void
 TestPrintSigned32()
 {
   PoisonOutput();
-  sprintf(gOutput, "%" PRId32, int32_t(-342178));
+  snprintf_literal(gOutput, "%" PRId32, int32_t(-342178));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "-342178"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIi32, int32_t(5719283));
+  snprintf_literal(gOutput, "%" PRIi32, int32_t(5719283));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "5719283"));
 }
 
 static void
 TestPrintSigned64()
 {
   PoisonOutput();
-  sprintf(gOutput, "%" PRId64, int64_t(-INT64_C(432157943248732)));
+  snprintf_literal(gOutput, "%" PRId64, int64_t(-INT64_C(432157943248732)));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "-432157943248732"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIi64, int64_t(INT64_C(325719232983)));
+  snprintf_literal(gOutput, "%" PRIi64, int64_t(INT64_C(325719232983)));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "325719232983"));
 }
 
 static void
 TestPrintSignedN()
 {
   TestPrintSigned8();
   TestPrintSigned16();
   TestPrintSigned32();
   TestPrintSigned64();
 }
 
 static void
 TestPrintSignedLeast8()
 {
   PoisonOutput();
-  sprintf(gOutput, "%" PRIdLEAST8, int_least8_t(-17));
+  snprintf_literal(gOutput, "%" PRIdLEAST8, int_least8_t(-17));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "-17"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIiLEAST8, int_least8_t(42));
+  snprintf_literal(gOutput, "%" PRIiLEAST8, int_least8_t(42));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "42"));
 }
 
 static void
 TestPrintSignedLeast16()
 {
   PoisonOutput();
-  sprintf(gOutput, "%" PRIdLEAST16, int_least16_t(-289));
+  snprintf_literal(gOutput, "%" PRIdLEAST16, int_least16_t(-289));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "-289"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIiLEAST16, int_least16_t(728));
+  snprintf_literal(gOutput, "%" PRIiLEAST16, int_least16_t(728));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "728"));
 }
 
 static void
 TestPrintSignedLeast32()
 {
   PoisonOutput();
-  sprintf(gOutput, "%" PRIdLEAST32, int_least32_t(-342178));
+  snprintf_literal(gOutput, "%" PRIdLEAST32, int_least32_t(-342178));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "-342178"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIiLEAST32, int_least32_t(5719283));
+  snprintf_literal(gOutput, "%" PRIiLEAST32, int_least32_t(5719283));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "5719283"));
 }
 
 static void
 TestPrintSignedLeast64()
 {
   PoisonOutput();
-  sprintf(gOutput, "%" PRIdLEAST64, int_least64_t(-INT64_C(432157943248732)));
+  snprintf_literal(gOutput, "%" PRIdLEAST64, int_least64_t(-INT64_C(432157943248732)));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "-432157943248732"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIiLEAST64, int_least64_t(INT64_C(325719232983)));
+  snprintf_literal(gOutput, "%" PRIiLEAST64, int_least64_t(INT64_C(325719232983)));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "325719232983"));
 }
 
 static void
 TestPrintSignedLeastN()
 {
   TestPrintSignedLeast8();
   TestPrintSignedLeast16();
   TestPrintSignedLeast32();
   TestPrintSignedLeast64();
 }
 
 static void
 TestPrintSignedFast8()
 {
   PoisonOutput();
-  sprintf(gOutput, "%" PRIdFAST8, int_fast8_t(-17));
+  snprintf_literal(gOutput, "%" PRIdFAST8, int_fast8_t(-17));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "-17"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIiFAST8, int_fast8_t(42));
+  snprintf_literal(gOutput, "%" PRIiFAST8, int_fast8_t(42));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "42"));
 }
 
 static void
 TestPrintSignedFast16()
 {
   PoisonOutput();
-  sprintf(gOutput, "%" PRIdFAST16, int_fast16_t(-289));
+  snprintf_literal(gOutput, "%" PRIdFAST16, int_fast16_t(-289));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "-289"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIiFAST16, int_fast16_t(728));
+  snprintf_literal(gOutput, "%" PRIiFAST16, int_fast16_t(728));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "728"));
 }
 
 static void
 TestPrintSignedFast32()
 {
   PoisonOutput();
-  sprintf(gOutput, "%" PRIdFAST32, int_fast32_t(-342178));
+  snprintf_literal(gOutput, "%" PRIdFAST32, int_fast32_t(-342178));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "-342178"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIiFAST32, int_fast32_t(5719283));
+  snprintf_literal(gOutput, "%" PRIiFAST32, int_fast32_t(5719283));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "5719283"));
 }
 
 static void
 TestPrintSignedFast64()
 {
   PoisonOutput();
-  sprintf(gOutput, "%" PRIdFAST64, int_fast64_t(-INT64_C(432157943248732)));
+  snprintf_literal(gOutput, "%" PRIdFAST64, int_fast64_t(-INT64_C(432157943248732)));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "-432157943248732"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIiFAST64, int_fast64_t(INT64_C(325719232983)));
+  snprintf_literal(gOutput, "%" PRIiFAST64, int_fast64_t(INT64_C(325719232983)));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "325719232983"));
 }
 
 static void
 TestPrintSignedFastN()
 {
   TestPrintSignedFast8();
   TestPrintSignedFast16();
   TestPrintSignedFast32();
   TestPrintSignedFast64();
 }
 
 static void
 TestPrintSignedMax()
 {
   PoisonOutput();
-  sprintf(gOutput, "%" PRIdMAX, intmax_t(-INTMAX_C(432157943248732)));
+  snprintf_literal(gOutput, "%" PRIdMAX, intmax_t(-INTMAX_C(432157943248732)));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "-432157943248732"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIiMAX, intmax_t(INTMAX_C(325719232983)));
+  snprintf_literal(gOutput, "%" PRIiMAX, intmax_t(INTMAX_C(325719232983)));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "325719232983"));
 }
 
 static void
 TestPrintSignedPtr()
 {
   PoisonOutput();
-  sprintf(gOutput, "%" PRIdPTR, intptr_t(reinterpret_cast<void*>(12345678)));
+  snprintf_literal(gOutput, "%" PRIdPTR, intptr_t(reinterpret_cast<void*>(12345678)));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "12345678"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIiPTR, intptr_t(reinterpret_cast<void*>(87654321)));
+  snprintf_literal(gOutput, "%" PRIiPTR, intptr_t(reinterpret_cast<void*>(87654321)));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "87654321"));
 }
 
 static void
 TestPrintSigned()
 {
   TestPrintSignedN();
   TestPrintSignedLeastN();
@@ -244,318 +245,318 @@ TestPrintSigned()
  *
  * In these names N is the width of the type as described in C99 7.18.1.
  */
 
 static void
 TestPrintUnsigned8()
 {
   PoisonOutput();
-  sprintf(gOutput, "%" PRIo8, uint8_t(042));
+  snprintf_literal(gOutput, "%" PRIo8, uint8_t(042));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "42"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIu8, uint8_t(17));
+  snprintf_literal(gOutput, "%" PRIu8, uint8_t(17));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "17"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIx8, uint8_t(0x2a));
+  snprintf_literal(gOutput, "%" PRIx8, uint8_t(0x2a));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "2a"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIX8, uint8_t(0xCD));
+  snprintf_literal(gOutput, "%" PRIX8, uint8_t(0xCD));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "CD"));
 }
 
 static void
 TestPrintUnsigned16()
 {
   PoisonOutput();
-  sprintf(gOutput, "%" PRIo16, uint16_t(04242));
+  snprintf_literal(gOutput, "%" PRIo16, uint16_t(04242));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "4242"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIu16, uint16_t(1717));
+  snprintf_literal(gOutput, "%" PRIu16, uint16_t(1717));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "1717"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIx16, uint16_t(0x2a2a));
+  snprintf_literal(gOutput, "%" PRIx16, uint16_t(0x2a2a));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "2a2a"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIX16, uint16_t(0xCDCD));
+  snprintf_literal(gOutput, "%" PRIX16, uint16_t(0xCDCD));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "CDCD"));
 }
 
 static void
 TestPrintUnsigned32()
 {
   PoisonOutput();
-  sprintf(gOutput, "%" PRIo32, uint32_t(0424242));
+  snprintf_literal(gOutput, "%" PRIo32, uint32_t(0424242));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "424242"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIu32, uint32_t(171717));
+  snprintf_literal(gOutput, "%" PRIu32, uint32_t(171717));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "171717"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIx32, uint32_t(0x2a2a2a));
+  snprintf_literal(gOutput, "%" PRIx32, uint32_t(0x2a2a2a));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "2a2a2a"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIX32, uint32_t(0xCDCDCD));
+  snprintf_literal(gOutput, "%" PRIX32, uint32_t(0xCDCDCD));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "CDCDCD"));
 }
 
 static void
 TestPrintUnsigned64()
 {
   PoisonOutput();
-  sprintf(gOutput, "%" PRIo64, uint64_t(UINT64_C(0424242424242)));
+  snprintf_literal(gOutput, "%" PRIo64, uint64_t(UINT64_C(0424242424242)));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "424242424242"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIu64, uint64_t(UINT64_C(17171717171717171717)));
+  snprintf_literal(gOutput, "%" PRIu64, uint64_t(UINT64_C(17171717171717171717)));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "17171717171717171717"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIx64, uint64_t(UINT64_C(0x2a2a2a2a2a2a2a)));
+  snprintf_literal(gOutput, "%" PRIx64, uint64_t(UINT64_C(0x2a2a2a2a2a2a2a)));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "2a2a2a2a2a2a2a"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIX64, uint64_t(UINT64_C(0xCDCDCDCDCDCD)));
+  snprintf_literal(gOutput, "%" PRIX64, uint64_t(UINT64_C(0xCDCDCDCDCDCD)));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "CDCDCDCDCDCD"));
 }
 
 static void
 TestPrintUnsignedN()
 {
   TestPrintUnsigned8();
   TestPrintUnsigned16();
   TestPrintUnsigned32();
   TestPrintUnsigned64();
 }
 
 static void
 TestPrintUnsignedLeast8()
 {
   PoisonOutput();
-  sprintf(gOutput, "%" PRIoLEAST8, uint_least8_t(042));
+  snprintf_literal(gOutput, "%" PRIoLEAST8, uint_least8_t(042));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "42"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIuLEAST8, uint_least8_t(17));
+  snprintf_literal(gOutput, "%" PRIuLEAST8, uint_least8_t(17));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "17"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIxLEAST8, uint_least8_t(0x2a));
+  snprintf_literal(gOutput, "%" PRIxLEAST8, uint_least8_t(0x2a));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "2a"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIXLEAST8, uint_least8_t(0xCD));
+  snprintf_literal(gOutput, "%" PRIXLEAST8, uint_least8_t(0xCD));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "CD"));
 }
 
 static void
 TestPrintUnsignedLeast16()
 {
   PoisonOutput();
-  sprintf(gOutput, "%" PRIoLEAST16, uint_least16_t(04242));
+  snprintf_literal(gOutput, "%" PRIoLEAST16, uint_least16_t(04242));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "4242"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIuLEAST16, uint_least16_t(1717));
+  snprintf_literal(gOutput, "%" PRIuLEAST16, uint_least16_t(1717));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "1717"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIxLEAST16, uint_least16_t(0x2a2a));
+  snprintf_literal(gOutput, "%" PRIxLEAST16, uint_least16_t(0x2a2a));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "2a2a"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIXLEAST16, uint_least16_t(0xCDCD));
+  snprintf_literal(gOutput, "%" PRIXLEAST16, uint_least16_t(0xCDCD));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "CDCD"));
 }
 
 static void
 TestPrintUnsignedLeast32()
 {
   PoisonOutput();
-  sprintf(gOutput, "%" PRIoLEAST32, uint_least32_t(0424242));
+  snprintf_literal(gOutput, "%" PRIoLEAST32, uint_least32_t(0424242));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "424242"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIuLEAST32, uint_least32_t(171717));
+  snprintf_literal(gOutput, "%" PRIuLEAST32, uint_least32_t(171717));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "171717"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIxLEAST32, uint_least32_t(0x2a2a2a));
+  snprintf_literal(gOutput, "%" PRIxLEAST32, uint_least32_t(0x2a2a2a));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "2a2a2a"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIXLEAST32, uint_least32_t(0xCDCDCD));
+  snprintf_literal(gOutput, "%" PRIXLEAST32, uint_least32_t(0xCDCDCD));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "CDCDCD"));
 }
 
 static void
 TestPrintUnsignedLeast64()
 {
   PoisonOutput();
-  sprintf(gOutput, "%" PRIoLEAST64, uint_least64_t(UINT64_C(0424242424242)));
+  snprintf_literal(gOutput, "%" PRIoLEAST64, uint_least64_t(UINT64_C(0424242424242)));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "424242424242"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIuLEAST64,
+  snprintf_literal(gOutput, "%" PRIuLEAST64,
           uint_least64_t(UINT64_C(17171717171717171717)));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "17171717171717171717"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIxLEAST64, uint_least64_t(UINT64_C(0x2a2a2a2a2a2a2a)));
+  snprintf_literal(gOutput, "%" PRIxLEAST64, uint_least64_t(UINT64_C(0x2a2a2a2a2a2a2a)));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "2a2a2a2a2a2a2a"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIXLEAST64, uint_least64_t(UINT64_C(0xCDCDCDCDCDCD)));
+  snprintf_literal(gOutput, "%" PRIXLEAST64, uint_least64_t(UINT64_C(0xCDCDCDCDCDCD)));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "CDCDCDCDCDCD"));
 }
 
 static void
 TestPrintUnsignedLeastN()
 {
   TestPrintUnsignedLeast8();
   TestPrintUnsignedLeast16();
   TestPrintUnsignedLeast32();
   TestPrintUnsignedLeast64();
 }
 
 static void
 TestPrintUnsignedFast8()
 {
   PoisonOutput();
-  sprintf(gOutput, "%" PRIoFAST8, uint_fast8_t(042));
+  snprintf_literal(gOutput, "%" PRIoFAST8, uint_fast8_t(042));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "42"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIuFAST8, uint_fast8_t(17));
+  snprintf_literal(gOutput, "%" PRIuFAST8, uint_fast8_t(17));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "17"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIxFAST8, uint_fast8_t(0x2a));
+  snprintf_literal(gOutput, "%" PRIxFAST8, uint_fast8_t(0x2a));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "2a"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIXFAST8, uint_fast8_t(0xCD));
+  snprintf_literal(gOutput, "%" PRIXFAST8, uint_fast8_t(0xCD));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "CD"));
 }
 
 static void
 TestPrintUnsignedFast16()
 {
   PoisonOutput();
-  sprintf(gOutput, "%" PRIoFAST16, uint_fast16_t(04242));
+  snprintf_literal(gOutput, "%" PRIoFAST16, uint_fast16_t(04242));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "4242"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIuFAST16, uint_fast16_t(1717));
+  snprintf_literal(gOutput, "%" PRIuFAST16, uint_fast16_t(1717));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "1717"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIxFAST16, uint_fast16_t(0x2a2a));
+  snprintf_literal(gOutput, "%" PRIxFAST16, uint_fast16_t(0x2a2a));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "2a2a"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIXFAST16, uint_fast16_t(0xCDCD));
+  snprintf_literal(gOutput, "%" PRIXFAST16, uint_fast16_t(0xCDCD));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "CDCD"));
 }
 
 static void
 TestPrintUnsignedFast32()
 {
   PoisonOutput();
-  sprintf(gOutput, "%" PRIoFAST32, uint_fast32_t(0424242));
+  snprintf_literal(gOutput, "%" PRIoFAST32, uint_fast32_t(0424242));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "424242"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIuFAST32, uint_fast32_t(171717));
+  snprintf_literal(gOutput, "%" PRIuFAST32, uint_fast32_t(171717));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "171717"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIxFAST32, uint_fast32_t(0x2a2a2a));
+  snprintf_literal(gOutput, "%" PRIxFAST32, uint_fast32_t(0x2a2a2a));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "2a2a2a"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIXFAST32, uint_fast32_t(0xCDCDCD));
+  snprintf_literal(gOutput, "%" PRIXFAST32, uint_fast32_t(0xCDCDCD));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "CDCDCD"));
 }
 
 static void
 TestPrintUnsignedFast64()
 {
   PoisonOutput();
-  sprintf(gOutput, "%" PRIoFAST64, uint_fast64_t(UINT64_C(0424242424242)));
+  snprintf_literal(gOutput, "%" PRIoFAST64, uint_fast64_t(UINT64_C(0424242424242)));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "424242424242"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIuFAST64,
+  snprintf_literal(gOutput, "%" PRIuFAST64,
           uint_fast64_t(UINT64_C(17171717171717171717)));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "17171717171717171717"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIxFAST64, uint_fast64_t(UINT64_C(0x2a2a2a2a2a2a2a)));
+  snprintf_literal(gOutput, "%" PRIxFAST64, uint_fast64_t(UINT64_C(0x2a2a2a2a2a2a2a)));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "2a2a2a2a2a2a2a"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIXFAST64, uint_fast64_t(UINT64_C(0xCDCDCDCDCDCD)));
+  snprintf_literal(gOutput, "%" PRIXFAST64, uint_fast64_t(UINT64_C(0xCDCDCDCDCDCD)));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "CDCDCDCDCDCD"));
 }
 
 static void
 TestPrintUnsignedFastN()
 {
   TestPrintUnsignedFast8();
   TestPrintUnsignedFast16();
   TestPrintUnsignedFast32();
   TestPrintUnsignedFast64();
 }
 
 static void
 TestPrintUnsignedMax()
 {
   PoisonOutput();
-  sprintf(gOutput, "%" PRIoMAX, uintmax_t(UINTMAX_C(432157943248732)));
+  snprintf_literal(gOutput, "%" PRIoMAX, uintmax_t(UINTMAX_C(432157943248732)));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "14220563454333534"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIuMAX, uintmax_t(UINTMAX_C(325719232983)));
+  snprintf_literal(gOutput, "%" PRIuMAX, uintmax_t(UINTMAX_C(325719232983)));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "325719232983"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIxMAX, uintmax_t(UINTMAX_C(327281321873)));
+  snprintf_literal(gOutput, "%" PRIxMAX, uintmax_t(UINTMAX_C(327281321873)));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "4c337ca791"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIXMAX, uintmax_t(UINTMAX_C(912389523743523)));
+  snprintf_literal(gOutput, "%" PRIXMAX, uintmax_t(UINTMAX_C(912389523743523)));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "33DD03D75A323"));
 }
 
 static void
 TestPrintUnsignedPtr()
 {
   PoisonOutput();
-  sprintf(gOutput, "%" PRIoPTR, uintptr_t(reinterpret_cast<void*>(12345678)));
+  snprintf_literal(gOutput, "%" PRIoPTR, uintptr_t(reinterpret_cast<void*>(12345678)));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "57060516"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIuPTR, uintptr_t(reinterpret_cast<void*>(87654321)));
+  snprintf_literal(gOutput, "%" PRIuPTR, uintptr_t(reinterpret_cast<void*>(87654321)));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "87654321"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIxPTR, uintptr_t(reinterpret_cast<void*>(0x4c3a791)));
+  snprintf_literal(gOutput, "%" PRIxPTR, uintptr_t(reinterpret_cast<void*>(0x4c3a791)));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "4c3a791"));
 
   PoisonOutput();
-  sprintf(gOutput, "%" PRIXPTR, uintptr_t(reinterpret_cast<void*>(0xF328DB)));
+  snprintf_literal(gOutput, "%" PRIXPTR, uintptr_t(reinterpret_cast<void*>(0xF328DB)));
   MOZ_RELEASE_ASSERT(!strcmp(gOutput, "F328DB"));
 }
 
 static void
 TestPrintUnsigned()
 {
   TestPrintUnsignedN();
   TestPrintUnsignedLeastN();
--- a/netwerk/cache/nsDiskCacheMap.cpp
+++ b/netwerk/cache/nsDiskCacheMap.cpp
@@ -13,16 +13,17 @@
 
 #include <string.h>
 #include "nsPrintfCString.h"
 
 #include "nsISerializable.h"
 #include "nsSerializationHelper.h"
 
 #include "mozilla/MemoryReporting.h"
+#include "mozilla/Snprintf.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/VisualEventTracer.h"
 #include <algorithm>
 
 using namespace mozilla;
 
 /******************************************************************************
  *  nsDiskCacheMap
@@ -1135,18 +1136,18 @@ nsDiskCacheMap::GetFileForDiskCacheRecor
     if (createPath && (NS_FAILED(file->Exists(&exists)) || !exists)) {
         rv = file->Create(nsIFile::DIRECTORY_TYPE, 0700);
         if (NS_FAILED(rv))  return rv;
     }
 
     int16_t generation = record->Generation();
     char name[32];
     // Cut the beginning of the hash that was used in the path
-    ::sprintf(name, "%05X%c%02X", hash & 0xFFFFF, (meta ? 'm' : 'd'),
-              generation);
+    ::snprintf_literal(name, "%05X%c%02X", hash & 0xFFFFF, (meta ? 'm' : 'd'),
+               generation);
     rv = file->AppendNative(nsDependentCString(name));
     if (NS_FAILED(rv))  return rv;
     
     NS_IF_ADDREF(*result = file);
     return rv;
 }
 
 
@@ -1173,17 +1174,17 @@ nsDiskCacheMap::GetBlockFileForIndex(uin
 {
     if (!mCacheDirectory)  return NS_ERROR_NOT_AVAILABLE;
     
     nsCOMPtr<nsIFile> file;
     nsresult rv = mCacheDirectory->Clone(getter_AddRefs(file));
     if (NS_FAILED(rv))  return rv;
     
     char name[32];
-    ::sprintf(name, "_CACHE_%03d_", index + 1);
+    ::snprintf_literal(name, "_CACHE_%03d_", index + 1);
     rv = file->AppendNative(nsDependentCString(name));
     if (NS_FAILED(rv))  return rv;
     
     NS_IF_ADDREF(*result = file);
 
     return rv;
 }
 
--- a/netwerk/protocol/rtsp/rtsp/ASessionDescription.cpp
+++ b/netwerk/protocol/rtsp/rtsp/ASessionDescription.cpp
@@ -14,16 +14,18 @@
  * limitations under the License.
  */
 
 #define LOG_TAG "ASessionDescription"
 #include "RtspPrlog.h"
 
 #include "ASessionDescription.h"
 
+#include "mozilla/Snprintf.h"
+
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AString.h>
 
 #include <stdlib.h>
 
 namespace android {
 
 ASessionDescription::ASessionDescription()
@@ -209,41 +211,41 @@ bool ASessionDescription::getFormatType(
     unsigned long x = strtoul(lastSpacePos + 1, &end, 10);
     if (end <= lastSpacePos + 1 || *end != '\0') {
         return false;
     }
 
     *PT = x;
 
     char key[20];
-    sprintf(key, "a=rtpmap:%lu", x);
+    snprintf_literal(key, "a=rtpmap:%lu", x);
 
     if (!findAttribute(index, key, desc)) {
         // We only support dynamic payload type assignment for now.
         // If SDP description doesn't have the "a=rtpmap:" line, it is static
         // payload type assignment and we refuse to handle it.
         return false;
     }
 
-    sprintf(key, "a=fmtp:%lu", x);
+    snprintf_literal(key, "a=fmtp:%lu", x);
     if (!findAttribute(index, key, params)) {
         params->clear();
     }
 
     return true;
 }
 
 bool ASessionDescription::getDimensions(
         size_t index, unsigned long PT,
         int32_t *width, int32_t *height) const {
     *width = 0;
     *height = 0;
 
     char key[20];
-    sprintf(key, "a=framesize:%lu", PT);
+    snprintf_literal(key, "a=framesize:%lu", PT);
     AString value;
     if (!findAttribute(index, key, &value)) {
         return false;
     }
 
     const char *s = value.c_str();
     char *end;
     *width = strtoul(s, &end, 10);
--- a/netwerk/test/PropertiesTest.cpp
+++ b/netwerk/test/PropertiesTest.cpp
@@ -1,14 +1,15 @@
 /* -*- 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 "TestCommon.h"
+#include "mozilla/Snprintf.h"
 #include "nsXPCOM.h"
 #include "nsStringAPI.h"
 #include "nsIPersistentProperties2.h"
 #include "nsIServiceManager.h"
 #include "nsIComponentRegistrar.h"
 #include "nsIURL.h"
 #include "nsNetCID.h"
 #include "nsIChannel.h"
@@ -71,17 +72,17 @@ main(int argc, char* argv[])
   if (NS_FAILED(ret)) {
     printf("cannot load properties\n");
     return 1;
   }
   int i = 1;
   while (1) {
     char name[16];
     name[0] = 0;
-    sprintf(name, "%d", i);
+    snprintf_literal(name, "%d", i);
     nsAutoString v;
     ret = props->GetStringProperty(nsDependentCString(name), v);
     if (NS_FAILED(ret) || (!v.Length())) {
       break;
     }
     printf("\"%d\"=\"%s\"\n", i, NS_ConvertUTF16toUTF8(v).get());
     i++;
   }
--- a/toolkit/crashreporter/nsExceptionHandler.cpp
+++ b/toolkit/crashreporter/nsExceptionHandler.cpp
@@ -5,16 +5,17 @@
 
 #include "nsExceptionHandler.h"
 #include "nsDataHashtable.h"
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/dom/CrashReporterChild.h"
 #include "mozilla/Services.h"
 #include "nsIObserverService.h"
 #include "mozilla/unused.h"
+#include "mozilla/Snprintf.h"
 #include "mozilla/SyncRunnable.h"
 
 #include "nsThreadUtils.h"
 #include "nsXULAppAPI.h"
 #include "jsfriendapi.h"
 
 #if defined(XP_WIN32)
 #ifdef WIN32_LEAN_AND_MEAN
@@ -1432,17 +1433,17 @@ GetOrInit(nsIFile* aDir, const nsACStrin
 
 // Init the "install time" data.  We're taking an easy way out here
 // and just setting this to "the time when this version was first run".
 static nsresult
 InitInstallTime(nsACString& aInstallTime)
 {
   time_t t = time(nullptr);
   char buf[16];
-  sprintf(buf, "%ld", t);
+  snprintf_literal(buf, "%ld", t);
   aInstallTime = buf;
 
   return NS_OK;
 }
 
 // Ensure a directory exists and create it if missing.
 static nsresult
 EnsureDirectoryExists(nsIFile* dir)
--- a/toolkit/profile/nsToolkitProfileService.cpp
+++ b/toolkit/profile/nsToolkitProfileService.cpp
@@ -35,16 +35,17 @@
 
 #include "nsINIParser.h"
 #include "nsXREDirProvider.h"
 #include "nsAppRunner.h"
 #include "nsString.h"
 #include "nsReadableUtils.h"
 #include "nsNativeCharsetUtils.h"
 #include "mozilla/Attributes.h"
+#include "mozilla/Snprintf.h"
 
 using namespace mozilla;
 
 class nsToolkitProfile final : public nsIToolkitProfile
 {
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSITOOLKITPROFILE
@@ -964,26 +965,28 @@ nsToolkitProfileService::Flush()
     nsresult rv;
     uint32_t pCount = 0;
     nsToolkitProfile *cur;
 
     for (cur = mFirst; cur != nullptr; cur = cur->mNext)
         ++pCount;
 
     uint32_t length;
-    nsAutoArrayPtr<char> buffer (new char[100+MAXPATHLEN*pCount]);
+    const int bufsize = 100+MAXPATHLEN*pCount;
+    nsAutoArrayPtr<char> buffer (new char[bufsize]);
 
     NS_ENSURE_TRUE(buffer, NS_ERROR_OUT_OF_MEMORY);
 
-    char *end = buffer;
+    char *pos = buffer;
+    char *end = buffer + bufsize;
 
-    end += sprintf(end,
-                   "[General]\n"
-                   "StartWithLastProfile=%s\n\n",
-                   mStartWithLast ? "1" : "0");
+    pos += snprintf(pos, end - pos,
+                    "[General]\n"
+                    "StartWithLastProfile=%s\n\n",
+                    mStartWithLast ? "1" : "0");
 
     nsAutoCString path;
     cur = mFirst;
     pCount = 0;
 
     while (cur) {
         // if the profile dir is relative to appdir...
         bool isRelative;
@@ -992,42 +995,42 @@ nsToolkitProfileService::Flush()
             // we use a relative descriptor
             rv = cur->mRootDir->GetRelativeDescriptor(mAppData, path);
         } else {
             // otherwise, a persistent descriptor
             rv = cur->mRootDir->GetPersistentDescriptor(path);
             NS_ENSURE_SUCCESS(rv, rv);
         }
 
-        end += sprintf(end,
-                       "[Profile%u]\n"
-                       "Name=%s\n"
-                       "IsRelative=%s\n"
-                       "Path=%s\n",
-                       pCount, cur->mName.get(),
-                       isRelative ? "1" : "0", path.get());
+        pos += snprintf(pos, end - pos,
+                        "[Profile%u]\n"
+                        "Name=%s\n"
+                        "IsRelative=%s\n"
+                        "Path=%s\n",
+                        pCount, cur->mName.get(),
+                        isRelative ? "1" : "0", path.get());
 
         nsCOMPtr<nsIToolkitProfile> profile;
         rv = this->GetDefaultProfile(getter_AddRefs(profile));
         if (NS_SUCCEEDED(rv) && profile == cur) {
-            end += sprintf(end, "Default=1\n");
+            pos += snprintf(pos, end - pos, "Default=1\n");
         }
 
-        end += sprintf(end, "\n");
+        pos += snprintf(pos, end - pos, "\n");
 
         cur = cur->mNext;
         ++pCount;
     }
 
     FILE* writeFile;
     rv = mListFile->OpenANSIFileDesc("w", &writeFile);
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (buffer) {
-        length = end - buffer;
+        length = pos - buffer;
 
         if (fwrite(buffer, sizeof(char), length, writeFile) != length) {
             fclose(writeFile);
             return NS_ERROR_UNEXPECTED;
         }
     }
 
     fclose(writeFile);
--- a/tools/profiler/LulDwarf.cpp
+++ b/tools/profiler/LulDwarf.cpp
@@ -46,20 +46,22 @@
 #include <string.h>
 #include <stdlib.h>
 
 #include <map>
 #include <stack>
 #include <string>
 
 #include "mozilla/Assertions.h"
+#include "mozilla/Snprintf.h"
 
 #include "LulCommonExt.h"
 #include "LulDwarfInt.h"
 
+
 // Set this to 1 for verbose logging
 #define DEBUG_DWARF 0
 
 
 namespace lul {
 
 using std::string;
 
@@ -1658,149 +1660,149 @@ const char *CallFrameInfo::KindName(Entr
 bool CallFrameInfo::ReportIncomplete(Entry *entry) {
   reporter_->Incomplete(entry->offset, entry->kind);
   return false;
 }
 
 void CallFrameInfo::Reporter::Incomplete(uint64 offset,
                                          CallFrameInfo::EntryKind kind) {
   char buf[300];
-  snprintf(buf, sizeof(buf),
-           "%s: CFI %s at offset 0x%llx in '%s': entry ends early\n",
-           filename_.c_str(), CallFrameInfo::KindName(kind), offset,
-           section_.c_str());
+  snprintf_literal(buf,
+                   "%s: CFI %s at offset 0x%llx in '%s': entry ends early\n",
+                   filename_.c_str(), CallFrameInfo::KindName(kind), offset,
+                   section_.c_str());
   log_(buf);
 }
 
 void CallFrameInfo::Reporter::EarlyEHTerminator(uint64 offset) {
   char buf[300];
-  snprintf(buf, sizeof(buf),
-           "%s: CFI at offset 0x%llx in '%s': saw end-of-data marker"
-           " before end of section contents\n",
-           filename_.c_str(), offset, section_.c_str());
+  snprintf_literal(buf,
+                   "%s: CFI at offset 0x%llx in '%s': saw end-of-data marker"
+                   " before end of section contents\n",
+                   filename_.c_str(), offset, section_.c_str());
   log_(buf);
 }
 
 void CallFrameInfo::Reporter::CIEPointerOutOfRange(uint64 offset,
                                                    uint64 cie_offset) {
   char buf[300];
-  snprintf(buf, sizeof(buf),
-           "%s: CFI frame description entry at offset 0x%llx in '%s':"
-           " CIE pointer is out of range: 0x%llx\n",
-           filename_.c_str(), offset, section_.c_str(), cie_offset);
+  snprintf_literal(buf,
+                   "%s: CFI frame description entry at offset 0x%llx in '%s':"
+                   " CIE pointer is out of range: 0x%llx\n",
+                   filename_.c_str(), offset, section_.c_str(), cie_offset);
   log_(buf);
 }
 
 void CallFrameInfo::Reporter::BadCIEId(uint64 offset, uint64 cie_offset) {
   char buf[300];
-  snprintf(buf, sizeof(buf),
-           "%s: CFI frame description entry at offset 0x%llx in '%s':"
-           " CIE pointer does not point to a CIE: 0x%llx\n",
-           filename_.c_str(), offset, section_.c_str(), cie_offset);
+  snprintf_literal(buf,
+                   "%s: CFI frame description entry at offset 0x%llx in '%s':"
+                   " CIE pointer does not point to a CIE: 0x%llx\n",
+                   filename_.c_str(), offset, section_.c_str(), cie_offset);
   log_(buf);
 }
 
 void CallFrameInfo::Reporter::UnrecognizedVersion(uint64 offset, int version) {
   char buf[300];
-  snprintf(buf, sizeof(buf),
-           "%s: CFI frame description entry at offset 0x%llx in '%s':"
-           " CIE specifies unrecognized version: %d\n",
-           filename_.c_str(), offset, section_.c_str(), version);
+  snprintf_literal(buf,
+                   "%s: CFI frame description entry at offset 0x%llx in '%s':"
+                   " CIE specifies unrecognized version: %d\n",
+                   filename_.c_str(), offset, section_.c_str(), version);
   log_(buf);
 }
 
 void CallFrameInfo::Reporter::UnrecognizedAugmentation(uint64 offset,
                                                        const string &aug) {
   char buf[300];
-  snprintf(buf, sizeof(buf),
-           "%s: CFI frame description entry at offset 0x%llx in '%s':"
-           " CIE specifies unrecognized augmentation: '%s'\n",
-           filename_.c_str(), offset, section_.c_str(), aug.c_str());
+  snprintf_literal(buf,
+                   "%s: CFI frame description entry at offset 0x%llx in '%s':"
+                   " CIE specifies unrecognized augmentation: '%s'\n",
+                   filename_.c_str(), offset, section_.c_str(), aug.c_str());
   log_(buf);
 }
 
 void CallFrameInfo::Reporter::InvalidPointerEncoding(uint64 offset,
                                                      uint8 encoding) {
   char buf[300];
-  snprintf(buf, sizeof(buf),
-           "%s: CFI common information entry at offset 0x%llx in '%s':"
-           " 'z' augmentation specifies invalid pointer encoding: 0x%02x\n",
-           filename_.c_str(), offset, section_.c_str(), encoding);
+  snprintf_literal(buf,
+                   "%s: CFI common information entry at offset 0x%llx in '%s':"
+                   " 'z' augmentation specifies invalid pointer encoding: 0x%02x\n",
+                   filename_.c_str(), offset, section_.c_str(), encoding);
   log_(buf);
 }
 
 void CallFrameInfo::Reporter::UnusablePointerEncoding(uint64 offset,
                                                       uint8 encoding) {
   char buf[300];
-  snprintf(buf, sizeof(buf),
-           "%s: CFI common information entry at offset 0x%llx in '%s':"
-           " 'z' augmentation specifies a pointer encoding for which"
-           " we have no base address: 0x%02x\n",
-           filename_.c_str(), offset, section_.c_str(), encoding);
+  snprintf_literal(buf,
+                   "%s: CFI common information entry at offset 0x%llx in '%s':"
+                   " 'z' augmentation specifies a pointer encoding for which"
+                   " we have no base address: 0x%02x\n",
+                   filename_.c_str(), offset, section_.c_str(), encoding);
   log_(buf);
 }
 
 void CallFrameInfo::Reporter::RestoreInCIE(uint64 offset, uint64 insn_offset) {
   char buf[300];
-  snprintf(buf, sizeof(buf),
-           "%s: CFI common information entry at offset 0x%llx in '%s':"
-           " the DW_CFA_restore instruction at offset 0x%llx"
-           " cannot be used in a common information entry\n",
-           filename_.c_str(), offset, section_.c_str(), insn_offset);
+  snprintf_literal(buf,
+                   "%s: CFI common information entry at offset 0x%llx in '%s':"
+                   " the DW_CFA_restore instruction at offset 0x%llx"
+                   " cannot be used in a common information entry\n",
+                   filename_.c_str(), offset, section_.c_str(), insn_offset);
   log_(buf);
 }
 
 void CallFrameInfo::Reporter::BadInstruction(uint64 offset,
                                              CallFrameInfo::EntryKind kind,
                                              uint64 insn_offset) {
   char buf[300];
-  snprintf(buf, sizeof(buf),
-           "%s: CFI %s at offset 0x%llx in section '%s':"
-           " the instruction at offset 0x%llx is unrecognized\n",
-           filename_.c_str(), CallFrameInfo::KindName(kind),
-           offset, section_.c_str(), insn_offset);
+  snprintf_literal(buf,
+                   "%s: CFI %s at offset 0x%llx in section '%s':"
+                   " the instruction at offset 0x%llx is unrecognized\n",
+                   filename_.c_str(), CallFrameInfo::KindName(kind),
+                   offset, section_.c_str(), insn_offset);
   log_(buf);
 }
 
 void CallFrameInfo::Reporter::NoCFARule(uint64 offset,
                                         CallFrameInfo::EntryKind kind,
                                         uint64 insn_offset) {
   char buf[300];
-  snprintf(buf, sizeof(buf),
-           "%s: CFI %s at offset 0x%llx in section '%s':"
-           " the instruction at offset 0x%llx assumes that a CFA rule has"
-           " been set, but none has been set\n",
-           filename_.c_str(), CallFrameInfo::KindName(kind), offset,
-           section_.c_str(), insn_offset);
+  snprintf_literal(buf,
+                   "%s: CFI %s at offset 0x%llx in section '%s':"
+                   " the instruction at offset 0x%llx assumes that a CFA rule has"
+                   " been set, but none has been set\n",
+                   filename_.c_str(), CallFrameInfo::KindName(kind), offset,
+                   section_.c_str(), insn_offset);
   log_(buf);
 }
 
 void CallFrameInfo::Reporter::EmptyStateStack(uint64 offset,
                                               CallFrameInfo::EntryKind kind,
                                               uint64 insn_offset) {
   char buf[300];
-  snprintf(buf, sizeof(buf),
-           "%s: CFI %s at offset 0x%llx in section '%s':"
-           " the DW_CFA_restore_state instruction at offset 0x%llx"
-           " should pop a saved state from the stack, but the stack is empty\n",
-           filename_.c_str(), CallFrameInfo::KindName(kind), offset,
-           section_.c_str(), insn_offset);
+  snprintf_literal(buf,
+                   "%s: CFI %s at offset 0x%llx in section '%s':"
+                   " the DW_CFA_restore_state instruction at offset 0x%llx"
+                   " should pop a saved state from the stack, but the stack is empty\n",
+                   filename_.c_str(), CallFrameInfo::KindName(kind), offset,
+                   section_.c_str(), insn_offset);
   log_(buf);
 }
 
 void CallFrameInfo::Reporter::ClearingCFARule(uint64 offset,
                                               CallFrameInfo::EntryKind kind,
                                               uint64 insn_offset) {
   char buf[300];
-  snprintf(buf, sizeof(buf),
-           "%s: CFI %s at offset 0x%llx in section '%s':"
-           " the DW_CFA_restore_state instruction at offset 0x%llx"
-           " would clear the CFA rule in effect\n",
-           filename_.c_str(), CallFrameInfo::KindName(kind), offset,
-           section_.c_str(), insn_offset);
+  snprintf_literal(buf,
+                   "%s: CFI %s at offset 0x%llx in section '%s':"
+                   " the DW_CFA_restore_state instruction at offset 0x%llx"
+                   " would clear the CFA rule in effect\n",
+                   filename_.c_str(), CallFrameInfo::KindName(kind), offset,
+                   section_.c_str(), insn_offset);
   log_(buf);
 }
 
 
 const unsigned int DwarfCFIToModule::RegisterNames::I386() {
   /*
    8 "$eax", "$ecx", "$edx", "$ebx", "$esp", "$ebp", "$esi", "$edi",
    3 "$eip", "$eflags", "$unused1",
@@ -1885,17 +1887,17 @@ const UniqueString* DwarfCFIToModule::Re
     MOZ_ASSERT(i == kCFARegister);
     return usu_->ToUniqueString(".cfa");
   }
   unsigned reg = i;
   if (reg == return_address_)
     return usu_->ToUniqueString(".ra");
 
   char buf[30];
-  sprintf(buf, "dwarf_reg_%u", reg);
+  snprintf_literal(buf, "dwarf_reg_%u", reg);
   return usu_->ToUniqueString(buf);
 }
 
 bool DwarfCFIToModule::UndefinedRule(uint64 address, int reg) {
   reporter_->UndefinedNotSupported(entry_offset_, RegisterName(reg));
   // Treat this as a non-fatal error.
   return true;
 }
@@ -1958,18 +1960,18 @@ bool DwarfCFIToModule::End() {
   summ_->End();
   return true;
 }
 
 void DwarfCFIToModule::Reporter::UndefinedNotSupported(
     size_t offset,
     const UniqueString* reg) {
   char buf[300];
-  snprintf(buf, sizeof(buf),
-           "DwarfCFIToModule::Reporter::UndefinedNotSupported()\n");
+  snprintf_literal(buf,
+                   "DwarfCFIToModule::Reporter::UndefinedNotSupported()\n");
   log_(buf);
   //BPLOG(INFO) << file_ << ", section '" << section_
   //  << "': the call frame entry at offset 0x"
   //  << std::setbase(16) << offset << std::setbase(10)
   //  << " sets the rule for register '" << FromUniqueString(reg)
   //  << "' to 'undefined', but the Breakpad symbol file format cannot "
   //  << " express this";
 }
@@ -1988,20 +1990,20 @@ static bool is_power_of_2(uint64_t n)
 void DwarfCFIToModule::Reporter::ExpressionsNotSupported(
     size_t offset,
     const UniqueString* reg) {
   static uint64_t n_complaints = 0; // This isn't threadsafe
   n_complaints++;
   if (!is_power_of_2(n_complaints))
     return;
   char buf[300];
-  snprintf(buf, sizeof(buf),
-           "DwarfCFIToModule::Reporter::"
-           "ExpressionsNotSupported(shown %llu times)\n",
-           (unsigned long long int)n_complaints);
+  snprintf_literal(buf,
+                   "DwarfCFIToModule::Reporter::"
+                   "ExpressionsNotSupported(shown %llu times)\n",
+                   (unsigned long long int)n_complaints);
   log_(buf);
   //BPLOG(INFO) << file_ << ", section '" << section_
   //  << "': the call frame entry at offset 0x"
   //  << std::setbase(16) << offset << std::setbase(10)
   //  << " uses a DWARF expression to describe how to recover register '"
   //  << FromUniqueString(reg) << "', but this translator cannot yet "
   //  << "translate DWARF expressions to Breakpad postfix expressions (shown "
   //  << n_complaints << " times)";
--- a/tools/profiler/LulMain.cpp
+++ b/tools/profiler/LulMain.cpp
@@ -10,18 +10,19 @@
 #include <stdlib.h>
 #include <stdio.h>
 
 #include <algorithm>  // std::sort
 #include <string>
 
 #include "mozilla/Assertions.h"
 #include "mozilla/ArrayUtils.h"
+#include "mozilla/DebugOnly.h"
 #include "mozilla/MemoryChecking.h"
-#include "mozilla/DebugOnly.h"
+#include "mozilla/Snprintf.h"
 
 #include "LulCommonExt.h"
 #include "LulElfExt.h"
 
 #include "LulMainInt.h"
 
 #include "platform-linux-lul.h"  // for gettid()
 
@@ -79,37 +80,37 @@ ShowRule(const char* aNewReg, LExpr aExp
 {
   char buf[64];
   string res = string(aNewReg) + "=";
   switch (aExpr.mHow) {
     case LExpr::UNKNOWN:
       res += "Unknown";
       break;
     case LExpr::NODEREF:
-      sprintf(buf, "%s+%d", NameOf_DW_REG(aExpr.mReg), (int)aExpr.mOffset);
+      snprintf_literal(buf, "%s+%d", NameOf_DW_REG(aExpr.mReg), (int)aExpr.mOffset);
       res += buf;
       break;
     case LExpr::DEREF:
-      sprintf(buf, "*(%s+%d)", NameOf_DW_REG(aExpr.mReg), (int)aExpr.mOffset);
+      snprintf_literal(buf, "*(%s+%d)", NameOf_DW_REG(aExpr.mReg), (int)aExpr.mOffset);
       res += buf;
       break;
     default:
       res += "???";
       break;
   }
   return res;
 }
 
 void
 RuleSet::Print(void(*aLog)(const char*))
 {
   char buf[96];
-  sprintf(buf, "[%llx .. %llx]: let ",
-          (unsigned long long int)mAddr,
-          (unsigned long long int)(mAddr + mLen - 1));
+  snprintf_literal(buf, "[%llx .. %llx]: let ",
+                   (unsigned long long int)mAddr,
+                   (unsigned long long int)(mAddr + mLen - 1));
   string res = string(buf);
   res += ShowRule("cfa", mCfaExpr);
   res += " in";
   // For each reg we care about, print the recovery expression.
 #if defined(LUL_ARCH_x64) || defined(LUL_ARCH_x86)
   res += ShowRule(" RA", mXipExpr);
   res += ShowRule(" SP", mXspExpr);
   res += ShowRule(" BP", mXbpExpr);
@@ -324,20 +325,20 @@ SecMap::PrepareRuleSets(uintptr_t aStart
     // Use the values defined in comments in the class declaration.
     mSummaryMinAddr = 1;
     mSummaryMaxAddr = 0;
   } else {
     mSummaryMinAddr = mRuleSets[0].mAddr;
     mSummaryMaxAddr = mRuleSets[n-1].mAddr + mRuleSets[n-1].mLen - 1;
   }
   char buf[150];
-  snprintf(buf, sizeof(buf),
-           "PrepareRuleSets: %d entries, smin/smax 0x%llx, 0x%llx\n",
-           (int)n, (unsigned long long int)mSummaryMinAddr,
-                   (unsigned long long int)mSummaryMaxAddr);
+  snprintf_literal(buf,
+                   "PrepareRuleSets: %d entries, smin/smax 0x%llx, 0x%llx\n",
+                   (int)n, (unsigned long long int)mSummaryMinAddr,
+                           (unsigned long long int)mSummaryMaxAddr);
   buf[sizeof(buf)-1] = 0;
   mLog(buf);
 
   // Is now usable for binary search.
   mUsable = true;
 
   if (0) {
     mLog("\nRulesets after preening\n");
@@ -528,18 +529,18 @@ class PriMap {
     if (i == num_secMaps) {
       // It goes at the end.
       mSecMaps.push_back(aSecMap);
     } else {
       std::vector<SecMap*>::iterator iter = mSecMaps.begin() + i;
       mSecMaps.insert(iter, aSecMap);
     }
     char buf[100];
-    snprintf(buf, sizeof(buf), "AddSecMap: now have %d SecMaps\n",
-             (int)mSecMaps.size());
+    snprintf_literal(buf, "AddSecMap: now have %d SecMaps\n",
+                     (int)mSecMaps.size());
     buf[sizeof(buf)-1] = 0;
     mLog(buf);
   }
 
   // Remove and delete any SecMaps in the mapping, that intersect
   // with the specified address range.
   void RemoveSecMapsInRange(uintptr_t avma_min, uintptr_t avma_max) {
     MOZ_ASSERT(avma_min <= avma_max);
@@ -801,19 +802,19 @@ class PriMap {
 
 ////////////////////////////////////////////////////////////////
 // LUL                                                        //
 ////////////////////////////////////////////////////////////////
 
 #define LUL_LOG(_str) \
   do { \
     char buf[200]; \
-    snprintf(buf, sizeof(buf), \
-             "LUL: pid %d tid %d lul-obj %p: %s", \
-             getpid(), gettid(), this, (_str)); \
+    snprintf_literal(buf, \
+                     "LUL: pid %d tid %d lul-obj %p: %s", \
+                     getpid(), gettid(), this, (_str)); \
     buf[sizeof(buf)-1] = 0; \
     mLog(buf); \
   } while (0)
 
 LUL::LUL(void (*aLog)(const char*))
   : mLog(aLog)
   , mAdminMode(true)
   , mAdminThreadId(gettid())
@@ -845,20 +846,20 @@ LUL::MaybeShowStats()
   // But it's just stats printing, so we don't really care.
   uint32_t n_new = mStats - mStatsPrevious;
   if (n_new >= 5000) {
     uint32_t n_new_Context = mStats.mContext - mStatsPrevious.mContext;
     uint32_t n_new_CFI     = mStats.mCFI     - mStatsPrevious.mCFI;
     uint32_t n_new_Scanned = mStats.mScanned - mStatsPrevious.mScanned;
     mStatsPrevious = mStats;
     char buf[200];
-    snprintf(buf, sizeof(buf),
-             "LUL frame stats: TOTAL %5u"
-             "    CTX %4u    CFI %4u    SCAN %4u",
-             n_new, n_new_Context, n_new_CFI, n_new_Scanned);
+    snprintf_literal(buf,
+                     "LUL frame stats: TOTAL %5u"
+                     "    CTX %4u    CFI %4u    SCAN %4u",
+                     n_new, n_new_Context, n_new_CFI, n_new_Scanned);
     buf[sizeof(buf)-1] = 0;
     mLog(buf);
   }
 }
 
 
 void
 LUL::EnableUnwinding()
@@ -876,19 +877,19 @@ void
 LUL::NotifyAfterMap(uintptr_t aRXavma, size_t aSize,
                     const char* aFileName, const void* aMappedImage)
 {
   MOZ_ASSERT(mAdminMode);
   MOZ_ASSERT(gettid() == mAdminThreadId);
 
   mLog(":\n");
   char buf[200];
-  snprintf(buf, sizeof(buf), "NotifyMap %llx %llu %s\n",
-           (unsigned long long int)aRXavma, (unsigned long long int)aSize,
-           aFileName);
+  snprintf_literal(buf, "NotifyMap %llx %llu %s\n",
+                   (unsigned long long int)aRXavma, (unsigned long long int)aSize,
+                   aFileName);
   buf[sizeof(buf)-1] = 0;
   mLog(buf);
 
   // Ignore obviously-stupid notifications.
   if (aSize > 0) {
 
     // Here's a new mapping, for this object.
     SecMap* smap = new SecMap(mLog);
@@ -904,18 +905,18 @@ LUL::NotifyAfterMap(uintptr_t aRXavma, s
               string(aFileName), std::vector<string>(), smap,
               (void*)aRXavma, aSize, mUSU, mLog);
     }
 
     mLog("NotifyMap .. preparing entries\n");
 
     smap->PrepareRuleSets(aRXavma, aSize);
 
-    snprintf(buf, sizeof(buf),
-             "NotifyMap got %lld entries\n", (long long int)smap->Size());
+    snprintf_literal(buf,
+                     "NotifyMap got %lld entries\n", (long long int)smap->Size());
     buf[sizeof(buf)-1] = 0;
     mLog(buf);
 
     // Add it to the primary map (the top level set of mapped objects).
     mPriMap->AddSecMap(smap);
 
     // Tell the segment array about the mapping, so that the stack
     // scan and __kernel_syscall mechanisms know where valid code is.
@@ -927,18 +928,18 @@ LUL::NotifyAfterMap(uintptr_t aRXavma, s
 void
 LUL::NotifyExecutableArea(uintptr_t aRXavma, size_t aSize)
 {
   MOZ_ASSERT(mAdminMode);
   MOZ_ASSERT(gettid() == mAdminThreadId);
 
   mLog(":\n");
   char buf[200];
-  snprintf(buf, sizeof(buf), "NotifyExecutableArea %llx %llu\n",
-           (unsigned long long int)aRXavma, (unsigned long long int)aSize);
+  snprintf_literal(buf, "NotifyExecutableArea %llx %llu\n",
+                   (unsigned long long int)aRXavma, (unsigned long long int)aSize);
   buf[sizeof(buf)-1] = 0;
   mLog(buf);
 
   // Ignore obviously-stupid notifications.
   if (aSize > 0) {
     // Tell the segment array about the mapping, so that the stack
     // scan and __kernel_syscall mechanisms know where valid code is.
     mSegArray->add(aRXavma, aRXavma + aSize - 1, true);
@@ -949,34 +950,34 @@ LUL::NotifyExecutableArea(uintptr_t aRXa
 void
 LUL::NotifyBeforeUnmap(uintptr_t aRXavmaMin, uintptr_t aRXavmaMax)
 {
   MOZ_ASSERT(mAdminMode);
   MOZ_ASSERT(gettid() == mAdminThreadId);
 
   mLog(":\n");
   char buf[100];
-  snprintf(buf, sizeof(buf), "NotifyUnmap %016llx-%016llx\n",
-           (unsigned long long int)aRXavmaMin,
-           (unsigned long long int)aRXavmaMax);
+  snprintf_literal(buf, "NotifyUnmap %016llx-%016llx\n",
+                   (unsigned long long int)aRXavmaMin,
+                   (unsigned long long int)aRXavmaMax);
   buf[sizeof(buf)-1] = 0;
   mLog(buf);
 
   MOZ_ASSERT(aRXavmaMin <= aRXavmaMax);
 
   // Remove from the primary map, any secondary maps that intersect
   // with the address range.  Also delete the secondary maps.
   mPriMap->RemoveSecMapsInRange(aRXavmaMin, aRXavmaMax);
 
   // Tell the segment array that the address range no longer
   // contains valid code.
   mSegArray->add(aRXavmaMin, aRXavmaMax, false);
 
-  snprintf(buf, sizeof(buf), "NotifyUnmap: now have %d SecMaps\n",
-           (int)mPriMap->CountSecMaps());
+  snprintf_literal(buf, "NotifyUnmap: now have %d SecMaps\n",
+                   (int)mPriMap->CountSecMaps());
   buf[sizeof(buf)-1] = 0;
   mLog(buf);
 }
 
 
 size_t
 LUL::CountMappings()
 {
@@ -1138,33 +1139,33 @@ LUL::Unwind(/*OUT*/uintptr_t* aFramePCs,
   static const int NUM_SCANNED_WORDS = 50; // max allowed scan length
 
   while (true) {
 
     if (DEBUG_MAIN) {
       char buf[300];
       mLog("\n");
 #if defined(LUL_ARCH_x64) || defined(LUL_ARCH_x86)
-      snprintf(buf, sizeof(buf),
-               "LoopTop: rip %d/%llx  rsp %d/%llx  rbp %d/%llx\n",
-               (int)regs.xip.Valid(), (unsigned long long int)regs.xip.Value(),
-               (int)regs.xsp.Valid(), (unsigned long long int)regs.xsp.Value(),
-               (int)regs.xbp.Valid(), (unsigned long long int)regs.xbp.Value());
+      snprintf_literal(buf,
+                       "LoopTop: rip %d/%llx  rsp %d/%llx  rbp %d/%llx\n",
+                       (int)regs.xip.Valid(), (unsigned long long int)regs.xip.Value(),
+                       (int)regs.xsp.Valid(), (unsigned long long int)regs.xsp.Value(),
+                       (int)regs.xbp.Valid(), (unsigned long long int)regs.xbp.Value());
       buf[sizeof(buf)-1] = 0;
       mLog(buf);
 #elif defined(LUL_ARCH_arm)
-      snprintf(buf, sizeof(buf),
-               "LoopTop: r15 %d/%llx  r7 %d/%llx  r11 %d/%llx"
-               "  r12 %d/%llx  r13 %d/%llx  r14 %d/%llx\n",
-               (int)regs.r15.Valid(), (unsigned long long int)regs.r15.Value(),
-               (int)regs.r7.Valid(),  (unsigned long long int)regs.r7.Value(),
-               (int)regs.r11.Valid(), (unsigned long long int)regs.r11.Value(),
-               (int)regs.r12.Valid(), (unsigned long long int)regs.r12.Value(),
-               (int)regs.r13.Valid(), (unsigned long long int)regs.r13.Value(),
-               (int)regs.r14.Valid(), (unsigned long long int)regs.r14.Value());
+      snprintf_literal(buf,
+                       "LoopTop: r15 %d/%llx  r7 %d/%llx  r11 %d/%llx"
+                       "  r12 %d/%llx  r13 %d/%llx  r14 %d/%llx\n",
+                       (int)regs.r15.Valid(), (unsigned long long int)regs.r15.Value(),
+                       (int)regs.r7.Valid(),  (unsigned long long int)regs.r7.Value(),
+                       (int)regs.r11.Valid(), (unsigned long long int)regs.r11.Value(),
+                       (int)regs.r12.Valid(), (unsigned long long int)regs.r12.Value(),
+                       (int)regs.r13.Valid(), (unsigned long long int)regs.r13.Value(),
+                       (int)regs.r14.Valid(), (unsigned long long int)regs.r14.Value());
       buf[sizeof(buf)-1] = 0;
       mLog(buf);
 #else
 # error "Unsupported arch"
 #endif
     }
 
 #if defined(LUL_ARCH_x64) || defined(LUL_ARCH_x86)
@@ -1219,18 +1220,18 @@ LUL::Unwind(/*OUT*/uintptr_t* aFramePCs,
     // If this isn't the innermost frame, back up into the calling insn.
     if (*aFramesUsed > 1) {
       ia.Add(TaggedUWord((uintptr_t)(-1)));
     }
 
     RuleSet* ruleset = mPriMap->Lookup(ia.Value());
     if (DEBUG_MAIN) {
       char buf[100];
-      snprintf(buf, sizeof(buf), "ruleset for 0x%llx = %p\n",
-               (unsigned long long int)ia.Value(), ruleset);
+      snprintf_literal(buf, "ruleset for 0x%llx = %p\n",
+                       (unsigned long long int)ia.Value(), ruleset);
       buf[sizeof(buf)-1] = 0;
       mLog(buf);
     }
 
     /////////////////////////////////////////////
     ////
     // On 32 bit x86-linux, syscalls are often done via the VDSO
     // function __kernel_vsyscall, which doesn't have a corresponding
@@ -1619,23 +1620,23 @@ bool GetAndCheckStackTrace(LUL* aLUL, co
     nConsistent++;
   }
 
   // So, did we succeed?
   bool passed = nConsistent+1 == strlen(dstring);
 
   // Show the results.
   char buf[200];
-  snprintf(buf, sizeof(buf), "LULUnitTest:   dstring = %s\n", dstring);
+  snprintf_literal(buf, "LULUnitTest:   dstring = %s\n", dstring);
   buf[sizeof(buf)-1] = 0;
   aLUL->mLog(buf);
-  snprintf(buf, sizeof(buf),
-           "LULUnitTest:     %d consistent, %d in dstring: %s\n",
-           (int)nConsistent, (int)strlen(dstring),
-           passed ? "PASS" : "FAIL");
+  snprintf_literal(buf,
+                   "LULUnitTest:     %d consistent, %d in dstring: %s\n",
+                   (int)nConsistent, (int)strlen(dstring),
+                   passed ? "PASS" : "FAIL");
   buf[sizeof(buf)-1] = 0;
   aLUL->mLog(buf);
 
   return passed;
 }
 
 
 // Macro magic to create a set of 8 mutually recursive functions with
--- a/widget/nsBaseWidget.cpp
+++ b/widget/nsBaseWidget.cpp
@@ -47,16 +47,17 @@
 #include "mozilla/VsyncDispatcher.h"
 #include "mozilla/layers/APZCTreeManager.h"
 #include "mozilla/layers/APZEventState.h"
 #include "mozilla/layers/APZThreadUtils.h"
 #include "mozilla/layers/ChromeProcessController.h"
 #include "mozilla/layers/InputAPZContext.h"
 #include "mozilla/layers/APZCCallbackHelper.h"
 #include "mozilla/dom/TabParent.h"
+#include "mozilla/Snprintf.h"
 #include "nsRefPtrHashtable.h"
 #include "TouchEvents.h"
 #include "WritingModes.h"
 #ifdef ACCESSIBILITY
 #include "nsAccessibilityService.h"
 #endif
 
 #ifdef DEBUG
@@ -72,16 +73,17 @@ static int32_t gNumWidgets;
 
 #ifdef XP_MACOSX
 #include "nsCocoaFeatures.h"
 #endif
 
 #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
 static nsRefPtrHashtable<nsVoidPtrHashKey, nsIWidget>* sPluginWidgetList;
 #endif
+
 nsIRollupListener* nsBaseWidget::gRollupListener = nullptr;
 
 using namespace mozilla::layers;
 using namespace mozilla::ipc;
 using namespace mozilla::widget;
 using namespace mozilla;
 using base::Thread;
 
@@ -1965,17 +1967,17 @@ case _value: eventName.AssignLiteral(_na
     _ASSIGN_eventName(NS_XUL_COMMAND_UPDATE, "NS_XUL_COMMAND_UPDATE");
 
 #undef _ASSIGN_eventName
 
   default:
     {
       char buf[32];
 
-      sprintf(buf,"UNKNOWN: %d",aGuiEvent->message);
+      snprintf_literal(buf,"UNKNOWN: %d",aGuiEvent->message);
 
       CopyASCIItoUTF16(buf, eventName);
     }
     break;
   }
 
   return nsAutoString(eventName);
 }
--- a/xpcom/base/CodeAddressService.h
+++ b/xpcom/base/CodeAddressService.h
@@ -10,20 +10,16 @@
 #include "mozilla/Assertions.h"
 #include "mozilla/HashFunctions.h"
 #include "mozilla/IntegerPrintfMacros.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/Types.h"
 
 #include "nsStackWalk.h"
 
-#if defined(_MSC_VER) && _MSC_VER < 1900
-#define snprintf _snprintf
-#endif
-
 namespace mozilla {
 
 // This class is used to print details about code locations.
 //
 // |StringTable| must implement an Intern() method that returns an interned
 // copy of the string that was passed in, as well as a standard
 // SizeOfExcludingThis() method.
 //
--- a/xpcom/ds/TimeStamp_posix.cpp
+++ b/xpcom/ds/TimeStamp_posix.cpp
@@ -41,16 +41,17 @@
 #elif defined(__FreeBSD__)
 #define KP_START_SEC ki_start.tv_sec
 #define KP_START_USEC ki_start.tv_usec
 #else
 #define KP_START_SEC p_ustart_sec
 #define KP_START_USEC p_ustart_usec
 #endif
 
+#include "mozilla/Snprintf.h"
 #include "mozilla/TimeStamp.h"
 #include "nsCRT.h"
 #include "prprf.h"
 #include "prthread.h"
 #include "nsDebug.h"
 
 // Estimate of the smallest duration of time we can measure.
 static uint64_t sResolution;
@@ -266,17 +267,17 @@ ComputeProcessUptimeThread(void* aTime)
 
   *uptime = 0;
 
   if (!hz) {
     return;
   }
 
   char threadStat[40];
-  sprintf(threadStat, "/proc/self/task/%d/stat", (pid_t)syscall(__NR_gettid));
+  snprintf_literal(threadStat, "/proc/self/task/%d/stat", (pid_t)syscall(__NR_gettid));
 
   uint64_t threadJiffies = JiffiesSinceBoot(threadStat);
   uint64_t selfJiffies = JiffiesSinceBoot("/proc/self/stat");
 
   if (!threadJiffies || !selfJiffies) {
     return;
   }
 
--- a/xpcom/glue/nsCRTGlue.cpp
+++ b/xpcom/glue/nsCRTGlue.cpp
@@ -9,16 +9,18 @@
 #include "nsDebug.h"
 #include "prtime.h"
 
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
 #include <stdarg.h>
 
+#include "mozilla/Snprintf.h"
+
 #ifdef XP_WIN
 #include <io.h>
 #include <windows.h>
 #include "mozilla/UniquePtr.h"
 #endif
 
 #ifdef ANDROID
 #include <android/log.h>
@@ -307,18 +309,19 @@ stderr_to_file(const char* aFmt, va_list
 }
 
 void
 copy_stderr_to_file(const char* aFile)
 {
   if (sStderrCopy) {
     return;
   }
-  char* buf = (char*)malloc(strlen(aFile) + 16);
-  sprintf(buf, "%s.%u", aFile, (uint32_t)getpid());
+  size_t buflen = strlen(aFile) + 16;
+  char* buf = (char*)malloc(buflen);
+  snprintf(buf, buflen, "%s.%u", aFile, (uint32_t)getpid());
   sStderrCopy = fopen(buf, "w");
   free(buf);
   set_stderr_callback(stderr_to_file);
 }
 #endif
 
 #ifdef HAVE_VA_COPY
 #define VARARGS_ASSIGN(foo, bar)        VA_COPY(foo,bar)