Bug 1453456 - Remove nsCRT::IsAscii(null-terminated string) in favor of mozilla::IsAsciiNullTerminated. r=froydnj
authorJeff Walden <jwalden@mit.edu>
Mon, 25 Feb 2019 12:22:24 -0800
changeset 461682 18e52bd7c3adaa0e9bfae00942c935cb7568c054
parent 461681 e4565e7ddcb07bb6f4bc59623c821445d8e49069
child 461683 5ea654f841a45073afaf4df9ec4829932ef6c399
push id79250
push usercsabou@mozilla.com
push dateThu, 28 Feb 2019 14:36:24 +0000
treeherderautoland@00fe264dc8b6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1453456
milestone67.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 1453456 - Remove nsCRT::IsAscii(null-terminated string) in favor of mozilla::IsAsciiNullTerminated. r=froydnj
dom/media/gmp/GMPChild.cpp
dom/plugins/ipc/FunctionHook.cpp
mfbt/TextUtils.h
mfbt/tests/TestTextUtils.cpp
widget/windows/nsDataObj.cpp
xpcom/base/nsCRTGlue.h
xpcom/ds/nsAtomTable.cpp
xpcom/ds/nsCRT.h
xpcom/ds/nsStaticNameTable.cpp
--- a/dom/media/gmp/GMPChild.cpp
+++ b/dom/media/gmp/GMPChild.cpp
@@ -15,16 +15,17 @@
 #include "nsIFile.h"
 #include "nsXULAppAPI.h"
 #include "gmp-video-decode.h"
 #include "gmp-video-encode.h"
 #include "GMPPlatform.h"
 #include "mozilla/Algorithm.h"
 #include "mozilla/ipc/CrashReporterClient.h"
 #include "mozilla/ipc/ProcessChild.h"
+#include "mozilla/TextUtils.h"
 #include "GMPUtils.h"
 #include "prio.h"
 #include "base/task.h"
 #include "base/command_line.h"
 #include "ChromiumCDMAdapter.h"
 #include "GMPLog.h"
 
 using namespace mozilla::ipc;
@@ -259,17 +260,18 @@ mozilla::ipc::IPCResult GMPChild::RecvPr
   constexpr static const char16_t* whitelist[] = {
       u"dxva2.dll",        // Get monitor information
       u"evr.dll",          // MFGetStrideForBitmapInfoHeader
       u"mfplat.dll",       // MFCreateSample, MFCreateAlignedMemoryBuffer,
                            // MFCreateMediaType
       u"msmpeg2vdec.dll",  // H.264 decoder
       u"psapi.dll",        // For GetMappedFileNameW, see bug 1383611
   };
-  constexpr static bool (*IsASCII)(const char16_t*) = NS_IsAscii;
+  constexpr static bool (*IsASCII)(const char16_t*) =
+      IsAsciiNullTerminated<char16_t>;
   static_assert(AllOf(std::begin(whitelist), std::end(whitelist), IsASCII),
                 "Items in the whitelist must not contain non-ASCII "
                 "characters!");
 
   nsTArray<nsCString> libs;
   SplitAt(", ", aLibs, libs);
   for (nsCString lib : libs) {
     ToLowerCase(lib);
--- a/dom/plugins/ipc/FunctionHook.cpp
+++ b/dom/plugins/ipc/FunctionHook.cpp
@@ -1,14 +1,16 @@
 /* -*- 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/TextUtils.h"
+
 #include "FunctionHook.h"
 #include "FunctionBroker.h"
 #include "nsClassHashtable.h"
 #include "mozilla/ClearOnShutdown.h"
 
 #if defined(XP_WIN)
 #  include <shlobj.h>
 #  include "PluginModuleChild.h"
@@ -60,17 +62,17 @@ typedef nsClassHashtable<nsStringHashKey
 DllInterceptors* sDllInterceptorCache = nullptr;
 
 WindowsDllInterceptor* FunctionHook::GetDllInterceptorFor(
     const char* aModuleName) {
   if (!sDllInterceptorCache) {
     sDllInterceptorCache = new DllInterceptors();
   }
 
-  MOZ_ASSERT(NS_IsAscii(aModuleName),
+  MOZ_ASSERT(IsAsciiNullTerminated(aModuleName),
              "Non-ASCII module names are not supported");
   NS_ConvertASCIItoUTF16 moduleName(aModuleName);
 
   WindowsDllInterceptor* ret = sDllInterceptorCache->LookupOrAdd(moduleName);
   MOZ_ASSERT(ret);
   ret->Init(moduleName.get());
   return ret;
 }
--- a/mfbt/TextUtils.h
+++ b/mfbt/TextUtils.h
@@ -36,16 +36,34 @@ class MakeUnsignedChar<char32_t> {
 /** Returns true iff |aChar| is ASCII, i.e. in the range [0, 0x80). */
 template <typename Char>
 constexpr bool IsAscii(Char aChar) {
   using UnsignedChar = typename detail::MakeUnsignedChar<Char>::Type;
   auto uc = static_cast<UnsignedChar>(aChar);
   return uc < 0x80;
 }
 
+/**
+ * Returns true iff every character in the null-terminated string pointed to by
+ * |aChar| is ASCII, i.e. in the range [0, 0x80).
+ */
+template <typename Char>
+constexpr bool IsAsciiNullTerminated(const Char* aChar) {
+  while (Char c = *aChar++) {
+    if (!IsAscii(c)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+/**
+ * Returns true iff |aChar| is Latin-1 but not ASCII, i.e. in the range
+ * [0x80, 0xFF].
+ */
 template <typename Char>
 constexpr bool IsNonAsciiLatin1(Char aChar) {
   using UnsignedChar = typename detail::MakeUnsignedChar<Char>::Type;
   auto uc = static_cast<UnsignedChar>(aChar);
   return uc >= 0x80 && uc <= 0xFF;
 }
 
 /**
--- a/mfbt/tests/TestTextUtils.cpp
+++ b/mfbt/tests/TestTextUtils.cpp
@@ -8,16 +8,17 @@
 #include "mozilla/TextUtils.h"
 
 using mozilla::AsciiAlphanumericToNumber;
 using mozilla::IsAscii;
 using mozilla::IsAsciiAlpha;
 using mozilla::IsAsciiAlphanumeric;
 using mozilla::IsAsciiDigit;
 using mozilla::IsAsciiLowercaseAlpha;
+using mozilla::IsAsciiNullTerminated;
 using mozilla::IsAsciiUppercaseAlpha;
 
 static void TestIsAscii() {
   // char
 
   static_assert(!IsAscii(char(-1)), "char(-1) isn't ASCII");
 
   static_assert(IsAscii('\0'), "nul is ASCII");
@@ -96,16 +97,94 @@ static void TestIsAscii() {
   static_assert(IsAscii(U'{'), "U'{' is ASCII");
 
   static_assert(IsAscii(U'5'), "U'5' is ASCII");
 
   static_assert(IsAscii(U'\x7F'), "U'\\x7F' is ASCII");
   static_assert(!IsAscii(U'\x80'), "U'\\x80' isn't ASCII");
 }
 
+static void TestIsAsciiNullTerminated() {
+  // char
+
+  constexpr char allChar[] =
+      "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\0x0C\x0D\x0E\x0F"
+      "\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\0x1C\x1D\x1E\x1F"
+      "\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\0x2C\x2D\x2E\x2F"
+      "\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\0x3C\x3D\x3E\x3F"
+      "\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\0x4C\x4D\x4E\x4F"
+      "\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\0x5C\x5D\x5E\x5F"
+      "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\0x6C\x6D\x6E\x6F"
+      "\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\0x7C\x7D\x7E\x7F";
+
+  static_assert(IsAsciiNullTerminated(allChar), "allChar is ASCII");
+
+  constexpr char loBadChar[] = "\x80";
+
+  static_assert(!IsAsciiNullTerminated(loBadChar), "loBadChar isn't ASCII");
+
+  constexpr char hiBadChar[] = "\xFF";
+
+  static_assert(!IsAsciiNullTerminated(hiBadChar), "hiBadChar isn't ASCII");
+
+  // char16_t
+
+  constexpr char16_t allChar16[] =
+      u"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\0x0C\x0D\x0E\x0F"
+      "\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\0x1C\x1D\x1E\x1F"
+      "\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\0x2C\x2D\x2E\x2F"
+      "\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\0x3C\x3D\x3E\x3F"
+      "\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\0x4C\x4D\x4E\x4F"
+      "\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\0x5C\x5D\x5E\x5F"
+      "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\0x6C\x6D\x6E\x6F"
+      "\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\0x7C\x7D\x7E\x7F";
+
+  static_assert(IsAsciiNullTerminated(allChar16), "allChar16 is ASCII");
+
+  constexpr char16_t loBadChar16[] = u"\x80";
+
+  static_assert(!IsAsciiNullTerminated(loBadChar16), "loBadChar16 isn't ASCII");
+
+  constexpr char16_t hiBadChar16[] = u"\xFF";
+
+  static_assert(!IsAsciiNullTerminated(hiBadChar16), "hiBadChar16 isn't ASCII");
+
+  constexpr char16_t highestChar16[] = u"\uFFFF";
+
+  static_assert(!IsAsciiNullTerminated(highestChar16),
+                "highestChar16 isn't ASCII");
+
+  // char32_t
+
+  constexpr char32_t allChar32[] =
+      U"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\0x0C\x0D\x0E\x0F"
+      "\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\0x1C\x1D\x1E\x1F"
+      "\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\0x2C\x2D\x2E\x2F"
+      "\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\0x3C\x3D\x3E\x3F"
+      "\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\0x4C\x4D\x4E\x4F"
+      "\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\0x5C\x5D\x5E\x5F"
+      "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\0x6C\x6D\x6E\x6F"
+      "\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\0x7C\x7D\x7E\x7F";
+
+  static_assert(IsAsciiNullTerminated(allChar32), "allChar32 is ASCII");
+
+  constexpr char32_t loBadChar32[] = U"\x80";
+
+  static_assert(!IsAsciiNullTerminated(loBadChar32), "loBadChar32 isn't ASCII");
+
+  constexpr char32_t hiBadChar32[] = U"\xFF";
+
+  static_assert(!IsAsciiNullTerminated(hiBadChar32), "hiBadChar32 isn't ASCII");
+
+  constexpr char32_t highestChar32[] = {static_cast<char32_t>(-1), 0};
+
+  static_assert(!IsAsciiNullTerminated(highestChar32),
+                "highestChar32 isn't ASCII");
+}
+
 static void TestIsAsciiAlpha() {
   // char
 
   static_assert(!IsAsciiAlpha('@'), "'@' isn't ASCII alpha");
   static_assert('@' == 0x40, "'@' has value 0x40");
 
   static_assert('A' == 0x41, "'A' has value 0x41");
   static_assert(IsAsciiAlpha('A'), "'A' is ASCII alpha");
@@ -970,15 +1049,16 @@ static void TestIsAsciiDigit() {
   static_assert(!IsAsciiDigit(U'm'), "U'm' isn't an ASCII digit");
   static_assert(!IsAsciiDigit(U'y'), "U'y' isn't an ASCII digit");
   static_assert(!IsAsciiDigit(U'z'), "U'z' isn't an ASCII digit");
   static_assert(!IsAsciiDigit(U'{'), "U'{' isn't an ASCII digit");
 }
 
 int main() {
   TestIsAscii();
+  TestIsAsciiNullTerminated();
   TestIsAsciiAlpha();
   TestIsAsciiUppercaseAlpha();
   TestIsAsciiLowercaseAlpha();
   TestIsAsciiAlphanumeric();
   TestAsciiAlphanumericToNumber();
   TestIsAsciiDigit();
 }
--- a/widget/windows/nsDataObj.cpp
+++ b/widget/windows/nsDataObj.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 "mozilla/ArrayUtils.h"
+#include "mozilla/TextUtils.h"
 
 #include <ole2.h>
 #include <shlobj.h>
 
 #include "nsDataObj.h"
 #include "nsArrayUtils.h"
 #include "nsClipboard.h"
 #include "nsReadableUtils.h"
@@ -1152,17 +1153,17 @@ nsDataObj ::GetFileContentsInternetShort
                                                          mIOThread, true);
 
     rv = mozilla::widget::FaviconHelper::GetOutputIconPath(aUri, icoFile, true);
     NS_ENSURE_SUCCESS(rv, E_FAIL);
     nsString path;
     rv = icoFile->GetPath(path);
     NS_ENSURE_SUCCESS(rv, E_FAIL);
 
-    if (NS_IsAscii(path.get())) {
+    if (IsAsciiNullTerminated(path.get())) {
       LossyCopyUTF16toASCII(path, asciiPath);
       shortcutFormatStr =
           "[InternetShortcut]\r\nURL=%s\r\n"
           "IDList=\r\nHotKey=0\r\nIconFile=%s\r\n"
           "IconIndex=0\r\n";
     } else {
       int len =
           WideCharToMultiByte(CP_UTF7, 0, char16ptr_t(path.BeginReading()),
--- a/xpcom/base/nsCRTGlue.h
+++ b/xpcom/base/nsCRTGlue.h
@@ -88,26 +88,16 @@ inline char NS_ToUpper(char aChar) {
 
 inline char NS_ToLower(char aChar) {
   return (char)nsLowerUpperUtils::kUpper2Lower[(unsigned char)aChar];
 }
 
 bool NS_IsUpper(char aChar);
 bool NS_IsLower(char aChar);
 
-constexpr bool NS_IsAscii(const char16_t* aString) {
-  while (*aString) {
-    if (0x0080 <= *aString) {
-      return false;
-    }
-    aString++;
-  }
-  return true;
-}
-
 constexpr bool NS_IsAscii(const char* aString) {
   while (*aString) {
     if (0x80 & *aString) {
       return false;
     }
     aString++;
   }
   return true;
--- a/xpcom/ds/nsAtomTable.cpp
+++ b/xpcom/ds/nsAtomTable.cpp
@@ -7,16 +7,17 @@
 #include "mozilla/Assertions.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/HashFunctions.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/MruCache.h"
 #include "mozilla/Mutex.h"
 #include "mozilla/DebugOnly.h"
 #include "mozilla/Sprintf.h"
+#include "mozilla/TextUtils.h"
 #include "mozilla/Unused.h"
 
 #include "nsAtom.h"
 #include "nsAtomTable.h"
 #include "nsAutoPtr.h"
 #include "nsCRT.h"
 #include "nsDataHashtable.h"
 #include "nsGkAtoms.h"
@@ -503,17 +504,17 @@ void nsAtomSubTable::AddSizeOfExcludingT
 
 void nsAtomTable::RegisterStaticAtoms(const nsStaticAtom* aAtoms,
                                       size_t aAtomsLen) {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_RELEASE_ASSERT(!gStaticAtomsDone, "Static atom insertion is finished!");
 
   for (uint32_t i = 0; i < aAtomsLen; ++i) {
     const nsStaticAtom* atom = &aAtoms[i];
-    MOZ_ASSERT(nsCRT::IsAscii(atom->String()));
+    MOZ_ASSERT(IsAsciiNullTerminated(atom->String()));
     MOZ_ASSERT(NS_strlen(atom->String()) == atom->GetLength());
     MOZ_ASSERT(atom->IsAsciiLowercase() ==
                ::IsAsciiLowercase(atom->String(), atom->GetLength()));
 
     // This assertion ensures the static atom's precomputed hash value matches
     // what would be computed by mozilla::HashString(aStr), which is what we use
     // when atomizing strings. We compute this hash in Atom.py.
     MOZ_ASSERT(HashString(atom->String()) == atom->hash());
--- a/xpcom/ds/nsCRT.h
+++ b/xpcom/ds/nsCRT.h
@@ -84,24 +84,19 @@ class nsCRT {
   static int64_t atoll(const char* aStr);
 
   static char ToUpper(char aChar) { return NS_ToUpper(aChar); }
   static char ToLower(char aChar) { return NS_ToLower(aChar); }
 
   static bool IsUpper(char aChar) { return NS_IsUpper(aChar); }
   static bool IsLower(char aChar) { return NS_IsLower(aChar); }
 
-  static bool IsAscii(const char16_t* aString) { return NS_IsAscii(aString); }
   static bool IsAsciiSpace(char16_t aChar) {
     return NS_IsAsciiWhitespace(aChar);
   }
-  static bool IsAscii(const char* aString) { return NS_IsAscii(aString); }
-  static bool IsAscii(const char* aString, uint32_t aLength) {
-    return NS_IsAscii(aString, aLength);
-  }
 };
 
 inline bool NS_IS_SPACE(char16_t aChar) {
   return ((int(aChar) & 0x7f) == int(aChar)) && isspace(int(aChar));
 }
 
 #define NS_IS_CNTRL(i) ((((unsigned int)(i)) > 0x7f) ? (int)0 : iscntrl(i))
 #define NS_IS_DIGIT(i) ((((unsigned int)(i)) > 0x7f) ? (int)0 : isdigit(i))
--- a/xpcom/ds/nsStaticNameTable.cpp
+++ b/xpcom/ds/nsStaticNameTable.cpp
@@ -1,20 +1,22 @@
 /* -*- 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/. */
 
 /* Class to manage lookup of static names in a table. */
 
+#include "mozilla/HashFunctions.h"
+#include "mozilla/TextUtils.h"
+
 #include "nsCRT.h"
 
 #include "nscore.h"
-#include "mozilla/HashFunctions.h"
 #include "nsISupportsImpl.h"
 
 #include "nsStaticNameTable.h"
 
 using namespace mozilla;
 
 struct NameTableKey {
   NameTableKey(const nsDependentCString aNameArray[], const nsCString* aKeyStr)
@@ -102,17 +104,17 @@ nsStaticCaseInsensitiveNameTable::nsStat
     const char* raw = aNames[index];
 #ifdef DEBUG
     {
       // verify invariants of contents
       nsAutoCString temp1(raw);
       nsDependentCString temp2(raw);
       ToLowerCase(temp1);
       MOZ_ASSERT(temp1.Equals(temp2), "upper case char in table");
-      MOZ_ASSERT(nsCRT::IsAscii(raw),
+      MOZ_ASSERT(IsAsciiNullTerminated(raw),
                  "non-ascii string in table -- "
                  "case-insensitive matching won't work right");
     }
 #endif
     // use placement-new to initialize the string object
     nsDependentCString* strPtr = &mNameArray[index];
     new (strPtr) nsDependentCString(raw);