# HG changeset patch # User Chris Pearce # Date 1519264818 -46800 # Thu Feb 22 15:00:18 2018 +1300 # Node ID 43f6075d028ea136010a394fe35ab2306916d982 # Parent d2a43ef3a3a6a3c3d6faa4fb354cec5bea9d0187 Bug 1439433 - Length check FileBlockCache::mBlockChanges access. r=gerald I can't for the life of me figure out how we get into the situation where the block change list is empty here, or how we can get past some of the existing null checks in the code, but we can at least add some more checks to hopefully ensure we don't crash... MozReview-Commit-ID: 168G94IyrWt diff --git a/dom/media/FileBlockCache.cpp b/dom/media/FileBlockCache.cpp --- a/dom/media/FileBlockCache.cpp +++ b/dom/media/FileBlockCache.cpp @@ -449,31 +449,34 @@ nsresult FileBlockCache::Read(int64_t aO while (bytesToRead > 0) { int32_t blockIndex = static_cast(offset / BLOCK_SIZE); int32_t start = offset % BLOCK_SIZE; int32_t amount = std::min(BLOCK_SIZE - start, bytesToRead); // If the block is not yet written to file, we can just read from // the memory buffer, otherwise we need to read from file. int32_t bytesRead = 0; - RefPtr change = mBlockChanges[blockIndex]; + MOZ_ASSERT(!mBlockChanges.IsEmpty()); + MOZ_ASSERT(blockIndex >= 0 && + static_cast(blockIndex) < mBlockChanges.Length()); + RefPtr change = mBlockChanges.SafeElementAt(blockIndex); if (change && change->IsWrite()) { // Block isn't yet written to file. Read from memory buffer. const uint8_t* blockData = change->mData.get(); memcpy(dst, blockData + start, amount); bytesRead = amount; } else { if (change && change->IsMove()) { // The target block is the destination of a not-yet-completed move // action, so read from the move's source block from file. Note we // *don't* follow a chain of moves here, as a move's source index // is resolved when MoveBlock() is called, and the move's source's // block could be have itself been subject to a move (or write) // which happened *after* this move was recorded. - blockIndex = mBlockChanges[blockIndex]->mSourceBlockIndex; + blockIndex = change->mSourceBlockIndex; } // Block has been written to file, either as the source block of a move, // or as a stable (all changes made) block. Read the data directly // from file. nsresult res; { MutexAutoUnlock unlock(mDataMutex); MutexAutoLock lock(mFileMutex);