diff --git a/dom/encoding/EncodingUtils.cpp b/dom/encoding/EncodingUtils.cpp index 1272e506a5..2f148b719f 100644 --- a/dom/encoding/EncodingUtils.cpp +++ b/dom/encoding/EncodingUtils.cpp @@ -63,6 +63,7 @@ EncodingUtils::IsAsciiCompatible(const nsACString& aPreferredName) aPreferredName.LowerCaseEqualsLiteral("utf-16be") || aPreferredName.LowerCaseEqualsLiteral("utf-16le") || aPreferredName.LowerCaseEqualsLiteral("replacement") || + aPreferredName.LowerCaseEqualsLiteral("iso-2022-jp") || aPreferredName.LowerCaseEqualsLiteral("hz-gb-2312") || aPreferredName.LowerCaseEqualsLiteral("utf-7") || aPreferredName.LowerCaseEqualsLiteral("x-imap4-modified-utf7")); diff --git a/dom/media/AudioConverter.cpp b/dom/media/AudioConverter.cpp index ab9b11543d..6d4d583dc3 100644 --- a/dom/media/AudioConverter.cpp +++ b/dom/media/AudioConverter.cpp @@ -7,6 +7,7 @@ #include #include #include +#include "mozilla/CheckedInt.h" /* * Parts derived from MythTV AudioConvert Class @@ -262,8 +263,15 @@ AudioConverter::ResampleAudio(void* aOut, const void* aIn, size_t aFrames) if (!mResampler) { return 0; } - uint32_t outframes = ResampleRecipientFrames(aFrames); - uint32_t inframes = aFrames; + uint32_t outframes; + if (!ResampleRecipientFrames(aFrames, &outframes)) { + return 0; + } + CheckedUint32 inframesChecked(aFrames); + if (!inframesChecked.isValid()) { + return 0; + } + uint32_t inframes = inframesChecked.value(); int error; if (mOut.Format() == AudioConfig::FORMAT_FLT) { @@ -288,7 +296,7 @@ AudioConverter::ResampleAudio(void* aOut, const void* aIn, size_t aFrames) mResampler = nullptr; return 0; } - MOZ_ASSERT(inframes == aFrames, "Some frames will be dropped"); + MOZ_ASSERT(static_cast(inframes) == aFrames, "Some frames will be dropped"); return outframes; } @@ -373,17 +381,27 @@ AudioConverter::UpmixAudio(void* aOut, const void* aIn, size_t aFrames) const return aFrames; } -size_t -AudioConverter::ResampleRecipientFrames(size_t aFrames) const -{ +bool AudioConverter::ResampleRecipientFrames(size_t aFrames, + uint32_t* aOutFrames) const { if (!aFrames && mIn.Rate() != mOut.Rate()) { if (!mResampler) { - return 0; + *aOutFrames = 0; + return true; } // We drain by pushing in get_input_latency() samples of 0 aFrames = speex_resampler_get_input_latency(mResampler); } - return (uint64_t)aFrames * mOut.Rate() / mIn.Rate() + 1; + CheckedInt numerator = CheckedInt(aFrames) * mOut.Rate(); + if (!numerator.isValid()) { + return false; + } + CheckedUint32 outFrames(numerator.value() / mIn.Rate()); + outFrames += 1u; + if (!outFrames.isValid()) { + return false; + } + *aOutFrames = outFrames.value(); + return true; } size_t diff --git a/dom/media/AudioConverter.h b/dom/media/AudioConverter.h index 82817bf070..76219c852a 100644 --- a/dom/media/AudioConverter.h +++ b/dom/media/AudioConverter.h @@ -7,6 +7,7 @@ #define AudioConverter_h #include "MediaInfo.h" +#include "mozilla/CheckedInt.h" // Forward declaration typedef struct SpeexResamplerState_ SpeexResamplerState; @@ -163,9 +164,15 @@ public: AlignedBuffer* outputBuffer = &temp1; AlignedBuffer temp2; if (!frames || mOut.Rate() > mIn.Rate()) { + uint32_t resampledFrames; // We are upsampling or about to drain, we can't work in place. // Allocate another temporary buffer where the upsampling will occur. - if (!temp2.SetLength(FramesOutToSamples(ResampleRecipientFrames(frames)))) { + if (!ResampleRecipientFrames(frames, &resampledFrames)) { + return AudioDataBuffer(std::move(temp2)); + } + CheckedInt outputSamples = + CheckedInt(resampledFrames) * mOut.Channels(); + if (!outputSamples.isValid() || !temp2.SetLength(outputSamples.value())) { return AudioDataBuffer(Move(temp2)); } outputBuffer = &temp2; @@ -229,7 +236,7 @@ private: // Resampler context. SpeexResamplerState* mResampler; size_t ResampleAudio(void* aOut, const void* aIn, size_t aFrames); - size_t ResampleRecipientFrames(size_t aFrames) const; + bool ResampleRecipientFrames(size_t aFrames, uint32_t* aOutFrames) const; void RecreateResampler(); size_t DrainResampler(void* aOut); }; diff --git a/dom/media/webspeech/synth/SpeechSynthesis.cpp b/dom/media/webspeech/synth/SpeechSynthesis.cpp index 189e3590cc..e0ceac6c9f 100644 --- a/dom/media/webspeech/synth/SpeechSynthesis.cpp +++ b/dom/media/webspeech/synth/SpeechSynthesis.cpp @@ -293,6 +293,12 @@ SpeechSynthesis::ForceEnd() } } +void SpeechSynthesis::DisconnectFromOwner() { + Pause(); + Cancel(); + DOMEventTargetHelper::DisconnectFromOwner(); +} + NS_IMETHODIMP SpeechSynthesis::Observe(nsISupports* aSubject, const char* aTopic, const char16_t* aData) diff --git a/dom/media/webspeech/synth/SpeechSynthesis.h b/dom/media/webspeech/synth/SpeechSynthesis.h index 692ef73edb..55e7bb5df7 100644 --- a/dom/media/webspeech/synth/SpeechSynthesis.h +++ b/dom/media/webspeech/synth/SpeechSynthesis.h @@ -58,6 +58,8 @@ public: void GetVoices(nsTArray< RefPtr >& aResult); void ForceEnd(); + + void DisconnectFromOwner() override; IMPL_EVENT_HANDLER(voiceschanged) diff --git a/dom/media/webspeech/synth/nsSynthVoiceRegistry.cpp b/dom/media/webspeech/synth/nsSynthVoiceRegistry.cpp index dbcc77cecc..e81e470174 100644 --- a/dom/media/webspeech/synth/nsSynthVoiceRegistry.cpp +++ b/dom/media/webspeech/synth/nsSynthVoiceRegistry.cpp @@ -325,12 +325,12 @@ nsSynthVoiceRegistry::RemoveVoice(nsISpeechService* aService, (XRE_IsContentProcess()) ? "child" : "parent")); bool found = false; - VoiceData* retval = mUriVoiceMap.GetWeak(aUri, &found); + RefPtr retval = mUriVoiceMap.GetWeak(aUri, &found); - if(NS_WARN_IF(!(found))) { + if(NS_WARN_IF(!found)) { return NS_ERROR_NOT_AVAILABLE; } - if(NS_WARN_IF(!(aService == retval->mService))) { + if(NS_WARN_IF(aService != retval->mService)) { return NS_ERROR_INVALID_ARG; } diff --git a/extensions/universalchardet/src/base/moz.build b/extensions/universalchardet/src/base/moz.build index 62417f9ef4..c077affd0c 100644 --- a/extensions/universalchardet/src/base/moz.build +++ b/extensions/universalchardet/src/base/moz.build @@ -7,8 +7,6 @@ UNIFIED_SOURCES += [ 'CharDistribution.cpp', 'JpCntx.cpp', 'nsCharSetProber.cpp', - 'nsEscCharsetProber.cpp', - 'nsEscSM.cpp', 'nsEUCJPProber.cpp', 'nsLatin1Prober.cpp', 'nsMBCSGroupProber.cpp', diff --git a/extensions/universalchardet/src/base/nsEscCharsetProber.cpp b/extensions/universalchardet/src/base/nsEscCharsetProber.cpp deleted file mode 100644 index b4fbfeb00b..0000000000 --- a/extensions/universalchardet/src/base/nsEscCharsetProber.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * 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 "nsEscCharsetProber.h" -#include "nsUniversalDetector.h" - -nsEscCharSetProber::nsEscCharSetProber() -{ - mCodingSM = new nsCodingStateMachine(&ISO2022JPSMModel); - mState = eDetecting; - mDetectedCharset = nullptr; -} - -nsEscCharSetProber::~nsEscCharSetProber(void) -{ -} - -void nsEscCharSetProber::Reset(void) -{ - mState = eDetecting; - mCodingSM->Reset(); - mDetectedCharset = nullptr; -} - -nsProbingState nsEscCharSetProber::HandleData(const char* aBuf, uint32_t aLen) -{ - nsSMState codingState; - uint32_t i; - - for ( i = 0; i < aLen && mState == eDetecting; i++) - { - codingState = mCodingSM->NextState(aBuf[i]); - if (codingState == eItsMe) - { - mState = eFoundIt; - mDetectedCharset = mCodingSM->GetCodingStateMachine(); - return mState; - } - } - - return mState; -} - diff --git a/extensions/universalchardet/src/base/nsEscCharsetProber.h b/extensions/universalchardet/src/base/nsEscCharsetProber.h deleted file mode 100644 index 4507972d05..0000000000 --- a/extensions/universalchardet/src/base/nsEscCharsetProber.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * 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/. */ - -#ifndef nsEscCharSetProber_h__ -#define nsEscCharSetProber_h__ - -#include "nsCharSetProber.h" -#include "nsCodingStateMachine.h" -#include "nsAutoPtr.h" - -class nsEscCharSetProber: public nsCharSetProber { -public: - nsEscCharSetProber(); - virtual ~nsEscCharSetProber(void); - nsProbingState HandleData(const char* aBuf, uint32_t aLen); - const char* GetCharSetName() {return mDetectedCharset;} - nsProbingState GetState(void) {return mState;} - void Reset(void); - float GetConfidence(void){return (float)0.99;} - -protected: - void GetDistribution(uint32_t aCharLen, const char* aStr); - - nsAutoPtr mCodingSM; - nsProbingState mState; - const char * mDetectedCharset; -}; - -#endif /* nsEscCharSetProber_h__ */ - diff --git a/extensions/universalchardet/src/base/nsEscSM.cpp b/extensions/universalchardet/src/base/nsEscSM.cpp deleted file mode 100644 index 77a223fec3..0000000000 --- a/extensions/universalchardet/src/base/nsEscSM.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * 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 "nsCodingStateMachine.h" - -static const uint32_t ISO2022JP_cls [ 256 / 8 ] = { -PCK4BITS(2,0,0,0,0,0,0,0), // 00 - 07 -PCK4BITS(0,0,0,0,0,0,2,2), // 08 - 0f -PCK4BITS(0,0,0,0,0,0,0,0), // 10 - 17 -PCK4BITS(0,0,0,1,0,0,0,0), // 18 - 1f -PCK4BITS(0,0,0,0,7,0,0,0), // 20 - 27 -PCK4BITS(3,0,0,0,0,0,0,0), // 28 - 2f -PCK4BITS(0,0,0,0,0,0,0,0), // 30 - 37 -PCK4BITS(0,0,0,0,0,0,0,0), // 38 - 3f -PCK4BITS(6,0,4,0,8,0,0,0), // 40 - 47 -PCK4BITS(0,9,5,0,0,0,0,0), // 48 - 4f -PCK4BITS(0,0,0,0,0,0,0,0), // 50 - 57 -PCK4BITS(0,0,0,0,0,0,0,0), // 58 - 5f -PCK4BITS(0,0,0,0,0,0,0,0), // 60 - 67 -PCK4BITS(0,0,0,0,0,0,0,0), // 68 - 6f -PCK4BITS(0,0,0,0,0,0,0,0), // 70 - 77 -PCK4BITS(0,0,0,0,0,0,0,0), // 78 - 7f -PCK4BITS(2,2,2,2,2,2,2,2), // 80 - 87 -PCK4BITS(2,2,2,2,2,2,2,2), // 88 - 8f -PCK4BITS(2,2,2,2,2,2,2,2), // 90 - 97 -PCK4BITS(2,2,2,2,2,2,2,2), // 98 - 9f -PCK4BITS(2,2,2,2,2,2,2,2), // a0 - a7 -PCK4BITS(2,2,2,2,2,2,2,2), // a8 - af -PCK4BITS(2,2,2,2,2,2,2,2), // b0 - b7 -PCK4BITS(2,2,2,2,2,2,2,2), // b8 - bf -PCK4BITS(2,2,2,2,2,2,2,2), // c0 - c7 -PCK4BITS(2,2,2,2,2,2,2,2), // c8 - cf -PCK4BITS(2,2,2,2,2,2,2,2), // d0 - d7 -PCK4BITS(2,2,2,2,2,2,2,2), // d8 - df -PCK4BITS(2,2,2,2,2,2,2,2), // e0 - e7 -PCK4BITS(2,2,2,2,2,2,2,2), // e8 - ef -PCK4BITS(2,2,2,2,2,2,2,2), // f0 - f7 -PCK4BITS(2,2,2,2,2,2,2,2) // f8 - ff -}; - - -static const uint32_t ISO2022JP_st [ 9] = { -PCK4BITS(eStart, 3,eError,eStart,eStart,eStart,eStart,eStart),//00-07 -PCK4BITS(eStart,eStart,eError,eError,eError,eError,eError,eError),//08-0f -PCK4BITS(eError,eError,eError,eError,eItsMe,eItsMe,eItsMe,eItsMe),//10-17 -PCK4BITS(eItsMe,eItsMe,eItsMe,eItsMe,eItsMe,eItsMe,eError,eError),//18-1f -PCK4BITS(eError, 5,eError,eError,eError, 4,eError,eError),//20-27 -PCK4BITS(eError,eError,eError, 6,eItsMe,eError,eItsMe,eError),//28-2f -PCK4BITS(eError,eError,eError,eError,eError,eError,eItsMe,eItsMe),//30-37 -PCK4BITS(eError,eError,eError,eItsMe,eError,eError,eError,eError),//38-3f -PCK4BITS(eError,eError,eError,eError,eItsMe,eError,eStart,eStart) //40-47 -}; - -static const uint32_t ISO2022JPCharLenTable[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - -const SMModel ISO2022JPSMModel = { - {eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, ISO2022JP_cls }, - 10, - {eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, ISO2022JP_st }, - CHAR_LEN_TABLE(ISO2022JPCharLenTable), - "ISO-2022-JP", -}; diff --git a/extensions/universalchardet/src/base/nsUniversalDetector.cpp b/extensions/universalchardet/src/base/nsUniversalDetector.cpp index d272827b81..1cecfda61c 100644 --- a/extensions/universalchardet/src/base/nsUniversalDetector.cpp +++ b/extensions/universalchardet/src/base/nsUniversalDetector.cpp @@ -8,7 +8,6 @@ #include "nsUniversalDetector.h" #include "nsMBCSGroupProber.h" -#include "nsEscCharsetProber.h" #include "nsLatin1Prober.h" nsUniversalDetector::nsUniversalDetector() @@ -16,7 +15,6 @@ nsUniversalDetector::nsUniversalDetector() mDone = false; mBestGuess = -1; //illegal value as signal mInTag = false; - mEscCharSetProber = nullptr; mStart = true; mDetectedCharset = nullptr; @@ -33,8 +31,6 @@ nsUniversalDetector::~nsUniversalDetector() { for (int32_t i = 0; i < NUM_OF_CHARSET_PROBERS; i++) delete mCharSetProbers[i]; - - delete mEscCharSetProber; } void @@ -50,9 +46,6 @@ nsUniversalDetector::Reset() mInputState = ePureAscii; mLastChar = '\0'; - if (mEscCharSetProber) - mEscCharSetProber->Reset(); - uint32_t i; for (i = 0; i < NUM_OF_CHARSET_PROBERS; i++) if (mCharSetProbers[i]) @@ -117,12 +110,6 @@ nsresult nsUniversalDetector::HandleData(const char* aBuf, uint32_t aLen) //adjust state mInputState = eHighbyte; - //kill mEscCharSetProber if it is active - if (mEscCharSetProber) { - delete mEscCharSetProber; - mEscCharSetProber = nullptr; - } - //start multibyte and singlebyte charset prober if (nullptr == mCharSetProbers[0]) { @@ -140,12 +127,6 @@ nsresult nsUniversalDetector::HandleData(const char* aBuf, uint32_t aLen) } else { - //ok, just pure ascii so far - if ((ePureAscii == mInputState) && (aBuf[i] == '\033')) - { - //found escape character - mInputState = eEscAscii; - } mLastChar = aBuf[i]; } } @@ -153,19 +134,6 @@ nsresult nsUniversalDetector::HandleData(const char* aBuf, uint32_t aLen) nsProbingState st; switch (mInputState) { - case eEscAscii: - if (nullptr == mEscCharSetProber) { - mEscCharSetProber = new nsEscCharSetProber(); - if (nullptr == mEscCharSetProber) - return NS_ERROR_OUT_OF_MEMORY; - } - st = mEscCharSetProber->HandleData(aBuf, aLen); - if (st == eFoundIt) - { - mDone = true; - mDetectedCharset = mEscCharSetProber->GetCharSetName(); - } - break; case eHighbyte: for (i = 0; i < NUM_OF_CHARSET_PROBERS; i++) { @@ -231,8 +199,6 @@ void nsUniversalDetector::DataEnd() Report(mCharSetProbers[maxProber]->GetCharSetName()); } break; - case eEscAscii: - break; default: ; } diff --git a/extensions/universalchardet/src/base/nsUniversalDetector.h b/extensions/universalchardet/src/base/nsUniversalDetector.h index 345e74f9f9..d6025fc2dc 100644 --- a/extensions/universalchardet/src/base/nsUniversalDetector.h +++ b/extensions/universalchardet/src/base/nsUniversalDetector.h @@ -12,8 +12,7 @@ class nsCharSetProber; typedef enum { ePureAscii = 0, - eEscAscii = 1, - eHighbyte = 2 + eHighbyte = 1 } nsInputState; class nsUniversalDetector { @@ -37,7 +36,6 @@ protected: uint32_t mLanguageFilter; nsCharSetProber *mCharSetProbers[NUM_OF_CHARSET_PROBERS]; - nsCharSetProber *mEscCharSetProber; }; #endif diff --git a/gfx/thebes/gfxTextRun.cpp b/gfx/thebes/gfxTextRun.cpp index c715e69f80..79f4cfacc8 100644 --- a/gfx/thebes/gfxTextRun.cpp +++ b/gfx/thebes/gfxTextRun.cpp @@ -147,7 +147,6 @@ gfxTextRun::gfxTextRun(const gfxTextRunFactory::Parameters *aParams, : gfxShapedText(aLength, aFlags, aParams->mAppUnitsPerDevUnit) , mUserData(aParams->mUserData) , mFontGroup(aFontGroup) - , mReleasedFontGroup(false) , mShapingState(eShapingState_Normal) { NS_ASSERTION(mAppUnitsPerDevUnit > 0, "Invalid app unit scale"); @@ -184,30 +183,18 @@ gfxTextRun::~gfxTextRun() mFlags = 0xFFFFFFFF; #endif - // The cached ellipsis textrun (if any) in a fontgroup will have already - // been told to release its reference to the group, so we mustn't do that - // again here. - if (!mReleasedFontGroup) { #ifdef DEBUG - gfxTextPerfMetrics *tp = mFontGroup->GetTextPerfMetrics(); - if (tp) { - tp->current.textrunDestr++; - } -#endif - NS_RELEASE(mFontGroup); + gfxTextPerfMetrics* tp = mFontGroup->GetTextPerfMetrics(); + if (tp) { + tp->current.textrunDestr++; } +#endif + + NS_RELEASE(mFontGroup); MOZ_COUNT_DTOR(gfxTextRun); } -void -gfxTextRun::ReleaseFontGroup() -{ - NS_ASSERTION(!mReleasedFontGroup, "doubly released!"); - NS_RELEASE(mFontGroup); - mReleasedFontGroup = true; -} - bool gfxTextRun::SetPotentialLineBreaks(Range aRange, const uint8_t* aBreakBefore) { @@ -2541,17 +2528,11 @@ gfxFontGroup::InitScriptRun(DrawTarget* aDrawTarget, } } -gfxTextRun * -gfxFontGroup::GetEllipsisTextRun(int32_t aAppUnitsPerDevPixel, uint32_t aFlags, - LazyReferenceDrawTargetGetter& aRefDrawTargetGetter) -{ +already_AddRefed +gfxFontGroup::MakeEllipsisTextRun(int32_t aAppUnitsPerDevPixel, uint32_t aFlags, + DrawTarget* aRefDrawTarget) { MOZ_ASSERT(!(aFlags & ~TEXT_ORIENT_MASK), "flags here should only be used to specify orientation"); - if (mCachedEllipsisTextRun && - (mCachedEllipsisTextRun->GetFlags() & TEXT_ORIENT_MASK) == aFlags && - mCachedEllipsisTextRun->GetAppUnitsPerDevUnit() == aAppUnitsPerDevPixel) { - return mCachedEllipsisTextRun.get(); - } // Use a Unicode ellipsis if the font supports it, // otherwise use three ASCII periods as fallback. @@ -2562,20 +2543,11 @@ gfxFontGroup::GetEllipsisTextRun(int32_t aAppUnitsPerDevPixel, uint32_t aFlags, : nsDependentString(kASCIIPeriodsChar, ArrayLength(kASCIIPeriodsChar) - 1); - RefPtr refDT = aRefDrawTargetGetter.GetRefDrawTarget(); Parameters params = { - refDT, nullptr, nullptr, nullptr, 0, aAppUnitsPerDevPixel + aRefDrawTarget, nullptr, nullptr, nullptr, 0, aAppUnitsPerDevPixel }; - mCachedEllipsisTextRun = - MakeTextRun(ellipsis.get(), ellipsis.Length(), ¶ms, - aFlags | TEXT_IS_PERSISTENT, nullptr); - if (!mCachedEllipsisTextRun) { - return nullptr; - } - // don't let the presence of a cached ellipsis textrun prolong the - // fontgroup's life - mCachedEllipsisTextRun->ReleaseFontGroup(); - return mCachedEllipsisTextRun.get(); + return MakeTextRun(ellipsis.get(), ellipsis.Length(), ¶ms, + aFlags | TEXT_IS_PERSISTENT, nullptr); } already_AddRefed diff --git a/gfx/thebes/gfxTextRun.h b/gfx/thebes/gfxTextRun.h index 8189861756..c63365cb0f 100644 --- a/gfx/thebes/gfxTextRun.h +++ b/gfx/thebes/gfxTextRun.h @@ -755,8 +755,6 @@ private: bool mSkipDrawing; // true if the font group we used had a user font // download that's in progress, so we should hide text // until the download completes (or timeout fires) - bool mReleasedFontGroup; // we already called NS_RELEASE on - // mFontGroup, so don't do it again // shaping state for handling variant fallback features // such as subscript/superscript variant glyphs @@ -897,7 +895,6 @@ public: mUnderlineOffset = UNDERLINE_OFFSET_NOT_SET; mSkipDrawing = false; mHyphenWidth = -1; - mCachedEllipsisTextRun = nullptr; } // If there is a user font set, check to see whether the font list or any @@ -911,17 +908,11 @@ public: return mSkipDrawing; } - class LazyReferenceDrawTargetGetter { - public: - virtual already_AddRefed GetRefDrawTarget() = 0; - }; - // The gfxFontGroup keeps ownership of this textrun. - // It is only guaranteed to exist until the next call to GetEllipsisTextRun - // (which might use a different appUnitsPerDev value or flags) for the font - // group, or until UpdateUserFonts is called, or the fontgroup is destroyed. - // Get it/use it/forget it :) - don't keep a reference that might go stale. - gfxTextRun* GetEllipsisTextRun(int32_t aAppUnitsPerDevPixel, uint32_t aFlags, - LazyReferenceDrawTargetGetter& aRefDrawTargetGetter); + // Make a textrun for the ellipsis character (with fallback to "..." if + // ellipsis is not supported by the font). + already_AddRefed MakeEllipsisTextRun(int32_t aAppUnitsPerDevPixel, + uint32_t aFlags, + DrawTarget* aRefDrawTarget); protected: // search through pref fonts for a character, return nullptr if no matching pref font @@ -1093,10 +1084,6 @@ protected: gfxTextPerfMetrics *mTextPerf; - // Cache a textrun representing an ellipsis (useful for CSS text-overflow) - // at a specific appUnitsPerDevPixel size and orientation - RefPtr mCachedEllipsisTextRun; - // cache the most recent pref font to avoid general pref font lookup RefPtr mLastPrefFamily; RefPtr mLastPrefFont; diff --git a/layout/base/AccessibleCaretManager.cpp b/layout/base/AccessibleCaretManager.cpp index 4dd55009cc..eb40256f53 100644 --- a/layout/base/AccessibleCaretManager.cpp +++ b/layout/base/AccessibleCaretManager.cpp @@ -404,11 +404,21 @@ AccessibleCaretManager::UpdateCaretsForSelectionMode(UpdateCaretsHint aHint) if (firstCaretResult == PositionChangedResult::Changed || secondCaretResult == PositionChangedResult::Changed) { + nsWeakFrame weakStartFrame = startFrame; + nsWeakFrame weakEndFrame = endFrame; + // Flush layout to make the carets intersection correct. FlushLayout(); if (IsTerminated()) { return; } + if ((startFrame && !weakStartFrame.IsAlive()) || + (endFrame && !weakEndFrame.IsAlive())) { + mFirstCaret.get()->SetAppearance(Appearance::NormalNotShown); + mSecondCaret.get()->SetAppearance(Appearance::NormalNotShown); + DispatchCaretStateChangedEvent(CaretChangedReason::Visibilitychange); + return; + } } if (aHint == UpdateCaretsHint::Default) { diff --git a/layout/generic/TextOverflow.cpp b/layout/generic/TextOverflow.cpp index 3d78eaf911..6827b4f29a 100644 --- a/layout/generic/TextOverflow.cpp +++ b/layout/generic/TextOverflow.cpp @@ -27,34 +27,15 @@ namespace mozilla { namespace css { -class LazyReferenceRenderingDrawTargetGetterFromFrame final : - public gfxFontGroup::LazyReferenceDrawTargetGetter { -public: - typedef mozilla::gfx::DrawTarget DrawTarget; - - explicit LazyReferenceRenderingDrawTargetGetterFromFrame(nsIFrame* aFrame) - : mFrame(aFrame) {} - virtual already_AddRefed GetRefDrawTarget() override - { - RefPtr ctx = - mFrame->PresContext()->PresShell()->CreateReferenceRenderingContext(); - RefPtr dt = ctx->GetDrawTarget(); - return dt.forget(); - } -private: - nsIFrame* mFrame; -}; - -static gfxTextRun* -GetEllipsisTextRun(nsIFrame* aFrame) +static already_AddRefed +MakeEllipsisTextRun(nsIFrame* aFrame) { - RefPtr fm = - nsLayoutUtils::GetInflatedFontMetricsForFrame(aFrame); - LazyReferenceRenderingDrawTargetGetterFromFrame lazyRefDrawTargetGetter(aFrame); - return fm->GetThebesFontGroup()->GetEllipsisTextRun( + RefPtr fm = nsLayoutUtils::GetInflatedFontMetricsForFrame(aFrame); + RefPtr ctx = aFrame->PresContext()->PresShell()->CreateReferenceRenderingContext(); + return fm->GetThebesFontGroup()->MakeEllipsisTextRun( aFrame->PresContext()->AppUnitsPerDevPixel(), nsLayoutUtils::GetTextRunOrientFlagsForStyle(aFrame->StyleContext()), - lazyRefDrawTargetGetter); + ctx->GetDrawTarget()); } static nsIFrame* @@ -166,16 +147,22 @@ public: nsDisplayTextOverflowMarker(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, const nsRect& aRect, nscoord aAscent, const nsStyleTextOverflowSide* aStyle, - uint32_t aIndex) - : nsDisplayItem(aBuilder, aFrame), mRect(aRect), - mStyle(aStyle), mAscent(aAscent), mIndex(aIndex) { + uint32_t aIndex, gfxTextRun* aTextRun) + : nsDisplayItem(aBuilder, aFrame) + , mRect(aRect) + , mStyle(aStyle) + , mAscent(aAscent) + , mIndex(aIndex) + , mTextRun(aTextRun) { MOZ_COUNT_CTOR(nsDisplayTextOverflowMarker); } + #ifdef NS_BUILD_REFCNT_LOGGING virtual ~nsDisplayTextOverflowMarker() { MOZ_COUNT_DTOR(nsDisplayTextOverflowMarker); } #endif + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) override { *aSnap = false; @@ -208,10 +195,11 @@ public: nsPoint aOffsetFromRect); NS_DISPLAY_DECL_NAME("TextOverflow", TYPE_TEXT_OVERFLOW) private: - nsRect mRect; // in reference frame coordinates + nsRect mRect; // in reference frame coordinates const nsStyleTextOverflowSide* mStyle; nscoord mAscent; // baseline for the marker text in mRect uint32_t mIndex; + RefPtr mTextRun; // pre-cached textrun, if available }; static void @@ -259,21 +247,18 @@ nsDisplayTextOverflowMarker::PaintTextToContext(nsRenderingContext* aCtx, } pt += aOffsetFromRect; - if (mStyle->mType == NS_STYLE_TEXT_OVERFLOW_ELLIPSIS) { - gfxTextRun* textRun = GetEllipsisTextRun(mFrame); - if (textRun) { - NS_ASSERTION(!textRun->IsRightToLeft(), - "Ellipsis textruns should always be LTR!"); - gfxPoint gfxPt(pt.x, pt.y); - textRun->Draw(gfxTextRun::Range(textRun), gfxPt, - gfxTextRun::DrawParams(aCtx->ThebesContext())); - } - } else { - RefPtr fm = - nsLayoutUtils::GetInflatedFontMetricsForFrame(mFrame); - nsLayoutUtils::DrawString(mFrame, *fm, aCtx, mStyle->mString.get(), - mStyle->mString.Length(), pt); + if (mTextRun) { + gfxPoint gfxPt(pt.x, pt.y); + mTextRun->Draw(gfxTextRun::Range(mTextRun), gfxPt, + gfxTextRun::DrawParams(aCtx->ThebesContext())); + return; } + + MOZ_ASSERT(mStyle->mType != NS_STYLE_TEXT_OVERFLOW_ELLIPSIS); + RefPtr fm = + nsLayoutUtils::GetInflatedFontMetricsForFrame(mFrame); + nsLayoutUtils::DrawString(mFrame, *fm, aCtx, mStyle->mString.get(), + mStyle->mString.Length(), pt); } TextOverflow::TextOverflow(nsDisplayListBuilder* aBuilder, @@ -784,7 +769,10 @@ TextOverflow::CreateMarkers(const nsLineBox* aLine, markerRect, clipState); nsDisplayItem* marker = new (mBuilder) nsDisplayTextOverflowMarker(mBuilder, mBlock, markerRect, - aLine->GetLogicalAscent(), mIStart.mStyle, 0); + aLine->GetLogicalAscent(), mIStart.mStyle, 0, + mIStart.mStyle->mType == NS_STYLE_TEXT_OVERFLOW_ELLIPSIS ? + GetEllipsisTextRun() : + nullptr); mMarkerList.AppendNewToTop(marker); } @@ -801,11 +789,21 @@ TextOverflow::CreateMarkers(const nsLineBox* aLine, markerRect, clipState); nsDisplayItem* marker = new (mBuilder) nsDisplayTextOverflowMarker(mBuilder, mBlock, markerRect, - aLine->GetLogicalAscent(), mIEnd.mStyle, 1); + aLine->GetLogicalAscent(), mIEnd.mStyle, 1, + mIEnd.mStyle->mType == NS_STYLE_TEXT_OVERFLOW_ELLIPSIS ? + GetEllipsisTextRun() : + nullptr); mMarkerList.AppendNewToTop(marker); } } +gfxTextRun* TextOverflow::GetEllipsisTextRun() { + if (!mEllipsisTextRun) { + mEllipsisTextRun = MakeEllipsisTextRun(mBlock); + } + return mEllipsisTextRun; +} + void TextOverflow::Marker::SetupString(nsIFrame* aFrame) { @@ -814,7 +812,7 @@ TextOverflow::Marker::SetupString(nsIFrame* aFrame) } if (mStyle->mType == NS_STYLE_TEXT_OVERFLOW_ELLIPSIS) { - gfxTextRun* textRun = GetEllipsisTextRun(aFrame); + RefPtr textRun = MakeEllipsisTextRun(aFrame); if (textRun) { mISize = textRun->GetAdvanceWidth(); } else { diff --git a/layout/generic/TextOverflow.h b/layout/generic/TextOverflow.h index 5c20ba68c2..9700f83a16 100644 --- a/layout/generic/TextOverflow.h +++ b/layout/generic/TextOverflow.h @@ -203,6 +203,8 @@ class TextOverflow { bool aCreateIStart, bool aCreateIEnd, const LogicalRect& aInsideMarkersArea); + gfxTextRun* GetEllipsisTextRun(); + LogicalRect mContentArea; nsDisplayListBuilder* mBuilder; nsIFrame* mBlock; @@ -250,6 +252,8 @@ class TextOverflow { Marker mIStart; // the inline start marker Marker mIEnd; // the inline end marker + + RefPtr mEllipsisTextRun; // Cached ellipsis textrun, if available }; } // namespace css diff --git a/media/ffvpx/README_MCP b/media/ffvpx/README_MCP index f87750c446..e6b817f29d 100644 --- a/media/ffvpx/README_MCP +++ b/media/ffvpx/README_MCP @@ -41,3 +41,8 @@ Run in the ffmpeg original tree: $ for i in `cat $PATH_CENTRAL/media/ffvpx/FILES`; do diff $REV_LASTSYNC HEAD >> patch.diff; done Then apply patch.diff on the ffvpx tree. Compilation will reveal if any files are missing. + +======================== + +After updating, apply patches: +flac-alloc-failure.patch fix leak in flac decoder in case of alloc failure diff --git a/media/ffvpx/flac-alloc-failure.patch b/media/ffvpx/flac-alloc-failure.patch new file mode 100644 index 0000000000..61330f2761 --- /dev/null +++ b/media/ffvpx/flac-alloc-failure.patch @@ -0,0 +1,25 @@ +diff --git a/media/ffvpx/libavcodec/flacdec.c b/media/ffvpx/libavcodec/flacdec.c +index 3d41a1af7f..8189d6af53 100644 +--- a/media/ffvpx/libavcodec/flacdec.c ++++ b/media/ffvpx/libavcodec/flacdec.c +@@ -146,8 +146,10 @@ static int allocate_buffers(FLACContext *s) + return buf_size; + + av_fast_malloc(&s->decoded_buffer, &s->decoded_buffer_size, buf_size); +- if (!s->decoded_buffer) ++ if (!s->decoded_buffer) { ++ memset(s->decoded, 0, sizeof(s->decoded)); + return AVERROR(ENOMEM); ++ } + + ret = av_samples_fill_arrays((uint8_t **)s->decoded, NULL, + s->decoded_buffer, +@@ -525,7 +527,7 @@ static int decode_frame(FLACContext *s) + fi.samplerate = s->flac_stream_info.samplerate; + s->flac_stream_info.samplerate = s->avctx->sample_rate = fi.samplerate; + +- if (!s->got_streaminfo) { ++ if (!s->got_streaminfo || !s->decoded_buffer) { + ret = allocate_buffers(s); + if (ret < 0) + return ret; diff --git a/media/ffvpx/libavcodec/flacdec.c b/media/ffvpx/libavcodec/flacdec.c index 42546728be..36fe29f65a 100644 --- a/media/ffvpx/libavcodec/flacdec.c +++ b/media/ffvpx/libavcodec/flacdec.c @@ -146,8 +146,10 @@ static int allocate_buffers(FLACContext *s) return buf_size; av_fast_malloc(&s->decoded_buffer, &s->decoded_buffer_size, buf_size); - if (!s->decoded_buffer) + if (!s->decoded_buffer) { + memset(s->decoded, 0, sizeof(s->decoded)); return AVERROR(ENOMEM); + } ret = av_samples_fill_arrays((uint8_t **)s->decoded, NULL, s->decoded_buffer, @@ -525,7 +527,7 @@ static int decode_frame(FLACContext *s) fi.samplerate = s->flac_stream_info.samplerate; s->flac_stream_info.samplerate = s->avctx->sample_rate = fi.samplerate; - if (!s->got_streaminfo) { + if (!s->got_streaminfo || !s->decoded_buffer) { ret = allocate_buffers(s); if (ret < 0) return ret; diff --git a/media/libvorbis/lib/vorbis_sharedbook.c b/media/libvorbis/lib/vorbis_sharedbook.c index 444f42b5aa..137486e540 100644 --- a/media/libvorbis/lib/vorbis_sharedbook.c +++ b/media/libvorbis/lib/vorbis_sharedbook.c @@ -352,9 +352,13 @@ int vorbis_book_init_decode(codebook *c,const static_codebook *s){ /* perform sort */ ogg_uint32_t *codes=_make_words(s->lengthlist,s->entries,c->used_entries); - ogg_uint32_t **codep=alloca(sizeof(*codep)*n); + ogg_uint32_t **codep=_ogg_malloc(sizeof(*codep)*n); - if(codes==NULL)goto err_out; + if(codes==NULL || codep==NULL){ + if(codes)_ogg_free(codes); + if(codep)_ogg_free(codep); + goto err_out; + } for(i=0;icodelist=_ogg_malloc(n*sizeof(*c->codelist)); + if(c->codelist==NULL){ + _ogg_free(sortindex); + _ogg_free(codep); + _ogg_free(codes); + goto err_out; + } /* the index is a reverse index */ for(i=0;icodelist[sortindex[i]]=codes[i]; @@ -377,12 +393,20 @@ int vorbis_book_init_decode(codebook *c,const static_codebook *s){ c->valuelist=_book_unquantize(s,n,sortindex); c->dec_index=_ogg_malloc(n*sizeof(*c->dec_index)); + if(c->dec_index==NULL){ + _ogg_free(sortindex); + goto err_out; + } for(n=0,i=0;ientries;i++) if(s->lengthlist[i]>0) c->dec_index[sortindex[n++]]=i; c->dec_codelengths=_ogg_malloc(n*sizeof(*c->dec_codelengths)); + if(c->dec_codelengths==NULL){ + _ogg_free(sortindex); + goto err_out; + } c->dec_maxlength=0; for(n=0,i=0;ientries;i++) if(s->lengthlist[i]>0){ @@ -390,6 +414,7 @@ int vorbis_book_init_decode(codebook *c,const static_codebook *s){ if(s->lengthlist[i]>c->dec_maxlength) c->dec_maxlength=s->lengthlist[i]; } + _ogg_free(sortindex); if(n==1 && c->dec_maxlength==1){ /* special case the 'single entry codebook' with a single bit @@ -397,6 +422,7 @@ int vorbis_book_init_decode(codebook *c,const static_codebook *s){ unmodified decode paths. */ c->dec_firsttablen=1; c->dec_firsttable=_ogg_calloc(2,sizeof(*c->dec_firsttable)); + if(c->dec_firsttable==NULL)goto err_out; c->dec_firsttable[0]=c->dec_firsttable[1]=1; }else{ @@ -406,6 +432,7 @@ int vorbis_book_init_decode(codebook *c,const static_codebook *s){ tabn=1<dec_firsttablen; c->dec_firsttable=_ogg_calloc(tabn,sizeof(*c->dec_firsttable)); + if(c->dec_firsttable==NULL)goto err_out; for(i=0;idec_codelengths[i]<=c->dec_firsttablen){ diff --git a/netwerk/base/nsFileStreams.cpp b/netwerk/base/nsFileStreams.cpp index 5a82dea1bf..cf4c1f8d58 100644 --- a/netwerk/base/nsFileStreams.cpp +++ b/netwerk/base/nsFileStreams.cpp @@ -5,6 +5,8 @@ #include "ipc/IPCMessageUtils.h" +#include + #if defined(XP_UNIX) #include #elif defined(XP_WIN) @@ -235,7 +237,8 @@ nsFileStreamBase::Read(char* aBuf, uint32_t aCount, uint32_t* aResult) return NS_OK; } - int32_t bytesRead = PR_Read(mFD, aBuf, aCount); + MOZ_ASSERT(aCount <= INT32_MAX); + int32_t bytesRead = PR_Read(mFD, aBuf, std::min(aCount, INT32_MAX)); if (bytesRead == -1) { return NS_ErrorAccordingToNSPR(); } @@ -291,7 +294,8 @@ nsFileStreamBase::Write(const char *buf, uint32_t count, uint32_t *result) if (mFD == nullptr) return NS_BASE_STREAM_CLOSED; - int32_t cnt = PR_Write(mFD, buf, count); + MOZ_ASSERT(count <= INT32_MAX); + int32_t cnt = PR_Write(mFD, buf, std::min(count, INT32_MAX)); if (cnt == -1) { return NS_ErrorAccordingToNSPR(); } diff --git a/security/nss/lib/certhigh/certhigh.c b/security/nss/lib/certhigh/certhigh.c index 7ae80b193e..18956e18e4 100644 --- a/security/nss/lib/certhigh/certhigh.c +++ b/security/nss/lib/certhigh/certhigh.c @@ -1035,7 +1035,7 @@ CERT_CertChainFromCert(CERTCertificate *cert, SECCertUsage usage, NSSCertificate *stanCert; PLArenaPool *arena; NSSUsage nssUsage; - int i, len; + int i = 0, len; NSSTrustDomain *td = STAN_GetDefaultTrustDomain(); NSSCryptoContext *cc = STAN_GetDefaultCryptoContext(); @@ -1072,7 +1072,6 @@ CERT_CertChainFromCert(CERTCertificate *cert, SECCertUsage usage, chain->certs = (SECItem *)PORT_ArenaAlloc(arena, len * sizeof(SECItem)); if (!chain->certs) goto loser; - i = 0; stanCert = stanChain[i]; while (stanCert) { SECItem derCert; @@ -1084,7 +1083,7 @@ CERT_CertChainFromCert(CERTCertificate *cert, SECCertUsage usage, derCert.data = (unsigned char *)stanCert->encoding.data; derCert.type = siBuffer; if (SECITEM_CopyItem(arena, &chain->certs[i], &derCert) != SECSuccess) { - CERT_DestroyCertificate(cCert); + /* loser: will release stanChain[i]; don't release it here too. */ goto loser; } stanCert = stanChain[++i]; @@ -1106,7 +1105,9 @@ CERT_CertChainFromCert(CERTCertificate *cert, SECCertUsage usage, nss_ZFreeIf(stanChain); return chain; loser: - i = 0; + /* Release only the chain entries not already released by the copy + * loop above; entries 0..i-1 have already had their BuildChain + * reference dropped, so start at i to avoid an over-release. */ stanCert = stanChain[i]; while (stanCert) { CERTCertificate *cCert = STAN_GetCERTCertificate(stanCert); diff --git a/security/nss/lib/pk11wrap/pk11obj.c b/security/nss/lib/pk11wrap/pk11obj.c index d26351ad25..bec2aeb920 100644 --- a/security/nss/lib/pk11wrap/pk11obj.c +++ b/security/nss/lib/pk11wrap/pk11obj.c @@ -840,11 +840,11 @@ PK11_SignWithMechanism(SECKEYPrivateKey *key, CK_MECHANISM_TYPE mechanism, if (haslock) PK11_ExitSlotMonitor(slot); pk11_CloseSession(slot, session, owner); - sig->len = len; if (crv != CKR_OK) { PORT_SetError(PK11_MapError(crv)); return SECFailure; } + sig->len = len; return SECSuccess; } @@ -888,11 +888,11 @@ PK11_SignWithSymKey(PK11SymKey *symKey, CK_MECHANISM_TYPE mechanism, if (haslock) PK11_ExitSlotMonitor(slot); pk11_CloseSession(slot, session, owner); - sig->len = len; if (crv != CKR_OK) { PORT_SetError(PK11_MapError(crv)); return SECFailure; } + sig->len = len; return SECSuccess; } diff --git a/security/nss/lib/softoken/pkcs11c.c b/security/nss/lib/softoken/pkcs11c.c index 464bc43c3b..8b3605e1e0 100644 --- a/security/nss/lib/softoken/pkcs11c.c +++ b/security/nss/lib/softoken/pkcs11c.c @@ -3111,7 +3111,7 @@ NSC_SignFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, { SFTKSession *session; SFTKSessionContext *context; - unsigned int outlen; + unsigned int outlen = 0; unsigned int maxoutlen = *pulSignatureLen; CK_RV crv; diff --git a/toolkit/modules/CharsetMenu.jsm b/toolkit/modules/CharsetMenu.jsm index f6479c0248..64e0575278 100644 --- a/toolkit/modules/CharsetMenu.jsm +++ b/toolkit/modules/CharsetMenu.jsm @@ -25,8 +25,7 @@ const kAutoDetectors = [ /** * This set contains encodings that are in the Encoding Standard, except: - * - XSS-dangerous encodings (except ISO-2022-JP which is assumed to be - * too common not to be included). + * - XSS-dangerous encodings. * - x-user-defined, which practically never makes sense as an end-user-chosen * override. * - Encodings that IE11 doesn't have in its correspoding menu. @@ -65,7 +64,7 @@ const kEncodings = new Set([ // Japanese "Shift_JIS", "EUC-JP", - "ISO-2022-JP", + // "ISO-2022-JP", // Intentionally not in menu. // Korean "EUC-KR", // Thai