tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 973529d127fbfbb49fc7fdb2895feaaa758a698f
parent 32d5e28eaadb7959e00008ef31e35ba35330033f
Author: Lee Salzman <lsalzman@mozilla.com>
Date:   Thu,  2 Oct 2025 14:01:56 +0000

Bug 1991899 - Use RecordedEventArray for variable-sized recording data. r=aosmond

Differential Revision: https://phabricator.services.mozilla.com/D267087

Diffstat:
Mgfx/2d/RecordedEvent.h | 79+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mgfx/2d/RecordedEventImpl.h | 174+++++++++++++++++++++++++++++++++++++------------------------------------------
2 files changed, 160 insertions(+), 93 deletions(-)

diff --git a/gfx/2d/RecordedEvent.h b/gfx/2d/RecordedEvent.h @@ -541,6 +541,85 @@ class RecordedStrokeOptionsMixin { UniquePtr<Float[]> mDashPatternStorage; }; +template <typename T> +class RecordedEventArray { + public: + T* data() { return mData.get(); } + const T* data() const { return mData.get(); } + size_t size() const { return mSize; } + bool empty() const { return !mSize; } + + void Assign(const T* aData, size_t aSize) { + mSize = aSize; + mData = MakeUnique<T[]>(aSize); + PodCopy(mData.get(), aData, aSize); + } + + bool TryAlloc(size_t aSize) { + if (mSize > 0) { + MOZ_ASSERT_UNREACHABLE(); + return false; + } + mData = MakeUniqueFallible<T[]>(aSize); + if (!mData) { + return false; + } + mSize = aSize; + return true; + } + + template <typename S> + void Write(S& aStream) const { + if (mSize) { + aStream.write(reinterpret_cast<const char*>(mData.get()), + sizeof(T) * mSize); + } + } + + template <typename S> + bool Read(S& aStream, size_t aSize) { + if (!aStream.good() || !TryAlloc(aSize)) { + return false; + } + aStream.read(reinterpret_cast<char*>(mData.get()), sizeof(T) * mSize); + if (!aStream.good()) { + Clear(); + return false; + } + return true; + } + + void Clear() { + mSize = 0; + mData.reset(); + } + + protected: + size_t mSize = 0; + UniquePtr<T[]> mData; +}; + +class RecordedEventCString : public RecordedEventArray<char> { + public: + explicit RecordedEventCString(const char* aStr = nullptr) { + if (aStr) { + if (size_t len = strlen(aStr)) { + Assign(aStr, len + 1); + } + } + } + + template <typename S> + bool Read(S& aStream, size_t aSize) { + if (!RecordedEventArray<char>::Read(aStream, aSize) || + (size() > 0 && !memchr(data(), '\0', size()))) { + Clear(); + return false; + } + return true; + } +}; + template <class Derived> class RecordedEventDerived : public RecordedEvent { using RecordedEvent::RecordedEvent; diff --git a/gfx/2d/RecordedEventImpl.h b/gfx/2d/RecordedEventImpl.h @@ -1566,7 +1566,7 @@ class RecordedFontDescriptor bool mHasDesc; FontType mType; - std::vector<uint8_t> mData; + RecordedEventArray<uint8_t> mData; uint32_t mIndex; ReferencePtr mRefPtr; @@ -1609,7 +1609,7 @@ class RecordedUnscaledFontCreation ReferencePtr mRefPtr; uint64_t mFontDataKey; uint32_t mIndex; - std::vector<uint8_t> mInstanceData; + RecordedEventArray<uint8_t> mInstanceData; template <class S> MOZ_IMPLICIT RecordedUnscaledFontCreation(S& aStream); @@ -1676,8 +1676,8 @@ class RecordedScaledFontCreation ReferencePtr mRefPtr; ReferencePtr mUnscaledFont; Float mGlyphSize; - std::vector<uint8_t> mInstanceData; - std::vector<FontVariation> mVariations; + RecordedEventArray<uint8_t> mInstanceData; + RecordedEventArray<FontVariation> mVariations; template <class S> MOZ_IMPLICIT RecordedScaledFontCreation(S& aStream); @@ -1765,8 +1765,7 @@ class RecordedFilterNodeSetAttribute mNode(aNode), mIndex(aIndex), mArgType(aArgType) { - mPayload.resize(sizeof(T)); - memcpy(&mPayload.front(), &aArgument, sizeof(T)); + mPayload.Assign(reinterpret_cast<const uint8_t*>(&aArgument), sizeof(T)); } RecordedFilterNodeSetAttribute(FilterNode* aNode, uint32_t aIndex, @@ -1775,8 +1774,8 @@ class RecordedFilterNodeSetAttribute mNode(aNode), mIndex(aIndex), mArgType(ARGTYPE_FLOAT_ARRAY) { - mPayload.resize(sizeof(Float) * aSize); - memcpy(&mPayload.front(), aFloat, sizeof(Float) * aSize); + mPayload.Assign(reinterpret_cast<const uint8_t*>(aFloat), + sizeof(Float) * aSize); } bool PlayEvent(Translator* aTranslator) const override; @@ -1793,7 +1792,7 @@ class RecordedFilterNodeSetAttribute uint32_t mIndex; ArgType mArgType; - std::vector<uint8_t> mPayload; + RecordedEventArray<uint8_t> mPayload; template <class S> MOZ_IMPLICIT RecordedFilterNodeSetAttribute(S& aStream); @@ -1855,8 +1854,8 @@ class RecordedLink : public RecordedEventDerived<RecordedLink> { private: friend class RecordedEvent; - std::string mLocalDest; - std::string mURI; + RecordedEventCString mLocalDest; + RecordedEventCString mURI; Rect mRect; template <class S> @@ -1880,7 +1879,7 @@ class RecordedDestination : public RecordedEventDerived<RecordedDestination> { private: friend class RecordedEvent; - std::string mDestination; + RecordedEventCString mDestination; Point mPoint; template <class S> @@ -4221,10 +4220,8 @@ void RecordedFontDescriptor::Record(S& aStream) const { WriteElement(aStream, mType); WriteElement(aStream, mRefPtr); WriteElement(aStream, mIndex); - WriteElement(aStream, (size_t)mData.size()); - if (mData.size()) { - aStream.write((char*)mData.data(), mData.size()); - } + WriteElement(aStream, mData.size()); + mData.Write(aStream); } inline void RecordedFontDescriptor::OutputSimpleEventInfo( @@ -4235,7 +4232,7 @@ inline void RecordedFontDescriptor::OutputSimpleEventInfo( inline void RecordedFontDescriptor::SetFontDescriptor(const uint8_t* aData, uint32_t aSize, uint32_t aIndex) { - mData.assign(aData, aData + aSize); + mData.Assign(aData, aSize); mIndex = aIndex; } @@ -4246,14 +4243,14 @@ RecordedFontDescriptor::RecordedFontDescriptor(S& aStream) ReadElement(aStream, mRefPtr); ReadElement(aStream, mIndex); - size_t size; + size_t size = 0; ReadElement(aStream, size); if (!aStream.good()) { return; } - if (size) { - mData.resize(size); - aStream.read((char*)mData.data(), size); + if (size && !mData.Read(aStream, size)) { + aStream.SetIsBad(); + return; } } @@ -4279,10 +4276,8 @@ void RecordedUnscaledFontCreation::Record(S& aStream) const { WriteElement(aStream, mRefPtr); WriteElement(aStream, mFontDataKey); WriteElement(aStream, mIndex); - WriteElement(aStream, (size_t)mInstanceData.size()); - if (mInstanceData.size()) { - aStream.write((char*)mInstanceData.data(), mInstanceData.size()); - } + WriteElement(aStream, mInstanceData.size()); + mInstanceData.Write(aStream); } inline void RecordedUnscaledFontCreation::OutputSimpleEventInfo( @@ -4293,7 +4288,7 @@ inline void RecordedUnscaledFontCreation::OutputSimpleEventInfo( inline void RecordedUnscaledFontCreation::SetFontInstanceData( const uint8_t* aData, uint32_t aSize) { if (aSize) { - mInstanceData.assign(aData, aData + aSize); + mInstanceData.Assign(aData, aSize); } } @@ -4304,14 +4299,14 @@ RecordedUnscaledFontCreation::RecordedUnscaledFontCreation(S& aStream) ReadElement(aStream, mFontDataKey); ReadElement(aStream, mIndex); - size_t size; + size_t size = 0; ReadElement(aStream, size); if (!aStream.good()) { return; } - if (size) { - mInstanceData.resize(size); - aStream.read((char*)mInstanceData.data(), size); + if (size && !mInstanceData.Read(aStream, size)) { + aStream.SetIsBad(); + return; } } @@ -4360,15 +4355,10 @@ void RecordedScaledFontCreation::Record(S& aStream) const { WriteElement(aStream, mRefPtr); WriteElement(aStream, mUnscaledFont); WriteElement(aStream, mGlyphSize); - WriteElement(aStream, (size_t)mInstanceData.size()); - if (mInstanceData.size()) { - aStream.write((char*)mInstanceData.data(), mInstanceData.size()); - } - WriteElement(aStream, (size_t)mVariations.size()); - if (mVariations.size()) { - aStream.write((char*)mVariations.data(), - sizeof(FontVariation) * mVariations.size()); - } + WriteElement(aStream, mInstanceData.size()); + mInstanceData.Write(aStream); + WriteElement(aStream, mVariations.size()); + mVariations.Write(aStream); } inline void RecordedScaledFontCreation::OutputSimpleEventInfo( @@ -4380,10 +4370,10 @@ inline void RecordedScaledFontCreation::SetFontInstanceData( const uint8_t* aData, uint32_t aSize, const FontVariation* aVariations, uint32_t aNumVariations) { if (aSize) { - mInstanceData.assign(aData, aData + aSize); + mInstanceData.Assign(aData, aSize); } if (aNumVariations) { - mVariations.assign(aVariations, aVariations + aNumVariations); + mVariations.Assign(aVariations, aNumVariations); } } @@ -4394,25 +4384,24 @@ RecordedScaledFontCreation::RecordedScaledFontCreation(S& aStream) ReadElement(aStream, mUnscaledFont); ReadElement(aStream, mGlyphSize); - size_t size; + size_t size = 0; ReadElement(aStream, size); if (!aStream.good()) { return; } - if (size) { - mInstanceData.resize(size); - aStream.read((char*)mInstanceData.data(), size); + if (size && !mInstanceData.Read(aStream, size)) { + aStream.SetIsBad(); + return; } - size_t numVariations; + size_t numVariations = 0; ReadElement(aStream, numVariations); if (!aStream.good()) { return; } - if (numVariations) { - mVariations.resize(numVariations); - aStream.read((char*)mVariations.data(), - sizeof(FontVariation) * numVariations); + if (numVariations && !mVariations.Read(aStream, numVariations)) { + aStream.SetIsBad(); + return; } } @@ -4490,9 +4479,12 @@ inline bool RecordedFilterNodeSetAttribute::PlayEvent( return false; } -#define REPLAY_SET_ATTRIBUTE(type, argtype) \ - case ARGTYPE_##argtype: \ - ReplaySetAttribute(node, mIndex, *(type*)&mPayload.front()); \ +#define REPLAY_SET_ATTRIBUTE(type, argtype) \ + case ARGTYPE_##argtype: \ + if (mPayload.size() < sizeof(type)) { \ + return false; \ + } \ + ReplaySetAttribute(node, mIndex, *(type*)mPayload.data()); \ break switch (mArgType) { @@ -4511,7 +4503,7 @@ inline bool RecordedFilterNodeSetAttribute::PlayEvent( REPLAY_SET_ATTRIBUTE(DeviceColor, COLOR); case ARGTYPE_FLOAT_ARRAY: node->SetAttribute(mIndex, - reinterpret_cast<const Float*>(&mPayload.front()), + reinterpret_cast<const Float*>(mPayload.data()), mPayload.size() / sizeof(Float)); break; } @@ -4524,8 +4516,8 @@ void RecordedFilterNodeSetAttribute::Record(S& aStream) const { WriteElement(aStream, mNode); WriteElement(aStream, mIndex); WriteElement(aStream, mArgType); - WriteElement(aStream, uint64_t(mPayload.size())); - aStream.write((const char*)&mPayload.front(), mPayload.size()); + WriteElement(aStream, mPayload.size()); + mPayload.Write(aStream); } template <class S> @@ -4535,14 +4527,16 @@ RecordedFilterNodeSetAttribute::RecordedFilterNodeSetAttribute(S& aStream) ReadElement(aStream, mIndex); ReadElementConstrained(aStream, mArgType, ArgType::ARGTYPE_UINT32, ArgType::ARGTYPE_FLOAT_ARRAY); - uint64_t size; + size_t size = 0; ReadElement(aStream, size); if (!aStream.good()) { return; } - mPayload.resize(size_t(size)); - aStream.read((char*)&mPayload.front(), size); + if (size && !mPayload.Read(aStream, size)) { + aStream.SetIsBad(); + return; + } } inline void RecordedFilterNodeSetAttribute::OutputSimpleEventInfo( @@ -4601,48 +4595,44 @@ inline bool RecordedLink::PlayEvent(Translator* aTranslator) const { if (!dt) { return false; } - dt->Link(mLocalDest.c_str(), mURI.c_str(), mRect); + dt->Link(mLocalDest.data(), mURI.data(), mRect); return true; } template <class S> void RecordedLink::Record(S& aStream) const { WriteElement(aStream, mRect); - uint32_t len = mLocalDest.length(); - WriteElement(aStream, len); - if (len) { - aStream.write(mLocalDest.data(), len); - } - len = mURI.length(); - WriteElement(aStream, len); - if (len) { - aStream.write(mURI.data(), len); - } + WriteElement(aStream, mLocalDest.size()); + mLocalDest.Write(aStream); + WriteElement(aStream, mURI.size()); + mURI.Write(aStream); } template <class S> RecordedLink::RecordedLink(S& aStream) : RecordedEventDerived(LINK) { ReadElement(aStream, mRect); - uint32_t len; - ReadElement(aStream, len); - mLocalDest.resize(size_t(len)); - if (len && aStream.good()) { - aStream.read(&mLocalDest.front(), len); + size_t localDestLen = 0; + ReadElement(aStream, localDestLen); + if (!aStream.good() || + (localDestLen && !mLocalDest.Read(aStream, localDestLen))) { + aStream.SetIsBad(); + return; } - ReadElement(aStream, len); - mURI.resize(size_t(len)); - if (len && aStream.good()) { - aStream.read(&mURI.front(), len); + size_t uriLen = 0; + ReadElement(aStream, uriLen); + if (!aStream.good() || (uriLen && !mURI.Read(aStream, uriLen))) { + aStream.SetIsBad(); + return; } } inline void RecordedLink::OutputSimpleEventInfo( std::stringstream& aStringStream) const { if (mLocalDest.empty()) { - aStringStream << "Link [" << mURI << " @ " << mRect << "]"; + aStringStream << "Link [" << mURI.data() << " @ " << mRect << "]"; } else { - aStringStream << "Link [" << mLocalDest << " / " << mURI << " @ " << mRect - << "]"; + aStringStream << "Link [" << mLocalDest.data() << " / " << mURI.data() + << " @ " << mRect << "]"; } } @@ -4651,35 +4641,33 @@ inline bool RecordedDestination::PlayEvent(Translator* aTranslator) const { if (!dt) { return false; } - dt->Destination(mDestination.c_str(), mPoint); + dt->Destination(mDestination.data(), mPoint); return true; } template <class S> void RecordedDestination::Record(S& aStream) const { WriteElement(aStream, mPoint); - uint32_t len = mDestination.length(); - WriteElement(aStream, len); - if (len) { - aStream.write(mDestination.data(), len); - } + WriteElement(aStream, mDestination.size()); + mDestination.Write(aStream); } template <class S> RecordedDestination::RecordedDestination(S& aStream) : RecordedEventDerived(DESTINATION) { ReadElement(aStream, mPoint); - uint32_t len; + size_t len = 0; ReadElement(aStream, len); - mDestination.resize(size_t(len)); - if (len && aStream.good()) { - aStream.read(&mDestination.front(), len); + if (!aStream.good() || (len && !mDestination.Read(aStream, len))) { + aStream.SetIsBad(); + return; } } inline void RecordedDestination::OutputSimpleEventInfo( std::stringstream& aStringStream) const { - aStringStream << "Destination [" << mDestination << " @ " << mPoint << "]"; + aStringStream << "Destination [" << mDestination.data() << " @ " << mPoint + << "]"; } #define FOR_EACH_EVENT(f) \