diff --git a/dom/media/MediaData.h b/dom/media/MediaData.h index 4fe8dbc5f2..5c1684fc6c 100644 --- a/dom/media/MediaData.h +++ b/dom/media/MediaData.h @@ -106,8 +106,16 @@ public: AlignedBuffer& operator=(AlignedBuffer&& aOther) { - this->~AlignedBuffer(); - new (this) AlignedBuffer(Move(aOther)); + if (&aOther == this) { + return *this; + } + mData = aOther.mData; + mLength = aOther.mLength; + mBuffer = Move(aOther.mBuffer); + mCapacity = aOther.mCapacity; + aOther.mData = nullptr; + aOther.mLength = 0; + aOther.mCapacity = 0; return *this; } diff --git a/gfx/ots/src/ots.h b/gfx/ots/src/ots.h index 4d2be16898..26f3d85a41 100644 --- a/gfx/ots/src/ots.h +++ b/gfx/ots/src/ots.h @@ -87,8 +87,7 @@ class Buffer { if (n_bytes > 1024 * 1024 * 1024) { return OTS_FAILURE(); } - if ((offset_ + n_bytes > length_) || - (offset_ > length_ - n_bytes)) { + if (length_ < n_bytes || offset_ > length_ - n_bytes) { return OTS_FAILURE(); } if (buf) { @@ -99,7 +98,7 @@ class Buffer { } inline bool ReadU8(uint8_t *value) { - if (offset_ + 1 > length_) { + if (length_ < 1 || offset_ > length_ - 1) { return OTS_FAILURE(); } *value = buffer_[offset_]; @@ -108,7 +107,7 @@ class Buffer { } bool ReadU16(uint16_t *value) { - if (offset_ + 2 > length_) { + if (length_ < 2 || offset_ > length_ - 2) { return OTS_FAILURE(); } std::memcpy(value, buffer_ + offset_, sizeof(uint16_t)); @@ -122,7 +121,7 @@ class Buffer { } bool ReadU24(uint32_t *value) { - if (offset_ + 3 > length_) { + if (length_ < 3 || offset_ > length_ - 3) { return OTS_FAILURE(); } *value = static_cast(buffer_[offset_]) << 16 | @@ -133,7 +132,7 @@ class Buffer { } bool ReadU32(uint32_t *value) { - if (offset_ + 4 > length_) { + if (length_ < 4 || offset_ > length_ - 4) { return OTS_FAILURE(); } std::memcpy(value, buffer_ + offset_, sizeof(uint32_t)); @@ -147,7 +146,7 @@ class Buffer { } bool ReadR64(uint64_t *value) { - if (offset_ + 8 > length_) { + if (length_ < 8 || offset_ > length_ - 8) { return OTS_FAILURE(); } std::memcpy(value, buffer_ + offset_, sizeof(uint64_t)); diff --git a/gfx/ots/src/stat.cc b/gfx/ots/src/stat.cc index 9b78281093..4648dc6e8e 100644 --- a/gfx/ots/src/stat.cc +++ b/gfx/ots/src/stat.cc @@ -53,10 +53,6 @@ bool OpenTypeSTAT::Parse(const uint8_t* data, size_t length) { this->minorVersion = 2; } - if (this->designAxisSize < sizeof(AxisRecord)) { - return Drop("Invalid designAxisSize"); - } - size_t headerEnd = table.offset(); if (this->designAxisCount == 0) { @@ -65,9 +61,13 @@ bool OpenTypeSTAT::Parse(const uint8_t* data, size_t length) { this->designAxesOffset = 0; } } else { + if (this->designAxisSize < sizeof(AxisRecord)) { + return Drop("Invalid designAxisSize"); + } if (this->designAxesOffset < headerEnd || - size_t(this->designAxesOffset) + - size_t(this->designAxisCount) * size_t(this->designAxisSize) > length) { + size_t(this->designAxesOffset) > length || + size_t(this->designAxisCount) * size_t(this->designAxisSize) > + length - size_t(this->designAxesOffset)) { return Drop("Invalid designAxesOffset"); } } diff --git a/js/src/jit/JitFrames.cpp b/js/src/jit/JitFrames.cpp index 7ee9b24eab..65b0e8abfb 100644 --- a/js/src/jit/JitFrames.cpp +++ b/js/src/jit/JitFrames.cpp @@ -1049,31 +1049,31 @@ MarkThisAndArguments(JSTracer* trc, const JitFrameIterator& frame) if (!CalleeTokenIsFunction(layout->calleeToken())) return; - size_t nargs = layout->numActualArgs(); - size_t nformals = 0; - JSFunction* fun = CalleeTokenToFunction(layout->calleeToken()); - if (!frame.isExitFrameLayout() && - !fun->nonLazyScript()->mayReadFrameArgsDirectly()) - { - nformals = fun->nargs(); - } + size_t numFormals = fun->nargs(); + size_t numArgs = Max(layout->numActualArgs(), numFormals); + size_t firstArg = 0; - size_t newTargetOffset = Max(nargs, fun->nargs()); + if (!frame.isExitFrameLayout() && + !fun->nonLazyScript()->mayReadFrameArgsDirectly()) { + firstArg = numFormals; + } Value* argv = layout->argv(); // Trace |this|. TraceRoot(trc, argv, "ion-thisv"); - // Trace actual arguments beyond the formals. Note + 1 for thisv. - for (size_t i = nformals + 1; i < nargs + 1; i++) - TraceRoot(trc, &argv[i], "ion-argv"); + // Trace arguments. Note + 1 for thisv. + for (size_t i = firstArg; i < numArgs; i++) { + TraceRoot(trc, &argv[i + 1], "ion-argv"); + } // Always mark the new.target from the frame. It's not in the snapshots. // +1 to pass |this| - if (CalleeTokenIsConstructing(layout->calleeToken())) - TraceRoot(trc, &argv[1 + newTargetOffset], "ion-newTarget"); + if (CalleeTokenIsConstructing(layout->calleeToken())) { + TraceRoot(trc, &argv[1 + numArgs], "ion-newTarget"); + } } #ifdef JS_NUNBOX32 diff --git a/netwerk/protocol/http/Http2Session.cpp b/netwerk/protocol/http/Http2Session.cpp index 0bd9440034..d61e3c6e2f 100644 --- a/netwerk/protocol/http/Http2Session.cpp +++ b/netwerk/protocol/http/Http2Session.cpp @@ -90,6 +90,7 @@ Http2Session::Http2Session(nsISocketTransport *aSocketTransport, uint32_t versio , mClosed(false) , mCleanShutdown(false) , mTLSProfileConfirmed(false) + , mAggregatedHeaderSize(0) , mGoAwayReason(NO_HTTP_ERROR) , mClientGoAwayReason(UNASSIGNED) , mPeerGoAwayReason(UNASSIGNED) @@ -1262,6 +1263,13 @@ Http2Session::RecvHeaders(Http2Session *self) RETURN_SESSION_ERROR(self, PROTOCOL_ERROR); } + uint32_t frameSize = self->mInputFrameDataSize - paddingControlBytes - + priorityLen - paddingLength; + if (self->mAggregatedHeaderSize + frameSize > + gHttpHandler->MaxHttpResponseHeaderSize()) { + LOG(("Http2Session %p header exceeds the limit\n", self)); + RETURN_SESSION_ERROR(self, PROTOCOL_ERROR); + } if (!self->mInputFrameDataStream) { // Cannot find stream. We can continue the session, but we need to // uncompress the header block to maintain the correct compression context @@ -1274,7 +1282,7 @@ Http2Session::RecvHeaders(Http2Session *self) self->GenerateRstStream(PROTOCOL_ERROR, self->mInputFrameID); self->mDecompressBuffer.Append(&self->mInputFrameBuffer[kFrameHeaderBytes + paddingControlBytes + priorityLen], - self->mInputFrameDataSize - paddingControlBytes - priorityLen - paddingLength); + frameSize); if (self->mInputFrameFlags & kFlag_END_HEADERS) { rv = self->UncompressAndDiscard(false); @@ -1301,11 +1309,17 @@ Http2Session::RecvHeaders(Http2Session *self) // queue up any compression bytes self->mDecompressBuffer.Append(&self->mInputFrameBuffer[kFrameHeaderBytes + paddingControlBytes + priorityLen], - self->mInputFrameDataSize - paddingControlBytes - priorityLen - paddingLength); + frameSize); self->mInputFrameDataStream->UpdateTransportReadEvents(self->mInputFrameDataSize); self->mLastDataReadEpoch = self->mLastReadEpoch; + if (!isContinuation) { + self->mAggregatedHeaderSize = frameSize; + } else { + self->mAggregatedHeaderSize += frameSize; + } + if (!endHeadersFlag) { // more are coming - don't process yet self->ResetDownstreamState(); return NS_OK; @@ -1613,6 +1627,15 @@ Http2Session::RecvPushPromise(Http2Session *self) self->mInputFrameDataSize)); RETURN_SESSION_ERROR(self, PROTOCOL_ERROR); } + + uint32_t frameSize = self->mInputFrameDataSize - paddingControlBytes - + promiseLen - paddingLength; + + if (self->mAggregatedHeaderSize + frameSize > + gHttpHandler->MaxHttpResponseHeaderSize()) { + LOG(("Http2Session:RecvPushPromise %p header exceeds the limit\n", self)); + RETURN_SESSION_ERROR(self, PROTOCOL_ERROR); + } LOG3(("Http2Session::RecvPushPromise %p ID 0x%X assoc ID 0x%X " "paddingLength %d padded %d\n", @@ -1683,7 +1706,7 @@ Http2Session::RecvPushPromise(Http2Session *self) // Need to decompress the headers even though we aren't using them yet in // order to keep the compression context consistent for other frames self->mDecompressBuffer.Append(&self->mInputFrameBuffer[kFrameHeaderBytes + paddingControlBytes + promiseLen], - self->mInputFrameDataSize - paddingControlBytes - promiseLen - paddingLength); + frameSize); if (self->mInputFrameFlags & kFlag_END_PUSH_PROMISE) { rv = self->UncompressAndDiscard(true); if (NS_FAILED(rv)) { @@ -1697,7 +1720,13 @@ Http2Session::RecvPushPromise(Http2Session *self) } self->mDecompressBuffer.Append(&self->mInputFrameBuffer[kFrameHeaderBytes + paddingControlBytes + promiseLen], - self->mInputFrameDataSize - paddingControlBytes - promiseLen - paddingLength); + frameSize); + + if (self->mInputFrameType != FRAME_TYPE_CONTINUATION) { + self->mAggregatedHeaderSize = frameSize; + } else { + self->mAggregatedHeaderSize += frameSize; + } if (!(self->mInputFrameFlags & kFlag_END_PUSH_PROMISE)) { LOG3(("Http2Session::RecvPushPromise not finishing processing for multi-frame push\n")); diff --git a/netwerk/protocol/http/Http2Session.h b/netwerk/protocol/http/Http2Session.h index 9d6b8c8611..355813f59e 100644 --- a/netwerk/protocol/http/Http2Session.h +++ b/netwerk/protocol/http/Http2Session.h @@ -483,6 +483,9 @@ private: // to make sure streams aren't shared across sessions. uint64_t mSerial; + // Aggregate size of continued headers (pushed and pulled) + uint32_t mAggregatedHeaderSize; + // If push is disabled, we want to be able to send PROTOCOL_ERRORs if we // receive a PUSH_PROMISE, but we have to wait for the SETTINGS ACK before // we can actually tell the other end to go away. These help us keep track diff --git a/xpcom/io/nsLocalFileWin.cpp b/xpcom/io/nsLocalFileWin.cpp index 8b063802ed..0b9b8f8ded 100644 --- a/xpcom/io/nsLocalFileWin.cpp +++ b/xpcom/io/nsLocalFileWin.cpp @@ -3095,7 +3095,8 @@ nsLocalFile::IsExecutable(bool* aResult) "wsc", "wsf", "wsh", - "xll" // MS Excel dynamic link library + "xll", // MS Excel dynamic link library + "xrm-ms" }; nsDependentSubstring ext = Substring(path, dotIdx + 1); for (size_t i = 0; i < ArrayLength(executableExts); ++i) {