From 0ba5d5dad15cb62673c2cbf69bdb8739c6ef68fe Mon Sep 17 00:00:00 2001 From: Cameron Kaiser Date: Tue, 6 Mar 2018 20:08:17 -0800 Subject: [PATCH] #478: M1416307 M1430557 M1416529 M1324042 M1428947 M1437087 M1440926 M1425520 --- docshell/base/nsDocShell.cpp | 21 +++++++++++---------- docshell/base/nsIRefreshURI.idl | 15 ++++++--------- dom/base/nsDocumentEncoder.cpp | 2 +- dom/media/MediaData.cpp | 2 +- dom/svg/DOMSVGPathSegList.cpp | 21 +++++++++++++++++++-- editor/libeditor/nsEditor.cpp | 9 ++++++++- gfx/layers/ImageContainer.cpp | 25 ++++++++++++++----------- intl/uconv/ucvtw/nsBIG5ToUnicode.cpp | 12 +++++++++++- intl/uconv/ucvtw/nsUnicodeToBIG5.cpp | 21 +++++++++++++++------ layout/generic/nsTextFrame.cpp | 6 +++++- netwerk/protocol/http/Http2Session.cpp | 18 +++++++++--------- netwerk/protocol/http/Http2Stream.cpp | 14 ++++++++++++++ netwerk/protocol/http/Http2Stream.h | 1 + 13 files changed, 115 insertions(+), 52 deletions(-) diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 50a7f6c6e..6baa001a7 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -6630,9 +6630,17 @@ nsDocShell::ForceRefreshURI(nsIURI* aURI, int32_t aDelay, bool aMetaRefresh, nsI */ loadInfo->SetReferrer(mCurrentURI); - /* Don't ever "guess" on which owner to use to avoid picking - * the current owner. - */ + // Set the triggering pricipal to aPrincipal if available, or current + // document's principal otherwise. + nsCOMPtr principal = aPrincipal; + if (!principal) { + nsCOMPtr doc = GetDocument(); + if (MOZ_UNLIKELY(!doc)) { + return NS_ERROR_FAILURE; + } + principal = doc->NodePrincipal(); + } + loadInfo->SetOwner(principal); // equivalent for SetTriggeringPrincipal loadInfo->SetOwnerIsExplicit(true); /* Check if this META refresh causes a redirection @@ -6660,13 +6668,6 @@ nsDocShell::ForceRefreshURI(nsIURI* aURI, int32_t aDelay, bool aMetaRefresh, nsI loadInfo->SetLoadType(nsIDocShellLoadInfo::loadRefresh); } - // If the principal is null, the refresh will have a triggeringPrincipal - // derived from the referrer URI, or will be set to the system principal - // if there is no refererrer. See LoadURI() - if (aPrincipal) { - loadInfo->SetOwner(aPrincipal); // as called prior to bug 1286472 - } - /* * LoadURI(...) will cancel all refresh timers... This causes the * Timer and its refreshData instance to be released... diff --git a/docshell/base/nsIRefreshURI.idl b/docshell/base/nsIRefreshURI.idl index 5abd829da..04f18eee0 100644 --- a/docshell/base/nsIRefreshURI.idl +++ b/docshell/base/nsIRefreshURI.idl @@ -19,9 +19,8 @@ interface nsIRefreshURI : nsISupports { * * @param aUri The uri to refresh. * @param aPrincipal The triggeringPrincipal for the refresh load - * May be null, in which case a principal will be built based on the - * referrer URI of the previous docshell load, or will use the system - * principal when there is no referrer. + * May be null, in which case the principal of current document will be + * applied. * @param aMillis The number of milliseconds to wait. * @param aRepeat Flag to indicate if the uri is to be * repeatedly refreshed every aMillis milliseconds. @@ -37,9 +36,8 @@ interface nsIRefreshURI : nsISupports { * * @param aURI The URI to refresh. * @param aPrincipal The triggeringPrincipal for the refresh load - * May be null, in which case a principal will be built based on the - * referrer URI of the previous docshell load, or will use the system - * principal when there is no referrer. + * May be null, in which case the principal of current document will be + * applied. * @param aMillis The number of milliseconds by which this refresh would * be delayed if it were not being forced. * @param aMetaRefresh Flag to indicate if this is a meta refresh. @@ -70,9 +68,8 @@ interface nsIRefreshURI : nsISupports { * * @param aBaseURI base URI to resolve refresh uri with. * @param aPrincipal The triggeringPrincipal for the refresh load - * May be null, in which case a principal will be built based on the - * referrer URI of the previous docshell load, or will use the system - * principal when there is no referrer. + * May be null, in which case the principal of current document will be + * applied. * @param aHeader The meta refresh header string. */ void setupRefreshURIFromHeader(in nsIURI aBaseURI, diff --git a/dom/base/nsDocumentEncoder.cpp b/dom/base/nsDocumentEncoder.cpp index c1c1ef8ff..4e36a2f65 100644 --- a/dom/base/nsDocumentEncoder.cpp +++ b/dom/base/nsDocumentEncoder.cpp @@ -562,7 +562,7 @@ nsDocumentEncoder::SerializeToStringRecursive(nsINode* aNode, } if (!aDontSerializeRoot) { - rv = SerializeNodeEnd(node, aStr); + rv = SerializeNodeEnd(maybeFixedNode, aStr); NS_ENSURE_SUCCESS(rv, rv); } diff --git a/dom/media/MediaData.cpp b/dom/media/MediaData.cpp index d2f9cc06e..80ebc3a4b 100644 --- a/dom/media/MediaData.cpp +++ b/dom/media/MediaData.cpp @@ -79,7 +79,7 @@ ValidatePlane(const VideoData::YCbCrBuffer::Plane& aPlane) return aPlane.mWidth <= PlanarYCbCrImage::MAX_DIMENSION && aPlane.mHeight <= PlanarYCbCrImage::MAX_DIMENSION && aPlane.mWidth * aPlane.mHeight < MAX_VIDEO_WIDTH * MAX_VIDEO_HEIGHT && - aPlane.mStride > 0; + aPlane.mStride > 0 && aPlane.mWidth <= aPlane.mStride; } #ifdef MOZ_WIDGET_GONK diff --git a/dom/svg/DOMSVGPathSegList.cpp b/dom/svg/DOMSVGPathSegList.cpp index edacdfc93..0b811cdb1 100644 --- a/dom/svg/DOMSVGPathSegList.cpp +++ b/dom/svg/DOMSVGPathSegList.cpp @@ -460,6 +460,18 @@ DOMSVGPathSegList::ReplaceItem(DOMSVGPathSeg& aNewItem, float segAsRaw[1 + NS_SVG_PATH_SEG_MAX_ARGS]; domItem->ToSVGPathSegEncodedData(segAsRaw); + if (AnimListMirrorsBaseList()) { + // The anim val list is in sync with the base val list - remove mirroring + // animVal item if necessary. We do this *before* touching InternalList() + // so the removed item can correctly store its internal value. + DOMSVGPathSegList* animVal = + GetDOMWrapperIfExists(InternalAList().GetAnimValKey()); + if (animVal->ItemAt(aIndex)) { + animVal->ItemAt(aIndex)->RemovingFromList(); + animVal->ItemAt(aIndex) = nullptr; + } + } + if (!InternalList().mData.ReplaceElementsAt(internalIndex, 1 + oldArgCount, segAsRaw, 1 + newArgCount, fallible)) { @@ -474,8 +486,13 @@ DOMSVGPathSegList::ReplaceItem(DOMSVGPathSeg& aNewItem, int32_t delta = newArgCount - oldArgCount; if (delta != 0) { - for (uint32_t i = aIndex + 1; i < LengthNoFlush(); ++i) { - mItems[i].mInternalDataIndex += delta; + // Sync up the internal indexes of all ItemProxys that come after aIndex: + UpdateListIndicesFromIndex(aIndex + 1, delta); + if (AnimListMirrorsBaseList()) { + // The anim val list is in sync with the base val list + DOMSVGPathSegList* animVal = + GetDOMWrapperIfExists(InternalAList().GetAnimValKey()); + animVal->UpdateListIndicesFromIndex(aIndex + 1, delta); } } diff --git a/editor/libeditor/nsEditor.cpp b/editor/libeditor/nsEditor.cpp index dfe99d8ed..14befa257 100644 --- a/editor/libeditor/nsEditor.cpp +++ b/editor/libeditor/nsEditor.cpp @@ -176,7 +176,14 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsEditor) NS_IMPL_CYCLE_COLLECTION_UNLINK(mEditorObservers) NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocStateListeners) NS_IMPL_CYCLE_COLLECTION_UNLINK(mEventTarget) - NS_IMPL_CYCLE_COLLECTION_UNLINK(mEventListener) + + if (tmp->mEventListener) { + nsEditorEventListener* listener = + reinterpret_cast(tmp->mEventListener.get()); + listener->Disconnect(); + tmp->mEventListener = nullptr; + } + NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsEditor) diff --git a/gfx/layers/ImageContainer.cpp b/gfx/layers/ImageContainer.cpp index 0474b84cb..50e810088 100644 --- a/gfx/layers/ImageContainer.cpp +++ b/gfx/layers/ImageContainer.cpp @@ -430,12 +430,15 @@ static void CopyPlane(uint8_t *aDst, const uint8_t *aSrc, const gfx::IntSize &aSize, int32_t aStride, int32_t aSkip) { + int32_t height = aSize.height; + int32_t width = aSize.width; + + MOZ_RELEASE_ASSERT(width <= aStride); + if (!aSkip) { // Fast path: planar input. - memcpy(aDst, aSrc, aSize.height * aStride); + memcpy(aDst, aSrc, height * aStride); } else { - int32_t height = aSize.height; - int32_t width = aSize.width; for (int y = 0; y < height; ++y) { const uint8_t *src = aSrc; uint8_t *dst = aDst; @@ -453,13 +456,11 @@ CopyPlane(uint8_t *aDst, const uint8_t *aSrc, bool RecyclingPlanarYCbCrImage::CopyData(const Data& aData) { - mData = aData; - // update buffer size // Use uint32_t throughout to match AllocateBuffer's param and mBufferSize const auto checkedSize = - CheckedInt(mData.mCbCrStride) * mData.mCbCrSize.height * 2 + - CheckedInt(mData.mYStride) * mData.mYSize.height; + CheckedInt(aData.mCbCrStride) * aData.mCbCrSize.height * 2 + + CheckedInt(aData.mYStride) * aData.mYSize.height; if (!checkedSize.isValid()) return false; @@ -468,22 +469,24 @@ RecyclingPlanarYCbCrImage::CopyData(const Data& aData) // get new buffer mBuffer = AllocateBuffer(size); - if (!mBuffer) + if (MOZ_UNLIKELY(!mBuffer)) return false; // update buffer size mBufferSize = size; + mData = aData; mData.mYChannel = mBuffer.get(); mData.mCbChannel = mData.mYChannel + mData.mYStride * mData.mYSize.height; mData.mCrChannel = mData.mCbChannel + mData.mCbCrStride * mData.mCbCrSize.height; + mData.mYSkip = mData.mCbSkip = mData.mCrSkip = 0; CopyPlane(mData.mYChannel, aData.mYChannel, - mData.mYSize, mData.mYStride, mData.mYSkip); + aData.mYSize, aData.mYStride, aData.mYSkip); CopyPlane(mData.mCbChannel, aData.mCbChannel, - mData.mCbCrSize, mData.mCbCrStride, mData.mCbSkip); + aData.mCbCrSize, aData.mCbCrStride, aData.mCbSkip); CopyPlane(mData.mCrChannel, aData.mCrChannel, - mData.mCbCrSize, mData.mCbCrStride, mData.mCrSkip); + aData.mCbCrSize, aData.mCbCrStride, aData.mCrSkip); mSize = aData.mPicSize; return true; diff --git a/intl/uconv/ucvtw/nsBIG5ToUnicode.cpp b/intl/uconv/ucvtw/nsBIG5ToUnicode.cpp index 8dbf84a14..b07df3d76 100644 --- a/intl/uconv/ucvtw/nsBIG5ToUnicode.cpp +++ b/intl/uconv/ucvtw/nsBIG5ToUnicode.cpp @@ -152,7 +152,17 @@ nsBIG5ToUnicode::GetMaxLength(const char* aSrc, { // The length of the output in UTF-16 code units never exceeds the length // of the input in bytes. - *aDestLength = aSrcLength + (mPendingTrail ? 1 : 0) + (mBig5Lead ? 1 : 0); + mozilla::CheckedInt32 length = aSrcLength; + if (mPendingTrail) { + length += 1; + } + if (mBig5Lead) { + length += 1; + } + if (!length.isValid()) { + return NS_ERROR_OUT_OF_MEMORY; + } + *aDestLength = length.value(); return NS_OK; } diff --git a/intl/uconv/ucvtw/nsUnicodeToBIG5.cpp b/intl/uconv/ucvtw/nsUnicodeToBIG5.cpp index c3c9658df..b30be2f9b 100644 --- a/intl/uconv/ucvtw/nsUnicodeToBIG5.cpp +++ b/intl/uconv/ucvtw/nsUnicodeToBIG5.cpp @@ -211,12 +211,21 @@ nsUnicodeToBIG5::GetMaxLength(const char16_t* aSrc, int32_t aSrcLength, int32_t* aDestLength) { - *aDestLength = (aSrcLength * 2) + - (mPendingTrail ? 1 : 0) + - // If the lead ends up being paired, the bytes produced - // are already included above. - // If not, it produces a single '?'. - (mUtf16Lead ? 1 : 0); + mozilla::CheckedInt32 length = aSrcLength; + length *= 2; + if (mPendingTrail) { + length += 1; + } + // If the lead ends up being paired, the bytes produced + // are already included above. + // If not, it produces a single '?'. + if (mUtf16Lead) { + length += 1; + } + if (!length.isValid()) { + return NS_ERROR_OUT_OF_MEMORY; + } + *aDestLength = length.value(); return NS_OK; } diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp index d4e0e5d65..f01cd5d9f 100644 --- a/layout/generic/nsTextFrame.cpp +++ b/layout/generic/nsTextFrame.cpp @@ -9345,9 +9345,13 @@ nsTextFrame::GetRenderedText(uint32_t aStartOffset, startOffset = aStartOffset; endOffset = std::min(INT32_MAX, aEndOffset); } + + // If startOffset and/or endOffset are inside of trimmedOffsets' range, + // then clamp the edges of trimmedOffsets accordingly. + int32_t origTrimmedOffsetsEnd = trimmedOffsets.GetEnd(); trimmedOffsets.mStart = std::max(trimmedOffsets.mStart, startOffset); - trimmedOffsets.mLength = std::min(trimmedOffsets.GetEnd(), + trimmedOffsets.mLength = std::min(origTrimmedOffsetsEnd, endOffset) - trimmedOffsets.mStart; if (trimmedOffsets.mLength <= 0) { offsetInRenderedString = nextOffsetInRenderedString; diff --git a/netwerk/protocol/http/Http2Session.cpp b/netwerk/protocol/http/Http2Session.cpp index 05c69b63b..4260bcfc1 100644 --- a/netwerk/protocol/http/Http2Session.cpp +++ b/netwerk/protocol/http/Http2Session.cpp @@ -1014,6 +1014,15 @@ Http2Session::CleanupStream(Http2Stream *aStream, nsresult aResult, return; } + Http2PushedStream *pushSource = aStream->PushSource(); + if (pushSource) { + // aStream is a synthetic attached to an even push + MOZ_ASSERT(pushSource->GetConsumerStream() == aStream); + MOZ_ASSERT(!aStream->StreamID()); + MOZ_ASSERT(!(pushSource->StreamID() & 0x1)); + aStream->ClearPushSource(); + } + if (aStream->DeferCleanup(aResult)) { LOG3(("Http2Session::CleanupStream 0x%X deferred\n", aStream->StreamID())); return; @@ -1024,15 +1033,6 @@ Http2Session::CleanupStream(Http2Stream *aStream, nsresult aResult, return; } - Http2PushedStream *pushSource = aStream->PushSource(); - if (pushSource) { - // aStream is a synthetic attached to an even push - MOZ_ASSERT(pushSource->GetConsumerStream() == aStream); - MOZ_ASSERT(!aStream->StreamID()); - MOZ_ASSERT(!(pushSource->StreamID() & 0x1)); - pushSource->SetConsumerStream(nullptr); - } - if (!aStream->RecvdFin() && !aStream->RecvdReset() && aStream->StreamID()) { LOG3(("Stream had not processed recv FIN, sending RST code %X\n", aResetCode)); GenerateRstStream(aResetCode, aStream->StreamID()); diff --git a/netwerk/protocol/http/Http2Stream.cpp b/netwerk/protocol/http/Http2Stream.cpp index fea9b6155..444dee1e9 100644 --- a/netwerk/protocol/http/Http2Stream.cpp +++ b/netwerk/protocol/http/Http2Stream.cpp @@ -101,10 +101,20 @@ Http2Stream::Http2Stream(nsAHttpTransaction *httpTransaction, Http2Stream::~Http2Stream() { + ClearPushSource(); ClearTransactionsBlockedOnTunnel(); mStreamID = Http2Session::kDeadStreamID; } +void +Http2Stream::ClearPushSource() +{ + if (mPushSource) { + mPushSource->SetConsumerStream(nullptr); + mPushSource = nullptr; + } +} + // ReadSegments() is used to write data down the socket. Generally, HTTP // request data is pulled from the approriate transaction and // converted to HTTP/2 data. Sometimes control data like a window-update is @@ -1091,6 +1101,10 @@ Http2Stream::ConvertPushHeaders(Http2Decompressor *decompressor, void Http2Stream::Close(nsresult reason) { + // In case we are connected to a push, make sure the push knows we are closed, + // so it doesn't try to give us any more DATA that comes on it after our close. + ClearPushSource(); + mTransaction->Close(reason); } diff --git a/netwerk/protocol/http/Http2Stream.h b/netwerk/protocol/http/Http2Stream.h index b5bec97c3..3cd2e424f 100644 --- a/netwerk/protocol/http/Http2Stream.h +++ b/netwerk/protocol/http/Http2Stream.h @@ -47,6 +47,7 @@ public: uint32_t StreamID() { return mStreamID; } Http2PushedStream *PushSource() { return mPushSource; } + void ClearPushSource(); stateType HTTPState() { return mState; } void SetHTTPState(stateType val) { mState = val; }