Bug 1462912 - fixed BufferList::Extract to handle the case where the call consumes the entirety of the BufferList; r=froydnj
authorAlex Gaynor <agaynor@mozilla.com>
Tue, 22 May 2018 13:04:59 -0400
changeset 419306 96a6ea5ea3468b4c9e20ff8d9795a7ef136213a9
parent 419305 32f3c058a394ea8ccf095650702b4ab8e2a8a805
child 419307 9055d9d89a4bca5cf48dda789299559aefca4e54
child 419308 59118f646da40f20320aadf81f7e9cd4cd92d70f
child 419428 9dd16444bdda45f7baa1482b3efbd7788ec7e272
push id34034
push userncsoregi@mozilla.com
push dateTue, 22 May 2018 22:00:26 +0000
treeherdermozilla-central@96a6ea5ea346 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1462912
milestone62.0a1
first release with
nightly linux32
96a6ea5ea346 / 62.0a1 / 20180522220730 / files
nightly linux64
96a6ea5ea346 / 62.0a1 / 20180522220730 / files
nightly mac
96a6ea5ea346 / 62.0a1 / 20180522220730 / files
nightly win32
96a6ea5ea346 / 62.0a1 / 20180522220730 / files
nightly win64
96a6ea5ea346 / 62.0a1 / 20180522220730 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1462912 - fixed BufferList::Extract to handle the case where the call consumes the entirety of the BufferList; r=froydnj MozReview-Commit-ID: 1LWODn8JaNL
mfbt/BufferList.h
mfbt/tests/TestBufferList.cpp
--- a/mfbt/BufferList.h
+++ b/mfbt/BufferList.h
@@ -609,17 +609,24 @@ BufferList<AllocPolicy>::Extract(IterImp
     size_t segmentsToCopy = segmentsNeeded - lastSegmentSize.isSome();
     for (size_t i = 0; i < segmentsToCopy; ++i) {
       result.mSegments.infallibleAppend(
         Segment(mSegments[aIter.mSegment].mData,
                 mSegments[aIter.mSegment].mSize,
                 mSegments[aIter.mSegment].mCapacity));
       aIter.Advance(*this, aIter.RemainingInSegment());
     }
-    MOZ_RELEASE_ASSERT(aIter.mSegment == copyStart + segmentsToCopy);
+    // Due to the way IterImpl works, there are two cases here: (1) if we've
+    // consumed the entirety of the BufferList, then the iterator is pointed at
+    // the end of the final segment, (2) otherwise it is pointed at the start
+    // of the next segment. We want to verify that we really consumed all
+    // |segmentsToCopy| segments.
+    MOZ_RELEASE_ASSERT(
+      (aIter.mSegment == copyStart + segmentsToCopy) ||
+      (aIter.Done() && aIter.mSegment == copyStart + segmentsToCopy - 1));
     mSegments.erase(mSegments.begin() + copyStart,
                     mSegments.begin() + copyStart + segmentsToCopy);
 
     // Reset the iter's position for what we just deleted.
     aIter.mSegment -= segmentsToCopy;
 
     if (lastSegmentSize.isSome()) {
       // We called reserve() on result.mSegments so infallibleAppend is safe.
--- a/mfbt/tests/TestBufferList.cpp
+++ b/mfbt/tests/TestBufferList.cpp
@@ -274,10 +274,22 @@ int main(void)
   BufferList bl8(0, 0, 16);
   bl8.WriteBytes("abcdefgh12345678", 16);
   iter = bl8.Iter();
   BufferList bl9 = bl8.Extract(iter, 8, &success);
   MOZ_RELEASE_ASSERT(success);
   MOZ_RELEASE_ASSERT(bl9.Size() == 8);
   MOZ_RELEASE_ASSERT(!iter.Done());
 
+  BufferList bl10(0, 0, 8);
+  bl10.WriteBytes("abcdefgh", 8);
+  bl10.WriteBytes("12345678", 8);
+  iter = bl10.Iter();
+  BufferList bl11 = bl10.Extract(iter, 16, &success);
+  MOZ_RELEASE_ASSERT(success);
+  MOZ_RELEASE_ASSERT(bl11.Size() == 16);
+  MOZ_RELEASE_ASSERT(iter.Done());
+  iter = bl11.Iter();
+  MOZ_RELEASE_ASSERT(bl11.ReadBytes(iter, data, 16));
+  MOZ_RELEASE_ASSERT(memcmp(data, "abcdefgh12345678", 16) == 0);
+
   return 0;
 }