Bug 730425 - Perform an additional range checks in stream read functions. r=roc a=lsblakk
--- a/content/media/nsMediaCache.cpp
+++ b/content/media/nsMediaCache.cpp
@@ -1989,26 +1989,28 @@ nsMediaCacheStream::Read(char* aBuffer,
return NS_ERROR_FAILURE;
PRUint32 count = 0;
// Read one block (or part of a block) at a time
while (count < aCount) {
PRUint32 streamBlock = PRUint32(mStreamOffset/BLOCK_SIZE);
PRUint32 offsetInStreamBlock =
PRUint32(mStreamOffset - streamBlock*BLOCK_SIZE);
- PRInt32 size = PR_MIN(aCount - count, BLOCK_SIZE - offsetInStreamBlock);
+ PRInt64 size = PR_MIN(aCount - count, BLOCK_SIZE - offsetInStreamBlock);
if (mStreamLength >= 0) {
// Don't try to read beyond the end of the stream
PRInt64 bytesRemaining = mStreamLength - mStreamOffset;
if (bytesRemaining <= 0) {
// Get out of here and return NS_OK
break;
}
- size = PR_MIN(size, PRInt32(bytesRemaining));
+ size = PR_MIN(size, bytesRemaining);
+ // Clamp size until 64-bit file size issues (bug 500784) are fixed.
+ size = PR_MIN(size, PRInt64(PR_INT32_MAX));
}
PRInt32 bytes;
PRUint32 channelBlock = PRUint32(mChannelOffset/BLOCK_SIZE);
PRInt32 cacheBlock = streamBlock < mBlocks.Length() ? mBlocks[streamBlock] : -1;
if (channelBlock == streamBlock && mStreamOffset < mChannelOffset) {
// We can just use the data in mPartialBlockBuffer. In fact we should
// use it rather than waiting for the block to fill and land in
@@ -2036,17 +2038,18 @@ nsMediaCacheStream::Read(char* aBuffer,
return NS_ERROR_FAILURE;
}
continue;
}
gMediaCache->NoteBlockUsage(this, cacheBlock, mCurrentMode, TimeStamp::Now());
PRInt64 offset = cacheBlock*BLOCK_SIZE + offsetInStreamBlock;
- nsresult rv = gMediaCache->ReadCacheFile(offset, aBuffer + count, size, &bytes);
+ NS_ABORT_IF_FALSE(size >= 0 && size <= PR_INT32_MAX, "Size out of range.");
+ nsresult rv = gMediaCache->ReadCacheFile(offset, aBuffer + count, PRInt32(size), &bytes);
if (NS_FAILED(rv)) {
if (count == 0)
return rv;
// If we did successfully read some data, may as well return it
break;
}
}
mStreamOffset += bytes;
@@ -2075,25 +2078,27 @@ nsMediaCacheStream::ReadFromCache(char*
// Read one block (or part of a block) at a time
PRUint32 count = 0;
PRInt64 streamOffset = aOffset;
while (count < aCount) {
PRUint32 streamBlock = PRUint32(streamOffset/BLOCK_SIZE);
PRUint32 offsetInStreamBlock =
PRUint32(streamOffset - streamBlock*BLOCK_SIZE);
- PRInt32 size = PR_MIN(aCount - count, BLOCK_SIZE - offsetInStreamBlock);
+ PRInt64 size = PR_MIN(aCount - count, BLOCK_SIZE - offsetInStreamBlock);
if (mStreamLength >= 0) {
// Don't try to read beyond the end of the stream
PRInt64 bytesRemaining = mStreamLength - streamOffset;
if (bytesRemaining <= 0) {
return NS_ERROR_FAILURE;
}
- size = PR_MIN(size, PRInt32(bytesRemaining));
+ size = PR_MIN(size, bytesRemaining);
+ // Clamp size until 64-bit file size issues (bug 500784) are fixed.
+ size = PR_MIN(size, PRInt64(PR_INT32_MAX));
}
PRInt32 bytes;
PRUint32 channelBlock = PRUint32(mChannelOffset/BLOCK_SIZE);
PRInt32 cacheBlock = streamBlock < mBlocks.Length() ? mBlocks[streamBlock] : -1;
if (channelBlock == streamBlock && streamOffset < mChannelOffset) {
// We can just use the data in mPartialBlockBuffer. In fact we should
// use it rather than waiting for the block to fill and land in
@@ -2102,17 +2107,18 @@ nsMediaCacheStream::ReadFromCache(char*
memcpy(aBuffer + count,
reinterpret_cast<char*>(mPartialBlockBuffer) + offsetInStreamBlock, bytes);
} else {
if (cacheBlock < 0) {
// We expect all blocks to be cached! Fail!
return NS_ERROR_FAILURE;
}
PRInt64 offset = cacheBlock*BLOCK_SIZE + offsetInStreamBlock;
- nsresult rv = gMediaCache->ReadCacheFile(offset, aBuffer + count, size, &bytes);
+ NS_ABORT_IF_FALSE(size >= 0 && size <= PR_INT32_MAX, "Size out of range.");
+ nsresult rv = gMediaCache->ReadCacheFile(offset, aBuffer + count, PRInt32(size), &bytes);
if (NS_FAILED(rv)) {
return rv;
}
}
streamOffset += bytes;
count += bytes;
}