☠☠ backed out by 1db845973613 ☠ ☠ | |
author | Matthew Gregan <kinetik@flim.org> |
Tue, 11 Nov 2014 08:58:52 +1300 | |
changeset 214865 | 992ad9a82996555b404e14cc187cc60b766a4dd7 |
parent 214864 | d54ee2df476366f462a70171ea3a43407e19d456 |
child 214866 | dc2e15a7df8d327e2c359cf0bb4e899c9fc755a6 |
push id | 51587 |
push user | mgregan@mozilla.com |
push date | Mon, 10 Nov 2014 20:25:31 +0000 |
treeherder | mozilla-inbound@992ad9a82996 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | roc |
bugs | 1085175 |
milestone | 36.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/media/MediaCache.cpp +++ b/dom/media/MediaCache.cpp @@ -1168,16 +1168,17 @@ MediaCache::Update() MediaCacheStream* stream = mStreams[i]; if (stream->mClosed) continue; // 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; if (stream->mIsTransportSeekable) { if (desiredOffset > stream->mChannelOffset && desiredOffset <= stream->mChannelOffset + SEEK_VS_READ_THRESHOLD) { // Assume it's more efficient to just keep reading up to the // desired position instead of trying to seek @@ -1700,16 +1701,17 @@ MediaCacheStream::NotifyDataLength(int64 void MediaCacheStream::NotifyDataStarted(int64_t aOffset) { NS_ASSERTION(NS_IsMainThread(), "Only call on main thread"); 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 // the stream is at least that long. mStreamLength = std::max(mStreamLength, mChannelOffset); } } @@ -2129,33 +2131,38 @@ MediaCacheStream::Seek(int32_t aWhence, { NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread"); ReentrantMonitorAutoEnter mon(gMediaCache->GetReentrantMonitor()); if (mClosed) 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); gMediaCache->QueueUpdate(); return NS_OK; } int64_t @@ -2187,21 +2194,20 @@ MediaCacheStream::Read(char* aBuffer, ui if (mStreamLength >= 0) { // Don't try to read beyond the end of the stream int64_t bytesRemaining = mStreamLength - mStreamOffset; if (bytesRemaining <= 0) { // Get out of here and return NS_OK 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. if (count > 0) { // Some data has been read, so return what we've got instead of // blocking or trying to find a stream with a partial block. break; @@ -2219,17 +2225,20 @@ MediaCacheStream::Read(char* aBuffer, ui streamWithPartialBlock = stream; break; } } if (streamWithPartialBlock) { // 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<int64_t>(size, streamWithPartialBlock->mChannelOffset - mStreamOffset); + int64_t bytes = std::min<int64_t>(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<char*>(streamWithPartialBlock->mPartialBlockBuffer.get()) + offsetInStreamBlock, bytes); if (mCurrentMode == MODE_METADATA) { streamWithPartialBlock->mMetadataInPartialBlockBuffer = true; } mStreamOffset += bytes; count = bytes; break; @@ -2243,16 +2252,17 @@ MediaCacheStream::Read(char* aBuffer, ui return NS_ERROR_FAILURE; } continue; } 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)) { if (count == 0) return rv; // If we did successfully read some data, may as well return it break; } @@ -2279,19 +2289,17 @@ MediaCacheStream::ReadAt(int64_t aOffset ReentrantMonitorAutoEnter mon(gMediaCache->GetReentrantMonitor()); nsresult rv = Seek(nsISeekableStream::NS_SEEK_SET, aOffset); if (NS_FAILED(rv)) return rv; return Read(aBuffer, aCount, aBytes); } 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) return NS_ERROR_FAILURE; // Read one block (or part of a block) at a time uint32_t count = 0; int64_t streamOffset = aOffset; @@ -2303,28 +2311,31 @@ MediaCacheStream::ReadFromCache(char* aB if (mStreamLength >= 0) { // Don't try to read beyond the end of the stream int64_t bytesRemaining = mStreamLength - streamOffset; if (bytesRemaining <= 0) { 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)); } int32_t bytes; uint32_t channelBlock = uint32_t(mChannelOffset/BLOCK_SIZE); int32_t 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 // the cache. - bytes = std::min<int64_t>(size, mChannelOffset - streamOffset); + // Clamp bytes until 64-bit file size issues are fixed. + int64_t toCopy = std::min<int64_t>(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<char*>(mPartialBlockBuffer.get()) + offsetInStreamBlock, bytes); } else { if (cacheBlock < 0) { // We expect all blocks to be cached! Fail! return NS_ERROR_FAILURE; } int64_t offset = cacheBlock*BLOCK_SIZE + offsetInStreamBlock;
--- a/media/libnestegg/include/nestegg-stdint.h +++ b/media/libnestegg/include/nestegg-stdint.h @@ -1,7 +1,8 @@ #ifdef _WIN32 typedef __int64 int64_t; typedef unsigned __int64 uint64_t; +#define INT64_MAX 9223372036854775807LL #else #include <stdint.h> #endif
--- a/media/libnestegg/src/nestegg.c +++ b/media/libnestegg/src/nestegg.c @@ -2101,16 +2101,19 @@ nestegg_get_cue_point(nestegg * ctx, uns return 0; } int 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) return -1; ctx->last_valid = 0; while (ctx->ancestor) ne_ctx_pop(ctx);