commit a58cea744ac5b93b99a66554e1029b2c7aa3255d Author: Matthew Gregan Date: Tue Nov 11 08:58:52 2014 +1300 Bug 1085175. r=roc, a=dveditz Modified content/media/MediaCache.cpp diff --git a/content/media/MediaCache.cpp b/content/media/MediaCache.cpp index 598d905..c99f724 100644 --- a/content/media/MediaCache.cpp +++ b/content/media/MediaCache.cpp @@ -1174,6 +1174,7 @@ MediaCache::Update() // Figure out where we should be reading from. It's the first // uncached byte after the current mStreamOffset. int64_t dataOffset = stream->GetCachedDataEndInternal(stream->mStreamOffset); + MOZ_ASSERT(dataOffset >= 0); // Compute where we'd actually seek to to read at readOffset int64_t desiredOffset = dataOffset; @@ -1702,6 +1703,7 @@ MediaCacheStream::NotifyDataStarted(int64_t aOffset) ReentrantMonitorAutoEnter mon(gMediaCache->GetReentrantMonitor()); NS_WARN_IF_FALSE(aOffset == mChannelOffset, "Server is giving us unexpected offset"); + MOZ_ASSERT(aOffset >= 0); mChannelOffset = aOffset; if (mStreamLength >= 0) { // If we started reading at a certain offset, then for sure @@ -2118,23 +2120,28 @@ MediaCacheStream::Seek(int32_t aWhence, int64_t aOffset) return NS_ERROR_FAILURE; int64_t oldOffset = mStreamOffset; + int64_t newOffset = mStreamOffset; switch (aWhence) { case PR_SEEK_END: if (mStreamLength < 0) return NS_ERROR_FAILURE; - mStreamOffset = mStreamLength + aOffset; + newOffset = mStreamLength + aOffset; break; case PR_SEEK_CUR: - mStreamOffset += aOffset; + newOffset += aOffset; break; case PR_SEEK_SET: - mStreamOffset = aOffset; + newOffset = aOffset; break; default: NS_ERROR("Unknown whence"); return NS_ERROR_FAILURE; } + if (newOffset < 0) + return NS_ERROR_FAILURE; + mStreamOffset = newOffset; + CACHE_LOG(PR_LOG_DEBUG, ("Stream %p Seek to %lld", this, (long long)mStreamOffset)); gMediaCache->NoteSeek(this, oldOffset); @@ -2176,11 +2183,10 @@ MediaCacheStream::Read(char* aBuffer, uint32_t aCount, uint32_t* aBytes) break; } size = std::min(size, bytesRemaining); - // Clamp size until 64-bit file size issues (bug 500784) are fixed. + // Clamp size until 64-bit file size issues are fixed. size = std::min(size, int64_t(INT32_MAX)); } - int32_t bytes; int32_t cacheBlock = streamBlock < mBlocks.Length() ? mBlocks[streamBlock] : -1; if (cacheBlock < 0) { // We don't have a complete cached block here. @@ -2208,7 +2214,10 @@ MediaCacheStream::Read(char* aBuffer, uint32_t aCount, uint32_t* aBytes) // 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 // the cache. - bytes = std::min(size, streamWithPartialBlock->mChannelOffset - mStreamOffset); + int64_t bytes = std::min(size, streamWithPartialBlock->mChannelOffset - mStreamOffset); + // Clamp bytes until 64-bit file size issues are fixed. + bytes = std::min(bytes, int64_t(INT32_MAX)); + NS_ABORT_IF_FALSE(bytes >= 0 && bytes <= aCount, "Bytes out of range."); memcpy(aBuffer, reinterpret_cast(streamWithPartialBlock->mPartialBlockBuffer.get()) + offsetInStreamBlock, bytes); if (mCurrentMode == MODE_METADATA) { @@ -2232,6 +2241,7 @@ MediaCacheStream::Read(char* aBuffer, uint32_t aCount, uint32_t* aBytes) gMediaCache->NoteBlockUsage(this, cacheBlock, mCurrentMode, TimeStamp::Now()); int64_t offset = cacheBlock*BLOCK_SIZE + offsetInStreamBlock; + int32_t bytes; NS_ABORT_IF_FALSE(size >= 0 && size <= INT32_MAX, "Size out of range."); nsresult rv = gMediaCache->ReadCacheFile(offset, aBuffer + count, int32_t(size), &bytes); if (NS_FAILED(rv)) { @@ -2268,9 +2278,7 @@ MediaCacheStream::ReadAt(int64_t aOffset, char* aBuffer, } nsresult -MediaCacheStream::ReadFromCache(char* aBuffer, - int64_t aOffset, - int64_t aCount) +MediaCacheStream::ReadFromCache(char* aBuffer, int64_t aOffset, int64_t aCount) { ReentrantMonitorAutoEnter mon(gMediaCache->GetReentrantMonitor()); if (mClosed) @@ -2292,7 +2300,7 @@ MediaCacheStream::ReadFromCache(char* aBuffer, return NS_ERROR_FAILURE; } size = std::min(size, bytesRemaining); - // Clamp size until 64-bit file size issues (bug 500784) are fixed. + // Clamp size until 64-bit file size issues are fixed. size = std::min(size, int64_t(INT32_MAX)); } @@ -2303,7 +2311,10 @@ MediaCacheStream::ReadFromCache(char* aBuffer, // 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 // the cache. - bytes = std::min(size, mChannelOffset - streamOffset); + // Clamp bytes until 64-bit file size issues are fixed. + int64_t toCopy = std::min(size, mChannelOffset - streamOffset); + bytes = std::min(toCopy, int64_t(INT32_MAX)); + NS_ABORT_IF_FALSE(bytes >= 0 && bytes <= toCopy, "Bytes out of range."); memcpy(aBuffer + count, reinterpret_cast(mPartialBlockBuffer.get()) + offsetInStreamBlock, bytes); } else { Modified media/libnestegg/include/nestegg-stdint.h diff --git a/media/libnestegg/include/nestegg-stdint.h b/media/libnestegg/include/nestegg-stdint.h index 599a7a5..c315991 100644 --- a/media/libnestegg/include/nestegg-stdint.h +++ b/media/libnestegg/include/nestegg-stdint.h @@ -1,6 +1,9 @@ #ifdef _WIN32 typedef __int64 int64_t; typedef unsigned __int64 uint64_t; +#if !defined(INT64_MAX) +#define INT64_MAX 9223372036854775807LL +#endif #else #include #endif Modified media/libnestegg/src/nestegg.c diff --git a/media/libnestegg/src/nestegg.c b/media/libnestegg/src/nestegg.c index 8813cf2..56884d7 100644 --- a/media/libnestegg/src/nestegg.c +++ b/media/libnestegg/src/nestegg.c @@ -1950,6 +1950,9 @@ nestegg_offset_seek(nestegg * ctx, uint64_t offset) { int r; + if (offset > INT64_MAX) + return -1; + /* Seek and set up parser state for segment-level element (Cluster). */ r = ne_io_seek(ctx->io, offset, NESTEGG_SEEK_SET); if (r != 0)