Bug 730425 - Perform an additional range checks in stream read functions. r=roc a=lsblakk
authorMatthew Gregan <kinetik@flim.org>
Fri, 02 Mar 2012 13:59:32 +1300
changeset 35275 c23ed8a949b2b27cb5df8a5621b8e60cef01a539
parent 35274 2b31786f3b3e9bce8050b91c7f4d8d9f98937e46
child 35276 855980ed722de7f6785df13d5f7aa3de5a4902e4
push id2030
push usermgregan@mozilla.com
push dateFri, 02 Mar 2012 10:16:01 +0000
reviewersroc, lsblakk
bugs730425
milestone1.9.2.28pre
Bug 730425 - Perform an additional range checks in stream read functions. r=roc a=lsblakk
content/media/nsMediaCache.cpp
--- 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;
   }