#478: M1416307 M1430557 M1416529 M1324042 M1428947 M1437087 M1440926 M1425520

This commit is contained in:
Cameron Kaiser 2018-03-06 20:08:17 -08:00
parent 636587d3d7
commit 0ba5d5dad1
13 changed files with 115 additions and 52 deletions

View File

@ -6630,9 +6630,17 @@ nsDocShell::ForceRefreshURI(nsIURI* aURI, int32_t aDelay, bool aMetaRefresh, nsI
*/ */
loadInfo->SetReferrer(mCurrentURI); loadInfo->SetReferrer(mCurrentURI);
/* Don't ever "guess" on which owner to use to avoid picking // Set the triggering pricipal to aPrincipal if available, or current
* the current owner. // document's principal otherwise.
*/ nsCOMPtr<nsIPrincipal> principal = aPrincipal;
if (!principal) {
nsCOMPtr<nsIDocument> doc = GetDocument();
if (MOZ_UNLIKELY(!doc)) {
return NS_ERROR_FAILURE;
}
principal = doc->NodePrincipal();
}
loadInfo->SetOwner(principal); // equivalent for SetTriggeringPrincipal
loadInfo->SetOwnerIsExplicit(true); loadInfo->SetOwnerIsExplicit(true);
/* Check if this META refresh causes a redirection /* 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); 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 * LoadURI(...) will cancel all refresh timers... This causes the
* Timer and its refreshData instance to be released... * Timer and its refreshData instance to be released...

View File

@ -19,9 +19,8 @@ interface nsIRefreshURI : nsISupports {
* *
* @param aUri The uri to refresh. * @param aUri The uri to refresh.
* @param aPrincipal The triggeringPrincipal for the refresh load * @param aPrincipal The triggeringPrincipal for the refresh load
* May be null, in which case a principal will be built based on the * May be null, in which case the principal of current document will be
* referrer URI of the previous docshell load, or will use the system * applied.
* principal when there is no referrer.
* @param aMillis The number of milliseconds to wait. * @param aMillis The number of milliseconds to wait.
* @param aRepeat Flag to indicate if the uri is to be * @param aRepeat Flag to indicate if the uri is to be
* repeatedly refreshed every aMillis milliseconds. * repeatedly refreshed every aMillis milliseconds.
@ -37,9 +36,8 @@ interface nsIRefreshURI : nsISupports {
* *
* @param aURI The URI to refresh. * @param aURI The URI to refresh.
* @param aPrincipal The triggeringPrincipal for the refresh load * @param aPrincipal The triggeringPrincipal for the refresh load
* May be null, in which case a principal will be built based on the * May be null, in which case the principal of current document will be
* referrer URI of the previous docshell load, or will use the system * applied.
* principal when there is no referrer.
* @param aMillis The number of milliseconds by which this refresh would * @param aMillis The number of milliseconds by which this refresh would
* be delayed if it were not being forced. * be delayed if it were not being forced.
* @param aMetaRefresh Flag to indicate if this is a meta refresh. * @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 aBaseURI base URI to resolve refresh uri with.
* @param aPrincipal The triggeringPrincipal for the refresh load * @param aPrincipal The triggeringPrincipal for the refresh load
* May be null, in which case a principal will be built based on the * May be null, in which case the principal of current document will be
* referrer URI of the previous docshell load, or will use the system * applied.
* principal when there is no referrer.
* @param aHeader The meta refresh header string. * @param aHeader The meta refresh header string.
*/ */
void setupRefreshURIFromHeader(in nsIURI aBaseURI, void setupRefreshURIFromHeader(in nsIURI aBaseURI,

View File

@ -562,7 +562,7 @@ nsDocumentEncoder::SerializeToStringRecursive(nsINode* aNode,
} }
if (!aDontSerializeRoot) { if (!aDontSerializeRoot) {
rv = SerializeNodeEnd(node, aStr); rv = SerializeNodeEnd(maybeFixedNode, aStr);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
} }

View File

@ -79,7 +79,7 @@ ValidatePlane(const VideoData::YCbCrBuffer::Plane& aPlane)
return aPlane.mWidth <= PlanarYCbCrImage::MAX_DIMENSION && return aPlane.mWidth <= PlanarYCbCrImage::MAX_DIMENSION &&
aPlane.mHeight <= PlanarYCbCrImage::MAX_DIMENSION && aPlane.mHeight <= PlanarYCbCrImage::MAX_DIMENSION &&
aPlane.mWidth * aPlane.mHeight < MAX_VIDEO_WIDTH * MAX_VIDEO_HEIGHT && aPlane.mWidth * aPlane.mHeight < MAX_VIDEO_WIDTH * MAX_VIDEO_HEIGHT &&
aPlane.mStride > 0; aPlane.mStride > 0 && aPlane.mWidth <= aPlane.mStride;
} }
#ifdef MOZ_WIDGET_GONK #ifdef MOZ_WIDGET_GONK

View File

@ -460,6 +460,18 @@ DOMSVGPathSegList::ReplaceItem(DOMSVGPathSeg& aNewItem,
float segAsRaw[1 + NS_SVG_PATH_SEG_MAX_ARGS]; float segAsRaw[1 + NS_SVG_PATH_SEG_MAX_ARGS];
domItem->ToSVGPathSegEncodedData(segAsRaw); 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, if (!InternalList().mData.ReplaceElementsAt(internalIndex, 1 + oldArgCount,
segAsRaw, 1 + newArgCount, segAsRaw, 1 + newArgCount,
fallible)) { fallible)) {
@ -474,8 +486,13 @@ DOMSVGPathSegList::ReplaceItem(DOMSVGPathSeg& aNewItem,
int32_t delta = newArgCount - oldArgCount; int32_t delta = newArgCount - oldArgCount;
if (delta != 0) { if (delta != 0) {
for (uint32_t i = aIndex + 1; i < LengthNoFlush(); ++i) { // Sync up the internal indexes of all ItemProxys that come after aIndex:
mItems[i].mInternalDataIndex += delta; 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);
} }
} }

View File

@ -176,7 +176,14 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsEditor)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mEditorObservers) NS_IMPL_CYCLE_COLLECTION_UNLINK(mEditorObservers)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocStateListeners) NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocStateListeners)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mEventTarget) NS_IMPL_CYCLE_COLLECTION_UNLINK(mEventTarget)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mEventListener)
if (tmp->mEventListener) {
nsEditorEventListener* listener =
reinterpret_cast<nsEditorEventListener*>(tmp->mEventListener.get());
listener->Disconnect();
tmp->mEventListener = nullptr;
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsEditor) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsEditor)

View File

@ -430,12 +430,15 @@ static void
CopyPlane(uint8_t *aDst, const uint8_t *aSrc, CopyPlane(uint8_t *aDst, const uint8_t *aSrc,
const gfx::IntSize &aSize, int32_t aStride, int32_t aSkip) 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) { if (!aSkip) {
// Fast path: planar input. // Fast path: planar input.
memcpy(aDst, aSrc, aSize.height * aStride); memcpy(aDst, aSrc, height * aStride);
} else { } else {
int32_t height = aSize.height;
int32_t width = aSize.width;
for (int y = 0; y < height; ++y) { for (int y = 0; y < height; ++y) {
const uint8_t *src = aSrc; const uint8_t *src = aSrc;
uint8_t *dst = aDst; uint8_t *dst = aDst;
@ -453,13 +456,11 @@ CopyPlane(uint8_t *aDst, const uint8_t *aSrc,
bool bool
RecyclingPlanarYCbCrImage::CopyData(const Data& aData) RecyclingPlanarYCbCrImage::CopyData(const Data& aData)
{ {
mData = aData;
// update buffer size // update buffer size
// Use uint32_t throughout to match AllocateBuffer's param and mBufferSize // Use uint32_t throughout to match AllocateBuffer's param and mBufferSize
const auto checkedSize = const auto checkedSize =
CheckedInt<uint32_t>(mData.mCbCrStride) * mData.mCbCrSize.height * 2 + CheckedInt<uint32_t>(aData.mCbCrStride) * aData.mCbCrSize.height * 2 +
CheckedInt<uint32_t>(mData.mYStride) * mData.mYSize.height; CheckedInt<uint32_t>(aData.mYStride) * aData.mYSize.height;
if (!checkedSize.isValid()) if (!checkedSize.isValid())
return false; return false;
@ -468,22 +469,24 @@ RecyclingPlanarYCbCrImage::CopyData(const Data& aData)
// get new buffer // get new buffer
mBuffer = AllocateBuffer(size); mBuffer = AllocateBuffer(size);
if (!mBuffer) if (MOZ_UNLIKELY(!mBuffer))
return false; return false;
// update buffer size // update buffer size
mBufferSize = size; mBufferSize = size;
mData = aData;
mData.mYChannel = mBuffer.get(); mData.mYChannel = mBuffer.get();
mData.mCbChannel = mData.mYChannel + mData.mYStride * mData.mYSize.height; mData.mCbChannel = mData.mYChannel + mData.mYStride * mData.mYSize.height;
mData.mCrChannel = mData.mCbChannel + mData.mCbCrStride * mData.mCbCrSize.height; mData.mCrChannel = mData.mCbChannel + mData.mCbCrStride * mData.mCbCrSize.height;
mData.mYSkip = mData.mCbSkip = mData.mCrSkip = 0;
CopyPlane(mData.mYChannel, aData.mYChannel, CopyPlane(mData.mYChannel, aData.mYChannel,
mData.mYSize, mData.mYStride, mData.mYSkip); aData.mYSize, aData.mYStride, aData.mYSkip);
CopyPlane(mData.mCbChannel, aData.mCbChannel, CopyPlane(mData.mCbChannel, aData.mCbChannel,
mData.mCbCrSize, mData.mCbCrStride, mData.mCbSkip); aData.mCbCrSize, aData.mCbCrStride, aData.mCbSkip);
CopyPlane(mData.mCrChannel, aData.mCrChannel, CopyPlane(mData.mCrChannel, aData.mCrChannel,
mData.mCbCrSize, mData.mCbCrStride, mData.mCrSkip); aData.mCbCrSize, aData.mCbCrStride, aData.mCrSkip);
mSize = aData.mPicSize; mSize = aData.mPicSize;
return true; return true;

View File

@ -152,7 +152,17 @@ nsBIG5ToUnicode::GetMaxLength(const char* aSrc,
{ {
// The length of the output in UTF-16 code units never exceeds the length // The length of the output in UTF-16 code units never exceeds the length
// of the input in bytes. // 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; return NS_OK;
} }

View File

@ -211,12 +211,21 @@ nsUnicodeToBIG5::GetMaxLength(const char16_t* aSrc,
int32_t aSrcLength, int32_t aSrcLength,
int32_t* aDestLength) int32_t* aDestLength)
{ {
*aDestLength = (aSrcLength * 2) + mozilla::CheckedInt32 length = aSrcLength;
(mPendingTrail ? 1 : 0) + length *= 2;
// If the lead ends up being paired, the bytes produced if (mPendingTrail) {
// are already included above. length += 1;
// If not, it produces a single '?'. }
(mUtf16Lead ? 1 : 0); // 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; return NS_OK;
} }

View File

@ -9345,9 +9345,13 @@ nsTextFrame::GetRenderedText(uint32_t aStartOffset,
startOffset = aStartOffset; startOffset = aStartOffset;
endOffset = std::min<uint32_t>(INT32_MAX, aEndOffset); endOffset = std::min<uint32_t>(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<uint32_t>(trimmedOffsets.mStart, trimmedOffsets.mStart = std::max<uint32_t>(trimmedOffsets.mStart,
startOffset); startOffset);
trimmedOffsets.mLength = std::min<uint32_t>(trimmedOffsets.GetEnd(), trimmedOffsets.mLength = std::min<uint32_t>(origTrimmedOffsetsEnd,
endOffset) - trimmedOffsets.mStart; endOffset) - trimmedOffsets.mStart;
if (trimmedOffsets.mLength <= 0) { if (trimmedOffsets.mLength <= 0) {
offsetInRenderedString = nextOffsetInRenderedString; offsetInRenderedString = nextOffsetInRenderedString;

View File

@ -1014,6 +1014,15 @@ Http2Session::CleanupStream(Http2Stream *aStream, nsresult aResult,
return; 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)) { if (aStream->DeferCleanup(aResult)) {
LOG3(("Http2Session::CleanupStream 0x%X deferred\n", aStream->StreamID())); LOG3(("Http2Session::CleanupStream 0x%X deferred\n", aStream->StreamID()));
return; return;
@ -1024,15 +1033,6 @@ Http2Session::CleanupStream(Http2Stream *aStream, nsresult aResult,
return; 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()) { if (!aStream->RecvdFin() && !aStream->RecvdReset() && aStream->StreamID()) {
LOG3(("Stream had not processed recv FIN, sending RST code %X\n", aResetCode)); LOG3(("Stream had not processed recv FIN, sending RST code %X\n", aResetCode));
GenerateRstStream(aResetCode, aStream->StreamID()); GenerateRstStream(aResetCode, aStream->StreamID());

View File

@ -101,10 +101,20 @@ Http2Stream::Http2Stream(nsAHttpTransaction *httpTransaction,
Http2Stream::~Http2Stream() Http2Stream::~Http2Stream()
{ {
ClearPushSource();
ClearTransactionsBlockedOnTunnel(); ClearTransactionsBlockedOnTunnel();
mStreamID = Http2Session::kDeadStreamID; mStreamID = Http2Session::kDeadStreamID;
} }
void
Http2Stream::ClearPushSource()
{
if (mPushSource) {
mPushSource->SetConsumerStream(nullptr);
mPushSource = nullptr;
}
}
// ReadSegments() is used to write data down the socket. Generally, HTTP // ReadSegments() is used to write data down the socket. Generally, HTTP
// request data is pulled from the approriate transaction and // request data is pulled from the approriate transaction and
// converted to HTTP/2 data. Sometimes control data like a window-update is // converted to HTTP/2 data. Sometimes control data like a window-update is
@ -1091,6 +1101,10 @@ Http2Stream::ConvertPushHeaders(Http2Decompressor *decompressor,
void void
Http2Stream::Close(nsresult reason) 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); mTransaction->Close(reason);
} }

View File

@ -47,6 +47,7 @@ public:
uint32_t StreamID() { return mStreamID; } uint32_t StreamID() { return mStreamID; }
Http2PushedStream *PushSource() { return mPushSource; } Http2PushedStream *PushSource() { return mPushSource; }
void ClearPushSource();
stateType HTTPState() { return mState; } stateType HTTPState() { return mState; }
void SetHTTPState(stateType val) { mState = val; } void SetHTTPState(stateType val) { mState = val; }