Bug 1717808 - aIter must be valid after extracting last segment of a BufferList, r=glandium

When advancing to Beta, we stop adding sentinels after serialized data
in IPC::Message objects. These sentinels would cause all Extract calls
to not reach the end of the message buffer on Nightly. This patch fixes
an assertion failure which can occur when extract calls fully empty the
buffer, and the finished iterator is advanced by 0 bytes.

Differential Revision: https://phabricator.services.mozilla.com/D118838
This commit is contained in:
Nika Layzell 2021-07-07 18:03:03 +00:00
Родитель 7e30d9ee03
Коммит 0e22f3df51
2 изменённых файлов: 25 добавлений и 0 удалений

Просмотреть файл

@ -658,6 +658,20 @@ BufferList<AllocPolicy> BufferList<AllocPolicy>::Extract(IterImpl& aIter,
aIter.mAbsoluteOffset -= removedBytes;
mSize -= removedBytes;
// If our iterator is already at the end, we just removed the very last
// segment of our buffer list and need to shift the iterator back to point
// at the end of the previous segment.
if (aIter.Done()) {
MOZ_ASSERT(lastSegmentSize.isNothing());
if (mSegments.empty()) {
MOZ_ASSERT(aIter.mSegment == 0);
aIter.mData = aIter.mDataEnd = nullptr;
} else {
MOZ_ASSERT(aIter.mSegment == mSegments.length() - 1);
aIter.mData = aIter.mDataEnd = mSegments.back().End();
}
}
if (lastSegmentSize.isSome()) {
// We called reserve() on result.mSegments so infallibleAppend is safe.
result.mSegments.infallibleAppend(
@ -673,6 +687,15 @@ BufferList<AllocPolicy> BufferList<AllocPolicy>::Extract(IterImpl& aIter,
AssertConsistentSize();
result.AssertConsistentSize();
// Ensure that the iterator is still valid when Extract returns.
#ifdef DEBUG
if (!mSegments.empty()) {
auto& segment = mSegments[aIter.mSegment];
MOZ_ASSERT(segment.Start() <= aIter.mData);
MOZ_ASSERT(aIter.mDataEnd == segment.End());
}
#endif
*aSuccess = true;
return result;
}

Просмотреть файл

@ -299,6 +299,8 @@ int main(void) {
MOZ_RELEASE_ASSERT(success);
MOZ_RELEASE_ASSERT(bl11.Size() == 16);
MOZ_RELEASE_ASSERT(iter.Done());
MOZ_RELEASE_ASSERT(iter.AdvanceAcrossSegments(bl10, 0));
MOZ_RELEASE_ASSERT(iter.Done());
iter = bl11.Iter();
MOZ_RELEASE_ASSERT(bl11.ReadBytes(iter, data, 16));
MOZ_RELEASE_ASSERT(memcmp(data, "abcdefgh12345678", 16) == 0);