diff --git a/dom/base/StructuredCloneHolder.cpp b/dom/base/StructuredCloneHolder.cpp index 71eab63138..a7afd310cb 100644 --- a/dom/base/StructuredCloneHolder.cpp +++ b/dom/base/StructuredCloneHolder.cpp @@ -1343,7 +1343,6 @@ StructuredCloneHolder::CustomReadTransferHandler(JSContext* aCx, static_cast(aContent); nsCOMPtr parent = do_QueryInterface(mParent); RefPtr canvas = OffscreenCanvas::CreateFromCloneData(parent, data); - delete data; JS::Rooted value(aCx); if (!GetOrCreateDOMReflector(aCx, canvas, &value)) { @@ -1351,6 +1350,7 @@ StructuredCloneHolder::CustomReadTransferHandler(JSContext* aCx, return false; } + delete data; aReturnObject.set(&value.toObject()); return true; } @@ -1363,7 +1363,6 @@ StructuredCloneHolder::CustomReadTransferHandler(JSContext* aCx, static_cast(aContent); nsCOMPtr parent = do_QueryInterface(mParent); RefPtr bitmap = ImageBitmap::CreateFromCloneData(parent, data); - delete data; JS::Rooted value(aCx); if (!GetOrCreateDOMReflector(aCx, bitmap, &value)) { @@ -1371,6 +1370,7 @@ StructuredCloneHolder::CustomReadTransferHandler(JSContext* aCx, return false; } + delete data; aReturnObject.set(&value.toObject()); return true; } diff --git a/dom/base/nsLineBreaker.cpp b/dom/base/nsLineBreaker.cpp index 02fb97b40e..07416ec90b 100644 --- a/dom/base/nsLineBreaker.cpp +++ b/dom/base/nsLineBreaker.cpp @@ -10,6 +10,7 @@ #include "nsHyphenationManager.h" #include "nsHyphenator.h" #include "mozilla/gfx/2D.h" +#include "mozilla/ScopeExit.h" nsLineBreaker::nsLineBreaker() : mCurrentWordLanguage(nullptr), @@ -57,6 +58,14 @@ SetupCapitalization(const char16_t* aWord, uint32_t aLength, nsresult nsLineBreaker::FlushCurrentWord() { + auto cleanup = mozilla::MakeScopeExit([&] { + mCurrentWord.Clear(); + mTextItems.Clear(); + mCurrentWordContainsComplexChar = false; + mCurrentWordContainsMixedLang = false; + mCurrentWordLanguage = nullptr; + }); + uint32_t length = mCurrentWord.Length(); AutoTArray breakState; if (!breakState.AppendElements(length)) @@ -137,11 +146,6 @@ nsLineBreaker::FlushCurrentWord() offset += ti->mLength; } - mCurrentWord.Clear(); - mTextItems.Clear(); - mCurrentWordContainsComplexChar = false; - mCurrentWordContainsMixedLang = false; - mCurrentWordLanguage = nullptr; return NS_OK; } diff --git a/dom/media/ADTSDemuxer.cpp b/dom/media/ADTSDemuxer.cpp index cc68a34947..16daac6d4e 100644 --- a/dom/media/ADTSDemuxer.cpp +++ b/dom/media/ADTSDemuxer.cpp @@ -5,12 +5,10 @@ #include "ADTSDemuxer.h" -#include - -#include "nsAutoPtr.h" -#include "VideoUtils.h" #include "TimeUnits.h" -#include "prenv.h" +#include "VideoUtils.h" +#include "mozilla/UniquePtr.h" +#include #ifdef PR_LOGGING extern mozilla::LazyLogModule gMediaDemuxerLog; @@ -160,11 +158,11 @@ public: } // Returns whether the valid - bool Parse(int64_t aOffset, uint8_t* aStart, uint8_t* aEnd) { + bool Parse(int64_t aOffset, const uint8_t* aStart, const uint8_t* aEnd) { MOZ_ASSERT(aStart && aEnd); bool found = false; - uint8_t* ptr = aStart; + const uint8_t* ptr = aStart; // Require at least 7 bytes of data at the end of the buffer for the minimum // ADTS frame header. while (ptr < aEnd - 7 && !found) { @@ -214,7 +212,7 @@ public: // if one was found. After returning, the variable passed to 'aBytesToSkip' holds // the amount of bytes to be skipped (if any) in order to jump across a large // ID3v2 tag spanning multiple buffers. - bool Parse(int64_t aOffset, uint8_t* aStart, uint8_t* aEnd) { + bool Parse(int64_t aOffset, const uint8_t* aStart, const uint8_t* aEnd) { const bool found = mFrame.Parse(aOffset, aStart, aEnd); if (mFrame.Length() && !mFirstFrame.Length()) { @@ -728,7 +726,7 @@ ADTSTrackDemuxer::GetNextFrame(const adts::Frame& aFrame) RefPtr frame = new MediaRawData(); frame->mOffset = offset; - nsAutoPtr frameWriter(frame->CreateWriter()); + UniquePtr frameWriter(frame->CreateWriter()); if (!frameWriter->SetSize(length)) { ADTSLOG("GetNext() Exit failed to allocated media buffer"); return nullptr; @@ -842,4 +840,30 @@ ADTSTrackDemuxer::AverageFrameLength() const return 0.0; } +/* static */ bool +ADTSDemuxer::ADTSSniffer(const uint8_t* aData, const uint32_t aLength) +{ + if (aLength < 7) { + return false; + } + // Avoid seeking if blob doesn't start with an ADTS marker. + if (!adts::FrameHeader::MatchesSync(aData)) { + return false; + } + auto parser = MakeUnique(); + + if (!parser->Parse(0, aData, aData + aLength)) { + return false; + } + const adts::Frame& currentFrame = parser->CurrentFrame(); + // Check for sync marker after the found frame, since it's + // possible to find sync marker in AAC data. If sync marker + // exists after the current frame then we've found a frame + // header. + int64_t nextFrameHeaderOffset = currentFrame.Offset() + currentFrame.Length(); + return int64_t(aLength) > nextFrameHeaderOffset && + aLength - nextFrameHeaderOffset >= 2 && + adts::FrameHeader::MatchesSync(aData + nextFrameHeaderOffset); +} + } // namespace mozilla diff --git a/dom/media/ADTSDemuxer.h b/dom/media/ADTSDemuxer.h index e1daa29e67..fcd3b1f272 100644 --- a/dom/media/ADTSDemuxer.h +++ b/dom/media/ADTSDemuxer.h @@ -32,6 +32,9 @@ public: TrackInfo::TrackType aType, uint32_t aTrackNumber) override; bool IsSeekable() const override; + // Return true if a valid ADTS frame header could be found. + static bool ADTSSniffer(const uint8_t* aData, const uint32_t aLength); + private: bool InitInternal(); diff --git a/netwerk/mime/nsMimeTypes.h b/netwerk/mime/nsMimeTypes.h index 7434db383c..41950a7e71 100644 --- a/netwerk/mime/nsMimeTypes.h +++ b/netwerk/mime/nsMimeTypes.h @@ -88,7 +88,7 @@ #define AUDIO_3GPP2 "audio/3gpp2" #define AUDIO_MIDI "audio/x-midi" #define AUDIO_MATROSKA "audio/x-matroska" -#define AUDIO_FLAC "audio/flac" +#define AUDIO_AAC "audio/aac" #define BINARY_OCTET_STREAM "binary/octet-stream" diff --git a/netwerk/protocol/http/nsHttpConnection.cpp b/netwerk/protocol/http/nsHttpConnection.cpp index 706dba7e3b..d889d73971 100644 --- a/netwerk/protocol/http/nsHttpConnection.cpp +++ b/netwerk/protocol/http/nsHttpConnection.cpp @@ -323,7 +323,8 @@ nsHttpConnection::StartSpdy(uint8_t spdyVersion) if (!mTLSFilter) { mTransaction = mSpdySession; } else { - mTLSFilter->SetProxiedTransaction(mSpdySession); + rv = mTLSFilter->SetProxiedTransaction(mSpdySession); + NS_ENSURE_SUCCESS_VOID(rv); } if (mDontReuse) { mSpdySession->DontReuse(); @@ -355,6 +356,7 @@ nsHttpConnection::EnsureNPNComplete(nsresult &aOut0RTTWriteHandshakeValue, nsCOMPtr securityInfo; nsCOMPtr ssl; nsAutoCString negotiatedNPN; + nsAutoCString transactionNPN; GetSecurityInfo(getter_AddRefs(securityInfo)); if (!securityInfo) { @@ -373,6 +375,18 @@ nsHttpConnection::EnsureNPNComplete(nsresult &aOut0RTTWriteHandshakeValue, } rv = ssl->GetNegotiatedNPN(negotiatedNPN); + + // Check if the connection NPN matches negotiated NPN. + transactionNPN = mConnInfo->GetNPNToken(); + LOG(("negotiatedNPN: %s - transactionNPN: %s", negotiatedNPN.get(), + transactionNPN.get())); + if (!transactionNPN.IsEmpty() && negotiatedNPN != transactionNPN) { + LOG(("Resetting connection due to mismatched NPN token")); + DontReuse(); + mTransaction->Close(NS_ERROR_NET_RESET); + return true; + } + if (!m0RTTChecked && (rv == NS_ERROR_NOT_CONNECTED) && !mConnInfo->UsingProxy()) { // There is no ALPN info (yet!). We need to consider doing 0RTT. We diff --git a/toolkit/components/mediasniffer/nsMediaSniffer.cpp b/toolkit/components/mediasniffer/nsMediaSniffer.cpp index dcf9e56e0b..d00dea894b 100644 --- a/toolkit/components/mediasniffer/nsMediaSniffer.cpp +++ b/toolkit/components/mediasniffer/nsMediaSniffer.cpp @@ -3,17 +3,18 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "nsMediaSniffer.h" -#include "nsIHttpChannel.h" -#include "nsString.h" -#include "nsMimeTypes.h" +#include "ADTSDemuxer.h" +#include "FlacDemuxer.h" #include "mozilla/ArrayUtils.h" #include "mozilla/ModuleUtils.h" #include "mp3sniff.h" #include "nestegg/nestegg.h" -#include "FlacDemuxer.h" - #include "nsIClassInfoImpl.h" +#include "nsIHttpChannel.h" +#include "nsMediaSniffer.h" +#include "nsMimeTypes.h" +#include "nsString.h" + #include // The minimum number of bytes that are needed to attempt to sniff an mp4 file. @@ -50,8 +51,8 @@ nsMediaSnifferEntry sFtypEntries[] = { PATTERN_ENTRY("\xFF\xFF\xFF\xFF", "mmp4", VIDEO_MP4), }; -static bool MatchesBrands(const uint8_t aData[4], nsACString& aSniffedType) -{ +static bool +MatchesBrands(const uint8_t aData[4], nsACString& aSniffedType) { for (size_t i = 0; i < mozilla::ArrayLength(sFtypEntries); ++i) { const auto& currentEntry = sFtypEntries[i]; bool matched = true; @@ -74,8 +75,8 @@ static bool MatchesBrands(const uint8_t aData[4], nsACString& aSniffedType) // This function implements sniffing algorithm for MP4 family file types, // including MP4 (described at http://mimesniff.spec.whatwg.org/#signature-for-mp4), // M4A (Apple iTunes audio), and 3GPP. -static bool MatchesMP4(const uint8_t* aData, const uint32_t aLength, nsACString& aSniffedType) -{ +static bool +MatchesMP4(const uint8_t* aData, const uint32_t aLength, nsACString& aSniffedType) { if (aLength <= MP4_MIN_BYTES_COUNT) { return false; } @@ -108,29 +109,33 @@ static bool MatchesMP4(const uint8_t* aData, const uint32_t aLength, nsACString& return false; } -static bool MatchesWebM(const uint8_t* aData, const uint32_t aLength) -{ +static bool +MatchesWebM(const uint8_t* aData, const uint32_t aLength) { return nestegg_sniff((uint8_t*)aData, aLength) ? true : false; } // This function implements mp3 sniffing based on parsing // packet headers and looking for expected boundaries. -static bool MatchesMP3(const uint8_t* aData, const uint32_t aLength) -{ +static bool +MatchesMP3(const uint8_t* aData, const uint32_t aLength) { return mp3_sniff(aData, (long)aLength); } -static bool MatchesFLAC(const uint8_t* aData, const uint32_t aLength) -{ +static bool +MatchesFLAC(const uint8_t* aData, const uint32_t aLength) { return mozilla::FlacDemuxer::FlacSniffer(aData, aLength); } +static bool MatchesADTS(const uint8_t* aData, const uint32_t aLength) +{ + return mozilla::ADTSDemuxer::ADTSSniffer(aData, aLength); +} + NS_IMETHODIMP nsMediaSniffer::GetMIMETypeFromContent(nsIRequest* aRequest, const uint8_t* aData, const uint32_t aLength, - nsACString& aSniffedType) -{ + nsACString& aSniffedType) { nsCOMPtr channel = do_QueryInterface(aRequest); if (channel) { nsLoadFlags loadFlags = 0; @@ -184,6 +189,13 @@ nsMediaSniffer::GetMIMETypeFromContent(nsIRequest* aRequest, return NS_OK; } + // Note: Sniff for ADTS content before flac. + // The flac decoder can easily produce false negatives. + if (MatchesADTS(aData, clampedLength)) { + aSniffedType.AssignLiteral(AUDIO_AAC); + return NS_OK; + } + // Flac frames are generally big, often in excess of 24kB. // Using a size of MAX_BYTES_SNIFFED effectively means that we will only // recognize flac content if it starts with a frame.