diff --git a/accessible/jsat/Gestures.jsm b/accessible/jsat/Gestures.jsm index b6f9733d9e..cc431614c7 100644 --- a/accessible/jsat/Gestures.jsm +++ b/accessible/jsat/Gestures.jsm @@ -13,10 +13,8 @@ DoubleTap -> TripleTap (x) -> TapHold (x) - -> Explore (x) TripleTap -> DoubleTapHold (x) - -> Explore (x) Dwell -> DwellEnd (v) @@ -39,7 +37,6 @@ 'use strict'; -const Ci = Components.interfaces; const Cu = Components.utils; this.EXPORTED_SYMBOLS = ['GestureSettings', 'GestureTracker']; // jshint ignore:line @@ -73,8 +70,6 @@ const TAP_MAX_RADIUS = 0.2; // Directness coefficient. It is based on the maximum 15 degree angle between // consequent pointer move lines. const DIRECTNESS_COEFF = 1.44; -// The virtual touch ID generated by a mouse event. -const MOUSE_ID = 'mouse'; // Amount in inches from the edges of the screen for it to be an edge swipe const EDGE = 0.1; // Multiply timeouts by this constant, x2 works great too for slower users. @@ -211,7 +206,6 @@ this.GestureTracker = { // jshint ignore:line if (aDetail.type !== 'pointerdown') { return; } - let points = aDetail.points; let GestureConstructor = aGesture || (IS_ANDROID ? DoubleTap : Tap); this._create(GestureConstructor); this._update(aDetail, aTimeStamp); @@ -270,6 +264,7 @@ this.GestureTracker = { // jshint ignore:line this._create(gestureType, current.startTime, current.points, current.lastEvent); } else { + this.current.clearTimer(); delete this.current; } } @@ -608,6 +603,9 @@ TravelGesture.prototype = Object.create(Gesture.prototype); * this._travelTo gesture iff at least one point crosses this._threshold. */ TravelGesture.prototype.test = function TravelGesture_test() { + if (!this._travelTo) { + return; + } for (let identifier in this.points) { let point = this.points[identifier]; if (point.totalDistanceTraveled / Utils.dpi > this._threshold) { @@ -680,10 +678,10 @@ DoubleTapHoldEnd.prototype.type = 'doubletapholdend'; * @param {Function} aRejectToOnWait A constructor for the next gesture to * reject to in case no pointermove or pointerup happens within the * GestureSettings.dwellThreshold. - * @param {Function} aRejectToOnPointerDown A constructor for the gesture to - * reject to if a finger comes down immediately after the tap. * @param {Function} aTravelTo An optional constuctor for the next gesture to * reject to in case the the TravelGesture test fails. + * @param {Function} aRejectToOnPointerDown A constructor for the gesture to + * reject to if a finger comes down immediately after the tap. */ function TapGesture(aTimeStamp, aPoints, aLastEvent, aRejectToOnWait, aTravelTo, aRejectToOnPointerDown) { this._rejectToOnWait = aRejectToOnWait; @@ -722,11 +720,12 @@ TapGesture.prototype.pointerup = function TapGesture_pointerup(aPoints) { }; TapGesture.prototype.pointerdown = function TapGesture_pointerdown(aPoints, aTimeStamp) { - TravelGesture.prototype.pointerdown.call(this, aPoints, aTimeStamp); if (this._pointerUpTimer) { clearTimeout(this._pointerUpTimer); delete this._pointerUpTimer; this._deferred.reject(this._rejectToOnPointerDown); + } else { + TravelGesture.prototype.pointerdown.call(this, aPoints, aTimeStamp); } }; @@ -771,7 +770,7 @@ DoubleTap.prototype.type = 'doubletap'; */ function TripleTap(aTimeStamp, aPoints, aLastEvent) { this._inProgress = true; - TapGesture.call(this, aTimeStamp, aPoints, aLastEvent, DoubleTapHold); + TapGesture.call(this, aTimeStamp, aPoints, aLastEvent, DoubleTapHold, null, null); } TripleTap.prototype = Object.create(TapGesture.prototype); diff --git a/accessible/xpcom/xpcAccessible.cpp b/accessible/xpcom/xpcAccessible.cpp index 3803ce6038..a4f03c373c 100644 --- a/accessible/xpcom/xpcAccessible.cpp +++ b/accessible/xpcom/xpcAccessible.cpp @@ -41,12 +41,17 @@ xpcAccessible::GetNextSibling(nsIAccessible** aNextSibling) if (IntlGeneric().IsNull()) return NS_ERROR_FAILURE; - if (!Intl()) - return NS_ERROR_FAILURE; + if (IntlGeneric().IsAccessible()) { + nsresult rv = NS_OK; + NS_IF_ADDREF(*aNextSibling = ToXPC(Intl()->GetSiblingAtOffset(1, &rv))); + return rv; + } - nsresult rv = NS_OK; - NS_IF_ADDREF(*aNextSibling = ToXPC(Intl()->GetSiblingAtOffset(1, &rv))); - return rv; + ProxyAccessible* proxy = IntlGeneric().AsProxy(); + NS_ENSURE_STATE(proxy); + + NS_IF_ADDREF(*aNextSibling = ToXPC(proxy->NextSibling())); + return *aNextSibling ? NS_OK : NS_ERROR_FAILURE; } NS_IMETHODIMP @@ -57,12 +62,17 @@ xpcAccessible::GetPreviousSibling(nsIAccessible** aPreviousSibling) if (IntlGeneric().IsNull()) return NS_ERROR_FAILURE; - if (!Intl()) - return NS_ERROR_FAILURE; + if (IntlGeneric().IsAccessible()) { + nsresult rv = NS_OK; + NS_IF_ADDREF(*aPreviousSibling = ToXPC(Intl()->GetSiblingAtOffset(-1, &rv))); + return rv; + } - nsresult rv = NS_OK; - NS_IF_ADDREF(*aPreviousSibling = ToXPC(Intl()->GetSiblingAtOffset(-1, &rv))); - return rv; + ProxyAccessible* proxy = IntlGeneric().AsProxy(); + NS_ENSURE_STATE(proxy); + + NS_IF_ADDREF(*aPreviousSibling = ToXPC(proxy->PrevSibling())); + return *aPreviousSibling ? NS_OK : NS_ERROR_FAILURE; } NS_IMETHODIMP @@ -157,10 +167,12 @@ xpcAccessible::GetIndexInParent(int32_t* aIndexInParent) if (IntlGeneric().IsNull()) return NS_ERROR_FAILURE; - if (!Intl()) - return NS_ERROR_FAILURE; + if (IntlGeneric().IsAccessible()) { + *aIndexInParent = Intl()->IndexInParent(); + } else if (IntlGeneric().IsProxy()) { + *aIndexInParent = IntlGeneric().AsProxy()->IndexInParent(); + } - *aIndexInParent = Intl()->IndexInParent(); return *aIndexInParent != -1 ? NS_OK : NS_ERROR_FAILURE; } @@ -239,10 +251,13 @@ xpcAccessible::GetState(uint32_t* aState, uint32_t* aExtraState) { NS_ENSURE_ARG_POINTER(aState); - if (!Intl()) + if (IntlGeneric().IsNull()) nsAccUtils::To32States(states::DEFUNCT, aState, aExtraState); - else + else if (Intl()) nsAccUtils::To32States(Intl()->State(), aState, aExtraState); + else + nsAccUtils::To32States(IntlGeneric().AsProxy()->State(), aState, + aExtraState); return NS_OK; } @@ -252,11 +267,16 @@ xpcAccessible::GetName(nsAString& aName) { aName.Truncate(); - if (!Intl()) + if (IntlGeneric().IsNull()) return NS_ERROR_FAILURE; nsAutoString name; - Intl()->Name(name); + if (ProxyAccessible* proxy = IntlGeneric().AsProxy()) { + proxy->Name(name); + } else { + Intl()->Name(name); + } + aName.Assign(name); return NS_OK; @@ -265,11 +285,16 @@ xpcAccessible::GetName(nsAString& aName) NS_IMETHODIMP xpcAccessible::GetDescription(nsAString& aDescription) { - if (!Intl()) + if (IntlGeneric().IsNull()) return NS_ERROR_FAILURE; nsAutoString desc; - Intl()->Description(desc); + if (ProxyAccessible* proxy = IntlGeneric().AsProxy()) { + proxy->Description(desc); + } else { + Intl()->Description(desc); + } + aDescription.Assign(desc); return NS_OK; @@ -278,21 +303,33 @@ xpcAccessible::GetDescription(nsAString& aDescription) NS_IMETHODIMP xpcAccessible::GetLanguage(nsAString& aLanguage) { - if (!Intl()) + if (IntlGeneric().IsNull()) return NS_ERROR_FAILURE; - Intl()->Language(aLanguage); + nsAutoString lang; + if (ProxyAccessible* proxy = IntlGeneric().AsProxy()) { + proxy->Language(lang); + } else { + Intl()->Language(lang); + } + + aLanguage.Assign(lang); return NS_OK; } NS_IMETHODIMP xpcAccessible::GetValue(nsAString& aValue) { - if (!Intl()) + if (IntlGeneric().IsNull()) return NS_ERROR_FAILURE; nsAutoString value; - Intl()->Value(value); + if (ProxyAccessible* proxy = IntlGeneric().AsProxy()) { + proxy->Value(value); + } else { + Intl()->Value(value); + } + aValue.Assign(value); return NS_OK; @@ -379,10 +416,16 @@ xpcAccessible::GetBounds(int32_t* aX, int32_t* aY, NS_ENSURE_ARG_POINTER(aHeight); *aHeight = 0; - if (!Intl()) + if (IntlGeneric().IsNull()) return NS_ERROR_FAILURE; - nsIntRect rect = Intl()->Bounds(); + nsIntRect rect; + if (Accessible* acc = IntlGeneric().AsAccessible()) { + rect = acc->Bounds(); + } else { + rect = IntlGeneric().AsProxy()->Bounds(); + } + *aX = rect.x; *aY = rect.y; *aWidth = rect.width; diff --git a/accessible/xul/XULMenuAccessible.cpp b/accessible/xul/XULMenuAccessible.cpp index fde8c970b3..f93e9ad99c 100644 --- a/accessible/xul/XULMenuAccessible.cpp +++ b/accessible/xul/XULMenuAccessible.cpp @@ -407,6 +407,8 @@ XULMenupopupAccessible:: mSelectControl = do_QueryInterface(mContent->GetFlattenedTreeParent()); if (!mSelectControl) mGenericTypes &= ~eSelect; + + mStateFlags |= eNoXBLKids; } uint64_t diff --git a/b2g/locales/en-US/chrome/overrides/appstrings.properties b/b2g/locales/en-US/chrome/overrides/appstrings.properties index 3beaac64b3..96d43b6aea 100644 --- a/b2g/locales/en-US/chrome/overrides/appstrings.properties +++ b/b2g/locales/en-US/chrome/overrides/appstrings.properties @@ -30,7 +30,7 @@ externalProtocolUnknown= externalProtocolChkMsg=Remember my choice for all links of this type. externalProtocolLaunchBtn=Launch application malwareBlocked=The site at %S has been reported as an attack site and has been blocked based on your security preferences. -phishingBlocked=The website at %S has been reported as a web forgery designed to trick users into sharing personal or financial information. +deceptiveBlocked=This web page at %S has been reported as a deceptive site and has been blocked based on your security preferences. cspBlocked=This page has a content security policy that prevents it from being loaded in this way. corruptedContentError=The page you are trying to view cannot be shown because an error in the data transmission was detected. remoteXUL=This page uses an unsupported technology that is no longer available by default in Firefox. diff --git a/browser/locales/en-US/chrome/overrides/appstrings.properties b/browser/locales/en-US/chrome/overrides/appstrings.properties index 7d8936a84e..342fa78c2a 100644 --- a/browser/locales/en-US/chrome/overrides/appstrings.properties +++ b/browser/locales/en-US/chrome/overrides/appstrings.properties @@ -32,7 +32,7 @@ externalProtocolChkMsg=Remember my choice for all links of this type. externalProtocolLaunchBtn=Launch application malwareBlocked=The site at %S has been reported as an attack site and has been blocked based on your security preferences. unwantedBlocked=The site at %S has been reported as serving unwanted software and has been blocked based on your security preferences. -phishingBlocked=The website at %S has been reported as a web forgery designed to trick users into sharing personal or financial information. +deceptiveBlocked=This web page at %S has been reported as a deceptive site and has been blocked based on your security preferences. forbiddenBlocked=The site at %S has been blocked by your browser configuration. cspBlocked=This page has a content security policy that prevents it from being embedded in this way. xssBlockMode=This page contains an XSS attack that has been blocked for your security. diff --git a/config/external/nss/Makefile.in b/config/external/nss/Makefile.in index b1d1960d5f..cc56afeacd 100644 --- a/config/external/nss/Makefile.in +++ b/config/external/nss/Makefile.in @@ -264,13 +264,6 @@ DEFAULT_GMAKE_FLAGS += MAKE_OBJDIR='$$(INSTALL) -D $$(OBJDIR)' # it, creating race conditions. See bug #836220 DEFAULT_GMAKE_FLAGS += TARGETS='$$(LIBRARY) $$(SHARED_LIBRARY) $$(PROGRAM)' -ifndef WARNINGS_AS_ERRORS -DEFAULT_GMAKE_FLAGS += NSS_ENABLE_WERROR=0 -endif -ifeq ($(OS_TARGET),Android) -DEFAULT_GMAKE_FLAGS += NSS_ENABLE_WERROR=0 -endif - NSS_SRCDIR = $(topsrcdir) NSS_DIRS = @@ -370,6 +363,10 @@ endif # MOZ_FOLD_LIBS include $(topsrcdir)/config/rules.mk +ifeq (1,$(ALLOW_COMPILER_WARNINGS)) +DEFAULT_GMAKE_FLAGS += NSS_ENABLE_WERROR=0 +endif + # Can't pass this in DEFAULT_GMAKE_FLAGS because that overrides # definitions in NSS, so just export it into the sub-make's environment. ifeq (WINNT_1,$(OS_TARGET)_$(MOZ_MEMORY)) diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 9307bddc67..8a6620d85b 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -4948,7 +4948,7 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI* aURI, uint32_t bucketId; if (NS_ERROR_PHISHING_URI == aError) { - error.AssignLiteral("phishingBlocked"); + error.AssignLiteral("deceptiveBlocked"); bucketId = IsFrame() ? nsISecurityUITelemetry::WARNING_PHISHING_PAGE_FRAME : nsISecurityUITelemetry::WARNING_PHISHING_PAGE_TOP; } else { diff --git a/dom/base/test/chrome.ini b/dom/base/test/chrome.ini index 8dbaecd22a..cd8a4cad9d 100644 --- a/dom/base/test/chrome.ini +++ b/dom/base/test/chrome.ini @@ -1,5 +1,5 @@ [DEFAULT] -skip-if = buildapp == 'b2g' +skip-if = buildapp == 'b2g' || os == 'android' support-files = file_url.jsm file_empty.html diff --git a/dom/base/test/mochitest.ini b/dom/base/test/mochitest.ini index 435f953ca7..79f5f323d6 100644 --- a/dom/base/test/mochitest.ini +++ b/dom/base/test/mochitest.ini @@ -591,6 +591,7 @@ skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop spec [test_bug564047.html] [test_bug564863.xhtml] [test_bug567350.html] +[test_bug574596.html] [test_bug578096.html] skip-if = (buildapp == 'b2g' && (toolkit != 'gonk' || debug)) # b2g-debug(debug-only failure; crash) b2g-desktop(Bug 931116, b2g desktop specific, initial triage) [test_bug585978.html] diff --git a/dom/base/test/chrome/test_bug574596.html b/dom/base/test/test_bug574596.html similarity index 85% rename from dom/base/test/chrome/test_bug574596.html rename to dom/base/test/test_bug574596.html index 6a3df07f03..0978f4333d 100644 --- a/dom/base/test/chrome/test_bug574596.html +++ b/dom/base/test/test_bug574596.html @@ -5,10 +5,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=574596 --> Test for Bug 574596 - - - - + + + Mozilla Bug 574596 diff --git a/dom/browser-element/BrowserElementChildPreload.js b/dom/browser-element/BrowserElementChildPreload.js index 0e80c0f786..16862a2b56 100644 --- a/dom/browser-element/BrowserElementChildPreload.js +++ b/dom/browser-element/BrowserElementChildPreload.js @@ -1876,7 +1876,7 @@ BrowserElementChild.prototype = { sendAsyncMsg('error', { type: 'cspBlocked' }); return; case Cr.NS_ERROR_PHISHING_URI : - sendAsyncMsg('error', { type: 'phishingBlocked' }); + sendAsyncMsg('error', { type: 'deceptiveBlocked' }); return; case Cr.NS_ERROR_MALWARE_URI : sendAsyncMsg('error', { type: 'malwareBlocked' }); diff --git a/dom/locales/en-US/chrome/appstrings.properties b/dom/locales/en-US/chrome/appstrings.properties index a0efb17fd5..c1e916a9d4 100644 --- a/dom/locales/en-US/chrome/appstrings.properties +++ b/dom/locales/en-US/chrome/appstrings.properties @@ -31,7 +31,7 @@ externalProtocolChkMsg=Remember my choice for all links of this type. externalProtocolLaunchBtn=Launch application malwareBlocked=The site at %S has been reported as an attack site and has been blocked based on your security preferences. unwantedBlocked=The site at %S has been reported as serving unwanted software and has been blocked based on your security preferences. -phishingBlocked=The website at %S has been reported as a web forgery designed to trick users into sharing personal or financial information. +deceptiveBlocked=This web page at %S has been reported as a deceptive site and has been blocked based on your security preferences. forbiddenBlocked=The site at %S has been blocked by your browser configuration. cspBlocked=This page has a content security policy that prevents it from being loaded in this way. corruptedContentError=The page you are trying to view cannot be shown because an error in the data transmission was detected. diff --git a/dom/system/gonk/NetworkUtils.h b/dom/system/gonk/NetworkUtils.h index ff899d3ad3..7a3534a1e9 100644 --- a/dom/system/gonk/NetworkUtils.h +++ b/dom/system/gonk/NetworkUtils.h @@ -191,7 +191,7 @@ public: nsString mPreExternalIfname; nsString mCurInternalIfname; nsString mCurExternalIfname; - long mThreshold; + long long mThreshold; long mIpaddr; long mMask; long mGateway_long; diff --git a/dom/system/gonk/TimeZoneSettingObserver.cpp b/dom/system/gonk/TimeZoneSettingObserver.cpp index 3941bd3233..512f799088 100644 --- a/dom/system/gonk/TimeZoneSettingObserver.cpp +++ b/dom/system/gonk/TimeZoneSettingObserver.cpp @@ -45,8 +45,10 @@ public: NS_DECL_NSIOBSERVER TimeZoneSettingObserver(); - virtual ~TimeZoneSettingObserver(); static nsresult SetTimeZone(const JS::Value &aValue, JSContext *aContext); + +protected: + virtual ~TimeZoneSettingObserver(); }; class TimeZoneSettingCb final : public nsISettingsServiceCallback @@ -111,6 +113,9 @@ public: ERR("TimeZoneSettingCb::HandleError: %s\n", NS_LossyConvertUTF16toASCII(aName).get()); return NS_OK; } + +protected: + ~TimeZoneSettingCb() {} }; NS_IMPL_ISUPPORTS(TimeZoneSettingCb, nsISettingsServiceCallback) diff --git a/layout/base/RestyleManager.cpp b/layout/base/RestyleManager.cpp index 3a6fd3bc57..7fee4699b9 100644 --- a/layout/base/RestyleManager.cpp +++ b/layout/base/RestyleManager.cpp @@ -98,9 +98,7 @@ RestyleManager::RestyleManager(nsPresContext* aPresContext) , mPendingRestyles(ELEMENT_HAS_PENDING_RESTYLE | ELEMENT_IS_POTENTIAL_RESTYLE_ROOT | ELEMENT_IS_CONDITIONAL_RESTYLE_ANCESTOR) -#ifdef DEBUG , mIsProcessingRestyles(false) -#endif #ifdef RESTYLE_LOGGING , mLoggingDepth(0) #endif @@ -1744,9 +1742,7 @@ RestyleManager::ProcessPendingRestyles() // Process non-animation restyles... MOZ_ASSERT(!mIsProcessingRestyles, "Nesting calls to ProcessPendingRestyles?"); -#ifdef DEBUG mIsProcessingRestyles = true; -#endif // Before we process any restyles, we need to ensure that style // resulting from any animations is up-to-date, so that if any style @@ -1755,7 +1751,7 @@ RestyleManager::ProcessPendingRestyles() bool haveNonAnimation = mHavePendingNonAnimationRestyles || mDoRebuildAllStyleData; if (haveNonAnimation) { - IncrementAnimationGeneration(); + ++mAnimationGeneration; UpdateOnlyAnimationStyles(); } else { // If we don't have non-animation style updates, then we have queued @@ -1788,9 +1784,7 @@ RestyleManager::ProcessPendingRestyles() mPresContext->TransitionManager()->SetInAnimationOnlyStyleUpdate(false); } -#ifdef DEBUG mIsProcessingRestyles = false; -#endif NS_ASSERTION(haveNonAnimation || !mHavePendingNonAnimationRestyles, "should not have added restyles"); diff --git a/layout/base/RestyleManager.h b/layout/base/RestyleManager.h index 2b90089b91..23c625eb91 100644 --- a/layout/base/RestyleManager.h +++ b/layout/base/RestyleManager.h @@ -108,7 +108,14 @@ public: // This is normally performed automatically by ProcessPendingRestyles // but it is also called when we have out-of-band changes to animations // such as changes made through the Web Animations API. - void IncrementAnimationGeneration() { ++mAnimationGeneration; } + void IncrementAnimationGeneration() { + // We update the animation generation at start of each call to + // ProcessPendingRestyles so we should ignore any subsequent (redundant) + // calls that occur while we are still processing restyles. + if (!mIsProcessingRestyles) { + ++mAnimationGeneration; + } + } // Whether rule matching should skip styles associated with animation bool SkipAnimationRules() const { return mSkipAnimationRules; } @@ -562,9 +569,11 @@ private: RestyleTracker mPendingRestyles; -#ifdef DEBUG + // Are we currently in the middle of a call to ProcessRestyles? + // This flag is used both as a debugging aid to assert that we are not + // performing nested calls to ProcessPendingRestyles, as well as to ignore + // redundant calls to IncrementAnimationGeneration. bool mIsProcessingRestyles; -#endif #ifdef RESTYLE_LOGGING int32_t mLoggingDepth; diff --git a/layout/base/tests/chrome/test_bug370436.html b/layout/base/tests/chrome/test_bug370436.html index 49e0934b26..9ad8511aba 100644 --- a/layout/base/tests/chrome/test_bug370436.html +++ b/layout/base/tests/chrome/test_bug370436.html @@ -42,27 +42,32 @@ function startTest() ta.focus(); ta.selectionStart = ta.selectionEnd = ta.value.length; +// Note: This test, intentionally or by accident, relies on sending button '0' +// with contextMenu, which triggers some key-equiv stuff in +// PresShell::AdjustContextMenuKeyEvent. +var mouseParams = { type: 'contextmenu', button: 0 }; + /* Put cursor at start and middle of "sheep" */ synthesizeKey("VK_UP", {}) - synthesizeMouse(ta, 0, 0, { type : "contextmenu" }); + synthesizeMouse(ta, 0, 0, mouseParams); synthesizeKey("VK_RIGHT", {}) - synthesizeMouse(ta, 0, 0, { type : "contextmenu" }); + synthesizeMouse(ta, 0, 0, mouseParams); synthesizeKey("VK_RIGHT", {}) - synthesizeMouse(ta, 0, 0, { type : "contextmenu" }); + synthesizeMouse(ta, 0, 0, mouseParams); /* Put cursor at the end of "hello" */ synthesizeKey("VK_UP", {}) - synthesizeMouse(ta, 0, 0, { type : "contextmenu" }); + synthesizeMouse(ta, 0, 0, mouseParams); synthesizeKey("VK_RIGHT", {}) synthesizeKey("VK_RIGHT", {}) synthesizeKey("VK_RIGHT", {}) - synthesizeMouse(ta, 0, 0, { type : "contextmenu" }); + synthesizeMouse(ta, 0, 0, mouseParams); synthesizeKey("VK_RIGHT", {}) - synthesizeMouse(ta, 0, 0, { type : "contextmenu" }); + synthesizeMouse(ta, 0, 0, mouseParams); /* Put cursor on "welcome" */ synthesizeKey("VK_UP", {}) - synthesizeMouse(ta, 0, 0, { type : "contextmenu" }); + synthesizeMouse(ta, 0, 0, mouseParams); is(words.pop(), "welcome", "Word 1 selected correctly"); is(words.pop(), "world" , "Word 2 selected correctly"); diff --git a/layout/inspector/tests/chrome/GentiumPlus-R.woff b/layout/inspector/tests/chrome/GentiumPlus-R.woff index e9b2e8a814..ebefd081a8 100644 Binary files a/layout/inspector/tests/chrome/GentiumPlus-R.woff and b/layout/inspector/tests/chrome/GentiumPlus-R.woff differ diff --git a/layout/inspector/tests/chrome/chrome.ini b/layout/inspector/tests/chrome/chrome.ini index ce80f45923..4b2139fe04 100644 --- a/layout/inspector/tests/chrome/chrome.ini +++ b/layout/inspector/tests/chrome/chrome.ini @@ -1,5 +1,5 @@ [DEFAULT] -skip-if = buildapp == 'b2g' +skip-if = buildapp == 'b2g' || os == 'android' support-files = GentiumPlus-R.woff [test_bug467669.css] diff --git a/layout/inspector/tests/chrome/test_bug708874.xul b/layout/inspector/tests/chrome/test_bug708874.xul index fd5985e708..24056b321c 100644 --- a/layout/inspector/tests/chrome/test_bug708874.xul +++ b/layout/inspector/tests/chrome/test_bug708874.xul @@ -258,16 +258,15 @@ function testInvalid() { } function testNotElement() { - var values = [null, undefined, {}]; - try { - for each (value in values); { - DOMUtils.hasPseudoClassLock(value, ":hover"); - DOMUtils.addPseudoClassLock(value, ":hover"); - DOMUtils.removePseudoClassLock(value, ":hover"); - DOMUtils.clearPseudoClassLocks(value); - } - } catch(e) { - // just make sure we don't crash on non-elements + for (var value of [null, undefined, {}]) { + SimpleTest.doesThrow(() => DOMUtils.hasPseudoClassLock(value, ":hover"), + "hasPseudoClassLock should throw for " + value); + SimpleTest.doesThrow(() => DOMUtils.addPseudoClassLock(value, ":hover"), + "addPseudoClassLock should throw for " + value); + SimpleTest.doesThrow(() => DOMUtils.removePseudoClassLock(value, ":hover"), + "removePseudoClassLock should throw for " + value); + SimpleTest.doesThrow(() => DOMUtils.clearPseudoClassLocks(value), + "clearPseudoClassLocks should throw for " + value); } } ]]> diff --git a/layout/mathml/nsMathMLmtableFrame.cpp b/layout/mathml/nsMathMLmtableFrame.cpp index 0ec6d98e6a..951757ee0b 100644 --- a/layout/mathml/nsMathMLmtableFrame.cpp +++ b/layout/mathml/nsMathMLmtableFrame.cpp @@ -227,7 +227,7 @@ ApplyBorderToStyle(const nsMathMLmtdFrame* aFrame, } static nsMargin -ComputeBorderOverflow(nsMathMLmtdFrame* aFrame, nsStyleBorder aStyleBorder) +ComputeBorderOverflow(nsMathMLmtdFrame* aFrame, const nsStyleBorder& aStyleBorder) { nsMargin overflow; int32_t rowIndex; diff --git a/layout/xul/crashtests/366203-1.xul b/layout/xul/crashtests/366203-1.xul new file mode 100644 index 0000000000..3e2b96d30d --- /dev/null +++ b/layout/xul/crashtests/366203-1.xul @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/layout/xul/crashtests/367185-1.xhtml b/layout/xul/crashtests/367185-1.xhtml new file mode 100644 index 0000000000..08fd39fa11 --- /dev/null +++ b/layout/xul/crashtests/367185-1.xhtml @@ -0,0 +1,11 @@ + + + + +Testcase bug - ASSERTION: shouldn't use unconstrained widths anymore with nested marquees + + + + + diff --git a/layout/xul/crashtests/617089.html b/layout/xul/crashtests/617089.html new file mode 100644 index 0000000000..22e5f6d535 --- /dev/null +++ b/layout/xul/crashtests/617089.html @@ -0,0 +1,9 @@ + + + +
+
+
+
+ + diff --git a/layout/xul/crashtests/716503.html b/layout/xul/crashtests/716503.html new file mode 100644 index 0000000000..250ad2ba40 --- /dev/null +++ b/layout/xul/crashtests/716503.html @@ -0,0 +1,11 @@ + + + + +
+ diff --git a/layout/xul/crashtests/crashtests.list b/layout/xul/crashtests/crashtests.list index 716816b213..4ee6654c60 100644 --- a/layout/xul/crashtests/crashtests.list +++ b/layout/xul/crashtests/crashtests.list @@ -31,6 +31,8 @@ load 350460.xul load 360642-1.xul load 365151.xul load 366112-1.xul +asserts(0-50) load 366203-1.xul # bug 1217984 +asserts(24) asserts-if(Android&&!asyncPan,9) load 367185-1.xhtml # bug 1220345 load 369942-1.xhtml load 374102-1.xul load 376137-1.html @@ -61,7 +63,7 @@ load 404192.xhtml load 407152.xul load 408904-1.xul load 412479-1.xhtml -asserts(4) load 415394-1.xhtml # Bug 163838 +asserts(4) asserts-if(gtkWidget&&browserIsRemote,6) load 415394-1.xhtml # Bug 163838, bug 1195474 load 417509.xul load 420424-1.xul load 430356-1.xhtml @@ -75,7 +77,7 @@ load 434458-1.xul load 452185.html load 460900-1.xul load 464149-1.xul -asserts-if(winWidget,1) load 464407-1.xhtml # Bug 450974 +asserts-if(winWidget,1) asserts-if(Android,0-1) load 464407-1.xhtml # Bug 450974 on win, Bug 1267054 on Android load 467080.xul load 467481-1.xul load 470063-1.html @@ -92,4 +94,6 @@ asserts(1) load 538308-1.xul load 557174-1.xml load 564705-1.xul load 583957-1.html +load 617089.html load menulist-focused.xhtml +load 716503.html diff --git a/layout/xul/grid/reftests/reftest.list b/layout/xul/grid/reftests/reftest.list index b224e62644..a7ef9fa32b 100644 --- a/layout/xul/grid/reftests/reftest.list +++ b/layout/xul/grid/reftests/reftest.list @@ -3,16 +3,16 @@ skip-if((B2G&&browserIsRemote)||Mulet) == column-sizing-1.xul column-sizing-1-re skip-if((B2G&&browserIsRemote)||Mulet) == row-or-column-sizing-1.xul row-or-column-sizing-2.xul # Initial mulet triage: parity with B2G/B2G Desktop skip-if((B2G&&browserIsRemote)||Mulet) == row-or-column-sizing-1.xul row-or-column-sizing-3.xul # Initial mulet triage: parity with B2G/B2G Desktop skip-if((B2G&&browserIsRemote)||Mulet) == row-or-column-sizing-1.xul row-or-column-sizing-4.xul # Initial mulet triage: parity with B2G/B2G Desktop -skip-if((B2G&&browserIsRemote)||Mulet) == z-order-1.xul z-order-1-ref.xul # Initial mulet triage: parity with B2G/B2G Desktop -skip-if((B2G&&browserIsRemote)||Mulet) == z-order-2.xul z-order-2-ref.xul # Initial mulet triage: parity with B2G/B2G Desktop -skip-if((B2G&&browserIsRemote)||Mulet) == not-full-basic.xul not-full-basic-ref.xhtml # Initial mulet triage: parity with B2G/B2G Desktop -skip-if((B2G&&browserIsRemote)||Mulet) == not-full-grid-pack-align.xul not-full-basic-ref.xhtml # Initial mulet triage: parity with B2G/B2G Desktop -skip-if((B2G&&browserIsRemote)||Mulet) == not-full-row-group-align.xul not-full-row-group-align-ref.xhtml # does anyone want/need this behavior? # Initial mulet triage: parity with B2G/B2G Desktop -skip-if((B2G&&browserIsRemote)||Mulet) == not-full-row-group-pack.xul not-full-row-group-pack-ref.xhtml # Initial mulet triage: parity with B2G/B2G Desktop -skip-if((B2G&&browserIsRemote)||Mulet) == not-full-row-group-direction.xul not-full-row-group-direction-ref.xhtml # Initial mulet triage: parity with B2G/B2G Desktop -skip-if((B2G&&browserIsRemote)||Mulet) == not-full-row-leaf-align.xul not-full-basic-ref.xhtml # Initial mulet triage: parity with B2G/B2G Desktop -skip-if((B2G&&browserIsRemote)||Mulet) == not-full-row-leaf-pack.xul not-full-row-leaf-pack-ref.xhtml # Initial mulet triage: parity with B2G/B2G Desktop -skip-if((B2G&&browserIsRemote)||Mulet) == not-full-row-leaf-direction.xul not-full-row-leaf-pack-ref.xhtml -skip-if(B2G||Mulet) random-if(transparentScrollbars) fails-if(Android&&browserIsRemote) fuzzy-if(OSX==1010,1,565) == scrollable-columns.xul scrollable-columns-ref.xhtml # bug 650597, 732569 # Initial mulet triage: parity with B2G/B2G Desktop +skip-if((B2G&&browserIsRemote)||Mulet) fuzzy-if(skiaContent,1,60000) == z-order-1.xul z-order-1-ref.xul # Initial mulet triage: parity with B2G/B2G Desktop +skip-if((B2G&&browserIsRemote)||Mulet) fuzzy-if(skiaContent,1,60000) == z-order-2.xul z-order-2-ref.xul # Initial mulet triage: parity with B2G/B2G Desktop +skip-if((B2G&&browserIsRemote)||Mulet) fuzzy-if(skiaContent,1,60000) == not-full-basic.xul not-full-basic-ref.xhtml # Initial mulet triage: parity with B2G/B2G Desktop +skip-if((B2G&&browserIsRemote)||Mulet) fuzzy-if(skiaContent,1,110000) == not-full-grid-pack-align.xul not-full-basic-ref.xhtml # Initial mulet triage: parity with B2G/B2G Desktop +skip-if((B2G&&browserIsRemote)||Mulet) fuzzy-if(skiaContent,1,30000) == not-full-row-group-align.xul not-full-row-group-align-ref.xhtml # does anyone want/need this behavior? # Initial mulet triage: parity with B2G/B2G Desktop +skip-if((B2G&&browserIsRemote)||Mulet) fuzzy-if(skiaContent,1,10000) == not-full-row-group-pack.xul not-full-row-group-pack-ref.xhtml # Initial mulet triage: parity with B2G/B2G Desktop +skip-if((B2G&&browserIsRemote)||Mulet) fuzzy-if(skiaContent,1,50000) == not-full-row-group-direction.xul not-full-row-group-direction-ref.xhtml # Initial mulet triage: parity with B2G/B2G Desktop +skip-if((B2G&&browserIsRemote)||Mulet) fuzzy-if(skiaContent,1,60000) == not-full-row-leaf-align.xul not-full-basic-ref.xhtml # Initial mulet triage: parity with B2G/B2G Desktop +skip-if((B2G&&browserIsRemote)||Mulet) fuzzy-if(skiaContent,1,50000) == not-full-row-leaf-pack.xul not-full-row-leaf-pack-ref.xhtml # Initial mulet triage: parity with B2G/B2G Desktop +skip-if((B2G&&browserIsRemote)||Mulet) fuzzy-if(skiaContent,1,80000) == not-full-row-leaf-direction.xul not-full-row-leaf-pack-ref.xhtml +skip-if(B2G||Mulet) random-if(transparentScrollbars) fuzzy-if(OSX==1010,1,565) == scrollable-columns.xul scrollable-columns-ref.xhtml # bug 650597 # Initial mulet triage: parity with B2G/B2G Desktop fails skip-if((B2G&&browserIsRemote)||Mulet) == scrollable-rows.xul scrollable-rows-ref.xhtml # Initial mulet triage: parity with B2G/B2G Desktop skip-if((B2G&&browserIsRemote)||Mulet) == sizing-2d.xul sizing-2d-ref.xul # Initial mulet triage: parity with B2G/B2G Desktop diff --git a/layout/xul/test/browser.ini b/layout/xul/test/browser.ini index 708007d197..3fa28b1536 100644 --- a/layout/xul/test/browser.ini +++ b/layout/xul/test/browser.ini @@ -3,5 +3,6 @@ [browser_bug685470.js] [browser_bug703210.js] [browser_bug706743.js] +skip-if = (os == 'linux') # Bug 1157576 [browser_bug1163304.js] skip-if = os != 'linux' && os != 'win' // Due to testing menubar behavior with keyboard diff --git a/layout/xul/test/browser_bug685470.js b/layout/xul/test/browser_bug685470.js index 8bd3ba21ad..c86231bc76 100644 --- a/layout/xul/test/browser_bug685470.js +++ b/layout/xul/test/browser_bug685470.js @@ -6,28 +6,14 @@ add_task(function* () { SpecialPowers.pushPrefEnv({"set": [["ui.tooltipDelay", 0]]}, resolve); }); - var popup = false; - var doc; - var win; - var p1; + yield BrowserTestUtils.synthesizeMouseAtCenter("#p1", { type: "mousemove" }, + gBrowser.selectedBrowser); + yield BrowserTestUtils.synthesizeMouseAtCenter("#p1", { }, gBrowser.selectedBrowser); - let onPopupShown = function(aEvent) { - popup = true; - } - document.addEventListener("popupshown", onPopupShown, true); + // Wait until the tooltip timeout triggers that would normally have opened the popup. + yield new Promise(resolve => setTimeout(resolve, 0)); + is(document.getElementById("aHTMLTooltip").state, "closed", "local tooltip is closed"); + is(document.getElementById("remoteBrowserTooltip").state, "closed", "remote tooltip is closed"); - // Send a mousemove at a known position to start the test. - BrowserTestUtils.synthesizeMouseAtCenter("#p1", { type: "mousemove" }, - gBrowser.selectedBrowser); - BrowserTestUtils.synthesizeMouseAtCenter("#p1", { }, gBrowser.selectedBrowser); - - yield new Promise(resolve => { - setTimeout(function() { - is(popup, false, "shouldn't get tooltip after click"); - resolve(); - }, 200); - }); - - document.removeEventListener("popupshown", onPopupShown, true); gBrowser.removeCurrentTab(); }); diff --git a/layout/xul/test/browser_bug703210.js b/layout/xul/test/browser_bug703210.js index 728d2adbfd..cfd626b1cd 100644 --- a/layout/xul/test/browser_bug703210.js +++ b/layout/xul/test/browser_bug703210.js @@ -15,14 +15,14 @@ add_task(function* () { // Send a mousemove at a known position to start the test. yield BrowserTestUtils.synthesizeMouseAtCenter("#p2", { type: "mousemove" }, browser); - let popupShownPromise = BrowserTestUtils.waitForEvent(document, "popupshown", event => { + let popupShownPromise = BrowserTestUtils.waitForEvent(document, "popupshown", false, event => { is(event.originalTarget.localName, "tooltip", "tooltip is showing"); return true; }); yield BrowserTestUtils.synthesizeMouseAtCenter("#p1", { type: "mousemove" }, browser); yield popupShownPromise; - let popupHiddenPromise = BrowserTestUtils.waitForEvent(document, "popuphidden", event => { + let popupHiddenPromise = BrowserTestUtils.waitForEvent(document, "popuphidden", false, event => { is(event.originalTarget.localName, "tooltip", "tooltip is hidden"); return true; }); diff --git a/layout/xul/test/test_bug477754.xul b/layout/xul/test/test_bug477754.xul index 111c5b805d..f72b1fffa5 100644 --- a/layout/xul/test/test_bug477754.xul +++ b/layout/xul/test/test_bug477754.xul @@ -38,8 +38,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=477754 }, false); function doTest() { - is(Math.round(testAnchor.getBoundingClientRect().right) - - Math.round(testPopup.getBoundingClientRect().right), 10, + is(Math.round(testAnchor.getBoundingClientRect().right - + testPopup.getBoundingClientRect().right), 10, "RTL popup's right offset should be equal to the x offset passed to openPopup"); testPopup.hidePopup(); SimpleTest.finish(); diff --git a/layout/xul/test/test_bug987230.xul b/layout/xul/test/test_bug987230.xul index 2a61221d71..b2b47f4700 100644 --- a/layout/xul/test/test_bug987230.xul +++ b/layout/xul/test/test_bug987230.xul @@ -49,6 +49,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=987230 /** Test for Bug 987230 **/ SimpleTest.waitForExplicitFinish(); + SimpleTest.requestCompleteLog(); + const Ci = Components.interfaces; const Cc = Components.classes; @@ -68,6 +70,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=987230 let x = aOffsetX + win.mozInnerScreenX + rect.left; let y = aOffsetY + win.mozInnerScreenY + rect.top; + info("Sending mousedown+up for offsets: " + aOffsetX + ", " + aOffsetY + + "; innerscreen: " + win.mozInnerScreenX + ", " + win.mozInnerScreenY + + "; rect: " + rect.left + ", " + rect.top + "."); + info("Resulting x, y, scale: " + x + ", " + y + ", " + scale); + info("Final params: " + (x * scale) + ", " + (y * scale)); utils.sendNativeMouseEvent(x * scale, y * scale, mouseDown, 0, null); utils.sendNativeMouseEvent(x * scale, y * scale, mouseUp, 0, null); } @@ -85,6 +92,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=987230 let outsideOfFrameX = (window.mozInnerScreenX + frameRect.width + 100) * scale; let outsideOfFrameY = Math.max(0, window.mozInnerScreenY - 100) * scale; + info("Mousemove: " + outsideOfFrameX + ", " + outsideOfFrameY + + " (from innerscreen " + window.mozInnerScreenX + ", " + window.mozInnerScreenY + + " and rect width " + frameRect.width + " and scale " + scale + ")"); utils.sendNativeMouseEvent(outsideOfFrameX, outsideOfFrameY, mouseMove, 0, null); SimpleTest.finish(); } diff --git a/layout/xul/test/test_windowminmaxsize.xul b/layout/xul/test/test_windowminmaxsize.xul index d41f6a5f5e..2d54ee39f3 100644 --- a/layout/xul/test/test_windowminmaxsize.xul +++ b/layout/xul/test/test_windowminmaxsize.xul @@ -207,8 +207,8 @@ function titledPanelWindowOpened(panelwindow) { var panel = panelwindow.document.documentElement.firstChild; panel.openPopup(); - panel.addEventListener("popupshown", function() doTitledPanelTest(panel), false); - panel.addEventListener("popuphidden", function() done(panelwindow), false); + panel.addEventListener("popupshown", () => doTitledPanelTest(panel), false); + panel.addEventListener("popuphidden", () => done(panelwindow), false); } function doTitledPanelTest(panel) diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 1483a48877..90e819190d 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -5510,6 +5510,10 @@ pref("reader.parse-node-limit", 3000); // is disabled by default. pref("reader.parse-on-load.force-enabled", false); +// Whether we include full URLs in browser console errors. This is disabled +// by default because some platforms will persist these, leading to privacy issues. +pref("reader.errors.includeURLs", false); + // The default relative font size in reader mode (1-9) pref("reader.font_size", 5); diff --git a/netwerk/base/nsSimpleURI.cpp b/netwerk/base/nsSimpleURI.cpp index e716e4ac2b..c506619bc9 100644 --- a/netwerk/base/nsSimpleURI.cpp +++ b/netwerk/base/nsSimpleURI.cpp @@ -236,7 +236,7 @@ nsSimpleURI::SetScheme(const nsACString &scheme) const nsPromiseFlatCString &flat = PromiseFlatCString(scheme); if (!net_IsValidScheme(flat)) { - NS_ERROR("the given url scheme contains invalid characters"); + NS_WARNING("the given url scheme contains invalid characters"); return NS_ERROR_MALFORMED_URI; } diff --git a/netwerk/cache2/CacheFile.cpp b/netwerk/cache2/CacheFile.cpp index f6efda7b84..49b265c9d3 100644 --- a/netwerk/cache2/CacheFile.cpp +++ b/netwerk/cache2/CacheFile.cpp @@ -1170,7 +1170,7 @@ CacheFile::GetChunkLocked(uint32_t aIndex, ECallerType aCaller, return NS_OK; } - int64_t off = aIndex * kChunkSize; + int64_t off = aIndex * static_cast(kChunkSize); if (off < mDataSize) { // We cannot be here if this is memory only entry since the chunk must exist @@ -1312,7 +1312,7 @@ CacheFile::PreloadChunks(uint32_t aIndex) uint32_t limit = aIndex + mPreloadChunkCount; for (uint32_t i = aIndex; i < limit; ++i) { - int64_t off = i * kChunkSize; + int64_t off = i * static_cast(kChunkSize); if (off >= mDataSize) { // This chunk is beyond EOF. @@ -1774,6 +1774,8 @@ CacheFile::DataSize(int64_t* aSize) bool CacheFile::IsDoomed() { + CacheFileAutoLock lock(this); + if (!mHandle) return false; @@ -1842,7 +1844,7 @@ CacheFile::WriteMetadataIfNeededLocked(bool aFireAndForget) return; if (!IsDirty() || mOutput || mInputs.Length() || mChunks.Count() || - mWritingMetadata || mOpeningFile) + mWritingMetadata || mOpeningFile || mKill) return; if (!aFireAndForget) { diff --git a/netwerk/cache2/CacheFileIOManager.cpp b/netwerk/cache2/CacheFileIOManager.cpp index 4b0ada8d42..5461aae69d 100644 --- a/netwerk/cache2/CacheFileIOManager.cpp +++ b/netwerk/cache2/CacheFileIOManager.cpp @@ -3692,7 +3692,7 @@ CacheFileIOManager::CheckAndCreateDir(nsIFile *aFile, const char *aDir, NS_ENSURE_SUCCESS(rv, rv); if (!isEmpty) { - // Don't check the result, if this fails, that's OK. We do this + // Don't check the result, if this fails, it's OK. We do this // only for the doomed directory that doesn't need to be deleted // for the cost of completely disabling the whole browser. TrashDirectory(file); diff --git a/netwerk/cookie/nsCookieService.cpp b/netwerk/cookie/nsCookieService.cpp index 74141b24ea..c0e415b30d 100644 --- a/netwerk/cookie/nsCookieService.cpp +++ b/netwerk/cookie/nsCookieService.cpp @@ -2669,7 +2669,7 @@ nsCookieService::EnsureReadComplete() nsCString baseDomain, name, value, host, path; bool hasResult; - AutoTArray array; + nsTArray array(kMaxNumberOfCookies); while (1) { rv = stmt->ExecuteStep(&hasResult); if (NS_FAILED(rv)) { @@ -4105,8 +4105,8 @@ nsCookieService::PurgeCookies(int64_t aCurrentTimeInUsec) ("PurgeCookies(): beginning purge with %ld cookies and %lld oldest age", mDBState->cookieCount, aCurrentTimeInUsec - mDBState->cookieOldestTime)); - typedef AutoTArray PurgeList; - PurgeList purgeList; + typedef nsTArray PurgeList; + PurgeList purgeList(kMaxNumberOfCookies); nsCOMPtr removedList = do_CreateInstance(NS_ARRAY_CONTRACTID); diff --git a/netwerk/cookie/test/unit/test_bug1155169.js b/netwerk/cookie/test/unit/test_bug1155169.js index f2e810b2df..6806ffe6d5 100644 --- a/netwerk/cookie/test/unit/test_bug1155169.js +++ b/netwerk/cookie/test/unit/test_bug1155169.js @@ -1,4 +1,4 @@ -const {utils: Cu, interfaces: Ci, classes: Cc} = Components; +var {utils: Cu, interfaces: Ci, classes: Cc} = Components; Cu.import("resource://gre/modules/Services.jsm"); diff --git a/netwerk/cookie/test/unit/test_bug643051.js b/netwerk/cookie/test/unit/test_bug643051.js index 72e067f1c2..d6695054ea 100644 --- a/netwerk/cookie/test/unit/test_bug643051.js +++ b/netwerk/cookie/test/unit/test_bug643051.js @@ -1,5 +1,5 @@ -const Cc = Components.classes; -const Ci = Components.interfaces; +var Cc = Components.classes; +var Ci = Components.interfaces; Components.utils.import("resource://gre/modules/NetUtil.jsm"); Components.utils.import("resource://gre/modules/Services.jsm"); diff --git a/netwerk/cookie/test/unit/test_parser_0001.js b/netwerk/cookie/test/unit/test_parser_0001.js index 02bd037217..f885972a0a 100644 --- a/netwerk/cookie/test/unit/test_parser_0001.js +++ b/netwerk/cookie/test/unit/test_parser_0001.js @@ -1,5 +1,5 @@ -const Cc = Components.classes; -const Ci = Components.interfaces; +var Cc = Components.classes; +var Ci = Components.interfaces; Components.utils.import("resource://gre/modules/NetUtil.jsm"); Components.utils.import("resource://gre/modules/Services.jsm"); diff --git a/netwerk/cookie/test/unit/test_parser_0019.js b/netwerk/cookie/test/unit/test_parser_0019.js index bae76fa19c..7811b01fe6 100644 --- a/netwerk/cookie/test/unit/test_parser_0019.js +++ b/netwerk/cookie/test/unit/test_parser_0019.js @@ -1,5 +1,5 @@ -const Cc = Components.classes; -const Ci = Components.interfaces; +var Cc = Components.classes; +var Ci = Components.interfaces; Components.utils.import("resource://gre/modules/NetUtil.jsm"); Components.utils.import("resource://gre/modules/Services.jsm"); diff --git a/netwerk/cookie/test/unit_ipc/test_ipc_parser_0001.js b/netwerk/cookie/test/unit_ipc/test_ipc_parser_0001.js index ed2647d2e8..988c8d1961 100644 --- a/netwerk/cookie/test/unit_ipc/test_ipc_parser_0001.js +++ b/netwerk/cookie/test/unit_ipc/test_ipc_parser_0001.js @@ -1,4 +1,4 @@ -const Cu = Components.utils; +var Cu = Components.utils; Cu.import("resource://gre/modules/Services.jsm"); diff --git a/netwerk/cookie/test/unit_ipc/test_ipc_parser_0019.js b/netwerk/cookie/test/unit_ipc/test_ipc_parser_0019.js index 5e763986e4..535ac6e343 100644 --- a/netwerk/cookie/test/unit_ipc/test_ipc_parser_0019.js +++ b/netwerk/cookie/test/unit_ipc/test_ipc_parser_0019.js @@ -1,4 +1,4 @@ -const Cu = Components.utils; +var Cu = Components.utils; Cu.import("resource://gre/modules/Services.jsm"); diff --git a/netwerk/dns/mdns/libmdns/nsDNSServiceInfo.cpp b/netwerk/dns/mdns/libmdns/nsDNSServiceInfo.cpp index 8e696e1007..e2ba7e1a3a 100644 --- a/netwerk/dns/mdns/libmdns/nsDNSServiceInfo.cpp +++ b/netwerk/dns/mdns/libmdns/nsDNSServiceInfo.cpp @@ -196,7 +196,7 @@ NS_IMETHODIMP nsDNSServiceInfo::SetAttributes(nsIPropertyBag2* aAttributes) { mAttributes = aAttributes; - mIsAttributesSet = true; + mIsAttributesSet = aAttributes ? true : false; return NS_OK; } diff --git a/netwerk/dns/nsDNSService2.cpp b/netwerk/dns/nsDNSService2.cpp index d205bd65e6..bde1c59ef9 100644 --- a/netwerk/dns/nsDNSService2.cpp +++ b/netwerk/dns/nsDNSService2.cpp @@ -1052,7 +1052,7 @@ nsDNSService::SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const // - mLock size_t n = mallocSizeOf(this); - n += mResolver->SizeOfIncludingThis(mallocSizeOf); + n += mResolver ? mResolver->SizeOfIncludingThis(mallocSizeOf) : 0; n += mIPv4OnlyDomains.SizeOfExcludingThisIfUnshared(mallocSizeOf); n += mLocalDomains.SizeOfExcludingThis(mallocSizeOf); return n; diff --git a/netwerk/protocol/http/SpdySession31.cpp b/netwerk/protocol/http/SpdySession31.cpp index 994b8a3286..3ce491de1a 100644 --- a/netwerk/protocol/http/SpdySession31.cpp +++ b/netwerk/protocol/http/SpdySession31.cpp @@ -2100,6 +2100,8 @@ SpdySession31::WriteSegmentsAgain(nsAHttpSegmentWriter *writer, MOZ_ASSERT(!mNeedsCleanup, "cleanup stream set unexpectedly"); mNeedsCleanup = nullptr; /* just in case */ + // The writesegments() stack can clear mInputFrameDataStream so + // only reference this local copy of it afterwards SpdyStream31 *stream = mInputFrameDataStream; mSegmentWriter = writer; rv = mInputFrameDataStream->WriteSegments(this, count, countWritten); @@ -2108,7 +2110,7 @@ SpdySession31::WriteSegmentsAgain(nsAHttpSegmentWriter *writer, LOG3(("SpdySession31::WriteSegments session=%p stream=%p 0x%X " "stream channel pipe full\n", this, stream, stream ? stream->StreamID() : 0)); - channelPipeFull = mInputFrameDataStream->ChannelPipeFull(); + channelPipeFull = stream->ChannelPipeFull(); } mSegmentWriter = nullptr; diff --git a/netwerk/protocol/http/nsHttpChannelAuthProvider.cpp b/netwerk/protocol/http/nsHttpChannelAuthProvider.cpp index c132f40055..eff4dd9fc5 100644 --- a/netwerk/protocol/http/nsHttpChannelAuthProvider.cpp +++ b/netwerk/protocol/http/nsHttpChannelAuthProvider.cpp @@ -40,6 +40,15 @@ namespace net { #define HTTP_AUTH_DIALOG_SAME_ORIGIN_SUBRESOURCE 1 #define HTTP_AUTH_DIALOG_CROSS_ORIGIN_SUBRESOURCE 2 +#define HTTP_AUTH_BASIC_INSECURE 0 +#define HTTP_AUTH_BASIC_SECURE 1 +#define HTTP_AUTH_DIGEST_INSECURE 2 +#define HTTP_AUTH_DIGEST_SECURE 3 +#define HTTP_AUTH_NTLM_INSECURE 4 +#define HTTP_AUTH_NTLM_SECURE 5 +#define HTTP_AUTH_NEGOTIATE_INSECURE 6 +#define HTTP_AUTH_NEGOTIATE_SECURE 7 + #define MAX_DISPLAYED_USER_LENGTH 64 #define MAX_DISPLAYED_HOST_LENGTH 64 diff --git a/netwerk/system/linux/nsNotifyAddrListener_Linux.cpp b/netwerk/system/linux/nsNotifyAddrListener_Linux.cpp index ef919f8190..6fd6faf2c6 100644 --- a/netwerk/system/linux/nsNotifyAddrListener_Linux.cpp +++ b/netwerk/system/linux/nsNotifyAddrListener_Linux.cpp @@ -23,6 +23,9 @@ #include "mozilla/Services.h" #include "mozilla/Preferences.h" #include "mozilla/FileUtils.h" +#include "mozilla/SHA1.h" +#include "mozilla/Base64.h" +#include "mozilla/Telemetry.h" #ifdef MOZ_NUWA_PROCESS #include "ipc/Nuwa.h" @@ -99,6 +102,111 @@ nsNotifyAddrListener::GetLinkType(uint32_t *aLinkType) return NS_OK; } +// +// Figure out the current "network identification" string. +// +// It detects the IP of the default gateway in the routing table, then the MAC +// address of that IP in the ARP table before it hashes that string (to avoid +// information leakage). +// +void nsNotifyAddrListener::calculateNetworkId(void) +{ + const char *kProcRoute = "/proc/net/route"; /* IPv4 routes */ + const char *kProcArp = "/proc/net/arp"; + bool found = false; + + FILE *froute = fopen(kProcRoute, "r"); + if (froute) { + char buffer[512]; + uint32_t gw = 0; + char *l = fgets(buffer, sizeof(buffer), froute); + if (l) { + /* skip the title line */ + while (l) { + char interf[32]; + uint32_t dest; + uint32_t gateway; + l = fgets(buffer, sizeof(buffer), froute); + if (l) { + buffer[511]=0; /* as a precaution */ + int val = sscanf(buffer, "%31s %x %x", + interf, &dest, &gateway); + if ((3 == val) && !dest) { + gw = gateway; + break; + } + } + } + } + fclose(froute); + + if (gw) { + /* create a string to search for in the arp table */ + char searchfor[16]; + sprintf(searchfor, "%d.%d.%d.%d", + gw & 0xff, + (gw >> 8) & 0xff, + (gw >> 16) & 0xff, + gw >> 24); + + FILE *farp = fopen(kProcArp, "r"); + if (farp) { + l = fgets(buffer, sizeof(buffer), farp); + while (l) { + /* skip the title line */ + l = fgets(buffer, sizeof(buffer), farp); + if (l) { + buffer[511]=0; /* as a precaution */ + int p[4]; + char type[16]; + char flags[16]; + char hw[32]; + if (7 == sscanf(buffer, "%u.%u.%u.%u %15s %15s %31s", + &p[0], &p[1], &p[2], &p[3], + type, flags, hw)) { + uint32_t searchip = p[0] | (p[1] << 8) | + (p[2] << 16) | (p[3] << 24); + if (gw == searchip) { + LOG(("networkid: MAC %s\n", hw)); + nsAutoCString mac(hw); + // This 'addition' could potentially be a + // fixed number from the profile or something. + nsAutoCString addition("local-rubbish"); + nsAutoCString output; + SHA1Sum sha1; + nsCString combined(mac + addition); + sha1.update(combined.get(), combined.Length()); + uint8_t digest[SHA1Sum::kHashSize]; + sha1.finish(digest); + nsCString newString(reinterpret_cast(digest), + SHA1Sum::kHashSize); + Base64Encode(newString, output); + LOG(("networkid: id %s\n", output.get())); + if (mNetworkId != output) { + // new id + Telemetry::Accumulate(Telemetry::NETWORK_ID, 1); + mNetworkId = output; + } + else { + // same id + Telemetry::Accumulate(Telemetry::NETWORK_ID, 2); + } + found = true; + break; + } + } + } + } + fclose(farp); + } /* if (farp) */ + } /* if (gw) */ + } /* if (froute) */ + if (!found) { + // no id + Telemetry::Accumulate(Telemetry::NETWORK_ID, 0); + } +} + // // Check if there's a network interface available to do networking on. // @@ -252,6 +360,7 @@ void nsNotifyAddrListener::OnNetlinkMessage(int aNetlinkSocket) if (networkChange) { checkLink(); + calculateNetworkId(); } } @@ -288,6 +397,8 @@ nsNotifyAddrListener::Run() fds[1].events = POLLIN; fds[1].revents = 0; + calculateNetworkId(); + nsresult rv = NS_OK; bool shutdown = false; int pollWait = -1; diff --git a/netwerk/system/linux/nsNotifyAddrListener_Linux.h b/netwerk/system/linux/nsNotifyAddrListener_Linux.h index dcbfee94a5..a2b8f22779 100644 --- a/netwerk/system/linux/nsNotifyAddrListener_Linux.h +++ b/netwerk/system/linux/nsNotifyAddrListener_Linux.h @@ -61,6 +61,10 @@ private: // Sends the network event. nsresult SendEvent(const char *aEventID); + // Figure out the current "network identification" + void calculateNetworkId(void); + nsCString mNetworkId; + // Checks if there's a network "link" void checkLink(void); diff --git a/netwerk/system/mac/nsNetworkLinkService.h b/netwerk/system/mac/nsNetworkLinkService.h index 8dfae8a867..ee54622478 100644 --- a/netwerk/system/mac/nsNetworkLinkService.h +++ b/netwerk/system/mac/nsNetworkLinkService.h @@ -47,6 +47,8 @@ private: static void IPConfigChanged(SCDynamicStoreRef store, CFArrayRef changedKeys, void *info); + void calculateNetworkId(void); + nsCString mNetworkId; }; #endif /* NSNETWORKLINKSERVICEMAC_H_ */ diff --git a/netwerk/system/mac/nsNetworkLinkService.mm b/netwerk/system/mac/nsNetworkLinkService.mm index fda5ca8934..f499f1e3ab 100644 --- a/netwerk/system/mac/nsNetworkLinkService.mm +++ b/netwerk/system/mac/nsNetworkLinkService.mm @@ -3,7 +3,18 @@ * 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/. */ -#include "nsNetworkLinkService.h" +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include #include "nsCOMPtr.h" #include "nsIObserverService.h" #include "nsServiceManagerUtils.h" @@ -11,6 +22,9 @@ #include "nsCRT.h" #include "mozilla/Logging.h" #include "mozilla/Preferences.h" +#include "mozilla/SHA1.h" +#include "mozilla/Base64.h" +#include "nsNetworkLinkService.h" #import #import @@ -90,13 +104,180 @@ nsNetworkLinkService::GetLinkStatusKnown(bool *aIsUp) NS_IMETHODIMP nsNetworkLinkService::GetLinkType(uint32_t *aLinkType) { - NS_ENSURE_ARG_POINTER(aLinkType); + NS_ENSURE_ARG_POINTER(aLinkType); - // XXX This function has not yet been implemented for this platform - *aLinkType = nsINetworkLinkService::LINK_TYPE_UNKNOWN; - return NS_OK; + // XXX This function has not yet been implemented for this platform + *aLinkType = nsINetworkLinkService::LINK_TYPE_UNKNOWN; + return NS_OK; } +#ifndef SA_SIZE +#define SA_SIZE(sa) \ + ( (!(sa) || ((struct sockaddr *)(sa))->sa_len == 0) ? \ + sizeof(uint32_t) : \ + 1 + ( (((struct sockaddr *)(sa))->sa_len - 1) | (sizeof(uint32_t) - 1) ) ) +#endif + +static char *getMac(struct sockaddr_dl *sdl, char *buf, size_t bufsize) +{ + char *cp; + int n, p = 0; + + buf[0] = 0; + cp = (char *)LLADDR(sdl); + n = sdl->sdl_alen; + if (n > 0) { + while (--n >= 0) { + p += snprintf(&buf[p], bufsize - p, "%02x%s", + *cp++ & 0xff, n > 0 ? ":" : ""); + } + } + return buf; +} + +/* If the IP matches, get the MAC and return true */ +static bool matchIp(struct sockaddr_dl *sdl, struct sockaddr_inarp *addr, + char *ip, char *buf, size_t bufsize) +{ + if (sdl->sdl_alen) { + if (!strcmp(inet_ntoa(addr->sin_addr), ip)) { + getMac(sdl, buf, bufsize); + return true; /* done! */ + } + } + return false; /* continue */ +} + +/* + * Scan for the 'IP' address in the ARP table and store the corresponding MAC + * address in 'mac'. The output buffer is 'maclen' bytes big. + * + * Returns 'true' if it found the IP and returns a MAC. + */ +static bool scanArp(char *ip, char *mac, size_t maclen) +{ + int mib[6]; + char *lim, *next; + int st; + + mib[0] = CTL_NET; + mib[1] = PF_ROUTE; + mib[2] = 0; + mib[3] = AF_INET; + mib[4] = NET_RT_FLAGS; + mib[5] = RTF_LLINFO; + + size_t needed; + if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) { + return false; + } + if (needed == 0) { + // empty table + return false; + } + + UniquePtr buf(new char[needed]); + + for (;;) { + st = sysctl(mib, 6, &buf[0], &needed, NULL, 0); + if (st == 0 || errno != ENOMEM) { + break; + } + needed += needed / 8; + + auto tmp = MakeUnique(needed); + memcpy(&tmp[0], &buf[0], needed); + buf = Move(tmp); + } + if (st == -1) { + return false; + } + lim = &buf[needed]; + + struct rt_msghdr *rtm; + for (next = &buf[0]; next < lim; next += rtm->rtm_msglen) { + rtm = reinterpret_cast(next); + struct sockaddr_inarp *sin2 = + reinterpret_cast(rtm + 1); + struct sockaddr_dl *sdl = + reinterpret_cast + ((char *)sin2 + SA_SIZE(sin2)); + if (matchIp(sdl, sin2, ip, mac, maclen)) { + return true; + } + } + + return false; +} + +static int routingTable(char *gw) +{ + size_t needed; + int mib[6]; + struct rt_msghdr *rtm; + struct sockaddr *sa; + struct sockaddr_in *sockin; + + mib[0] = CTL_NET; + mib[1] = PF_ROUTE; + mib[2] = 0; + mib[3] = 0; + mib[4] = NET_RT_DUMP; + mib[5] = 0; + if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) { + return 1; + } + + UniquePtr buf(new char[needed]); + + if (sysctl(mib, 6, &buf[0], &needed, NULL, 0) < 0) { + return 3; + } + + rtm = reinterpret_cast(&buf[0]); + sa = reinterpret_cast(rtm + 1); + sa = reinterpret_cast(SA_SIZE(sa) + (char *)sa); + sockin = reinterpret_cast(sa); + inet_ntop(AF_INET, &sockin->sin_addr.s_addr, gw, MAXHOSTNAMELEN-1); + + return 0; +} + +// +// Figure out the current "network identification" string. +// +// It detects the IP of the default gateway in the routing table, then the MAC +// address of that IP in the ARP table before it hashes that string (to avoid +// information leakage). +// +void nsNetworkLinkService::calculateNetworkId(void) +{ + char hw[MAXHOSTNAMELEN]; + routingTable(hw); + + char mac[256]; // big enough for a printable MAC address + if (scanArp(hw, mac, sizeof(mac))) { + LOG(("networkid: MAC %s\n", hw)); + nsAutoCString mac(hw); + // This 'addition' could potentially be a + // fixed number from the profile or something. + nsAutoCString addition("local-rubbish"); + nsAutoCString output; + SHA1Sum sha1; + nsCString combined(mac + addition); + sha1.update(combined.get(), combined.Length()); + uint8_t digest[SHA1Sum::kHashSize]; + sha1.finish(digest); + nsCString newString(reinterpret_cast(digest), + SHA1Sum::kHashSize); + Base64Encode(newString, output); + LOG(("networkid: id %s\n", output.get())); + mNetworkId = output; + } + +} + + NS_IMETHODIMP nsNetworkLinkService::Observe(nsISupports *subject, const char *topic, @@ -298,8 +479,9 @@ nsNetworkLinkService::SendEvent(bool aNetworkChanged) { nsCOMPtr observerService = do_GetService("@mozilla.org/observer-service;1"); - if (!observerService) + if (!observerService) { return; + } const char *event; if (aNetworkChanged) { @@ -331,4 +513,5 @@ nsNetworkLinkService::ReachabilityChanged(SCNetworkReachabilityRef target, service->UpdateReachability(); service->SendEvent(false); + service->calculateNetworkId(); } diff --git a/netwerk/system/win32/nsNotifyAddrListener.cpp b/netwerk/system/win32/nsNotifyAddrListener.cpp index 8654851711..fdc0f9c78c 100644 --- a/netwerk/system/win32/nsNotifyAddrListener.cpp +++ b/netwerk/system/win32/nsNotifyAddrListener.cpp @@ -4,6 +4,10 @@ * 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/. */ +// We define this to make our use of inet_ntoa() pass. The "proper" function +// inet_ntop() doesn't exist on Windows XP. +#define _WINSOCK_DEPRECATED_NO_WARNINGS + #include #include #include @@ -29,6 +33,8 @@ #include "mozilla/Services.h" #include "nsCRT.h" #include "mozilla/Preferences.h" +#include "mozilla/SHA1.h" +#include "mozilla/Base64.h" #include #include @@ -141,11 +147,133 @@ nsNotifyAddrListener::GetLinkStatusKnown(bool *aIsUp) NS_IMETHODIMP nsNotifyAddrListener::GetLinkType(uint32_t *aLinkType) { - NS_ENSURE_ARG_POINTER(aLinkType); + NS_ENSURE_ARG_POINTER(aLinkType); - // XXX This function has not yet been implemented for this platform - *aLinkType = nsINetworkLinkService::LINK_TYPE_UNKNOWN; - return NS_OK; + // XXX This function has not yet been implemented for this platform + *aLinkType = nsINetworkLinkService::LINK_TYPE_UNKNOWN; + return NS_OK; +} + +static bool macAddr(BYTE addr[], DWORD len, char *buf, size_t buflen) +{ + buf[0] = '\0'; + if (!addr || !len || (len * 3 > buflen)) { + return false; + } + + for (DWORD i = 0; i < len; ++i) { + sprintf_s(buf + (i * 3), sizeof(buf + (i * 3)), + "%02x%s", addr[i], (i == len-1) ? "" : ":"); + } + return true; +} + +void nsNotifyAddrListener::findMac(char *gateway) +{ + // query for buffer size needed + DWORD dwActualSize = 0; + + // GetIpNetTable gets the IPv4 to physical address mapping table + DWORD status = GetIpNetTable(NULL, &dwActualSize, FALSE); + if (status == ERROR_INSUFFICIENT_BUFFER) { + // the expected route, now with a known buffer size + UniquePtr buf(new char[dwActualSize]); + PMIB_IPNETTABLE pIpNetTable = + reinterpret_cast(&buf[0]); + + status = GetIpNetTable(pIpNetTable, &dwActualSize, FALSE); + + if (status == NO_ERROR) { + for (DWORD i = 0; i < pIpNetTable->dwNumEntries; ++i) { + DWORD dwCurrIndex = pIpNetTable->table[i].dwIndex; + char hw[256]; + + if (!macAddr(pIpNetTable->table[i].bPhysAddr, + pIpNetTable->table[i].dwPhysAddrLen, + hw, sizeof(hw))) { + // failed to get the MAC + continue; + } + + struct in_addr addr; + addr.s_addr = pIpNetTable->table[i].dwAddr; + + if (!strcmp(gateway, inet_ntoa(addr))) { + LOG(("networkid: MAC %s\n", hw)); + nsAutoCString mac(hw); + // This 'addition' could potentially be a + // fixed number from the profile or something. + nsAutoCString addition("local-rubbish"); + nsAutoCString output; + SHA1Sum sha1; + nsCString combined(mac + addition); + sha1.update(combined.get(), combined.Length()); + uint8_t digest[SHA1Sum::kHashSize]; + sha1.finish(digest); + nsCString newString(reinterpret_cast(digest), + SHA1Sum::kHashSize); + Base64Encode(newString, output); + LOG(("networkid: id %s\n", output.get())); + mNetworkId = output; + break; + } + } + } + } +} + +// returns 'true' when the gw is found and stored +static bool defaultgw(char *gateway) // at least 128 bytes buffer +{ + PMIB_IPFORWARDTABLE pIpForwardTable = NULL; + + DWORD dwSize = 0; + if (GetIpForwardTable(NULL, &dwSize, 0) != ERROR_INSUFFICIENT_BUFFER) { + return false; + } + + UniquePtr buf(new char[dwSize]); + pIpForwardTable = reinterpret_cast(&buf[0]); + + // Note that the IPv4 addresses returned in GetIpForwardTable entries are + // in network byte order + + DWORD retVal = GetIpForwardTable(pIpForwardTable, &dwSize, 0); + if (retVal == NO_ERROR) { + for (unsigned int i = 0; i < pIpForwardTable->dwNumEntries; ++i) { + // Convert IPv4 addresses to strings + struct in_addr IpAddr; + IpAddr.S_un.S_addr = static_cast + (pIpForwardTable->table[i].dwForwardDest); + char szDestIp[128]; + strcpy_s(szDestIp, sizeof (szDestIp), inet_ntoa(IpAddr)); + + if (!strcmp("0.0.0.0", szDestIp)) { + // Default gateway! + IpAddr.S_un.S_addr = static_cast + (pIpForwardTable->table[i].dwForwardNextHop); + strcpy_s(gateway, 128, inet_ntoa(IpAddr)); + return true; + } + } // for loop + } + + return false; +} + +// +// Figure out the current "network identification" string. +// +// It detects the IP of the default gateway in the routing table, then the MAC +// address of that IP in the ARP table before it hashes that string (to avoid +// information leakage). +// +void nsNotifyAddrListener::calculateNetworkId(void) +{ + char gateway[128]; + if (defaultgw(gateway)) { + findMac(gateway); + } } // Static Callback function for NotifyIpInterfaceChange API. @@ -180,6 +308,8 @@ nsNotifyAddrListener::Run() mStartTime = TimeStamp::Now(); + calculateNetworkId(); + DWORD waitTime = INFINITE; if (!sNotifyIpInterfaceChange || !sCancelMibChangeNotify2 || !mIPv6Changes) { @@ -591,4 +721,5 @@ nsNotifyAddrListener::CheckLinkStatus(void) NS_NETWORK_LINK_DATA_UP : NS_NETWORK_LINK_DATA_DOWN); } } + calculateNetworkId(); } diff --git a/netwerk/system/win32/nsNotifyAddrListener.h b/netwerk/system/win32/nsNotifyAddrListener.h index 5521ecf19a..d9d709bde0 100644 --- a/netwerk/system/win32/nsNotifyAddrListener.h +++ b/netwerk/system/win32/nsNotifyAddrListener.h @@ -67,6 +67,11 @@ private: // Called for every detected network change nsresult NetworkChanged(); + // Figure out the current network identification + void calculateNetworkId(void); + void findMac(char *gateway); + nsCString mNetworkId; + HANDLE mCheckEvent; // set true when mCheckEvent means shutdown diff --git a/netwerk/test/PropertiesTest.cpp b/netwerk/test/PropertiesTest.cpp index e73d4b792a..75630734cc 100644 --- a/netwerk/test/PropertiesTest.cpp +++ b/netwerk/test/PropertiesTest.cpp @@ -55,11 +55,11 @@ main(int argc, char* argv[]) ret = NS_NewChannel(&channel, uri, systemPrincipal, - nsILoadInfo::SEC_NORMAL, + nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL, nsIContentPolicy::TYPE_OTHER); if (NS_FAILED(ret)) return 1; - ret = channel->Open(&in); + ret = channel->Open2(&in); if (NS_FAILED(ret)) return 1; nsIPersistentProperties* props; diff --git a/netwerk/test/TestCallbacks.cpp b/netwerk/test/TestCallbacks.cpp deleted file mode 100644 index e6f17c9435..0000000000 --- a/netwerk/test/TestCallbacks.cpp +++ /dev/null @@ -1,283 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* 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/. */ - -#include "TestCommon.h" -#include -#ifdef WIN32 -#include -#endif -#include "nspr.h" -#include "nscore.h" -#include "nsCOMPtr.h" -#include "nsIServiceManager.h" -#include "nsIStreamListener.h" -#include "nsIInputStream.h" -#include "nsIChannel.h" -#include "nsIURL.h" -#include "nsIInterfaceRequestor.h" -#include "nsIInterfaceRequestorUtils.h" -#include "nsIDNSService.h" -#include "mozilla/Attributes.h" - -#include "nsISimpleEnumerator.h" -#include "nsNetUtil.h" -#include "nsIScriptSecurityManager.h" -#include "nsServiceManagerUtils.h" -#include "nsStringAPI.h" - -static bool gError = false; -static int32_t gKeepRunning = 0; - -#define NS_IEQUALS_IID \ - { 0x11c5c8ee, 0x1dd2, 0x11b2, \ - { 0xa8, 0x93, 0xbb, 0x23, 0xa1, 0xb6, 0x27, 0x76 }} - -class nsIEquals : public nsISupports { -public: - NS_DECLARE_STATIC_IID_ACCESSOR(NS_IEQUALS_IID) - NS_IMETHOD Equals(void *aPtr, bool *_retval) = 0; -}; - -NS_DEFINE_STATIC_IID_ACCESSOR(nsIEquals, NS_IEQUALS_IID) - -class ConsumerContext final : public nsIEquals { - - ~ConsumerContext() {} - -public: - NS_DECL_THREADSAFE_ISUPPORTS - - ConsumerContext() { } - - NS_IMETHOD Equals(void *aPtr, bool *_retval) override { - *_retval = true; - if (aPtr != this) *_retval = false; - return NS_OK; - } -}; - -NS_IMPL_ISUPPORTS(ConsumerContext, nsIEquals) - -class Consumer : public nsIStreamListener { - - virtual ~Consumer(); - -public: - NS_DECL_THREADSAFE_ISUPPORTS - NS_DECL_NSIREQUESTOBSERVER - NS_DECL_NSISTREAMLISTENER - - Consumer(); - nsresult Init(nsIURI *aURI, nsIChannel *aChannel, nsISupports *aContext); - nsresult Validate(nsIRequest *request, nsISupports *aContext); - - // member data - bool mOnStart; // have we received an OnStart? - bool mOnStop; // have we received an onStop? - int32_t mOnDataCount; // number of times OnData was called. - nsCOMPtr mURI; - nsCOMPtr mChannel; - nsCOMPtr mContext; -}; - -// nsISupports implementation -NS_IMPL_ISUPPORTS(Consumer, nsIStreamListener, nsIRequestObserver) - - -// nsIRequestObserver implementation -NS_IMETHODIMP -Consumer::OnStartRequest(nsIRequest *request, nsISupports* aContext) { - fprintf(stderr, "Consumer::OnStart() -> in\n\n"); - - if (mOnStart) { - fprintf(stderr, "INFO: multiple OnStarts received\n"); - } - mOnStart = true; - - nsresult rv = Validate(request, aContext); - if (NS_FAILED(rv)) return rv; - - fprintf(stderr, "Consumer::OnStart() -> out\n\n"); - return rv; -} - -NS_IMETHODIMP -Consumer::OnStopRequest(nsIRequest *request, nsISupports *aContext, - nsresult aStatus) { - fprintf(stderr, "Consumer::OnStop() -> in\n\n"); - - if (!mOnStart) { - gError = true; - fprintf(stderr, "ERROR: No OnStart received\n"); - } - - if (mOnStop) { - fprintf(stderr, "INFO: multiple OnStops received\n"); - } - - fprintf(stderr, "INFO: received %d OnData()s\n", mOnDataCount); - - mOnStop = true; - - nsresult rv = Validate(request, aContext); - if (NS_FAILED(rv)) return rv; - - fprintf(stderr, "Consumer::OnStop() -> out\n\n"); - return rv; -} - - -// nsIStreamListener implementation -NS_IMETHODIMP -Consumer::OnDataAvailable(nsIRequest *request, nsISupports *aContext, - nsIInputStream *aIStream, - uint64_t aOffset, uint32_t aLength) { - fprintf(stderr, "Consumer::OnData() -> in\n\n"); - - if (!mOnStart) { - gError = true; - fprintf(stderr, "ERROR: No OnStart received\n"); - } - - mOnDataCount += 1; - - nsresult rv = Validate(request, aContext); - if (NS_FAILED(rv)) return rv; - - fprintf(stderr, "Consumer::OnData() -> out\n\n"); - return rv; -} - -// Consumer implementation -Consumer::Consumer() { - mOnStart = mOnStop = false; - mOnDataCount = 0; - gKeepRunning++; -} - -Consumer::~Consumer() { - fprintf(stderr, "Consumer::~Consumer -> in\n\n"); - - if (!mOnStart) { - gError = true; - fprintf(stderr, "ERROR: Never got an OnStart\n"); - } - - if (!mOnStop) { - gError = true; - fprintf(stderr, "ERROR: Never got an OnStop \n"); - } - - fprintf(stderr, "Consumer::~Consumer -> out\n\n"); - if (--gKeepRunning == 0) - QuitPumpingEvents(); -} - -nsresult -Consumer::Init(nsIURI *aURI, nsIChannel* aChannel, nsISupports *aContext) { - mURI = aURI; - mChannel = aChannel; - mContext = do_QueryInterface(aContext); - return NS_OK; -} - -nsresult -Consumer::Validate(nsIRequest* request, nsISupports *aContext) { - nsresult rv = NS_OK; - nsCOMPtr uri; - nsCOMPtr aChannel = do_QueryInterface(request); - - rv = aChannel->GetURI(getter_AddRefs(uri)); - if (NS_FAILED(rv)) return rv; - - bool same = false; - - rv = mURI->Equals(uri, &same); - if (NS_FAILED(rv)) return rv; - - if (!same) - fprintf(stderr, "INFO: URIs do not match\n"); - - rv = mContext->Equals((void*)aContext, &same); - if (NS_FAILED(rv)) return rv; - - if (!same) { - gError = true; - fprintf(stderr, "ERROR: Contexts do not match\n"); - } - return rv; -} - -nsresult StartLoad(const char *); - -int main(int argc, char *argv[]) { - if (test_common_init(&argc, &argv) != 0) - return -1; - - nsresult rv = NS_OK; - bool cmdLineURL = false; - - if (argc > 1) { - // run in signle url mode - cmdLineURL = true; - } - - rv = NS_InitXPCOM2(nullptr, nullptr, nullptr); - if (NS_FAILED(rv)) return -1; - - if (cmdLineURL) { - rv = StartLoad(argv[1]); - } else { - rv = StartLoad("http://badhostnamexyz/test.txt"); - } - if (NS_FAILED(rv)) return -1; - - // Enter the message pump to allow the URL load to proceed. - PumpEvents(); - - NS_ShutdownXPCOM(nullptr); - if (gError) { - fprintf(stderr, "\n\n-------ERROR-------\n\n"); - } - return 0; -} - -nsresult StartLoad(const char *aURISpec) { - nsresult rv = NS_OK; - - // create a context - ConsumerContext *context = new ConsumerContext; - nsCOMPtr contextSup = do_QueryInterface(context, &rv); - if (NS_FAILED(rv)) return rv; - - // create a uri - nsCOMPtr uri; - rv = NS_NewURI(getter_AddRefs(uri), aURISpec); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr secman = - do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv); - if (NS_FAILED(rv)) return rv; - nsCOMPtr systemPrincipal; - rv = secman->GetSystemPrincipal(getter_AddRefs(systemPrincipal)); - if (NS_FAILED(rv)) return rv; - - // create a channel - nsCOMPtr channel; - rv = NS_NewChannel(getter_AddRefs(channel), - uri, - systemPrincipal, - nsILoadInfo::SEC_NORMAL, - nsIContentPolicy::TYPE_OTHER); - if (NS_FAILED(rv)) return rv; - - Consumer *consumer = new Consumer; - rv = consumer->Init(uri, channel, contextSup); - if (NS_FAILED(rv)) return rv; - - // kick off the load - nsCOMPtr request; - return channel->AsyncOpen(static_cast(consumer), contextSup); -} diff --git a/netwerk/test/TestHttp.cpp b/netwerk/test/TestHttp.cpp deleted file mode 100644 index 3bb87592ce..0000000000 --- a/netwerk/test/TestHttp.cpp +++ /dev/null @@ -1,188 +0,0 @@ -#include "nsNetUtil.h" -#include "nsIEventQueueService.h" -#include "nsIServiceManager.h" -#include "nsIComponentRegistrar.h" -#include "nsIInterfaceRequestor.h" -#include "nsIInterfaceRequestorUtils.h" -#include "nsIProgressEventSink.h" -#include -#include "nsIContentPolicy.h" -#include "mozilla/LoadInfo.h" -#include "nsContentUtils.h" - -#define RETURN_IF_FAILED(rv, step) \ - PR_BEGIN_MACRO \ - if (NS_FAILED(rv)) { \ - printf(">>> %s failed: rv=%x\n", step, rv); \ - return rv;\ - } \ - PR_END_MACRO - -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); -static nsIEventQueue* gEventQ = nullptr; -static bool gKeepRunning = true; - -//----------------------------------------------------------------------------- -// nsIStreamListener implementation -//----------------------------------------------------------------------------- - -class MyListener : public nsIStreamListener -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIREQUESTOBSERVER - NS_DECL_NSISTREAMLISTENER - - MyListener() { } - virtual ~MyListener() {} -}; - -NS_IMPL_ISUPPORTS(MyListener, - nsIRequestObserver, - nsIStreamListener) - -NS_IMETHODIMP -MyListener::OnStartRequest(nsIRequest *req, nsISupports *ctxt) -{ - printf(">>> OnStartRequest\n"); - return NS_OK; -} - -NS_IMETHODIMP -MyListener::OnStopRequest(nsIRequest *req, nsISupports *ctxt, nsresult status) -{ - printf(">>> OnStopRequest status=%x\n", status); - gKeepRunning = false; - return NS_OK; -} - -NS_IMETHODIMP -MyListener::OnDataAvailable(nsIRequest *req, nsISupports *ctxt, - nsIInputStream *stream, - uint64_t offset, uint32_t count) -{ - printf(">>> OnDataAvailable [count=%u]\n", count); - - char buf[256]; - nsresult rv; - uint32_t bytesRead=0; - - while (count) { - uint32_t amount = std::min(count, sizeof(buf)); - - rv = stream->Read(buf, amount, &bytesRead); - if (NS_FAILED(rv)) { - printf(">>> stream->Read failed with rv=%x\n", rv); - return rv; - } - - fwrite(buf, 1, bytesRead, stdout); - - count -= bytesRead; - } - return NS_OK; -} - -//----------------------------------------------------------------------------- -// NotificationCallbacks implementation -//----------------------------------------------------------------------------- - -class MyNotifications : public nsIInterfaceRequestor - , public nsIProgressEventSink -{ -public: - NS_DECL_THREADSAFE_ISUPPORTS - NS_DECL_NSIINTERFACEREQUESTOR - NS_DECL_NSIPROGRESSEVENTSINK - - MyNotifications() { } - virtual ~MyNotifications() {} -}; - -NS_IMPL_ISUPPORTS(MyNotifications, - nsIInterfaceRequestor, - nsIProgressEventSink) - -NS_IMETHODIMP -MyNotifications::GetInterface(const nsIID &iid, void **result) -{ - return QueryInterface(iid, result); -} - -NS_IMETHODIMP -MyNotifications::OnStatus(nsIRequest *req, nsISupports *ctx, - nsresult status, const char16_t *statusText) -{ - printf("status: %x\n", status); - return NS_OK; -} - -NS_IMETHODIMP -MyNotifications::OnProgress(nsIRequest *req, nsISupports *ctx, - uint64_t progress, uint64_t progressMax) -{ - printf("progress: %llu/%llu\n", progress, progressMax); - return NS_OK; -} - -//----------------------------------------------------------------------------- -// main, etc.. -//----------------------------------------------------------------------------- - - -int main(int argc, char **argv) -{ - nsresult rv; - - if (argc == 1) { - printf("usage: TestHttp \n"); - return -1; - } - { - nsCOMPtr servMan; - NS_InitXPCOM2(getter_AddRefs(servMan), nullptr, nullptr); - nsCOMPtr registrar = do_QueryInterface(servMan); - NS_ASSERTION(registrar, "Null nsIComponentRegistrar"); - if (registrar) - registrar->AutoRegister(nullptr); - - // Create the Event Queue for this thread... - nsCOMPtr eqs = - do_GetService(kEventQueueServiceCID, &rv); - RETURN_IF_FAILED(rv, "do_GetService(EventQueueService)"); - - rv = eqs->CreateMonitoredThreadEventQueue(); - RETURN_IF_FAILED(rv, "CreateMonitoredThreadEventQueue"); - - rv = eqs->GetThreadEventQueue(NS_CURRENT_THREAD, &gEventQ); - RETURN_IF_FAILED(rv, "GetThreadEventQueue"); - - nsCOMPtr uri; - nsCOMPtr chan; - nsCOMPtr listener = new MyListener(); - nsCOMPtr callbacks = new MyNotifications(); - - rv = NS_NewURI(getter_AddRefs(uri), argv[1]); - RETURN_IF_FAILED(rv, "NS_NewURI"); - - rv = NS_NewChannel(getter_AddRefs(chan), - uri, - nsContentUtils::GetSystemPrincipal(), - nsILoadInfo::SEC_NORMAL, - nsIContentPolicy::TYPE_OTHER); - - RETURN_IF_FAILED(rv, "NS_NewChannel"); - - rv = chan->AsyncOpen(listener, nullptr); - RETURN_IF_FAILED(rv, "AsyncOpen"); - - while (gKeepRunning) - gEventQ->ProcessPendingEvents(); - - printf(">>> done\n"); - } // this scopes the nsCOMPtrs - // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM - rv = NS_ShutdownXPCOM(nullptr); - NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed"); - return 0; -} diff --git a/netwerk/test/TestOpen.cpp b/netwerk/test/TestOpen.cpp index 867b2610e2..5925efbb89 100644 --- a/netwerk/test/TestOpen.cpp +++ b/netwerk/test/TestOpen.cpp @@ -64,12 +64,12 @@ main(int argc, char **argv) rv = NS_NewChannel(getter_AddRefs(channel), uri, systemPrincipal, - nsILoadInfo::SEC_NORMAL, + nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL, nsIContentPolicy::TYPE_OTHER); RETURN_IF_FAILED(rv, "NS_NewChannel"); - rv = channel->Open(getter_AddRefs(stream)); - RETURN_IF_FAILED(rv, "channel->Open()"); + rv = channel->Open2(getter_AddRefs(stream)); + RETURN_IF_FAILED(rv, "channel->Open2()"); FILE* outfile = fopen(argv[2], "wb"); if (!outfile) { diff --git a/netwerk/test/TestRes.cpp b/netwerk/test/TestRes.cpp deleted file mode 100644 index 82bd994e10..0000000000 --- a/netwerk/test/TestRes.cpp +++ /dev/null @@ -1,264 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* 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/. */ - -#include "nsIResProtocolHandler.h" -#include "nsIServiceManager.h" -#include "nsIInputStream.h" -#include "nsIComponentManager.h" -#include "nsIComponentRegistrar.h" -#include "nsIStreamListener.h" -#include "nsIEventQueueService.h" -#include "nsIURI.h" -#include "nsCRT.h" -#include "nsNetCID.h" -#include "nsIScriptSecurityManager.h" -#include "nsILoadInfo.h" -#include "nsNetUtil.h" - -static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID); -static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); - -//////////////////////////////////////////////////////////////////////////////// - -nsresult -SetupMapping() -{ - nsresult rv; - - nsCOMPtr serv(do_GetService(kIOServiceCID, &rv)); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr ph; - rv = serv->GetProtocolHandler("res", getter_AddRefs(ph)); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr resPH = do_QueryInterface(ph, &rv); - if (NS_FAILED(rv)) return rv; - - rv = resPH->AppendSubstitution("foo", "file://y|/"); - if (NS_FAILED(rv)) return rv; - - rv = resPH->AppendSubstitution("foo", "file://y|/mozilla/dist/win32_D.OBJ/bin/"); - if (NS_FAILED(rv)) return rv; - - return rv; -} - -//////////////////////////////////////////////////////////////////////////////// - -nsresult -TestOpenInputStream(const char* url) -{ - nsresult rv; - - nsCOMPtr secman = - do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv); - if (NS_FAILED(rv)) return rv; - nsCOMPtr systemPrincipal; - rv = secman->GetSystemPrincipal(getter_AddRefs(systemPrincipal)); - if (NS_FAILED(rv)) return rv; - nsCOMPtr uri; - rv = NS_NewURI(getter_AddRefs(uri), url); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr channel; - rv = NS_NewChannel(getter_AddRefs(channel), - uri, - systemPrincipal, - nsILoadInfo::SEC_NORMAL, - nsIContentPolicy::TYPE_OTHER); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr in; - rv = channel->Open(getter_AddRefs(in)); - if (NS_FAILED(rv)) { - fprintf(stdout, "failed to OpenInputStream for %s\n", url); - return NS_OK; - } - - char buf[1024]; - while (1) { - uint32_t amt; - rv = in->Read(buf, sizeof(buf), &amt); - if (NS_FAILED(rv)) return rv; - if (amt == 0) break; // eof - - char* str = buf; - while (amt-- > 0) { - fputc(*str++, stdout); - } - } - nsCOMPtr uri; - char* str; - - rv = channel->GetOriginalURI(getter_AddRefs(uri)); - if (NS_FAILED(rv)) return rv; - rv = uri->GetSpec(&str); - if (NS_FAILED(rv)) return rv; - fprintf(stdout, "%s resolved to ", str); - free(str); - - rv = channel->GetURI(getter_AddRefs(uri)); - if (NS_FAILED(rv)) return rv; - rv = uri->GetSpec(&str); - if (NS_FAILED(rv)) return rv; - fprintf(stdout, "%s\n", str); - free(str); - - return NS_OK; -} - -//////////////////////////////////////////////////////////////////////////////// - -bool gDone = false; -nsIEventQueue* gEventQ = nullptr; - -class Listener : public nsIStreamListener -{ -public: - NS_DECL_ISUPPORTS - - Listener() {} - virtual ~Listener() {} - - NS_IMETHOD OnStartRequest(nsIRequest *request, nsISupports *ctxt) { - nsresult rv; - nsCOMPtr uri; - nsCOMPtr channel = do_QueryInterface(request); - - rv = channel->GetURI(getter_AddRefs(uri)); - if (NS_SUCCEEDED(rv)) { - char* str; - rv = uri->GetSpec(&str); - if (NS_SUCCEEDED(rv)) { - fprintf(stdout, "Starting to load %s\n", str); - free(str); - } - } - return NS_OK; - } - - NS_IMETHOD OnStopRequest(nsIRequest *request, nsISupports *ctxt, - nsresult aStatus) { - nsresult rv; - nsCOMPtr uri; - nsCOMPtr channel = do_QueryInterface(request); - - rv = channel->GetURI(getter_AddRefs(uri)); - if (NS_SUCCEEDED(rv)) { - char* str; - rv = uri->GetSpec(&str); - if (NS_SUCCEEDED(rv)) { - fprintf(stdout, "Ending load %s, status=%x\n", str, aStatus); - free(str); - } - } - gDone = true; - return NS_OK; - } - - NS_IMETHOD OnDataAvailable(nsIRequest *request, nsISupports *ctxt, - nsIInputStream *inStr, - uint64_t sourceOffset, uint32_t count) { - nsresult rv; - char buf[1024]; - while (count > 0) { - uint32_t amt; - rv = inStr->Read(buf, sizeof(buf), &amt); - count -= amt; - char* c = buf; - while (amt-- > 0) { - fputc(*c++, stdout); - } - } - return NS_OK; - } -}; - -NS_IMPL_ISUPPORTS(Listener, nsIStreamListener, nsIRequestObserver) - -nsresult -TestAsyncRead(const char* url) -{ - nsresult rv; - - nsCOMPtr eventQService = - do_GetService(kEventQueueServiceCID, &rv); - if (NS_FAILED(rv)) return rv; - - rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, &gEventQ); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr secman = - do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv); - if (NS_FAILED(rv)) return rv; - nsCOMPtr systemPrincipal; - rv = secman->GetSystemPrincipal(getter_AddRefs(systemPrincipal)); - if (NS_FAILED(rv)) return rv; - nsCOMPtr uri; - rv = NS_NewURI(getter_AddRefs(uri), url); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr channel; - rv = NS_NewChannel(getter_AddRefs(channel), - uri, - systemPrincipal, - nsILoadInfo::SEC_NORMAL, - nsIContentPolicy::TYPE_OTHER); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr listener = new Listener(); - if (listener == nullptr) - return NS_ERROR_OUT_OF_MEMORY; - rv = channel->AsyncOpen(nullptr, listener); - if (NS_FAILED(rv)) return rv; - - while (!gDone) { - PLEvent* event; - rv = gEventQ->GetEvent(&event); - if (NS_FAILED(rv)) return rv; - rv = gEventQ->HandleEvent(event); - if (NS_FAILED(rv)) return rv; - } - - return rv; -} - -int -main(int argc, char* argv[]) -{ - nsresult rv; - { - nsCOMPtr servMan; - NS_InitXPCOM2(getter_AddRefs(servMan), nullptr, nullptr); - nsCOMPtr registrar = do_QueryInterface(servMan); - NS_ASSERTION(registrar, "Null nsIComponentRegistrar"); - if (registrar) - registrar->AutoRegister(nullptr); - - NS_ASSERTION(NS_SUCCEEDED(rv), "AutoregisterComponents failed"); - - if (argc < 2) { - printf("usage: %s resource://foo/\n", argv[0]); - return -1; - } - - rv = SetupMapping(); - NS_ASSERTION(NS_SUCCEEDED(rv), "SetupMapping failed"); - if (NS_FAILED(rv)) return rv; - - rv = TestOpenInputStream(argv[1]); - NS_ASSERTION(NS_SUCCEEDED(rv), "TestOpenInputStream failed"); - - rv = TestAsyncRead(argv[1]); - NS_ASSERTION(NS_SUCCEEDED(rv), "TestAsyncRead failed"); - } // this scopes the nsCOMPtrs - // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM - rv = NS_ShutdownXPCOM(nullptr); - NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed"); - return rv; -} - -//////////////////////////////////////////////////////////////////////////////// diff --git a/netwerk/test/TestStreamChannel.cpp b/netwerk/test/TestStreamChannel.cpp deleted file mode 100644 index 80ee03d736..0000000000 --- a/netwerk/test/TestStreamChannel.cpp +++ /dev/null @@ -1,200 +0,0 @@ -/* 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/. */ - -#include "TestCommon.h" -#include "nsIComponentRegistrar.h" -#include "nsIStreamTransportService.h" -#include "nsIAsyncInputStream.h" -#include "nsIProgressEventSink.h" -#include "nsIInterfaceRequestor.h" -#include "nsIInterfaceRequestorUtils.h" -#include "nsIRequest.h" -#include "nsIServiceManager.h" -#include "nsIComponentManager.h" -#include "nsCOMPtr.h" -#include "nsMemory.h" -#include "nsStringAPI.h" -#include "nsIFileStreams.h" -#include "nsIStreamListener.h" -#include "nsIFile.h" -#include "nsNetUtil.h" -#include "nsAutoLock.h" -#include "mozilla/Logging.h" -#include - -//////////////////////////////////////////////////////////////////////////////// - -// -// set NSPR_LOG_MODULES=Test:5 -// -static PRLogModuleInfo *gTestLog = nullptr; -#define LOG(args) MOZ_LOG(gTestLog, mozilla::LogLevel::Debug, args) - -//////////////////////////////////////////////////////////////////////////////// - -static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID); - -//////////////////////////////////////////////////////////////////////////////// - -class MyListener : public nsIStreamListener -{ -public: - NS_DECL_ISUPPORTS - - MyListener() {} - virtual ~MyListener() {} - - NS_IMETHOD OnStartRequest(nsIRequest *req, nsISupports *ctx) - { - LOG(("MyListener::OnStartRequest\n")); - return NS_OK; - } - - NS_IMETHOD OnDataAvailable(nsIRequest *req, nsISupports *ctx, - nsIInputStream *stream, - uint32_t offset, uint32_t count) - { - LOG(("MyListener::OnDataAvailable [offset=%u count=%u]\n", offset, count)); - - char buf[500]; - nsresult rv; - - while (count) { - uint32_t n, amt = std::min(count, sizeof(buf)); - - rv = stream->Read(buf, amt, &n); - if (NS_FAILED(rv)) { - LOG((" read returned 0x%08x\n", rv)); - return rv; - } - - LOG((" read %u bytes\n", n)); - count -= n; - } - - return NS_OK; - } - - NS_IMETHOD OnStopRequest(nsIRequest *req, nsISupports *ctx, nsresult status) - { - LOG(("MyListener::OnStopRequest [status=%x]\n", status)); - QuitPumpingEvents(); - return NS_OK; - } -}; - -NS_IMPL_ISUPPORTS(MyListener, - nsIRequestObserver, - nsIStreamListener) - -//////////////////////////////////////////////////////////////////////////////// - -class MyCallbacks : public nsIInterfaceRequestor - , public nsIProgressEventSink -{ -public: - NS_DECL_ISUPPORTS - - MyCallbacks() {} - virtual ~MyCallbacks() {} - - NS_IMETHOD GetInterface(const nsID &iid, void **result) - { - return QueryInterface(iid, result); - } - - NS_IMETHOD OnStatus(nsIRequest *req, nsISupports *ctx, nsresult status, - const char16_t *statusArg) - { - LOG(("MyCallbacks::OnStatus [status=%x]\n", status)); - return NS_OK; - } - - NS_IMETHOD OnProgress(nsIRequest *req, nsISupports *ctx, - uint64_t progress, uint64_t progressMax) - { - LOG(("MyCallbacks::OnProgress [progress=%llu/%llu]\n", progress, progressMax)); - return NS_OK; - } -}; - -NS_IMPL_ISUPPORTS(MyCallbacks, - nsIInterfaceRequestor, - nsIProgressEventSink) - -//////////////////////////////////////////////////////////////////////////////// - -/** - * asynchronously copy file. - */ -static nsresult -RunTest(nsIFile *file) -{ - nsresult rv; - - LOG(("RunTest\n")); - - nsCOMPtr stream; - rv = NS_NewLocalFileInputStream(getter_AddRefs(stream), file); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr uri = do_CreateInstance(kSimpleURICID); - if (uri) - uri->SetSpec(NS_LITERAL_CSTRING("foo://bar")); - - nsCOMPtr chan; - rv = NS_NewInputStreamChannel(getter_AddRefs(chan), uri, stream); - if (NS_FAILED(rv)) return rv; - - rv = chan->SetNotificationCallbacks(new MyCallbacks()); - if (NS_FAILED(rv)) return rv; - - rv = chan->AsyncOpen(new MyListener(), nullptr); - if (NS_FAILED(rv)) return rv; - - PumpEvents(); - return NS_OK; -} - -//////////////////////////////////////////////////////////////////////////////// - -int -main(int argc, char* argv[]) -{ - if (test_common_init(&argc, &argv) != 0) - return -1; - - nsresult rv; - - if (argc < 2) { - printf("usage: %s \n", argv[0]); - return -1; - } - char* fileName = argv[1]; - { - nsCOMPtr servMan; - NS_InitXPCOM2(getter_AddRefs(servMan), nullptr, nullptr); - nsCOMPtr registrar = do_QueryInterface(servMan); - NS_ASSERTION(registrar, "Null nsIComponentRegistrar"); - if (registrar) - registrar->AutoRegister(nullptr); - - gTestLog = PR_NewLogModule("Test"); - - nsCOMPtr file; - rv = NS_NewNativeLocalFile(nsDependentCString(fileName), false, getter_AddRefs(file)); - if (NS_FAILED(rv)) return rv; - - rv = RunTest(file); - NS_ASSERTION(NS_SUCCEEDED(rv), "RunTest failed"); - - // give background threads a chance to finish whatever work they may - // be doing. - PR_Sleep(PR_SecondsToInterval(1)); - } // this scopes the nsCOMPtrs - // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM - rv = NS_ShutdownXPCOM(nullptr); - NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed"); - return NS_OK; -} diff --git a/netwerk/test/TestStreamLoader.cpp b/netwerk/test/TestStreamLoader.cpp index 62419052a7..79f8b23591 100644 --- a/netwerk/test/TestStreamLoader.cpp +++ b/netwerk/test/TestStreamLoader.cpp @@ -74,7 +74,7 @@ int main(int argc, char **argv) rv = NS_NewChannel(getter_AddRefs(chan), uri, systemPrincipal, - nsILoadInfo::SEC_NORMAL, + nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS, nsIContentPolicy::TYPE_OTHER); if (NS_FAILED(rv)) @@ -89,7 +89,7 @@ int main(int argc, char **argv) if (NS_FAILED(rv)) return -1; - rv = chan->AsyncOpen(loader, nullptr); + rv = chan->AsyncOpen2(loader); if (NS_FAILED(rv)) return -1; diff --git a/netwerk/test/TestUpload.cpp b/netwerk/test/TestUpload.cpp index 91433c3965..23e3d8aa24 100644 --- a/netwerk/test/TestUpload.cpp +++ b/netwerk/test/TestUpload.cpp @@ -140,7 +140,7 @@ main(int argc, char* argv[]) rv = NS_NewChannel(getter_AddRefs(channel), uri, systemPrincipal, - nsILoadInfo::SEC_NORMAL, + nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS, nsIContentPolicy::TYPE_OTHER); if (NS_FAILED(rv)) return -1; @@ -158,7 +158,7 @@ main(int argc, char* argv[]) } NS_ADDREF(listener); - channel->AsyncOpen(listener, nullptr); + channel->AsyncOpen2(listener); PumpEvents(); } // this scopes the nsCOMPtrs diff --git a/netwerk/test/moz.build b/netwerk/test/moz.build index 911b866f1f..78857d9692 100644 --- a/netwerk/test/moz.build +++ b/netwerk/test/moz.build @@ -18,7 +18,6 @@ GeckoSimplePrograms([ 'PropertiesTest', 'ReadNTLM', 'TestBlockingSocket', - 'TestCallbacks', 'TestDNS', 'TestIncrementalDownload', 'TestOpen', @@ -36,7 +35,6 @@ GeckoSimplePrograms([ # TestIDN', # TestIOThreads', # TestSocketTransport', -# TestStreamChannel', # TestStreamPump', # TestStreamTransport', # TestUDPSocketProvider', diff --git a/netwerk/wifi/nsWifiScannerDBus.cpp b/netwerk/wifi/nsWifiScannerDBus.cpp index 83782f1c44..182553e18f 100644 --- a/netwerk/wifi/nsWifiScannerDBus.cpp +++ b/netwerk/wifi/nsWifiScannerDBus.cpp @@ -3,6 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsWifiScannerDBus.h" +#include "mozilla/ipc/DBusMessageRefPtr.h" #include "nsWifiAccessPoint.h" namespace mozilla { @@ -38,9 +39,9 @@ nsWifiScannerDBus::SendMessage(const char* aInterface, const char* aPath, const char* aFuncCall) { - DBusMessage* msg = + RefPtr msg = already_AddRefed( dbus_message_new_method_call("org.freedesktop.NetworkManager", - aPath, aInterface, aFuncCall); + aPath, aInterface, aFuncCall)); if (!msg) { return NS_ERROR_FAILURE; } @@ -73,9 +74,9 @@ nsWifiScannerDBus::SendMessage(const char* aInterface, // http://dbus.freedesktop.org/doc/api/html/group__DBusConnection.html // Refer to function dbus_connection_send_with_reply_and_block. const uint32_t DBUS_DEFAULT_TIMEOUT = -1; - DBusMessage* reply = nullptr; - reply = dbus_connection_send_with_reply_and_block(mConnection, msg, - DBUS_DEFAULT_TIMEOUT, &err); + RefPtr reply = already_AddRefed( + dbus_connection_send_with_reply_and_block(mConnection, msg, + DBUS_DEFAULT_TIMEOUT, &err)); if (dbus_error_is_set(&err)) { dbus_error_free(&err); @@ -99,7 +100,6 @@ nsWifiScannerDBus::SendMessage(const char* aInterface, } else { rv = NS_ERROR_FAILURE; } - dbus_message_unref(reply); return rv; } diff --git a/netwerk/wifi/win_wifiScanner.cpp b/netwerk/wifi/win_wifiScanner.cpp index 4f405e0e10..a462b96969 100644 --- a/netwerk/wifi/win_wifiScanner.cpp +++ b/netwerk/wifi/win_wifiScanner.cpp @@ -75,7 +75,9 @@ WinWifiScanner::WinWifiScanner() // spurious LoadLibrary calls in the common case rather than load the // WLAN API in the edge case. mWlanLibrary = WinWLANLibrary::Load(); - MOZ_ASSERT(mWlanLibrary); + if (!mWlanLibrary) { + NS_WARNING("Could not initialize Windows Wi-Fi scanner"); + } } WinWifiScanner::~WinWifiScanner() diff --git a/toolkit/components/places/tests/browser/browser.ini b/toolkit/components/places/tests/browser/browser.ini index 1b57c1b679..c2cc93a26a 100644 --- a/toolkit/components/places/tests/browser/browser.ini +++ b/toolkit/components/places/tests/browser/browser.ini @@ -11,7 +11,7 @@ support-files = [browser_bug399606.js] [browser_bug646422.js] [browser_bug680727.js] -skip-if = buildapp == 'mulet' || e10s # Bug ?????? - test times out on try on all platforms, but works locally for markh! +skip-if = buildapp == 'mulet' # Bug ?????? - test times out on try on all platforms, but works locally for markh! [browser_colorAnalyzer.js] [browser_favicon_privatebrowsing_perwindowpb.js] [browser_favicon_setAndFetchFaviconForPage.js] diff --git a/toolkit/components/places/tests/browser/browser_bug680727.js b/toolkit/components/places/tests/browser/browser_bug680727.js index 112b20a5af..6d25ef1517 100644 --- a/toolkit/components/places/tests/browser/browser_bug680727.js +++ b/toolkit/components/places/tests/browser/browser_bug680727.js @@ -12,12 +12,11 @@ var gAsyncHistory = Cc["@mozilla.org/browser/history;1"].getService(Ci.mozIAsyncHistory); var proxyPrefValue; +var ourTab; function test() { waitForExplicitFinish(); - gBrowser.selectedTab = gBrowser.addTab(); - // Tests always connect to localhost, and per bug 87717, localhost is now // reachable in offline mode. To avoid this, disable any proxy. proxyPrefValue = Services.prefs.getIntPref("network.proxy.type"); @@ -30,33 +29,34 @@ function test() { // Go offline, expecting the error page. Services.io.offline = true; - window.addEventListener("DOMContentLoaded", errorListener, false); - content.location = kUniqueURI.spec; + + BrowserTestUtils.openNewForegroundTab(gBrowser).then(tab => { + ourTab = tab; + BrowserTestUtils.waitForContentEvent(ourTab.linkedBrowser, "DOMContentLoaded", + .then(errorListener); + BrowserTestUtils.loadURI(ourTab.linkedBrowser, kUniqueURI.spec); + }); } //------------------------------------------------------------------------------ // listen to loading the neterror page. (offline mode) function errorListener() { - if(content.location == "about:blank") { - info("got about:blank, which is expected once, so return"); - return; - } - - window.removeEventListener("DOMContentLoaded", errorListener, false); ok(Services.io.offline, "Services.io.offline is true."); // This is an error page. - is(gBrowser.contentDocument.documentURI.substring(0, 27), - "about:neterror?e=netOffline", - "Document URI is the error page."); + ContentTask.spawn(ourTab.linkedBrowser, kUniqueURI.spec, function(uri) { + is(content.document.documentURI.substring(0, 27), + "about:neterror?e=netOffline", + "Document URI is the error page."); - // But location bar should show the original request. - is(content.location.href, kUniqueURI.spec, - "Docshell URI is the original URI."); - - // Global history does not record URI of a failed request. - PlacesTestUtils.promiseAsyncUpdates().then(() => { - gAsyncHistory.isURIVisited(kUniqueURI, errorAsyncListener); + // But location bar should show the original request. + is(content.location.href, uri, + "Docshell URI is the original URI."); + }).then(() => { + // Global history does not record URI of a failed request. + return PlacesTestUtils.promiseAsyncUpdates().then(() => { + gAsyncHistory.isURIVisited(kUniqueURI, errorAsyncListener); + }); }); } @@ -69,30 +69,33 @@ function errorAsyncListener(aURI, aIsVisited) { // Now press the "Try Again" button, with offline mode off. Services.io.offline = false; - window.addEventListener("DOMContentLoaded", reloadListener, false); + BrowserTestUtils.waitForContentEvent(ourTab.linkedBrowser, "DOMContentLoaded") + .then(reloadListener); - ok(gBrowser.contentDocument.getElementById("errorTryAgain"), - "The error page has got a #errorTryAgain element"); - gBrowser.contentDocument.getElementById("errorTryAgain").click(); + ContentTask.spawn(ourTab.linkedBrowser, null, function() { + ok(content.document.getElementById("errorTryAgain"), + "The error page has got a #errorTryAgain element"); + content.document.getElementById("errorTryAgain").click(); + }); } //------------------------------------------------------------------------------ // listen to reload of neterror. function reloadListener() { - window.removeEventListener("DOMContentLoaded", reloadListener, false); - // This listener catches "DOMContentLoaded" on being called // nsIWPL::onLocationChange(...). That is right *AFTER* // IHistory::VisitURI(...) is called. ok(!Services.io.offline, "Services.io.offline is false."); - // This is not an error page. - is(gBrowser.contentDocument.documentURI, kUniqueURI.spec, - "Document URI is not the offline-error page, but the original URI."); - - // Check if global history remembers the successfully-requested URI. - PlacesTestUtils.promiseAsyncUpdates().then(() => { - gAsyncHistory.isURIVisited(kUniqueURI, reloadAsyncListener); + ContentTask.spawn(ourTab.linkedBrowser, kUniqueURI.spec, function(uri) { + // This is not an error page. + is(content.document.documentURI, uri, + "Document URI is not the offline-error page, but the original URI."); + }).then(() => { + // Check if global history remembers the successfully-requested URI. + PlacesTestUtils.promiseAsyncUpdates().then(() => { + gAsyncHistory.isURIVisited(kUniqueURI, reloadAsyncListener); + }); }); } @@ -101,10 +104,8 @@ function reloadAsyncListener(aURI, aIsVisited) { PlacesTestUtils.clearHistory().then(finish); } -registerCleanupFunction(function() { +registerCleanupFunction(function* () { Services.prefs.setIntPref("network.proxy.type", proxyPrefValue); Services.io.offline = false; - window.removeEventListener("DOMContentLoaded", errorListener, false); - window.removeEventListener("DOMContentLoaded", reloadListener, false); - gBrowser.removeCurrentTab(); + yield BrowserTestUtils.removeTab(ourTab); }); diff --git a/toolkit/components/reader/AboutReader.jsm b/toolkit/components/reader/AboutReader.jsm index d66b437f89..d458aeef9f 100644 --- a/toolkit/components/reader/AboutReader.jsm +++ b/toolkit/components/reader/AboutReader.jsm @@ -23,7 +23,10 @@ var gStrings = Services.strings.createBundle("chrome://global/locale/aboutReader var AboutReader = function(mm, win, articlePromise) { let url = this._getOriginalUrl(win); if (!(url.startsWith("http://") || url.startsWith("https://"))) { - Cu.reportError("Only http:// and https:// URLs can be loaded in about:reader"); + let errorMsg = "Only http:// and https:// URLs can be loaded in about:reader."; + if (Services.prefs.getBoolPref("reader.errors.includeURLs")) + errorMsg += " Tried to load: " + url + "."; + Cu.reportError(errorMsg); win.location.href = "about:blank"; return; } diff --git a/toolkit/components/reader/ReaderMode.jsm b/toolkit/components/reader/ReaderMode.jsm index 3005d426a1..1fcda45fa5 100644 --- a/toolkit/components/reader/ReaderMode.jsm +++ b/toolkit/components/reader/ReaderMode.jsm @@ -168,7 +168,20 @@ this.ReaderMode = { let urlIndex = content.indexOf("URL="); if (urlIndex > -1) { let url = content.substring(urlIndex + 4); - this._downloadDocument(url).then((doc) => resolve(doc)); + let ssm = Services.scriptSecurityManager; + let flags = ssm.LOAD_IS_AUTOMATIC_DOCUMENT_REPLACEMENT | + ssm.DISALLOW_INHERIT_PRINCIPAL; + try { + ssm.checkLoadURIStrWithPrincipal(doc.nodePrincipal, url, flags); + } catch (ex) { + let errorMsg = "Reader mode disallowed meta refresh (reason: " + ex + ")."; + if (Services.prefs.getBoolPref("reader.errors.includeURLs")) + errorMsg += " Refresh target URI: '" + url + "'."; + reject(errorMsg); + return; + } + // Otherwise, pass an object indicating our new URL: + reject({newURL: url}); return; } } diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json index b62d578f9a..4e0d726411 100644 --- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -1370,6 +1370,15 @@ "n_values": 3, "description": "Stats about what kind of resource requested http authentication. (0=top-level doc, 1=same origin subresources 2=cross-origin subresources)" }, + "HTTP_AUTH_TYPE_STATS": { + "alert_emails": ["rbarnes@mozilla.com"], + "bug_numbers": [1266571], + "expires_in_version": "52", + "kind": "enumerated", + "n_values": 8, + "releaseChannelCollection": "opt-out", + "description": "Recorded once for each HTTP 401 response. The value records the type of authentication and the TLS-enabled status. (0=basic/clear, 1=basic/tls, 2=digest/clear, 3=digest/tls, 4=ntlm/clear, 5=ntlm/tls, 6=negotiate/clear, 7=negotiate/tls)" + }, "SSL_HANDSHAKE_VERSION": { "expires_in_version": "never", "kind": "enumerated", @@ -3298,6 +3307,14 @@ "n_buckets": 10, "description": "Time spent in nsDiskCacheStreamIO::Close() on the main thread (ms)" }, + "NETWORK_ID": { + "alert_emails": ["necko@mozilla.com"], + "bug_numbers": [1240932], + "expires_in_version": "never", + "kind": "enumerated", + "n_values": 6, + "description": "Network identification (0=None, 1=New, 2=Same)" + }, "IDLE_NOTIFY_BACK_MS": { "expires_in_version": "40", "kind": "exponential", diff --git a/toolkit/modules/AsyncPrefs.jsm b/toolkit/modules/AsyncPrefs.jsm new file mode 100644 index 0000000000..a528e8a7c6 --- /dev/null +++ b/toolkit/modules/AsyncPrefs.jsm @@ -0,0 +1,172 @@ +/* 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"; + +this.EXPORTED_SYMBOLS = ["AsyncPrefs"]; + +const {interfaces: Ci, utils: Cu, classes: Cc} = Components; +Cu.import("resource://gre/modules/Services.jsm"); +Cu.import("resource://gre/modules/Task.jsm"); + +const kInChildProcess = Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT; + +const kAllowedPrefs = new Set([ + "testing.allowed-prefs.some-bool-pref", + "testing.allowed-prefs.some-char-pref", + "testing.allowed-prefs.some-int-pref", +]); + +const kPrefTypeMap = new Map([ + ["boolean", Services.prefs.PREF_BOOL], + ["number", Services.prefs.PREF_INT], + ["string", Services.prefs.PREF_STRING], +]); + +function maybeReturnErrorForReset(pref) { + if (!kAllowedPrefs.has(pref)) { + return `Resetting pref ${pref} from content is not allowed.`; + } + return false; +} + +function maybeReturnErrorForSet(pref, value) { + if (!kAllowedPrefs.has(pref)) { + return `Setting pref ${pref} from content is not allowed.`; + } + + let valueType = typeof value; + if (!kPrefTypeMap.has(valueType)) { + return `Can't set pref ${pref} to value of type ${valueType}.`; + } + let prefType = Services.prefs.getPrefType(pref); + if (prefType != Services.prefs.PREF_INVALID && + prefType != kPrefTypeMap.get(valueType)) { + return `Can't set pref ${pref} to a value with type ${valueType} that doesn't match the pref's type ${prefType}.`; + } + return false; +} + +var AsyncPrefs; +if (kInChildProcess) { + let gUniqueId = 0; + let gMsgMap = new Map(); + + AsyncPrefs = { + set: Task.async(function(pref, value) { + let error = maybeReturnErrorForSet(pref, value); + if (error) { + return Promise.reject(error); + } + + let msgId = ++gUniqueId; + return new Promise((resolve, reject) => { + gMsgMap.set(msgId, {resolve, reject}); + Services.cpmm.sendAsyncMessage("AsyncPrefs:SetPref", {pref, value, msgId}); + }); + }), + + reset: Task.async(function(pref) { + let error = maybeReturnErrorForReset(pref); + if (error) { + return Promise.reject(error); + } + + let msgId = ++gUniqueId; + return new Promise((resolve, reject) => { + gMsgMap.set(msgId, {resolve, reject}); + Services.cpmm.sendAsyncMessage("AsyncPrefs:ResetPref", {pref, msgId}); + }); + }), + + receiveMessage(msg) { + let promiseRef = gMsgMap.get(msg.data.msgId); + if (promiseRef) { + gMsgMap.delete(msg.data.msgId); + if (msg.data.success) { + promiseRef.resolve(); + } else { + promiseRef.reject(msg.data.message); + } + } + }, + + init() { + Services.cpmm.addMessageListener("AsyncPrefs:PrefSetFinished", this); + Services.cpmm.addMessageListener("AsyncPrefs:PrefResetFinished", this); + }, + }; +} else { + AsyncPrefs = { + methodForType: { + number: "setIntPref", + boolean: "setBoolPref", + string: "setCharPref", + }, + + set: Task.async(function(pref, value) { + let error = maybeReturnErrorForSet(pref, value); + if (error) { + return Promise.reject(error); + } + let methodToUse = this.methodForType[typeof value]; + try { + Services.prefs[methodToUse](pref, value); + return Promise.resolve(value); + } catch (ex) { + Cu.reportError(ex); + return Promise.reject(ex.message); + } + }), + + reset: Task.async(function(pref) { + let error = maybeReturnErrorForReset(pref); + if (error) { + return Promise.reject(error); + } + + try { + Services.prefs.clearUserPref(pref); + return Promise.resolve(); + } catch (ex) { + Cu.reportError(ex); + return Promise.reject(ex.message); + } + }), + + receiveMessage(msg) { + if (msg.name == "AsyncPrefs:SetPref") { + this.onPrefSet(msg); + } else { + this.onPrefReset(msg); + } + }, + + onPrefReset(msg) { + let {pref, msgId} = msg.data; + this.reset(pref).then(function() { + msg.target.sendAsyncMessage("AsyncPrefs:PrefResetFinished", {msgId, success: true}); + }, function(msg) { + msg.target.sendAsyncMessage("AsyncPrefs:PrefResetFinished", {msgId, success: false, message: msg}); + }); + }, + + onPrefSet(msg) { + let {pref, value, msgId} = msg.data; + this.set(pref, value).then(function() { + msg.target.sendAsyncMessage("AsyncPrefs:PrefSetFinished", {msgId, success: true}); + }, function(msg) { + msg.target.sendAsyncMessage("AsyncPrefs:PrefSetFinished", {msgId, success: false, message: msg}); + }); + }, + + init() { + Services.ppmm.addMessageListener("AsyncPrefs:SetPref", this); + Services.ppmm.addMessageListener("AsyncPrefs:ResetPref", this); + } + }; +} + +AsyncPrefs.init(); + diff --git a/toolkit/modules/moz.build b/toolkit/modules/moz.build index 3af73574ab..96d430a39c 100644 --- a/toolkit/modules/moz.build +++ b/toolkit/modules/moz.build @@ -21,6 +21,7 @@ EXTRA_JS_MODULES += [ 'addons/WebRequest.jsm', 'addons/WebRequestCommon.jsm', 'addons/WebRequestContent.js', + 'AsyncPrefs.jsm', 'Battery.jsm', 'BinarySearch.jsm', 'BrowserUtils.jsm', diff --git a/toolkit/modules/tests/browser/browser.ini b/toolkit/modules/tests/browser/browser.ini index fce24132cb..86a43a8188 100644 --- a/toolkit/modules/tests/browser/browser.ini +++ b/toolkit/modules/tests/browser/browser.ini @@ -4,6 +4,7 @@ support-files = metadata_*.html testremotepagemanager.html +[browser_AsyncPrefs.js] [browser_Battery.js] [browser_Deprecated.js] [browser_Finder.js] diff --git a/toolkit/modules/tests/browser/browser_AsyncPrefs.js b/toolkit/modules/tests/browser/browser_AsyncPrefs.js new file mode 100644 index 0000000000..1d20a37898 --- /dev/null +++ b/toolkit/modules/tests/browser/browser_AsyncPrefs.js @@ -0,0 +1,97 @@ +"use strict"; + +const kWhiteListedBool = "testing.allowed-prefs.some-bool-pref"; +const kWhiteListedChar = "testing.allowed-prefs.some-char-pref"; +const kWhiteListedInt = "testing.allowed-prefs.some-int-pref"; + +function resetPrefs() { + for (let pref of [kWhiteListedBool, kWhiteListedChar, kWhiteListedBool]) { + Services.prefs.clearUserPref(pref); + } +} + +registerCleanupFunction(resetPrefs); + +Services.prefs.getDefaultBranch("testing.allowed-prefs.").setBoolPref("some-bool-pref", false); +Services.prefs.getDefaultBranch("testing.allowed-prefs.").setCharPref("some-char-pref", ""); +Services.prefs.getDefaultBranch("testing.allowed-prefs.").setIntPref("some-int-pref", 0); + +function* runTest() { + let {AsyncPrefs} = Cu.import("resource://gre/modules/AsyncPrefs.jsm", {}); + const kInChildProcess = Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT; + + // Need to define these again because when run in a content task we have no scope access. + const kNotWhiteListed = "some.pref.thats.not.whitelisted"; + const kWhiteListedBool = "testing.allowed-prefs.some-bool-pref"; + const kWhiteListedChar = "testing.allowed-prefs.some-char-pref"; + const kWhiteListedInt = "testing.allowed-prefs.some-int-pref"; + + const procDesc = kInChildProcess ? "child process" : "parent process"; + + const valueResultMap = [ + [true, "Bool"], + [false, "Bool"], + [10, "Int"], + [-1, "Int"], + ["", "Char"], + ["stuff", "Char"], + [[], false], + [{}, false], + [BrowserUtils.makeURI("http://mozilla.org/"), false], + ]; + + const prefMap = [ + ["Bool", kWhiteListedBool], + ["Char", kWhiteListedChar], + ["Int", kWhiteListedInt], + ]; + + function doesFail(pref, value) { + let msg = `Should not succeed setting ${pref} to ${value} in ${procDesc}`; + return AsyncPrefs.set(pref, value).then(() => ok(false, msg), error => ok(true, msg + "; " + error)); + } + + function doesWork(pref, value) { + let msg = `Should be able to set ${pref} to ${value} in ${procDesc}`; + return AsyncPrefs.set(pref, value).then(() => ok(true, msg), error => ok(false, msg + "; " + error)); + } + + function doReset(pref) { + let msg = `Should be able to reset ${pref} in ${procDesc}`; + return AsyncPrefs.reset(pref).then(() => ok(true, msg), () => ok(false, msg)); + } + + for (let [val, ] of valueResultMap) { + yield doesFail(kNotWhiteListed, val); + is(Services.prefs.prefHasUserValue(kNotWhiteListed), false, "Pref shouldn't get changed"); + } + + let resetMsg = `Should not succeed resetting ${kNotWhiteListed} in ${procDesc}`; + AsyncPrefs.reset(kNotWhiteListed).then(() => ok(false, resetMsg), error => ok(true, resetMsg + "; " + error)); + + for (let [type, pref] of prefMap) { + for (let [val, result] of valueResultMap) { + if (result == type) { + yield doesWork(pref, val); + is(Services.prefs["get" + type + "Pref"](pref), val, "Pref should have been updated"); + yield doReset(pref); + } else { + yield doesFail(pref, val); + is(Services.prefs.prefHasUserValue(pref), false, `Pref ${pref} shouldn't get changed`); + } + } + } +} + +add_task(function* runInParent() { + yield runTest(); + resetPrefs(); +}); + +if (gMultiProcessBrowser) { + add_task(function* runInChild() { + ok(gBrowser.selectedBrowser.isRemoteBrowser, "Should actually run this in child process"); + yield ContentTask.spawn(gBrowser.selectedBrowser, null, runTest); + resetPrefs(); + }); +}