Bug 1171603 - Better size check in nsTSubstring::ReplacePrep. r=ehsan, a=sledru
authorAndrea Marchesini <amarchesini@mozilla.com>
Mon, 06 Jul 2015 14:27:35 -0400
changeset 273792 25e950d0b04102f8d37ce7f19b1bd752c4a29035
parent 273791 caca636b78f8e013ad710a90a9cfbb7299205cc1
child 273793 2e5f12e03d3673295a92a903f7fd2dfb39be9dca
push id4867
push userryanvm@gmail.com
push dateMon, 13 Jul 2015 18:55:25 +0000
treeherdermozilla-beta@d23402a8262f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan, sledru
bugs1171603
milestone40.0
Bug 1171603 - Better size check in nsTSubstring::ReplacePrep. r=ehsan, a=sledru
xpcom/string/nsTSubstring.cpp
xpcom/string/nsTSubstring.h
--- a/xpcom/string/nsTSubstring.cpp
+++ b/xpcom/string/nsTSubstring.cpp
@@ -1,14 +1,15 @@
 /* -*- 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/CheckedInt.h"
 #include "mozilla/double-conversion.h"
 #include "mozilla/MemoryReporting.h"
 
 using double_conversion::DoubleToStringConverter;
 
 #ifdef XPCOM_STRING_CONSTRUCTOR_OUT_OF_LINE
 nsTSubstring_CharT::nsTSubstring_CharT(char_type* aData, size_type aLength,
                                        uint32_t aFlags)
@@ -156,16 +157,41 @@ nsTSubstring_CharT::MutatePrep(size_type
 void
 nsTSubstring_CharT::Finalize()
 {
   ::ReleaseData(mData, mFlags);
   // mData, mLength, and mFlags are purposefully left dangling
 }
 
 bool
+nsTSubstring_CharT::ReplacePrep(index_type aCutStart,
+                                size_type aCutLength,
+                                size_type aNewLength)
+{
+  aCutLength = XPCOM_MIN(aCutLength, mLength - aCutStart);
+
+  mozilla::CheckedInt<size_type> newTotalLen = mLength;
+  newTotalLen += aNewLength;
+  newTotalLen -= aCutLength;
+  if (!newTotalLen.isValid()) {
+    return false;
+  }
+
+  if (aCutStart == mLength && Capacity() > newTotalLen.value()) {
+    mFlags &= ~F_VOIDED;
+    mData[newTotalLen.value()] = char_type(0);
+    mLength = newTotalLen.value();
+    return true;
+  }
+
+  return ReplacePrepInternal(aCutStart, aCutLength, aNewLength,
+                             newTotalLen.value());
+}
+
+bool
 nsTSubstring_CharT::ReplacePrepInternal(index_type aCutStart, size_type aCutLen,
                                         size_type aFragLen, size_type aNewLen)
 {
   char_type* oldData;
   uint32_t oldFlags;
   if (!MutatePrep(aNewLen, &oldData, &oldFlags)) {
     return false;  // out-of-memory
   }
--- a/xpcom/string/nsTSubstring.h
+++ b/xpcom/string/nsTSubstring.h
@@ -992,28 +992,17 @@ protected:
    * indicated by '_' have an unspecified value and can be freely
    * modified.  this function will null-terminate mData upon return.
    *
    * this function returns false if is unable to allocate sufficient
    * memory.
    */
   MOZ_WARN_UNUSED_RESULT bool ReplacePrep(index_type aCutStart,
                                           size_type aCutLength,
-                                          size_type aNewLength)
-  {
-    aCutLength = XPCOM_MIN(aCutLength, mLength - aCutStart);
-    uint32_t newTotalLen = mLength - aCutLength + aNewLength;
-    if (aCutStart == mLength && Capacity() > newTotalLen) {
-      mFlags &= ~F_VOIDED;
-      mData[newTotalLen] = char_type(0);
-      mLength = newTotalLen;
-      return true;
-    }
-    return ReplacePrepInternal(aCutStart, aCutLength, aNewLength, newTotalLen);
-  }
+                                          size_type aNewLength);
 
   MOZ_WARN_UNUSED_RESULT bool NS_FASTCALL ReplacePrepInternal(
     index_type aCutStart,
     size_type aCutLength,
     size_type aNewFragLength,
     size_type aNewTotalLength);
 
   /**