From a6c6ea844262105dd8215e2384413bf00533a035 Mon Sep 17 00:00:00 2001 From: Paul Adenot Date: Tue, 8 Feb 2022 16:36:38 +0000 Subject: [PATCH] Bug 1749761 - Fix signed->unsigned conversion in the WAV demuxer. r=media-playback-reviewers,alwu Differential Revision: https://phabricator.services.mozilla.com/D135502 --- dom/media/wave/WaveDemuxer.cpp | 52 +++++++++++++++++++--------------- dom/media/wave/WaveDemuxer.h | 21 +++++++------- 2 files changed, 39 insertions(+), 34 deletions(-) diff --git a/dom/media/wave/WaveDemuxer.cpp b/dom/media/wave/WaveDemuxer.cpp index adaab68370ff..79cf124bc232 100644 --- a/dom/media/wave/WaveDemuxer.cpp +++ b/dom/media/wave/WaveDemuxer.cpp @@ -124,8 +124,16 @@ bool WAVTrackDemuxer::Init() { mHeaderParser.Reset(); } - if (mDataLength > StreamLength() - mFirstChunkOffset) { - mDataLength = StreamLength() - mFirstChunkOffset; + int64_t streamLength = StreamLength(); + // If the chunk length and the resource length are not equal, use the + // resource length as the "real" data chunk length, if it's longer than the + // chunk size. + if (streamLength != -1) { + uint64_t streamLengthPositive = static_cast(streamLength); + if (streamLengthPositive > mFirstChunkOffset && + mDataLength > streamLengthPositive - mFirstChunkOffset) { + mDataLength = streamLengthPositive - mFirstChunkOffset; + } } mSamplesPerSecond = mFmtParser.FmtChunk().SampleRate(); @@ -286,7 +294,7 @@ TimeUnit WAVTrackDemuxer::FastSeek(const TimeUnit& aTime) { mOffset = OffsetFromChunkIndex(mChunkIndex); if (mOffset > mFirstChunkOffset && StreamLength() > 0) { - mOffset = std::min(StreamLength() - 1, mOffset); + mOffset = std::min(static_cast(StreamLength() - 1), mOffset); } return Duration(mChunkIndex); @@ -390,9 +398,9 @@ TimeUnit WAVTrackDemuxer::DurationFromBytes(uint32_t aNumBytes) const { return TimeUnit(); } - int64_t numSamples = aNumBytes * 8 / mChannels / mSampleFormat; + uint64_t numSamples = aNumBytes * 8 / mChannels / mSampleFormat; - int64_t numUSeconds = USECS_PER_S * numSamples / mSamplesPerSecond; + uint64_t numUSeconds = USECS_PER_S * numSamples / mSamplesPerSecond; if (USECS_PER_S * numSamples % mSamplesPerSecond > mSamplesPerSecond / 2) { numUSeconds++; @@ -442,7 +450,7 @@ already_AddRefed WAVTrackDemuxer::GetNextChunk( datachunk->mOffset = aRange.mStart; UniquePtr chunkWriter(datachunk->CreateWriter()); - if (!chunkWriter->SetSize(aRange.Length())) { + if (!chunkWriter->SetSize(static_cast(aRange.Length()))) { return nullptr; } @@ -484,7 +492,7 @@ already_AddRefed WAVTrackDemuxer::GetFileHeader( fileHeader->mOffset = aRange.mStart; UniquePtr headerWriter(fileHeader->CreateWriter()); - if (!headerWriter->SetSize(aRange.Length())) { + if (!headerWriter->SetSize(static_cast(aRange.Length()))) { return nullptr; } @@ -500,33 +508,28 @@ already_AddRefed WAVTrackDemuxer::GetFileHeader( return fileHeader.forget(); } -int64_t WAVTrackDemuxer::OffsetFromChunkIndex(int64_t aChunkIndex) const { +uint64_t WAVTrackDemuxer::OffsetFromChunkIndex(uint32_t aChunkIndex) const { return mFirstChunkOffset + aChunkIndex * DATA_CHUNK_SIZE; } -int64_t WAVTrackDemuxer::ChunkIndexFromOffset(int64_t aOffset) const { - int64_t chunkIndex = (aOffset - mFirstChunkOffset) / DATA_CHUNK_SIZE; - return std::max(0, chunkIndex); -} - -int64_t WAVTrackDemuxer::ChunkIndexFromTime( +uint64_t WAVTrackDemuxer::ChunkIndexFromTime( const media::TimeUnit& aTime) const { if (!mSamplesPerChunk || !mSamplesPerSecond) { return 0; } - int64_t chunkIndex = + uint64_t chunkIndex = (aTime.ToSeconds() * mSamplesPerSecond / mSamplesPerChunk) - 1; return chunkIndex; } void WAVTrackDemuxer::UpdateState(const MediaByteRange& aRange) { // Full chunk parsed, move offset to its end. - mOffset = aRange.mEnd; - mTotalChunkLen += aRange.Length(); + mOffset = static_cast(aRange.mEnd); + mTotalChunkLen += static_cast(aRange.Length()); } -int32_t WAVTrackDemuxer::Read(uint8_t* aBuffer, int64_t aOffset, - int32_t aSize) { +uint32_t WAVTrackDemuxer::Read(uint8_t* aBuffer, int64_t aOffset, + int32_t aSize) { const int64_t streamLen = StreamLength(); if (mInfo && streamLen > 0) { int64_t max = streamLen > aOffset ? streamLen - aOffset : 0; @@ -536,7 +539,7 @@ int32_t WAVTrackDemuxer::Read(uint8_t* aBuffer, int64_t aOffset, const nsresult rv = mSource.ReadAt(aOffset, reinterpret_cast(aBuffer), static_cast(aSize), &read); NS_ENSURE_SUCCESS(rv, 0); - return static_cast(read); + return read; } // RIFFParser @@ -637,11 +640,13 @@ bool HeaderParser::ChunkHeader::IsValid() const { } uint32_t HeaderParser::ChunkHeader::ChunkName() const { - return ((mRaw[0] << 24) | (mRaw[1] << 16) | (mRaw[2] << 8) | (mRaw[3])); + return static_cast( + ((mRaw[0] << 24) | (mRaw[1] << 16) | (mRaw[2] << 8) | (mRaw[3]))); } uint32_t HeaderParser::ChunkHeader::ChunkSize() const { - return ((mRaw[7] << 24) | (mRaw[6] << 16) | (mRaw[5] << 8) | (mRaw[4])); + return static_cast( + ((mRaw[7] << 24) | (mRaw[6] << 16) | (mRaw[5] << 8) | (mRaw[4]))); } void HeaderParser::ChunkHeader::Update(uint8_t c) { @@ -689,7 +694,8 @@ uint16_t FormatParser::FormatChunk::Channels() const { } uint32_t FormatParser::FormatChunk::SampleRate() const { - return (mRaw[7] << 24) | (mRaw[6] << 16) | (mRaw[5] << 8) | (mRaw[4]); + return static_cast((mRaw[7] << 24) | (mRaw[6] << 16) | + (mRaw[5] << 8) | (mRaw[4])); } uint16_t FormatParser::FormatChunk::FrameSize() const { diff --git a/dom/media/wave/WaveDemuxer.h b/dom/media/wave/WaveDemuxer.h index f91bfb0da608..a7ab65c00259 100644 --- a/dom/media/wave/WaveDemuxer.h +++ b/dom/media/wave/WaveDemuxer.h @@ -229,11 +229,10 @@ class WAVTrackDemuxer : public MediaTrackDemuxer, void UpdateState(const MediaByteRange& aRange); - int64_t OffsetFromChunkIndex(int64_t aChunkIndex) const; - int64_t ChunkIndexFromOffset(int64_t aOffet) const; - int64_t ChunkIndexFromTime(const media::TimeUnit& aTime) const; + uint64_t OffsetFromChunkIndex(uint32_t aChunkIndex) const; + uint64_t ChunkIndexFromTime(const media::TimeUnit& aTime) const; - int32_t Read(uint8_t* aBuffer, int64_t aOffset, int32_t aSize); + uint32_t Read(uint8_t* aBuffer, int64_t aOffset, int32_t aSize); MediaResourceIndex mSource; @@ -244,20 +243,20 @@ class WAVTrackDemuxer : public MediaTrackDemuxer, FormatParser mFmtParser; // ListChunkParser mListChunkParser; - int64_t mOffset; - int64_t mFirstChunkOffset; + uint64_t mOffset; + uint64_t mFirstChunkOffset; uint32_t mNumParsedChunks; - int32_t mChunkIndex; + uint32_t mChunkIndex; uint32_t mDataLength; uint64_t mTotalChunkLen; - int32_t mSamplesPerChunk; - int32_t mSamplesPerSecond; + uint32_t mSamplesPerChunk; + uint32_t mSamplesPerSecond; - int32_t mChannels; - int32_t mSampleFormat; + uint32_t mChannels; + uint32_t mSampleFormat; UniquePtr mInfo; };