diff options
Diffstat (limited to 'dom')
-rw-r--r-- | dom/base/nsContentUtils.cpp | 102 | ||||
-rw-r--r-- | dom/indexedDB/SafeRefPtr.h | 3 | ||||
-rw-r--r-- | dom/media/platforms/wrappers/MediaChangeMonitor.cpp | 27 | ||||
-rw-r--r-- | dom/media/platforms/wrappers/MediaChangeMonitor.h | 2 |
4 files changed, 83 insertions, 51 deletions
diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index 13a54f0214..21519d91e6 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -8951,13 +8951,19 @@ class StringBuilder { TextFragmentWithEncode, }; + struct LiteralSpan { + const char16_t* mData; + uint32_t mLength; + + Span<const char16_t> AsSpan() { return Span(mData, mLength); } + }; + union { nsAtom* mAtom; - const char16_t* mLiteral; + LiteralSpan mLiteral; nsString mString; const nsTextFragment* mTextFragment; }; - uint32_t mLength = 0; Type mType = Type::Unknown; }; @@ -8987,17 +8993,15 @@ class StringBuilder { u->mAtom = aAtom; u->mType = Unit::Type::Atom; uint32_t len = aAtom->GetLength(); - u->mLength = len; mLength += len; } template <int N> void Append(const char16_t (&aLiteral)[N]) { + constexpr uint32_t len = N - 1; Unit* u = AddUnit(); - u->mLiteral = aLiteral; + u->mLiteral = {aLiteral, len}; u->mType = Unit::Type::Literal; - uint32_t len = N - 1; - u->mLength = len; mLength += len; } @@ -9006,15 +9010,14 @@ class StringBuilder { uint32_t len = aString.Length(); new (&u->mString) nsString(std::move(aString)); u->mType = Unit::Type::String; - u->mLength = len; mLength += len; } - void AppendWithAttrEncode(nsString&& aString, uint32_t aLen) { + // aLen can be !isValid(), which will get propagated into mLength. + void AppendWithAttrEncode(nsString&& aString, CheckedInt<uint32_t> aLen) { Unit* u = AddUnit(); new (&u->mString) nsString(std::move(aString)); u->mType = Unit::Type::StringWithEncode; - u->mLength = aLen; mLength += aLen; } @@ -9023,15 +9026,15 @@ class StringBuilder { u->mTextFragment = aTextFragment; u->mType = Unit::Type::TextFragment; uint32_t len = aTextFragment->GetLength(); - u->mLength = len; mLength += len; } - void AppendWithEncode(const nsTextFragment* aTextFragment, uint32_t aLen) { + // aLen can be !isValid(), which will get propagated into mLength. + void AppendWithEncode(const nsTextFragment* aTextFragment, + CheckedInt<uint32_t> aLen) { Unit* u = AddUnit(); u->mTextFragment = aTextFragment; u->mType = Unit::Type::TextFragmentWithEncode; - u->mLength = aLen; mLength += aLen; } @@ -9062,7 +9065,7 @@ class StringBuilder { EncodeAttrString(u.mString, appender); break; case Unit::Type::Literal: - appender.Append(Span(u.mLiteral, u.mLength)); + appender.Append(u.mLiteral.AsSpan()); break; case Unit::Type::TextFragment: if (u.mTextFragment->Is2b()) { @@ -9187,7 +9190,7 @@ static_assert(sizeof(StringBuilder) <= StringBuilder::TARGET_SIZE, static void AppendEncodedCharacters(const nsTextFragment* aText, StringBuilder& aBuilder) { - uint32_t extraSpaceNeeded = 0; + uint32_t numEncodedChars = 0; uint32_t len = aText->GetLength(); if (aText->Is2b()) { const char16_t* data = aText->Get2b(); @@ -9195,16 +9198,10 @@ static void AppendEncodedCharacters(const nsTextFragment* aText, const char16_t c = data[i]; switch (c) { case '<': - extraSpaceNeeded += ArrayLength("<") - 2; - break; case '>': - extraSpaceNeeded += ArrayLength(">") - 2; - break; case '&': - extraSpaceNeeded += ArrayLength("&") - 2; - break; case 0x00A0: - extraSpaceNeeded += ArrayLength(" ") - 2; + ++numEncodedChars; break; default: break; @@ -9216,16 +9213,10 @@ static void AppendEncodedCharacters(const nsTextFragment* aText, const unsigned char c = data[i]; switch (c) { case '<': - extraSpaceNeeded += ArrayLength("<") - 2; - break; case '>': - extraSpaceNeeded += ArrayLength(">") - 2; - break; case '&': - extraSpaceNeeded += ArrayLength("&") - 2; - break; case 0x00A0: - extraSpaceNeeded += ArrayLength(" ") - 2; + ++numEncodedChars; break; default: break; @@ -9233,28 +9224,37 @@ static void AppendEncodedCharacters(const nsTextFragment* aText, } } - if (extraSpaceNeeded) { - aBuilder.AppendWithEncode(aText, len + extraSpaceNeeded); + if (numEncodedChars) { + // For simplicity, conservatively estimate the size of the string after + // encoding. This will result in reserving more memory than we actually + // need, but that should be fine unless the string has an enormous number of + // eg < in it. We subtract 1 for the null terminator, then 1 more for the + // existing character that will be replaced. + constexpr uint32_t maxCharExtraSpace = + std::max({ArrayLength("<"), ArrayLength(">"), + ArrayLength("&"), ArrayLength(" ")}) - + 2; + static_assert(maxCharExtraSpace < 100, "Possible underflow"); + CheckedInt<uint32_t> maxExtraSpace = + CheckedInt<uint32_t>(numEncodedChars) * maxCharExtraSpace; + aBuilder.AppendWithEncode(aText, maxExtraSpace + len); } else { aBuilder.Append(aText); } } -static uint32_t ExtraSpaceNeededForAttrEncoding(const nsAString& aValue) { +static CheckedInt<uint32_t> ExtraSpaceNeededForAttrEncoding( + const nsAString& aValue) { const char16_t* c = aValue.BeginReading(); const char16_t* end = aValue.EndReading(); - uint32_t extraSpaceNeeded = 0; + uint32_t numEncodedChars = 0; while (c < end) { switch (*c) { case '"': - extraSpaceNeeded += ArrayLength(""") - 2; - break; case '&': - extraSpaceNeeded += ArrayLength("&") - 2; - break; case 0x00A0: - extraSpaceNeeded += ArrayLength(" ") - 2; + ++numEncodedChars; break; default: break; @@ -9262,19 +9262,33 @@ static uint32_t ExtraSpaceNeededForAttrEncoding(const nsAString& aValue) { ++c; } - return extraSpaceNeeded; + if (!numEncodedChars) { + return 0; + } + + // For simplicity, conservatively estimate the size of the string after + // encoding. This will result in reserving more memory than we actually + // need, but that should be fine unless the string has an enormous number of + // & in it. We subtract 1 for the null terminator, then 1 more for the + // existing character that will be replaced. + constexpr uint32_t maxCharExtraSpace = + std::max({ArrayLength("""), ArrayLength("&"), + ArrayLength(" ")}) - + 2; + static_assert(maxCharExtraSpace < 100, "Possible underflow"); + return CheckedInt<uint32_t>(numEncodedChars) * maxCharExtraSpace; } static void AppendEncodedAttributeValue(const nsAttrValue& aValue, StringBuilder& aBuilder) { if (nsAtom* atom = aValue.GetStoredAtom()) { nsDependentAtomString atomStr(atom); - uint32_t space = ExtraSpaceNeededForAttrEncoding(atomStr); - if (!space) { + auto space = ExtraSpaceNeededForAttrEncoding(atomStr); + if (space.isValid() && !space.value()) { aBuilder.Append(atom); } else { aBuilder.AppendWithAttrEncode(nsString(atomStr), - atomStr.Length() + space); + space + atomStr.Length()); } return; } @@ -9282,9 +9296,9 @@ static void AppendEncodedAttributeValue(const nsAttrValue& aValue, // nsStringBuffer. nsString str; aValue.ToString(str); - uint32_t space = ExtraSpaceNeededForAttrEncoding(str); - if (space) { - aBuilder.AppendWithAttrEncode(std::move(str), str.Length() + space); + auto space = ExtraSpaceNeededForAttrEncoding(str); + if (!space.isValid() || space.value()) { + aBuilder.AppendWithAttrEncode(std::move(str), space + str.Length()); } else { aBuilder.Append(std::move(str)); } diff --git a/dom/indexedDB/SafeRefPtr.h b/dom/indexedDB/SafeRefPtr.h index 3d7a5d635e..91fa4dded1 100644 --- a/dom/indexedDB/SafeRefPtr.h +++ b/dom/indexedDB/SafeRefPtr.h @@ -219,8 +219,7 @@ class MOZ_IS_REFPTR MOZ_TRIVIAL_ABI SafeRefPtr { aOther.mRawPtr = nullptr; } SafeRefPtr& operator=(SafeRefPtr&& aOther) noexcept { - assign_assuming_AddRef(aOther.mRawPtr); - aOther.mRawPtr = nullptr; + assign_assuming_AddRef(aOther.forget().take()); return *this; } diff --git a/dom/media/platforms/wrappers/MediaChangeMonitor.cpp b/dom/media/platforms/wrappers/MediaChangeMonitor.cpp index 17387204ed..544abea161 100644 --- a/dom/media/platforms/wrappers/MediaChangeMonitor.cpp +++ b/dom/media/platforms/wrappers/MediaChangeMonitor.cpp @@ -519,6 +519,10 @@ RefPtr<MediaDataDecoder::InitPromise> MediaChangeMonitor::Init() { mDecoderInitialized = true; mConversionRequired = Some(mDecoder->NeedsConversion()); mCanRecycleDecoder = Some(CanRecycleDecoder()); + if (mPendingSeekThreshold) { + mDecoder->SetSeekThreshold(*mPendingSeekThreshold); + mPendingSeekThreshold.reset(); + } } return mInitPromise.ResolveOrRejectIfExists(std::move(aValue), __func__); @@ -686,11 +690,19 @@ bool MediaChangeMonitor::IsHardwareAccelerated( } void MediaChangeMonitor::SetSeekThreshold(const media::TimeUnit& aTime) { - if (mDecoder) { - mDecoder->SetSeekThreshold(aTime); - } else { - MediaDataDecoder::SetSeekThreshold(aTime); - } + GetCurrentSerialEventTarget()->Dispatch(NS_NewRunnableFunction( + "MediaChangeMonitor::SetSeekThreshold", + [self = RefPtr<MediaChangeMonitor>(this), time = aTime, this] { + // During the shutdown. + if (mShutdownPromise) { + return; + } + if (mDecoder && mDecoderInitialized) { + mDecoder->SetSeekThreshold(time); + } else { + mPendingSeekThreshold = Some(time); + } + })); } RefPtr<MediaChangeMonitor::CreateDecoderPromise> @@ -744,6 +756,11 @@ MediaResult MediaChangeMonitor::CreateDecoderAndInit(MediaRawData* aSample) { mConversionRequired = Some(mDecoder->NeedsConversion()); mCanRecycleDecoder = Some(CanRecycleDecoder()); + if (mPendingSeekThreshold) { + mDecoder->SetSeekThreshold(*mPendingSeekThreshold); + mPendingSeekThreshold.reset(); + } + if (!mFlushPromise.IsEmpty()) { // A Flush is pending, abort the current operation. mFlushPromise.Resolve(true, __func__); diff --git a/dom/media/platforms/wrappers/MediaChangeMonitor.h b/dom/media/platforms/wrappers/MediaChangeMonitor.h index a85c23fcb2..843dd9035b 100644 --- a/dom/media/platforms/wrappers/MediaChangeMonitor.h +++ b/dom/media/platforms/wrappers/MediaChangeMonitor.h @@ -135,6 +135,8 @@ class MediaChangeMonitor final Maybe<MediaDataDecoder::ConversionRequired> mConversionRequired; bool mDecoderInitialized = false; const CreateDecoderParamsForAsync mParams; + // Keep any seek threshold set for after decoder creation and initialization. + Maybe<media::TimeUnit> mPendingSeekThreshold; }; } // namespace mozilla |