diff options
Diffstat (limited to 'dom')
-rw-r--r-- | dom/base/DOMIntersectionObserver.cpp | 3 | ||||
-rw-r--r-- | dom/base/Element.cpp | 10 | ||||
-rw-r--r-- | dom/base/nsAttrValue.cpp | 10 | ||||
-rw-r--r-- | dom/base/nsContentSink.cpp | 3 | ||||
-rw-r--r-- | dom/base/nsContentUtils.cpp | 16 | ||||
-rw-r--r-- | dom/base/nsNodeInfoManager.cpp | 33 | ||||
-rw-r--r-- | dom/base/nsNodeInfoManager.h | 3 | ||||
-rw-r--r-- | dom/canvas/CanvasRenderingContext2D.cpp | 6 | ||||
-rw-r--r-- | dom/canvas/WebGLBuffer.cpp | 2 | ||||
-rw-r--r-- | dom/events/DataTransfer.cpp | 8 | ||||
-rw-r--r-- | dom/indexedDB/ActorsParent.cpp | 46 | ||||
-rw-r--r-- | dom/ipc/ContentParent.cpp | 17 | ||||
-rw-r--r-- | dom/media/AudioConverter.cpp | 108 | ||||
-rw-r--r-- | dom/xslt/base/txURIUtils.cpp | 4 |
14 files changed, 163 insertions, 106 deletions
diff --git a/dom/base/DOMIntersectionObserver.cpp b/dom/base/DOMIntersectionObserver.cpp index 389b93071..70b5534ba 100644 --- a/dom/base/DOMIntersectionObserver.cpp +++ b/dom/base/DOMIntersectionObserver.cpp @@ -339,6 +339,7 @@ DOMIntersectionObserver::Update(nsIDocument* aDocument, DOMHighResTimeStamp time for (size_t i = 0; i < mObservationTargets.Length(); ++i) { Element* target = mObservationTargets.ElementAt(i); nsIFrame* targetFrame = target->GetPrimaryFrame(); + nsIFrame* originalTargetFrame = targetFrame; nsRect targetRect; Maybe<nsRect> intersectionRect; bool isSameDoc = root && root->GetComposedDoc() == target->GetComposedDoc(); @@ -424,7 +425,7 @@ DOMIntersectionObserver::Update(nsIDocument* aDocument, DOMHighResTimeStamp time ); if (intersectionRect.isSome() && !isSameDoc) { nsRect rect = intersectionRect.value(); - nsPresContext* presContext = targetFrame->PresContext(); + nsPresContext* presContext = originalTargetFrame->PresContext(); nsLayoutUtils::TransformRect(rootFrame, presContext->PresShell()->GetRootScrollFrame(), rect); intersectionRect = Some(rect); diff --git a/dom/base/Element.cpp b/dom/base/Element.cpp index 5c3277e84..0054f4800 100644 --- a/dom/base/Element.cpp +++ b/dom/base/Element.cpp @@ -1283,7 +1283,7 @@ Element::ToggleAttribute(const nsAString& aName, if (aForce.WasPassed() && !aForce.Value()) { return false; } - nsCOMPtr<nsIAtom> nameAtom = NS_Atomize(nameToUse); + nsCOMPtr<nsIAtom> nameAtom = NS_AtomizeMainThread(nameToUse); if (!nameAtom) { aError.Throw(NS_ERROR_OUT_OF_MEMORY); return false; @@ -1316,7 +1316,7 @@ Element::SetAttribute(const nsAString& aName, nsAutoString nameToUse; const nsAttrName* name = InternalGetAttrNameFromQName(aName, &nameToUse); if (!name) { - nsCOMPtr<nsIAtom> nameAtom = NS_Atomize(nameToUse); + nsCOMPtr<nsIAtom> nameAtom = NS_AtomizeMainThread(nameToUse); if (!nameAtom) { aError.Throw(NS_ERROR_OUT_OF_MEMORY); return; @@ -1398,7 +1398,7 @@ Element::GetAttributeNS(const nsAString& aNamespaceURI, return; } - nsCOMPtr<nsIAtom> name = NS_Atomize(aLocalName); + nsCOMPtr<nsIAtom> name = NS_AtomizeMainThread(aLocalName); bool hasAttr = GetAttr(nsid, name, aReturn); if (!hasAttr) { SetDOMStringToNull(aReturn); @@ -1430,7 +1430,7 @@ Element::RemoveAttributeNS(const nsAString& aNamespaceURI, const nsAString& aLocalName, ErrorResult& aError) { - nsCOMPtr<nsIAtom> name = NS_Atomize(aLocalName); + nsCOMPtr<nsIAtom> name = NS_AtomizeMainThread(aLocalName); int32_t nsid = nsContentUtils::NameSpaceManager()->GetNameSpaceID(aNamespaceURI, nsContentUtils::IsChromeDoc(OwnerDoc())); @@ -1518,7 +1518,7 @@ Element::HasAttributeNS(const nsAString& aNamespaceURI, return false; } - nsCOMPtr<nsIAtom> name = NS_Atomize(aLocalName); + nsCOMPtr<nsIAtom> name = NS_AtomizeMainThread(aLocalName); return HasAttr(nsid, name); } diff --git a/dom/base/nsAttrValue.cpp b/dom/base/nsAttrValue.cpp index 8eb1aaf97..ebddcb7ed 100644 --- a/dom/base/nsAttrValue.cpp +++ b/dom/base/nsAttrValue.cpp @@ -742,7 +742,7 @@ nsAttrValue::GetAsAtom() const { switch (Type()) { case eString: - return NS_Atomize(GetStringValue()); + return NS_AtomizeMainThread(GetStringValue()); case eAtom: { @@ -754,7 +754,7 @@ nsAttrValue::GetAsAtom() const { nsAutoString val; ToString(val); - return NS_Atomize(val); + return NS_AtomizeMainThread(val); } } } @@ -1267,7 +1267,7 @@ nsAttrValue::ParseAtomArray(const nsAString& aValue) ++iter; } while (iter != end && !nsContentUtils::IsHTMLWhitespace(*iter)); - nsCOMPtr<nsIAtom> classAtom = NS_Atomize(Substring(start, iter)); + nsCOMPtr<nsIAtom> classAtom = NS_AtomizeMainThread(Substring(start, iter)); if (!classAtom) { Reset(); return; @@ -1308,7 +1308,7 @@ nsAttrValue::ParseAtomArray(const nsAString& aValue) ++iter; } while (iter != end && !nsContentUtils::IsHTMLWhitespace(*iter)); - classAtom = NS_Atomize(Substring(start, iter)); + classAtom = NS_AtomizeMainThread(Substring(start, iter)); if (!array->AppendElement(classAtom)) { Reset(); @@ -1757,7 +1757,7 @@ nsAttrValue::SetMiscAtomOrString(const nsAString* aValue) "Empty string?"); MiscContainer* cont = GetMiscContainer(); if (len <= NS_ATTRVALUE_MAX_STRINGLENGTH_ATOM) { - nsCOMPtr<nsIAtom> atom = NS_Atomize(*aValue); + nsCOMPtr<nsIAtom> atom = NS_AtomizeMainThread(*aValue); if (atom) { cont->mStringBits = reinterpret_cast<uintptr_t>(atom.forget().take()) | eAtomBase; diff --git a/dom/base/nsContentSink.cpp b/dom/base/nsContentSink.cpp index 85b3d07bf..490f0ec17 100644 --- a/dom/base/nsContentSink.cpp +++ b/dom/base/nsContentSink.cpp @@ -304,7 +304,8 @@ nsContentSink::ProcessHeaderData(nsIAtom* aHeader, const nsAString& aValue, mDocument->SetHeaderData(aHeader, aValue); - if (aHeader == nsGkAtoms::setcookie) { + if (aHeader == nsGkAtoms::setcookie && + Preferences::GetBool("dom.meta-set-cookie.enabled", true)) { // Don't allow setting cookies in cookie-averse documents. if (mDocument->IsCookieAverse()) { return NS_OK; diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index 3696195dd..1f9c17947 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -2947,11 +2947,11 @@ nsContentUtils::SplitQName(const nsIContent* aNamespaceResolver, if (*aNamespace == kNameSpaceID_Unknown) return NS_ERROR_FAILURE; - *aLocalName = NS_Atomize(Substring(colon + 1, end)).take(); + *aLocalName = NS_AtomizeMainThread(Substring(colon + 1, end)).take(); } else { *aNamespace = kNameSpaceID_None; - *aLocalName = NS_Atomize(aQName).take(); + *aLocalName = NS_AtomizeMainThread(aQName).take(); } NS_ENSURE_TRUE(aLocalName, NS_ERROR_OUT_OF_MEMORY); return NS_OK; @@ -2976,7 +2976,8 @@ nsContentUtils::GetNodeInfoFromQName(const nsAString& aNamespaceURI, const char16_t* end; qName.EndReading(end); - nsCOMPtr<nsIAtom> prefix = NS_Atomize(Substring(qName.get(), colon)); + nsCOMPtr<nsIAtom> prefix = + NS_AtomizeMainThread(Substring(qName.get(), colon)); rv = aNodeInfoManager->GetNodeInfo(Substring(colon + 1, end), prefix, nsID, aNodeType, aNodeInfo); @@ -3036,7 +3037,7 @@ nsContentUtils::SplitExpatName(const char16_t *aExpatName, nsIAtom **aPrefix, nameStart = (uriEnd + 1); if (nameEnd) { const char16_t *prefixStart = nameEnd + 1; - *aPrefix = NS_Atomize(Substring(prefixStart, pos)).take(); + *aPrefix = NS_AtomizeMainThread(Substring(prefixStart, pos)).take(); } else { nameEnd = pos; @@ -3049,7 +3050,7 @@ nsContentUtils::SplitExpatName(const char16_t *aExpatName, nsIAtom **aPrefix, nameEnd = pos; *aPrefix = nullptr; } - *aLocalName = NS_Atomize(Substring(nameStart, nameEnd)).take(); + *aLocalName = NS_AtomizeMainThread(Substring(nameStart, nameEnd)).take(); } // static @@ -3887,7 +3888,8 @@ nsContentUtils::GetEventMessageAndAtom(const nsAString& aName, } *aEventMessage = eUnidentifiedEvent; - nsCOMPtr<nsIAtom> atom = NS_Atomize(NS_LITERAL_STRING("on") + aName); + nsCOMPtr<nsIAtom> atom = + NS_AtomizeMainThread(NS_LITERAL_STRING("on") + aName); sUserDefinedEvents->AppendObject(atom); mapping.mAtom = atom; mapping.mMessage = eUnidentifiedEvent; @@ -3920,7 +3922,7 @@ nsContentUtils::GetEventMessageAndAtomForListener(const nsAString& aName, if (mapping.mMaybeSpecialSVGorSMILEvent) { // Try the atom version so that we should get the right message for // SVG/SMIL. - atom = NS_Atomize(NS_LITERAL_STRING("on") + aName); + atom = NS_AtomizeMainThread(NS_LITERAL_STRING("on") + aName); msg = GetEventMessage(atom); } else { atom = mapping.mAtom; diff --git a/dom/base/nsNodeInfoManager.cpp b/dom/base/nsNodeInfoManager.cpp index 80f0aa786..1f751ea71 100644 --- a/dom/base/nsNodeInfoManager.cpp +++ b/dom/base/nsNodeInfoManager.cpp @@ -112,7 +112,8 @@ nsNodeInfoManager::nsNodeInfoManager() mNonDocumentNodeInfos(0), mTextNodeInfo(nullptr), mCommentNodeInfo(nullptr), - mDocumentNodeInfo(nullptr) + mDocumentNodeInfo(nullptr), + mRecentlyUsedNodeInfos{} { nsLayoutStatics::AddRef(); @@ -232,11 +233,19 @@ nsNodeInfoManager::GetNodeInfo(nsIAtom *aName, nsIAtom *aPrefix, NodeInfo::NodeInfoInner tmpKey(aName, aPrefix, aNamespaceID, aNodeType, aExtraName); + uint32_t index = + GetNodeInfoInnerHashValue(&tmpKey) % RECENTLY_USED_NODEINFOS_SIZE; + NodeInfo* ni = mRecentlyUsedNodeInfos[index]; + if (ni && NodeInfoInnerKeyCompare(&(ni->mInner), &tmpKey)) { + RefPtr<NodeInfo> nodeInfo = ni; + return nodeInfo.forget(); + } + void *node = PL_HashTableLookup(mNodeInfoHash, &tmpKey); if (node) { RefPtr<NodeInfo> nodeInfo = static_cast<NodeInfo*>(node); - + mRecentlyUsedNodeInfos[index] = nodeInfo; return nodeInfo.forget(); } @@ -254,6 +263,7 @@ nsNodeInfoManager::GetNodeInfo(nsIAtom *aName, nsIAtom *aPrefix, NS_IF_ADDREF(mDocument); } + mRecentlyUsedNodeInfos[index] = newNodeInfo; return newNodeInfo.forget(); } @@ -272,16 +282,26 @@ nsNodeInfoManager::GetNodeInfo(const nsAString& aName, nsIAtom *aPrefix, NodeInfo::NodeInfoInner tmpKey(aName, aPrefix, aNamespaceID, aNodeType); + uint32_t index = + GetNodeInfoInnerHashValue(&tmpKey) % RECENTLY_USED_NODEINFOS_SIZE; + NodeInfo* ni = mRecentlyUsedNodeInfos[index]; + if (ni && NodeInfoInnerKeyCompare(&(ni->mInner), &tmpKey)) { + RefPtr<NodeInfo> nodeInfo = ni; + nodeInfo.forget(aNodeInfo); + return NS_OK; + } + void *node = PL_HashTableLookup(mNodeInfoHash, &tmpKey); if (node) { RefPtr<NodeInfo> nodeInfo = static_cast<NodeInfo*>(node); + mRecentlyUsedNodeInfos[index] = nodeInfo; nodeInfo.forget(aNodeInfo); return NS_OK; } - nsCOMPtr<nsIAtom> nameAtom = NS_Atomize(aName); + nsCOMPtr<nsIAtom> nameAtom = NS_AtomizeMainThread(aName); NS_ENSURE_TRUE(nameAtom, NS_ERROR_OUT_OF_MEMORY); RefPtr<NodeInfo> newNodeInfo = @@ -297,6 +317,7 @@ nsNodeInfoManager::GetNodeInfo(const nsAString& aName, nsIAtom *aPrefix, NS_IF_ADDREF(mDocument); } + mRecentlyUsedNodeInfos[index] = newNodeInfo; newNodeInfo.forget(aNodeInfo); return NS_OK; @@ -421,6 +442,12 @@ nsNodeInfoManager::RemoveNodeInfo(NodeInfo *aNodeInfo) } } + uint32_t index = + GetNodeInfoInnerHashValue(&aNodeInfo->mInner) % RECENTLY_USED_NODEINFOS_SIZE; + if (mRecentlyUsedNodeInfos[index] == aNodeInfo) { + mRecentlyUsedNodeInfos[index] = nullptr; + } + #ifdef DEBUG bool ret = #endif diff --git a/dom/base/nsNodeInfoManager.h b/dom/base/nsNodeInfoManager.h index 6ece66577..759dd391e 100644 --- a/dom/base/nsNodeInfoManager.h +++ b/dom/base/nsNodeInfoManager.h @@ -32,6 +32,8 @@ class NodeInfo; } // namespace dom } // namespace mozilla +#define RECENTLY_USED_NODEINFOS_SIZE 31 + class nsNodeInfoManager final { private: @@ -137,6 +139,7 @@ private: mozilla::dom::NodeInfo * MOZ_NON_OWNING_REF mCommentNodeInfo; // WEAK to avoid circular ownership mozilla::dom::NodeInfo * MOZ_NON_OWNING_REF mDocumentNodeInfo; // WEAK to avoid circular ownership RefPtr<nsBindingManager> mBindingManager; + mozilla::dom::NodeInfo* mRecentlyUsedNodeInfos[RECENTLY_USED_NODEINFOS_SIZE]; }; #endif /* nsNodeInfoManager_h___ */ diff --git a/dom/canvas/CanvasRenderingContext2D.cpp b/dom/canvas/CanvasRenderingContext2D.cpp index 4849fda57..111519c71 100644 --- a/dom/canvas/CanvasRenderingContext2D.cpp +++ b/dom/canvas/CanvasRenderingContext2D.cpp @@ -4219,6 +4219,12 @@ struct MOZ_STACK_CLASS CanvasBidiProcessor : public nsBidiPresUtils::BidiProcess if (state->gradientStyles[style]) { // Gradient pattern = GetGradientFor(style); } else if (state->patternStyles[style]) { // Pattern + if (mCtx->mCanvasElement) { + CanvasUtils::DoDrawImageSecurityCheck( + mCtx->mCanvasElement, state->patternStyles[style]->mPrincipal, + state->patternStyles[style]->mForceWriteOnly, + state->patternStyles[style]->mCORSUsed); + } pattern = GetPatternFor(style); } else { MOZ_ASSERT(false, "Should never reach here."); diff --git a/dom/canvas/WebGLBuffer.cpp b/dom/canvas/WebGLBuffer.cpp index f202c9950..1eaf37ac4 100644 --- a/dom/canvas/WebGLBuffer.cpp +++ b/dom/canvas/WebGLBuffer.cpp @@ -115,7 +115,7 @@ WebGLBuffer::BufferData(GLenum target, size_t size, const void* data, GLenum usa const ScopedLazyBind lazyBind(gl, target, this); mContext->InvalidateBufferFetching(); -#ifdef XP_MACOSX +#if defined(XP_MACOSX) || defined(MOZ_WIDGET_GTK) // bug 790879 if (gl->WorkAroundDriverBugs() && size > INT32_MAX) diff --git a/dom/events/DataTransfer.cpp b/dom/events/DataTransfer.cpp index 40a0f42e6..35e80fea4 100644 --- a/dom/events/DataTransfer.cpp +++ b/dom/events/DataTransfer.cpp @@ -39,6 +39,7 @@ #include "mozilla/dom/OSFileSystem.h" #include "mozilla/dom/Promise.h" #include "nsNetUtil.h" +#include "nsReadableUtils.h" namespace mozilla { namespace dom { @@ -644,6 +645,13 @@ DataTransfer::PrincipalMaySetData(const nsAString& aType, NS_WARNING("Disallowing adding x-moz-file or x-moz-file-promize types to DataTransfer"); return false; } + + // Disallow content from creating x-moz-place flavors, so that it cannot + // create fake Places smart queries exposing user data. + if (StringBeginsWith(aType, NS_LITERAL_STRING("text/x-moz-place"))) { + NS_WARNING("Disallowing adding moz-place types to DataTransfer"); + return false; + } } return true; } diff --git a/dom/indexedDB/ActorsParent.cpp b/dom/indexedDB/ActorsParent.cpp index 38621cee3..cd998c31c 100644 --- a/dom/indexedDB/ActorsParent.cpp +++ b/dom/indexedDB/ActorsParent.cpp @@ -23717,32 +23717,38 @@ TransactionDatabaseOperationBase::SendPreprocessInfoOrResults( MOZ_ASSERT(mTransaction); if (NS_WARN_IF(IsActorDestroyed())) { - // Don't send any notifications if the actor was destroyed already. + // Normally we wouldn't need to send any notifications if the actor was + // already destroyed, but this can be a VersionChangeOp which needs to + // notify its parent operation (OpenDatabaseOp) about the failure. + // So SendFailureResult needs to be called even when the actor was + // destroyed. Normal operations redundantly check if the actor was + // destroyed in SendSuccessResult and SendFailureResult, therefore it's + // ok to call it in all cases here. if (NS_SUCCEEDED(mResultCode)) { IDB_REPORT_INTERNAL_ERR(); mResultCode = NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; } - } else { - if (mTransaction->IsInvalidated() || mTransaction->IsAborted()) { - // Aborted transactions always see their requests fail with ABORT_ERR, - // even if the request succeeded or failed with another error. - mResultCode = NS_ERROR_DOM_INDEXEDDB_ABORT_ERR; - } else if (NS_SUCCEEDED(mResultCode)) { - if (aSendPreprocessInfo) { - // This should not release the IPDL reference. - mResultCode = SendPreprocessInfo(); - } else { - // This may release the IPDL reference. - mResultCode = SendSuccessResult(); - } + } else if (mTransaction->IsInvalidated() || mTransaction->IsAborted()) { + // Aborted transactions always see their requests fail with ABORT_ERR, + // even if the request succeeded or failed with another error. + mResultCode = NS_ERROR_DOM_INDEXEDDB_ABORT_ERR; + } + + if (NS_SUCCEEDED(mResultCode)) { + if (aSendPreprocessInfo) { + // This should not release the IPDL reference. + mResultCode = SendPreprocessInfo(); + } else { + // This may release the IPDL reference. + mResultCode = SendSuccessResult(); } + } - if (NS_FAILED(mResultCode)) { - // This should definitely release the IPDL reference. - if (!SendFailureResult(mResultCode)) { - // Abort the transaction. - mTransaction->Abort(mResultCode, /* aForce */ false); - } + if (NS_FAILED(mResultCode)) { + // This should definitely release the IPDL reference. + if (!SendFailureResult(mResultCode)) { + // Abort the transaction. + mTransaction->Abort(mResultCode, /* aForce */ false); } } diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 79446151c..97e3a4880 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -229,11 +229,6 @@ static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID); -#if defined(XP_WIN) -// e10s forced enable pref, defined in nsAppRunner.cpp -extern const char* kForceEnableE10sPref; -#endif - using base::ChildPrivileges; using base::KillProcess; @@ -1275,12 +1270,6 @@ ContentParent::Init() if (nsIPresShell::IsAccessibilityActive()) { #if !defined(XP_WIN) Unused << SendActivateA11y(0); -#else - // On Windows we currently only enable a11y in the content process - // for testing purposes. - if (Preferences::GetBool(kForceEnableE10sPref, false)) { - Unused << SendActivateA11y(a11y::AccessibleWrap::GetContentProcessIdFor(ChildID())); - } #endif } #endif @@ -2573,12 +2562,6 @@ ContentParent::Observe(nsISupports* aSubject, // accessibility gets initiated in chrome process. #if !defined(XP_WIN) Unused << SendActivateA11y(0); -#else - // On Windows we currently only enable a11y in the content process - // for testing purposes. - if (Preferences::GetBool(kForceEnableE10sPref, false)) { - Unused << SendActivateA11y(a11y::AccessibleWrap::GetContentProcessIdFor(ChildID())); - } #endif } else { // If possible, shut down accessibility in content process when diff --git a/dom/media/AudioConverter.cpp b/dom/media/AudioConverter.cpp index 25b981f43..002e79108 100644 --- a/dom/media/AudioConverter.cpp +++ b/dom/media/AudioConverter.cpp @@ -5,8 +5,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "AudioConverter.h" -#include <string.h> #include <speex/speex_resampler.h> +#include <string.h> #include <cmath> /* @@ -140,24 +140,28 @@ static inline int16_t clipTo15(int32_t aX) size_t AudioConverter::DownmixAudio(void* aOut, const void* aIn, size_t aFrames) const { - MOZ_ASSERT(mIn.Format() == AudioConfig::FORMAT_S16 || - mIn.Format() == AudioConfig::FORMAT_FLT); - MOZ_ASSERT(mIn.Channels() >= mOut.Channels()); - MOZ_ASSERT(mIn.Layout() == AudioConfig::ChannelLayout(mIn.Channels()), - "Can only downmix input data in SMPTE layout"); - MOZ_ASSERT(mOut.Layout() == AudioConfig::ChannelLayout(2) || - mOut.Layout() == AudioConfig::ChannelLayout(1)); + MOZ_DIAGNOSTIC_ASSERT(mIn.Format() == AudioConfig::FORMAT_S16 || + mIn.Format() == AudioConfig::FORMAT_FLT); + MOZ_DIAGNOSTIC_ASSERT(mIn.Channels() >= mOut.Channels()); + MOZ_DIAGNOSTIC_ASSERT( + mIn.Layout() == AudioConfig::ChannelLayout(mIn.Channels()), + "Can only downmix input data in SMPTE layout"); + MOZ_DIAGNOSTIC_ASSERT(mOut.Layout() == AudioConfig::ChannelLayout(2) || + mOut.Layout() == AudioConfig::ChannelLayout(1), + "Can only downmix to stereo or mono"); - uint32_t channels = mIn.Channels(); + uint32_t inChannels = mIn.Channels(); + uint32_t outChannels = mOut.Channels(); - if (channels == 1 && mOut.Channels() == 1) { + if (inChannels == outChannels) { + // Number of channels is equal; no processing needed, just move data. if (aOut != aIn) { memmove(aOut, aIn, FramesOutToBytes(aFrames)); } return aFrames; } - if (channels > 2) { + if (inChannels > 2) { if (mIn.Format() == AudioConfig::FORMAT_FLT) { // Downmix matrix. Per-row normalization 1 for rows 3,4 and 2 for rows 5-8. static const float dmatrix[6][8][2]= { @@ -174,12 +178,18 @@ AudioConverter::DownmixAudio(void* aOut, const void* aIn, size_t aFrames) const for (uint32_t i = 0; i < aFrames; i++) { float sampL = 0.0; float sampR = 0.0; - for (uint32_t j = 0; j < channels; j++) { - sampL += in[i*mIn.Channels()+j]*dmatrix[mIn.Channels()-3][j][0]; - sampR += in[i*mIn.Channels()+j]*dmatrix[mIn.Channels()-3][j][1]; + for (uint32_t j = 0; j < inChannels; j++) { + sampL += in[i * inChannels + j] * dmatrix[inChannels - 3][j][0]; + sampR += in[i * inChannels + j] * dmatrix[inChannels - 3][j][1]; + } + if (outChannels == 2) { + // Stereo + *out++ = sampL; + *out++ = sampR; + } else { + // Mono + *out++ = (sampL + sampR) * 0.5; } - *out++ = sampL; - *out++ = sampR; } } else if (mIn.Format() == AudioConfig::FORMAT_S16) { // Downmix matrix. Per-row normalization 1 for rows 3,4 and 2 for rows 5-8. @@ -198,45 +208,51 @@ AudioConverter::DownmixAudio(void* aOut, const void* aIn, size_t aFrames) const for (uint32_t i = 0; i < aFrames; i++) { int32_t sampL = 0; int32_t sampR = 0; - for (uint32_t j = 0; j < channels; j++) { - sampL+=in[i*channels+j]*dmatrix[channels-3][j][0]; - sampR+=in[i*channels+j]*dmatrix[channels-3][j][1]; + for (uint32_t j = 0; j < inChannels; j++) { + sampL += in[i * inChannels + j] * dmatrix[inChannels - 3][j][0]; + sampR += in[i * inChannels + j] * dmatrix[inChannels - 3][j][1]; + } + sampL = clipTo15((sampL + 8192) >> 14); + sampR = clipTo15((sampR + 8192) >> 14); + if (outChannels == 2) { + // Stereo + *out++ = sampL; + *out++ = sampR; + } else { + // Mono + *out++ = (sampL + sampR) * 0.5; } - *out++ = clipTo15((sampL + 8192)>>14); - *out++ = clipTo15((sampR + 8192)>>14); } } else { MOZ_DIAGNOSTIC_ASSERT(false, "Unsupported data type"); } - // If we are to continue downmixing to mono, start working on the output - // buffer. - aIn = aOut; - channels = 2; + return aFrames; } - if (mOut.Channels() == 1) { - if (mIn.Format() == AudioConfig::FORMAT_FLT) { - const float* in = static_cast<const float*>(aIn); - float* out = static_cast<float*>(aOut); - for (size_t fIdx = 0; fIdx < aFrames; ++fIdx) { - float sample = 0.0; - // The sample of the buffer would be interleaved. - sample = (in[fIdx*channels] + in[fIdx*channels + 1]) * 0.5; - *out++ = sample; - } - } else if (mIn.Format() == AudioConfig::FORMAT_S16) { - const int16_t* in = static_cast<const int16_t*>(aIn); - int16_t* out = static_cast<int16_t*>(aOut); - for (size_t fIdx = 0; fIdx < aFrames; ++fIdx) { - int32_t sample = 0.0; - // The sample of the buffer would be interleaved. - sample = (in[fIdx*channels] + in[fIdx*channels + 1]) * 0.5; - *out++ = sample; - } - } else { - MOZ_DIAGNOSTIC_ASSERT(false, "Unsupported data type"); + // If we get here, we're doing a stereo -> mono conversion. + MOZ_DIAGNOSTIC_ASSERT(inChannels == 2 && outChannels == 1); + + if (mIn.Format() == AudioConfig::FORMAT_FLT) { + const float* in = static_cast<const float*>(aIn); + float* out = static_cast<float*>(aOut); + for (size_t fIdx = 0; fIdx < aFrames; ++fIdx) { + float sample = 0.0; + // The sample of the buffer would be interleaved. + sample = (in[fIdx * inChannels] + in[fIdx * inChannels + 1]) * 0.5; + *out++ = sample; } + } else if (mIn.Format() == AudioConfig::FORMAT_S16) { + const int16_t* in = static_cast<const int16_t*>(aIn); + int16_t* out = static_cast<int16_t*>(aOut); + for (size_t fIdx = 0; fIdx < aFrames; ++fIdx) { + int32_t sample = 0.0; + // The sample of the buffer would be interleaved. + sample = (in[fIdx * inChannels] + in[fIdx * inChannels + 1]) * 0.5; + *out++ = sample; + } + } else { + MOZ_DIAGNOSTIC_ASSERT(false, "Unsupported data type"); } return aFrames; } diff --git a/dom/xslt/base/txURIUtils.cpp b/dom/xslt/base/txURIUtils.cpp index 3f3556f80..bce2f8d0f 100644 --- a/dom/xslt/base/txURIUtils.cpp +++ b/dom/xslt/base/txURIUtils.cpp @@ -45,6 +45,10 @@ void URIUtils::resolveHref(const nsAString& href, const nsAString& base, void URIUtils::ResetWithSource(nsIDocument *aNewDoc, nsINode *aSourceNode) { + if (!aSourceNode) { + return; + } + nsCOMPtr<nsIDocument> sourceDoc = aSourceNode->OwnerDoc(); nsIPrincipal* sourcePrincipal = sourceDoc->NodePrincipal(); |