diff options
author | wolfbeast <mcwerewolf@wolfbeast.com> | 2019-06-04 18:21:04 +0200 |
---|---|---|
committer | wolfbeast <mcwerewolf@wolfbeast.com> | 2019-06-04 18:21:04 +0200 |
commit | dee00a8a79394559e0e868cc72464c2de24583ac (patch) | |
tree | 18dc2e3db8127ceabcf9b03416b135bced2976ad /dom | |
parent | 851cfd198bc01020cd411d4f1cd6586222700269 (diff) | |
parent | 363bfeb2c06e5f57136ebdab8da1ebeba0591520 (diff) | |
download | UXP-dee00a8a79394559e0e868cc72464c2de24583ac.tar UXP-dee00a8a79394559e0e868cc72464c2de24583ac.tar.gz UXP-dee00a8a79394559e0e868cc72464c2de24583ac.tar.lz UXP-dee00a8a79394559e0e868cc72464c2de24583ac.tar.xz UXP-dee00a8a79394559e0e868cc72464c2de24583ac.zip |
Merge branch 'master' into Basilisk-release
Diffstat (limited to 'dom')
34 files changed, 231 insertions, 540 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/moz.build b/dom/base/moz.build index 77eb01ba6..ebb76d617 100755 --- a/dom/base/moz.build +++ b/dom/base/moz.build @@ -410,17 +410,12 @@ EXTRA_COMPONENTS += [ 'contentAreaDropListener.manifest', 'messageWakeupService.js', 'messageWakeupService.manifest', + 'SiteSpecificUserAgent.js', + 'SiteSpecificUserAgent.manifest', 'SlowScriptDebug.js', 'SlowScriptDebug.manifest', ] -# Firefox for Android provides an alternate version of this component -if not CONFIG['MOZ_FENNEC']: - EXTRA_COMPONENTS += [ - 'SiteSpecificUserAgent.js', - 'SiteSpecificUserAgent.manifest', - ] - EXTRA_JS_MODULES += [ 'DOMRequestHelper.jsm', 'IndexedDBHelper.jsm', @@ -471,7 +466,7 @@ include('/ipc/chromium/chromium-config.mozbuild') FINAL_LIBRARY = 'xul' -if CONFIG['MOZ_PHOENIX'] or CONFIG['MOZ_FENNEC'] or CONFIG['MOZ_XULRUNNER']: +if CONFIG['MOZ_PHOENIX'] or CONFIG['MOZ_XULRUNNER']: DEFINES['HAVE_SIDEBAR'] = True if CONFIG['MOZ_X11']: diff --git a/dom/base/nsAttrAndChildArray.cpp b/dom/base/nsAttrAndChildArray.cpp index b285ee003..9fd27262b 100644 --- a/dom/base/nsAttrAndChildArray.cpp +++ b/dom/base/nsAttrAndChildArray.cpp @@ -78,15 +78,8 @@ GetIndexFromCache(const nsAttrAndChildArray* aArray) } -/** - * Due to a compiler bug in VisualAge C++ for AIX, we need to return the - * address of the first index into mBuffer here, instead of simply returning - * mBuffer itself. - * - * See Bug 231104 for more information. - */ #define ATTRS(_impl) \ - reinterpret_cast<InternalAttr*>(&((_impl)->mBuffer[0])) + reinterpret_cast<InternalAttr*>((_impl)->mBuffer) #define NS_IMPL_EXTRA_SIZE \ 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/nsContentUtils.h b/dom/base/nsContentUtils.h index 98df92efb..299a8e859 100644 --- a/dom/base/nsContentUtils.h +++ b/dom/base/nsContentUtils.h @@ -13,10 +13,6 @@ #include <float.h> #endif -#if defined(SOLARIS) -#include <ieeefp.h> -#endif - #include "js/TypeDecls.h" #include "js/Value.h" #include "js/RootingAPI.h" diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index ac85e34c0..f9126f4da 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -9335,7 +9335,7 @@ nsGlobalWindow::EnterModalState() topWin->mSuspendedDoc = topDoc; if (topDoc) { - topDoc->SuppressEventHandling(nsIDocument::eAnimationsOnly); + topDoc->SuppressEventHandling(nsIDocument::eEvents); } nsGlobalWindow* inner = topWin->GetCurrentInnerWindowInternal(); @@ -9372,7 +9372,7 @@ nsGlobalWindow::LeaveModalState() if (topWin->mSuspendedDoc) { nsCOMPtr<nsIDocument> currentDoc = topWin->GetExtantDoc(); - topWin->mSuspendedDoc->UnsuppressEventHandlingAndFireEvents(nsIDocument::eAnimationsOnly, + topWin->mSuspendedDoc->UnsuppressEventHandlingAndFireEvents(nsIDocument::eEvents, currentDoc == topWin->mSuspendedDoc); topWin->mSuspendedDoc = nullptr; } diff --git a/dom/base/nsMappedAttributes.h b/dom/base/nsMappedAttributes.h index 9fa7572dd..f00b888b9 100644 --- a/dom/base/nsMappedAttributes.h +++ b/dom/base/nsMappedAttributes.h @@ -93,20 +93,13 @@ private: nsAttrValue mValue; }; - /** - * Due to a compiler bug in VisualAge C++ for AIX, we need to return the - * address of the first index into mAttrs here, instead of simply - * returning mAttrs itself. - * - * See Bug 231104 for more information. - */ const InternalAttr* Attrs() const { - return reinterpret_cast<const InternalAttr*>(&(mAttrs[0])); + return reinterpret_cast<const InternalAttr*>(mAttrs); } InternalAttr* Attrs() { - return reinterpret_cast<InternalAttr*>(&(mAttrs[0])); + return reinterpret_cast<InternalAttr*>(mAttrs); } uint16_t mAttrCount; 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/bindings/moz.build b/dom/bindings/moz.build index 7e1358e9c..043b3c494 100644 --- a/dom/bindings/moz.build +++ b/dom/bindings/moz.build @@ -139,7 +139,7 @@ FINAL_LIBRARY = 'xul' SPHINX_TREES['webidl'] = 'docs' SPHINX_PYTHON_PACKAGE_DIRS += ['mozwebidlcodegen'] -if CONFIG['MOZ_PHOENIX'] or CONFIG['MOZ_FENNEC'] or CONFIG['MOZ_XULRUNNER']: +if CONFIG['MOZ_PHOENIX'] or CONFIG['MOZ_XULRUNNER']: # This is needed for Window.webidl DEFINES['HAVE_SIDEBAR'] = True diff --git a/dom/browser-element/BrowserElementChildPreload.js b/dom/browser-element/BrowserElementChildPreload.js index 780dfa80e..5adff2cac 100644 --- a/dom/browser-element/BrowserElementChildPreload.js +++ b/dom/browser-element/BrowserElementChildPreload.js @@ -1010,11 +1010,7 @@ BrowserElementChild.prototype = { self._takeScreenshot(maxWidth, maxHeight, mimeType, domRequestID); }; - let maxDelayMS = 2000; - try { - maxDelayMS = Services.prefs.getIntPref('dom.browserElement.maxScreenshotDelayMS'); - } - catch(e) {} + let maxDelayMS = Services.prefs.getIntPref('dom.browserElement.maxScreenshotDelayMS', 2000); // Try to wait for the event loop to go idle before we take the screenshot, // but once we've waited maxDelayMS milliseconds, go ahead and take it @@ -1720,10 +1716,7 @@ BrowserElementChild.prototype = { // certerror? If yes, maybe we should add a property to the // event to to indicate whether there is a custom page. That would // let the embedder have more control over the desired behavior. - let errorPage = null; - try { - errorPage = Services.prefs.getCharPref(CERTIFICATE_ERROR_PAGE_PREF); - } catch (e) {} + let errorPage = Services.prefs.getCharPref(CERTIFICATE_ERROR_PAGE_PREF, ""); if (errorPage == 'certerror') { sendAsyncMsg('error', { type: 'certerror' }); diff --git a/dom/browser-element/BrowserElementParent.js b/dom/browser-element/BrowserElementParent.js index 67d05f0ab..8e4475bfa 100644 --- a/dom/browser-element/BrowserElementParent.js +++ b/dom/browser-element/BrowserElementParent.js @@ -23,15 +23,6 @@ function debug(msg) { //dump("BrowserElementParent - " + msg + "\n"); } -function getIntPref(prefName, def) { - try { - return Services.prefs.getIntPref(prefName); - } - catch(err) { - return def; - } -} - function handleWindowEvent(e) { if (this._browserElementParents) { let beps = ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys(this._browserElementParents); @@ -856,8 +847,8 @@ BrowserElementParent.prototype = { */ zoom: defineNoReturnMethod(function(zoom) { zoom *= 100; - zoom = Math.min(getIntPref("zoom.maxPercent", 300), zoom); - zoom = Math.max(getIntPref("zoom.minPercent", 50), zoom); + zoom = Math.min(Services.prefs.getIntPref("zoom.maxPercent", 300), zoom); + zoom = Math.max(Services.prefs.getIntPref("zoom.minPercent", 50), zoom); this._sendAsyncMsg('zoom', {zoom: zoom / 100.0}); }), diff --git a/dom/canvas/CanvasRenderingContext2D.cpp b/dom/canvas/CanvasRenderingContext2D.cpp index 4849fda57..2bf40732a 100644 --- a/dom/canvas/CanvasRenderingContext2D.cpp +++ b/dom/canvas/CanvasRenderingContext2D.cpp @@ -2406,7 +2406,11 @@ CanvasRenderingContext2D::SetStyleFromUnion(const StringOrCanvasGradientOrCanvas } if (aValue.IsCanvasPattern()) { - SetStyleFromPattern(aValue.GetAsCanvasPattern(), aWhichStyle); + CanvasPattern& pattern = aValue.GetAsCanvasPattern(); + SetStyleFromPattern(pattern, aWhichStyle); + if (pattern.mForceWriteOnly) { + SetWriteOnly(); + } return; } @@ -2581,11 +2585,12 @@ CanvasRenderingContext2D::CreatePattern(const CanvasImageSource& aSource, nsLayoutUtils::SurfaceFromElement(element, nsLayoutUtils::SFE_WANT_FIRST_FRAME, mTarget); - if (!res.GetSourceSurface()) { + RefPtr<SourceSurface> surface = res.GetSourceSurface(); + if (!surface) { return nullptr; } - RefPtr<CanvasPattern> pat = new CanvasPattern(this, res.GetSourceSurface(), repeatMode, + RefPtr<CanvasPattern> pat = new CanvasPattern(this, surface, repeatMode, res.mPrincipal, res.mIsWriteOnly, res.mCORSUsed); return pat.forget(); @@ -4895,8 +4900,8 @@ CanvasRenderingContext2D::CachedSurfaceFromElement(Element* aElement) res.mSize = res.mSourceSurface->GetSize(); res.mPrincipal = principal.forget(); - res.mIsWriteOnly = false; res.mImageRequest = imgRequest.forget(); + res.mIsWriteOnly = CheckWriteOnlySecurity(res.mCORSUsed, res.mPrincipal); return res; } diff --git a/dom/canvas/CanvasUtils.cpp b/dom/canvas/CanvasUtils.cpp index c7cfed83f..6c9addf59 100644 --- a/dom/canvas/CanvasUtils.cpp +++ b/dom/canvas/CanvasUtils.cpp @@ -126,5 +126,25 @@ CoerceDouble(const JS::Value& v, double* d) return true; } +bool CheckWriteOnlySecurity(bool aCORSUsed, nsIPrincipal* aPrincipal) { + if (!aPrincipal) { + return true; + } + + if (!aCORSUsed) { + nsIGlobalObject* incumbentSettingsObject = dom::GetIncumbentGlobal(); + if (NS_WARN_IF(!incumbentSettingsObject)) { + return true; + } + + nsIPrincipal* principal = incumbentSettingsObject->PrincipalOrNull(); + if (NS_WARN_IF(!principal) || !(principal->Subsumes(aPrincipal))) { + return true; + } + } + + return false; +} + } // namespace CanvasUtils } // namespace mozilla diff --git a/dom/canvas/CanvasUtils.h b/dom/canvas/CanvasUtils.h index a69b8bd72..264b2b5bb 100644 --- a/dom/canvas/CanvasUtils.h +++ b/dom/canvas/CanvasUtils.h @@ -11,6 +11,7 @@ #include "mozilla/dom/ToJSValue.h" #include "jsapi.h" #include "mozilla/FloatingPoint.h" +#include "nsLayoutUtils.h" class nsIPrincipal; @@ -156,6 +157,10 @@ DashArrayToJSVal(nsTArray<T>& dashes, } } +// returns true if write-only mode must used for this principal based on +// the incumbent global. +bool CheckWriteOnlySecurity(bool aCORSUsed, nsIPrincipal* aPrincipal); + } // namespace CanvasUtils } // namespace mozilla diff --git a/dom/canvas/ImageBitmap.cpp b/dom/canvas/ImageBitmap.cpp index 6efe1b318..4a1b6e3c2 100644 --- a/dom/canvas/ImageBitmap.cpp +++ b/dom/canvas/ImageBitmap.cpp @@ -315,36 +315,6 @@ private: const Maybe<IntRect>& mCropRect; }; -static bool -CheckSecurityForHTMLElements(bool aIsWriteOnly, bool aCORSUsed, nsIPrincipal* aPrincipal) -{ - MOZ_ASSERT(aPrincipal); - - if (aIsWriteOnly) { - return false; - } - - if (!aCORSUsed) { - nsIGlobalObject* incumbentSettingsObject = GetIncumbentGlobal(); - if (NS_WARN_IF(!incumbentSettingsObject)) { - return false; - } - - nsIPrincipal* principal = incumbentSettingsObject->PrincipalOrNull(); - if (NS_WARN_IF(!principal) || !(principal->Subsumes(aPrincipal))) { - return false; - } - } - - return true; -} - -static bool -CheckSecurityForHTMLElements(const nsLayoutUtils::SurfaceFromElementResult& aRes) -{ - return CheckSecurityForHTMLElements(aRes.mIsWriteOnly, aRes.mCORSUsed, aRes.mPrincipal); -} - /* * A wrapper to the nsLayoutUtils::SurfaceFromElement() function followed by the * security checking. @@ -365,7 +335,7 @@ GetSurfaceFromElement(nsIGlobalObject* aGlobal, HTMLElementType& aElement, } // Check origin-clean and pass back - *aWriteOnly = !CheckSecurityForHTMLElements(res); + *aWriteOnly = res.mIsWriteOnly; return surface.forget(); } @@ -818,7 +788,7 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLVideoElement& aVideoEl nsCOMPtr<nsIPrincipal> principal = aVideoEl.GetCurrentVideoPrincipal(); bool CORSUsed = aVideoEl.GetCORSMode() != CORS_NONE; - writeOnly = !CheckSecurityForHTMLElements(false, CORSUsed, principal); + writeOnly = CheckWriteOnlySecurity(CORSUsed, principal); // Create ImageBitmap. ImageContainer *container = aVideoEl.GetImageContainer(); 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/html/HTMLCanvasElement.cpp b/dom/html/HTMLCanvasElement.cpp index a01795d9e..4b5deab18 100644 --- a/dom/html/HTMLCanvasElement.cpp +++ b/dom/html/HTMLCanvasElement.cpp @@ -552,17 +552,23 @@ HTMLCanvasElement::CopyInnerTo(Element* aDest) HTMLCanvasElement* dest = static_cast<HTMLCanvasElement*>(aDest); dest->mOriginalCanvas = this; - nsCOMPtr<nsISupports> cxt; - dest->GetContext(NS_LITERAL_STRING("2d"), getter_AddRefs(cxt)); - RefPtr<CanvasRenderingContext2D> context2d = - static_cast<CanvasRenderingContext2D*>(cxt.get()); - if (context2d && !mPrintCallback) { - CanvasImageSource source; - source.SetAsHTMLCanvasElement() = this; - ErrorResult err; - context2d->DrawImage(source, - 0.0, 0.0, err); - rv = err.StealNSResult(); + // We make sure that the canvas is not zero sized since that would cause + // the DrawImage call below to return an error, which would cause printing + // to fail. + nsIntSize size = GetWidthHeight(); + if (size.height > 0 && size.width > 0) { + nsCOMPtr<nsISupports> cxt; + dest->GetContext(NS_LITERAL_STRING("2d"), getter_AddRefs(cxt)); + RefPtr<CanvasRenderingContext2D> context2d = + static_cast<CanvasRenderingContext2D*>(cxt.get()); + if (context2d && !mPrintCallback) { + CanvasImageSource source; + source.SetAsHTMLCanvasElement() = this; + ErrorResult err; + context2d->DrawImage(source, + 0.0, 0.0, err); + rv = err.StealNSResult(); + } } } return rv; 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/indexedDB/test/test_globalObjects_other.xul b/dom/indexedDB/test/test_globalObjects_other.xul index eb180a9b4..b527d66bd 100644 --- a/dom/indexedDB/test/test_globalObjects_other.xul +++ b/dom/indexedDB/test/test_globalObjects_other.xul @@ -31,14 +31,8 @@ Cu.import("resource://gre/modules/Services.jsm"); for (var stage of [ "install", "startup", "shutdown", "uninstall" ]) { for (var symbol of [ "IDBKeyRange", "indexedDB" ]) { - let pref; - try { - pref = Services.prefs.getBoolPref("indexeddbtest.bootstrap." + stage + - "." + symbol); - } - catch(ex) { - pref = false; - } + let pref = Services.prefs.getBoolPref("indexeddbtest.bootstrap." + stage + + "." + symbol, false); ok(pref, "Symbol '" + symbol + "' present during '" + stage + "'"); } } 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/plugins/base/nptypes.h b/dom/plugins/base/nptypes.h index 12a5fb78e..c36532472 100644 --- a/dom/plugins/base/nptypes.h +++ b/dom/plugins/base/nptypes.h @@ -22,18 +22,6 @@ typedef unsigned int uint32_t; typedef long long int64_t; typedef unsigned long long uint64_t; -#elif defined(_AIX) || defined(__sun) || defined(__osf__) || defined(IRIX) || defined(HPUX) - /* - * AIX and SunOS ship a inttypes.h header that defines [u]int32_t, - * but not bool for C. - */ - #include <inttypes.h> - - #ifndef __cplusplus - typedef int bool; - #define true 1 - #define false 0 - #endif #elif defined(bsdi) || defined(FREEBSD) || defined(OPENBSD) /* * BSD/OS, FreeBSD, and OpenBSD ship sys/types.h that define int32_t and diff --git a/dom/plugins/base/nsPluginsDirUnix.cpp b/dom/plugins/base/nsPluginsDirUnix.cpp index 6d112b4fe..e6956c34c 100644 --- a/dom/plugins/base/nsPluginsDirUnix.cpp +++ b/dom/plugins/base/nsPluginsDirUnix.cpp @@ -19,17 +19,7 @@ #include "nsIPrefService.h" #define LOCAL_PLUGIN_DLL_SUFFIX ".so" -#if defined(__hpux) -#define DEFAULT_X11_PATH "/usr/lib/X11R6/" -#undef LOCAL_PLUGIN_DLL_SUFFIX -#define LOCAL_PLUGIN_DLL_SUFFIX ".sl" -#define LOCAL_PLUGIN_DLL_ALT_SUFFIX ".so" -#elif defined(_AIX) -#define DEFAULT_X11_PATH "/usr/lib" -#define LOCAL_PLUGIN_DLL_ALT_SUFFIX ".a" -#elif defined(SOLARIS) -#define DEFAULT_X11_PATH "/usr/openwin/lib/" -#elif defined(LINUX) +#if defined(LINUX) #define DEFAULT_X11_PATH "/usr/X11R6/lib/" #elif defined(__APPLE__) #define DEFAULT_X11_PATH "/usr/X11R6/lib" @@ -102,11 +92,7 @@ static bool LoadExtraSharedLib(const char *name, char **soname, bool tryToGetSon #define PLUGIN_MAX_NUMBER_OF_EXTRA_LIBS 32 #define PREF_PLUGINS_SONAME "plugin.soname.list" -#if defined(SOLARIS) || defined(HPUX) -#define DEFAULT_EXTRA_LIBS_LIST "libXt" LOCAL_PLUGIN_DLL_SUFFIX ":libXext" LOCAL_PLUGIN_DLL_SUFFIX ":libXm" LOCAL_PLUGIN_DLL_SUFFIX -#else #define DEFAULT_EXTRA_LIBS_LIST "libXt" LOCAL_PLUGIN_DLL_SUFFIX ":libXext" LOCAL_PLUGIN_DLL_SUFFIX -#endif /* this function looks for user_pref("plugin.soname.list", "/usr/X11R6/lib/libXt.so.6:libXext.so"); @@ -280,15 +266,9 @@ nsresult nsPluginFile::LoadPlugin(PRLibrary **outLibrary) // work fine. -#if defined(SOLARIS) || defined(HPUX) - // Acrobat/libXm: Lazy resolving might cause crash later (bug 211587) - *outLibrary = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW); - pLibrary = *outLibrary; -#else // Some dlopen() doesn't recover from a failed PR_LD_NOW (bug 223744) *outLibrary = PR_LoadLibraryWithFlags(libSpec, 0); pLibrary = *outLibrary; -#endif if (!pLibrary) { LoadExtraSharedLibs(); // try reload plugin once more diff --git a/dom/presentation/PresentationDataChannelSessionTransport.js b/dom/presentation/PresentationDataChannelSessionTransport.js index 461e4f2cb..9af6213cb 100644 --- a/dom/presentation/PresentationDataChannelSessionTransport.js +++ b/dom/presentation/PresentationDataChannelSessionTransport.js @@ -109,13 +109,7 @@ PresentationTransportBuilder.prototype = { // TODO bug 1228235 we should have a way to let device providers customize // the time-out duration. - let timeout; - try { - timeout = Services.prefs.getIntPref("presentation.receiver.loading.timeout"); - } catch (e) { - // This happens if the pref doesn't exist, so we have a default value. - timeout = 10000; - } + let timeout = Services.prefs.getIntPref("presentation.receiver.loading.timeout", 10000); // The timer is to check if the negotiation finishes on time. this._timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); diff --git a/dom/push/PushServiceAndroidGCM.jsm b/dom/push/PushServiceAndroidGCM.jsm deleted file mode 100644 index ed07be339..000000000 --- a/dom/push/PushServiceAndroidGCM.jsm +++ /dev/null @@ -1,275 +0,0 @@ -/* jshint moz: true, esnext: true */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const Cc = Components.classes; -const Ci = Components.interfaces; -const Cu = Components.utils; -const Cr = Components.results; - -const {PushDB} = Cu.import("resource://gre/modules/PushDB.jsm"); -const {PushRecord} = Cu.import("resource://gre/modules/PushRecord.jsm"); -const {PushCrypto} = Cu.import("resource://gre/modules/PushCrypto.jsm"); -Cu.import("resource://gre/modules/Messaging.jsm"); /*global: Messaging */ -Cu.import("resource://gre/modules/Services.jsm"); /*global: Services */ -Cu.import("resource://gre/modules/Preferences.jsm"); /*global: Preferences */ -Cu.import("resource://gre/modules/Promise.jsm"); /*global: Promise */ -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); /*global: XPCOMUtils */ - -const Log = Cu.import("resource://gre/modules/AndroidLog.jsm", {}).AndroidLog.bind("Push"); - -this.EXPORTED_SYMBOLS = ["PushServiceAndroidGCM"]; - -XPCOMUtils.defineLazyGetter(this, "console", () => { - let {ConsoleAPI} = Cu.import("resource://gre/modules/Console.jsm", {}); - return new ConsoleAPI({ - dump: Log.i, - maxLogLevelPref: "dom.push.loglevel", - prefix: "PushServiceAndroidGCM", - }); -}); - -const kPUSHANDROIDGCMDB_DB_NAME = "pushAndroidGCM"; -const kPUSHANDROIDGCMDB_DB_VERSION = 5; // Change this if the IndexedDB format changes -const kPUSHANDROIDGCMDB_STORE_NAME = "pushAndroidGCM"; - -const FXA_PUSH_SCOPE = "chrome://fxa-push"; - -const prefs = new Preferences("dom.push."); - -/** - * The implementation of WebPush push backed by Android's GCM - * delivery. - */ -this.PushServiceAndroidGCM = { - _mainPushService: null, - _serverURI: null, - - newPushDB: function() { - return new PushDB(kPUSHANDROIDGCMDB_DB_NAME, - kPUSHANDROIDGCMDB_DB_VERSION, - kPUSHANDROIDGCMDB_STORE_NAME, - "channelID", - PushRecordAndroidGCM); - }, - - validServerURI: function(serverURI) { - if (!serverURI) { - return false; - } - - if (serverURI.scheme == "https") { - return true; - } - if (serverURI.scheme == "http") { - // Allow insecure server URLs for development and testing. - return !!prefs.get("testing.allowInsecureServerURL"); - } - console.info("Unsupported Android GCM dom.push.serverURL scheme", serverURI.scheme); - return false; - }, - - observe: function(subject, topic, data) { - switch (topic) { - case "nsPref:changed": - if (data == "dom.push.debug") { - // Reconfigure. - let debug = !!prefs.get("debug"); - console.info("Debug parameter changed; updating configuration with new debug", debug); - this._configure(this._serverURI, debug); - } - break; - case "PushServiceAndroidGCM:ReceivedPushMessage": - this._onPushMessageReceived(data); - break; - default: - break; - } - }, - - _onPushMessageReceived(data) { - // TODO: Use Messaging.jsm for this. - if (this._mainPushService == null) { - // Shouldn't ever happen, but let's be careful. - console.error("No main PushService! Dropping message."); - return; - } - if (!data) { - console.error("No data from Java! Dropping message."); - return; - } - data = JSON.parse(data); - console.debug("ReceivedPushMessage with data", data); - - let { headers, message } = this._messageAndHeaders(data); - - console.debug("Delivering message to main PushService:", message, headers); - this._mainPushService.receivedPushMessage( - data.channelID, "", headers, message, (record) => { - // Always update the stored record. - return record; - }); - }, - - _messageAndHeaders(data) { - // Default is no data (and no encryption). - let message = null; - let headers = null; - - if (data.message && data.enc && (data.enckey || data.cryptokey)) { - headers = { - encryption_key: data.enckey, - crypto_key: data.cryptokey, - encryption: data.enc, - encoding: data.con, - }; - // Ciphertext is (urlsafe) Base 64 encoded. - message = ChromeUtils.base64URLDecode(data.message, { - // The Push server may append padding. - padding: "ignore", - }); - } - return { headers, message }; - }, - - _configure: function(serverURL, debug) { - return Messaging.sendRequestForResult({ - type: "PushServiceAndroidGCM:Configure", - endpoint: serverURL.spec, - debug: debug, - }); - }, - - init: function(options, mainPushService, serverURL) { - console.debug("init()"); - this._mainPushService = mainPushService; - this._serverURI = serverURL; - - prefs.observe("debug", this); - Services.obs.addObserver(this, "PushServiceAndroidGCM:ReceivedPushMessage", false); - - return this._configure(serverURL, !!prefs.get("debug")).then(() => { - Messaging.sendRequestForResult({ - type: "PushServiceAndroidGCM:Initialized" - }); - }); - }, - - uninit: function() { - console.debug("uninit()"); - Messaging.sendRequestForResult({ - type: "PushServiceAndroidGCM:Uninitialized" - }); - - this._mainPushService = null; - Services.obs.removeObserver(this, "PushServiceAndroidGCM:ReceivedPushMessage"); - prefs.ignore("debug", this); - }, - - onAlarmFired: function() { - // No action required. - }, - - connect: function(records) { - console.debug("connect:", records); - // It's possible for the registration or subscriptions backing the - // PushService to not be registered with the underlying AndroidPushService. - // Expire those that are unrecognized. - return Messaging.sendRequestForResult({ - type: "PushServiceAndroidGCM:DumpSubscriptions", - }) - .then(subscriptions => { - console.debug("connect:", subscriptions); - // subscriptions maps chid => subscription data. - return Promise.all(records.map(record => { - if (subscriptions.hasOwnProperty(record.keyID)) { - console.debug("connect:", "hasOwnProperty", record.keyID); - return Promise.resolve(); - } - console.debug("connect:", "!hasOwnProperty", record.keyID); - // Subscription is known to PushService.jsm but not to AndroidPushService. Drop it. - return this._mainPushService.dropRegistrationAndNotifyApp(record.keyID) - .catch(error => { - console.error("connect: Error dropping registration", record.keyID, error); - }); - })); - }); - }, - - isConnected: function() { - return this._mainPushService != null; - }, - - disconnect: function() { - console.debug("disconnect"); - }, - - register: function(record) { - console.debug("register:", record); - let ctime = Date.now(); - let appServerKey = record.appServerKey ? - ChromeUtils.base64URLEncode(record.appServerKey, { - // The Push server requires padding. - pad: true, - }) : null; - let message = { - type: "PushServiceAndroidGCM:SubscribeChannel", - appServerKey: appServerKey, - } - if (record.scope == FXA_PUSH_SCOPE) { - message.service = "fxa"; - } - // Caller handles errors. - return Messaging.sendRequestForResult(message) - .then(data => { - console.debug("Got data:", data); - return PushCrypto.generateKeys() - .then(exportedKeys => - new PushRecordAndroidGCM({ - // Straight from autopush. - channelID: data.channelID, - pushEndpoint: data.endpoint, - // Common to all PushRecord implementations. - scope: record.scope, - originAttributes: record.originAttributes, - ctime: ctime, - systemRecord: record.systemRecord, - // Cryptography! - p256dhPublicKey: exportedKeys[0], - p256dhPrivateKey: exportedKeys[1], - authenticationSecret: PushCrypto.generateAuthenticationSecret(), - appServerKey: record.appServerKey, - }) - ); - }); - }, - - unregister: function(record) { - console.debug("unregister: ", record); - return Messaging.sendRequestForResult({ - type: "PushServiceAndroidGCM:UnsubscribeChannel", - channelID: record.keyID, - }); - }, - - reportDeliveryError: function(messageID, reason) { - console.warn("reportDeliveryError: Ignoring message delivery error", - messageID, reason); - }, -}; - -function PushRecordAndroidGCM(record) { - PushRecord.call(this, record); - this.channelID = record.channelID; -} - -PushRecordAndroidGCM.prototype = Object.create(PushRecord.prototype, { - keyID: { - get() { - return this.channelID; - }, - }, -}); diff --git a/dom/push/moz.build b/dom/push/moz.build index 35683120f..7eee8896f 100644 --- a/dom/push/moz.build +++ b/dom/push/moz.build @@ -14,20 +14,10 @@ EXTRA_JS_MODULES += [ 'PushDB.jsm', 'PushRecord.jsm', 'PushService.jsm', + 'PushServiceHttp2.jsm', + 'PushServiceWebSocket.jsm', ] -if not CONFIG['MOZ_FENNEC']: - # Everything but Fennec. - EXTRA_JS_MODULES += [ - 'PushServiceHttp2.jsm', - 'PushServiceWebSocket.jsm', - ] -else: - # Fennec only. - EXTRA_JS_MODULES += [ - 'PushServiceAndroidGCM.jsm', - ] - MOCHITEST_MANIFESTS += [ 'test/mochitest.ini', ] diff --git a/dom/tests/mochitest/localstorage/test_localStorageQuotaPrivateBrowsing_perwindowpb.html b/dom/tests/mochitest/localstorage/test_localStorageQuotaPrivateBrowsing_perwindowpb.html index 24d3e4ba3..4dcc361c1 100644 --- a/dom/tests/mochitest/localstorage/test_localStorageQuotaPrivateBrowsing_perwindowpb.html +++ b/dom/tests/mochitest/localstorage/test_localStorageQuotaPrivateBrowsing_perwindowpb.html @@ -14,13 +14,7 @@ const Ci = Components.interfaces; const CONTENT_PAGE = "http://mochi.test:8888/chrome/dom/tests/mochitest/localstorage/page_blank.html"; const slavePath = "/chrome/dom/tests/mochitest/localstorage/"; var currentTest = 1; -var quota; - -try { - quota = Services.prefs.getIntPref("dom.storage.default_quota"); -} catch (ex) { - quota = 5 * 1024; -} +var quota = Services.prefs.getIntPref("dom.storage.default_quota", 5 * 1024); Services.prefs.setIntPref("browser.startup.page", 0); Services.prefs.setIntPref("dom.storage.default_quota", 1); diff --git a/dom/webidl/moz.build b/dom/webidl/moz.build index aae7e479c..0fe10eff9 100644 --- a/dom/webidl/moz.build +++ b/dom/webidl/moz.build @@ -746,7 +746,7 @@ if CONFIG['MOZ_BUILD_APP'] in ['xulrunner'] or CONFIG['MOZ_PHOENIX'] or CONFIG[' 'BrowserFeedWriter.webidl', ] -if CONFIG['MOZ_PHOENIX'] or CONFIG['MOZ_FENNEC'] or CONFIG['MOZ_XULRUNNER']: +if CONFIG['MOZ_PHOENIX'] or CONFIG['MOZ_XULRUNNER']: WEBIDL_FILES += [ 'External.webidl', ] 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(); diff --git a/dom/xslt/xpath/txUnaryExpr.cpp b/dom/xslt/xpath/txUnaryExpr.cpp index 95682b5b2..ae20fda46 100644 --- a/dom/xslt/xpath/txUnaryExpr.cpp +++ b/dom/xslt/xpath/txUnaryExpr.cpp @@ -23,16 +23,7 @@ UnaryExpr::evaluate(txIEvalContext* aContext, txAExprResult** aResult) NS_ENSURE_SUCCESS(rv, rv); double value = exprRes->numberValue(); -#ifdef HPUX - /* - * Negation of a zero doesn't produce a negative - * zero on HPUX. Perform the operation by multiplying with - * -1. - */ - return aContext->recycler()->getNumberResult(-1 * value, aResult); -#else return aContext->recycler()->getNumberResult(-value, aResult); -#endif } TX_IMPL_EXPR_STUBS_1(UnaryExpr, NODESET_RESULT, expr) |