Bug 844820 - Fix two benign races in nsTArray around sEmptyHdr. a=bz
authorJustin Lebar <justin.lebar@gmail.com>
Tue, 26 Feb 2013 11:24:41 -0500
changeset 123022 dfb8986b9c1407bffac8f24e6450d64ad4266835
parent 123021 01b282dacd663bedf5c73e075fb40b3845f44e85
child 123023 24251a0088bfc2786d80b1858a25282b2474c701
push id24372
push useremorley@mozilla.com
push dateWed, 27 Feb 2013 13:22:59 +0000
treeherdermozilla-central@0a91da5f5eab [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs844820
milestone22.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 844820 - Fix two benign races in nsTArray around sEmptyHdr. a=bz
xpcom/glue/nsTArray-inl.h
xpcom/glue/nsTArray.h
--- a/xpcom/glue/nsTArray-inl.h
+++ b/xpcom/glue/nsTArray-inl.h
@@ -288,17 +288,17 @@ template<class Alloc>
 nsTArray_base<Alloc>::IsAutoArrayRestorer::~IsAutoArrayRestorer() {
   // Careful: We don't want to set mIsAutoArray = 1 on sEmptyHdr.
   if (mIsAuto && mArray.mHdr == mArray.EmptyHdr()) {
     // Call GetAutoArrayBufferUnsafe() because GetAutoArrayBuffer() asserts
     // that mHdr->mIsAutoArray is true, which surely isn't the case here.
     mArray.mHdr = mArray.GetAutoArrayBufferUnsafe(mElemAlign);
     mArray.mHdr->mLength = 0;
   }
-  else {
+  else if (mArray.mHdr != mArray.EmptyHdr()) {
     mArray.mHdr->mIsAutoArray = mIsAuto;
   }
 }
 
 template<class Alloc>
 template<class Allocator>
 bool
 nsTArray_base<Alloc>::SwapArrayElements(nsTArray_base<Allocator>& other,
--- a/xpcom/glue/nsTArray.h
+++ b/xpcom/glue/nsTArray.h
@@ -322,18 +322,24 @@ protected:
   void ShiftData(index_type start, size_type oldLen, size_type newLen,
                  size_type elemSize, size_t elemAlign);
 
   // This method increments the length member of the array's header.
   // Note that mHdr may actually be sEmptyHdr in the case where a
   // zero-length array is inserted into our array. But then n should
   // always be 0.
   void IncrementLength(uint32_t n) {
-    MOZ_ASSERT(mHdr != EmptyHdr() || n == 0, "bad data pointer");
-    mHdr->mLength += n;
+    if (mHdr == EmptyHdr()) {
+      if (MOZ_UNLIKELY(n != 0)) {
+        // Writing a non-zero length to the empty header would be extremely bad.
+        MOZ_CRASH();
+      }
+    } else {
+      mHdr->mLength += n;
+    }
   }
 
   // This method inserts blank slots into the array.
   // @param index the place to insert the new elements. This must be no
   //              greater than the current length of the array.
   // @param count the number of slots to insert
   // @param elementSize the size of an array element.
   // @param elemAlign the alignment in bytes of an array element.