Bug 1462912 - fixed BufferList::Extract to handle the case where the call consumes the entirety of the BufferList; r?froydnj
MozReview-Commit-ID: 1LWODn8JaNL
--- 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;
}