merge mozilla-central to autoland. r=merge a=merge

This commit is contained in:
Sebastian Hengst 2017-09-06 11:28:07 +02:00
commit 9d15132cd1
75 changed files with 529 additions and 293 deletions

View file

@ -437,9 +437,9 @@
position="bottomcenter topright" position="bottomcenter topright"
tabspecific="true" tabspecific="true"
noautofocus="true" noautofocus="true"
copyURL-title="&copyLinkCmd.label;" copyURL-title="&copyURLCmd.label;"
emailLink-title="&emailPageCmd.label;" emailLink-title="&emailPageCmd.label;"
sendToDevice-title="&sendTabToDevice.label;" sendToDevice-title="&sendToDevice.label3;"
sendToDevice-notReadyTitle="&sendToDevice.syncNotReady.label;"> sendToDevice-notReadyTitle="&sendToDevice.syncNotReady.label;">
<photonpanelmultiview id="pageActionPanelMultiView" <photonpanelmultiview id="pageActionPanelMultiView"
mainViewId="pageActionPanelMainView" mainViewId="pageActionPanelMainView"

View file

@ -91,7 +91,7 @@ add_task(async function setup() {
let appInfo = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo); let appInfo = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo);
let appVersion = parseInt(appInfo.version); let appVersion = parseInt(appInfo.version);
let spoofedVersion = appVersion - (appVersion % 10); let spoofedVersion = appVersion - ((appVersion - 3) % 7);
spoofedUserAgent = `Mozilla/5.0 (Windows NT 6.1; rv:${spoofedVersion}.0) Gecko/20100101 Firefox/${spoofedVersion}.0`; spoofedUserAgent = `Mozilla/5.0 (Windows NT 6.1; rv:${spoofedVersion}.0) Gecko/20100101 Firefox/${spoofedVersion}.0`;
}); });

View file

@ -553,7 +553,7 @@ These should match what Safari and other Apple applications use on OS X Lion. --
<!ENTITY bookmarkThisLinkCmd.accesskey "L"> <!ENTITY bookmarkThisLinkCmd.accesskey "L">
<!ENTITY bookmarkThisFrameCmd.label "Bookmark This Frame"> <!ENTITY bookmarkThisFrameCmd.label "Bookmark This Frame">
<!ENTITY bookmarkThisFrameCmd.accesskey "m"> <!ENTITY bookmarkThisFrameCmd.accesskey "m">
<!ENTITY copyLinkCmd.label "Copy Link"> <!ENTITY copyURLCmd.label "Copy URL">
<!ENTITY copyURLFeedback.label "Copied!"> <!ENTITY copyURLFeedback.label "Copied!">
<!ENTITY emailPageCmd.label "Email Link…"> <!ENTITY emailPageCmd.label "Email Link…">
<!ENTITY emailPageCmd.accesskey "E"> <!ENTITY emailPageCmd.accesskey "E">
@ -974,7 +974,7 @@ you can use these alternative items. Otherwise, their values should be empty. -
<!ENTITY pageAction.addToUrlbar.label "Add to Address Bar"> <!ENTITY pageAction.addToUrlbar.label "Add to Address Bar">
<!ENTITY pageAction.removeFromUrlbar.label "Remove from Address Bar"> <!ENTITY pageAction.removeFromUrlbar.label "Remove from Address Bar">
<!ENTITY sendTabToDevice.label "Send Tab to Device"> <!ENTITY sendToDevice.label3 "Send Page to Device">
<!ENTITY sendToDevice.syncNotReady.label "Syncing Devices…"> <!ENTITY sendToDevice.syncNotReady.label "Syncing Devices…">
<!ENTITY libraryButton.tooltip "View history, saved bookmarks, and more"> <!ENTITY libraryButton.tooltip "View history, saved bookmarks, and more">

View file

@ -7,7 +7,6 @@
#include "mozilla/BasePrincipal.h" #include "mozilla/BasePrincipal.h"
#include "nsDocShell.h" #include "nsDocShell.h"
#include "nsIAddonPolicyService.h"
#include "nsIContentSecurityPolicy.h" #include "nsIContentSecurityPolicy.h"
#include "nsIObjectInputStream.h" #include "nsIObjectInputStream.h"
#include "nsIObjectOutputStream.h" #include "nsIObjectOutputStream.h"
@ -331,24 +330,29 @@ BasePrincipal::GetIsInIsolatedMozBrowserElement(bool* aIsInIsolatedMozBrowserEle
return NS_OK; return NS_OK;
} }
bool nsresult
BasePrincipal::AddonHasPermission(const nsAString& aPerm) BasePrincipal::GetAddonPolicy(nsISupports** aResult)
{ {
nsAutoString addonId; *aResult = AddonPolicy();
NS_ENSURE_SUCCESS(GetAddonId(addonId), false); return NS_OK;
}
if (addonId.IsEmpty()) { extensions::WebExtensionPolicy*
return false; BasePrincipal::AddonPolicy()
{
if (Is<ContentPrincipal>()) {
return As<ContentPrincipal>()->AddonPolicy();
} }
return nullptr;
}
nsCOMPtr<nsIAddonPolicyService> aps = bool
do_GetService("@mozilla.org/addons/policy-service;1"); BasePrincipal::AddonHasPermission(const nsIAtom* aPerm)
NS_ENSURE_TRUE(aps, false); {
if (auto policy = AddonPolicy()) {
bool retval = false; return policy->HasPermission(aPerm);
nsresult rv = aps->AddonHasPermission(addonId, aPerm, &retval); }
NS_ENSURE_SUCCESS(rv, false); return false;
return retval;
} }
already_AddRefed<BasePrincipal> already_AddRefed<BasePrincipal>
@ -448,19 +452,10 @@ BasePrincipal::CloneStrippingUserContextIdAndFirstPartyDomain()
bool bool
BasePrincipal::AddonAllowsLoad(nsIURI* aURI, bool aExplicit /* = false */) BasePrincipal::AddonAllowsLoad(nsIURI* aURI, bool aExplicit /* = false */)
{ {
nsAutoString addonId; if (auto policy = AddonPolicy()) {
NS_ENSURE_SUCCESS(GetAddonId(addonId), false); return policy->CanAccessURI(aURI, aExplicit);
if (addonId.IsEmpty()) {
return false;
} }
return false;
nsCOMPtr<nsIAddonPolicyService> aps = do_GetService("@mozilla.org/addons/policy-service;1");
NS_ENSURE_TRUE(aps, false);
bool allowed = false;
nsresult rv = aps->AddonMayLoadURI(addonId, aURI, aExplicit, &allowed);
return NS_SUCCEEDED(rv) && allowed;
} }
void void

View file

@ -12,6 +12,7 @@
#include "mozilla/Attributes.h" #include "mozilla/Attributes.h"
#include "mozilla/OriginAttributes.h" #include "mozilla/OriginAttributes.h"
class nsIAtom;
class nsIContentSecurityPolicy; class nsIContentSecurityPolicy;
class nsIObjectOutputStream; class nsIObjectOutputStream;
class nsIObjectInputStream; class nsIObjectInputStream;
@ -20,6 +21,9 @@ class nsIURI;
class ExpandedPrincipal; class ExpandedPrincipal;
namespace mozilla { namespace mozilla {
namespace extensions {
class WebExtensionPolicy;
}
/* /*
* Base class from which all nsIPrincipal implementations inherit. Use this for * Base class from which all nsIPrincipal implementations inherit. Use this for
@ -64,6 +68,7 @@ public:
NS_IMETHOD SubsumesConsideringDomain(nsIPrincipal* other, bool* _retval) final; NS_IMETHOD SubsumesConsideringDomain(nsIPrincipal* other, bool* _retval) final;
NS_IMETHOD SubsumesConsideringDomainIgnoringFPD(nsIPrincipal* other, bool* _retval) final; NS_IMETHOD SubsumesConsideringDomainIgnoringFPD(nsIPrincipal* other, bool* _retval) final;
NS_IMETHOD CheckMayLoad(nsIURI* uri, bool report, bool allowIfInheritsPrincipal) final; NS_IMETHOD CheckMayLoad(nsIURI* uri, bool report, bool allowIfInheritsPrincipal) final;
NS_IMETHOD GetAddonPolicy(nsISupports** aResult) final;
NS_IMETHOD GetCsp(nsIContentSecurityPolicy** aCsp) override; NS_IMETHOD GetCsp(nsIContentSecurityPolicy** aCsp) override;
NS_IMETHOD SetCsp(nsIContentSecurityPolicy* aCsp) override; NS_IMETHOD SetCsp(nsIContentSecurityPolicy* aCsp) override;
NS_IMETHOD EnsureCSP(nsIDOMDocument* aDocument, nsIContentSecurityPolicy** aCSP) override; NS_IMETHOD EnsureCSP(nsIDOMDocument* aDocument, nsIContentSecurityPolicy** aCSP) override;
@ -81,7 +86,7 @@ public:
NS_IMETHOD GetUserContextId(uint32_t* aUserContextId) final; NS_IMETHOD GetUserContextId(uint32_t* aUserContextId) final;
NS_IMETHOD GetPrivateBrowsingId(uint32_t* aPrivateBrowsingId) final; NS_IMETHOD GetPrivateBrowsingId(uint32_t* aPrivateBrowsingId) final;
virtual bool AddonHasPermission(const nsAString& aPerm); virtual bool AddonHasPermission(const nsIAtom* aPerm);
virtual bool IsCodebasePrincipal() const { return false; }; virtual bool IsCodebasePrincipal() const { return false; };
@ -99,6 +104,7 @@ public:
const OriginAttributes& OriginAttributesRef() final { return mOriginAttributes; } const OriginAttributes& OriginAttributesRef() final { return mOriginAttributes; }
uint32_t AppId() const { return mOriginAttributes.mAppId; } uint32_t AppId() const { return mOriginAttributes.mAppId; }
extensions::WebExtensionPolicy* AddonPolicy();
uint32_t UserContextId() const { return mOriginAttributes.mUserContextId; } uint32_t UserContextId() const { return mOriginAttributes.mUserContextId; }
uint32_t PrivateBrowsingId() const { return mOriginAttributes.mPrivateBrowsingId; } uint32_t PrivateBrowsingId() const { return mOriginAttributes.mPrivateBrowsingId; }
bool IsInIsolatedMozBrowserElement() const { return mOriginAttributes.mInIsolatedMozBrowser; } bool IsInIsolatedMozBrowserElement() const { return mOriginAttributes.mInIsolatedMozBrowser; }

View file

@ -30,6 +30,7 @@
#include "mozilla/dom/nsCSPContext.h" #include "mozilla/dom/nsCSPContext.h"
#include "mozilla/dom/ScriptSettings.h" #include "mozilla/dom/ScriptSettings.h"
#include "mozilla/ClearOnShutdown.h" #include "mozilla/ClearOnShutdown.h"
#include "mozilla/ExtensionPolicyService.h"
#include "mozilla/Preferences.h" #include "mozilla/Preferences.h"
#include "mozilla/HashFunctions.h" #include "mozilla/HashFunctions.h"
@ -47,17 +48,10 @@ static bool URIIsImmutable(nsIURI* aURI)
!isMutable; !isMutable;
} }
static nsIAddonPolicyService* static inline ExtensionPolicyService&
GetAddonPolicyService(nsresult* aRv) EPS()
{ {
static nsCOMPtr<nsIAddonPolicyService> addonPolicyService; return ExtensionPolicyService::GetSingleton();
*aRv = NS_OK;
if (!addonPolicyService) {
addonPolicyService = do_GetService("@mozilla.org/addons/policy-service;1", aRv);
ClearOnShutdown(&addonPolicyService);
}
return addonPolicyService;
} }
NS_IMPL_CLASSINFO(ContentPrincipal, nullptr, nsIClassInfo::MAIN_THREAD_ONLY, NS_IMPL_CLASSINFO(ContentPrincipal, nullptr, nsIClassInfo::MAIN_THREAD_ONLY,
@ -425,34 +419,34 @@ ContentPrincipal::GetBaseDomain(nsACString& aBaseDomain)
return NS_OK; return NS_OK;
} }
WebExtensionPolicy*
ContentPrincipal::AddonPolicy()
{
if (!mAddon.isSome()) {
NS_ENSURE_TRUE(mCodebase, nullptr);
bool isMozExt;
if (NS_SUCCEEDED(mCodebase->SchemeIs("moz-extension", &isMozExt)) && isMozExt) {
mAddon.emplace(EPS().GetByURL(mCodebase.get()));
} else {
mAddon.emplace(nullptr);
}
}
return mAddon.value();
}
NS_IMETHODIMP NS_IMETHODIMP
ContentPrincipal::GetAddonId(nsAString& aAddonId) ContentPrincipal::GetAddonId(nsAString& aAddonId)
{ {
if (mAddonIdCache.isSome()) { auto policy = AddonPolicy();
aAddonId.Assign(mAddonIdCache.ref()); if (policy) {
return NS_OK; policy->GetId(aAddonId);
}
NS_ENSURE_TRUE(mCodebase, NS_ERROR_FAILURE);
nsresult rv;
bool isMozExt;
if (NS_SUCCEEDED(mCodebase->SchemeIs("moz-extension", &isMozExt)) && isMozExt) {
nsIAddonPolicyService* addonPolicyService = GetAddonPolicyService(&rv);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString addonId;
rv = addonPolicyService->ExtensionURIToAddonId(mCodebase, addonId);
NS_ENSURE_SUCCESS(rv, rv);
mAddonIdCache.emplace(addonId);
} else { } else {
mAddonIdCache.emplace(); aAddonId.Truncate();
} }
aAddonId.Assign(mAddonIdCache.ref());
return NS_OK; return NS_OK;
}; }
NS_IMETHODIMP NS_IMETHODIMP
ContentPrincipal::Read(nsIObjectInputStream* aStream) ContentPrincipal::Read(nsIObjectInputStream* aStream)

View file

@ -14,6 +14,7 @@
#include "nsNetUtil.h" #include "nsNetUtil.h"
#include "nsScriptSecurityManager.h" #include "nsScriptSecurityManager.h"
#include "mozilla/BasePrincipal.h" #include "mozilla/BasePrincipal.h"
#include "mozilla/extensions/WebExtensionPolicy.h"
class ContentPrincipal final : public mozilla::BasePrincipal class ContentPrincipal final : public mozilla::BasePrincipal
{ {
@ -47,6 +48,8 @@ public:
static nsresult static nsresult
GenerateOriginNoSuffixFromURI(nsIURI* aURI, nsACString& aOrigin); GenerateOriginNoSuffixFromURI(nsIURI* aURI, nsACString& aOrigin);
mozilla::extensions::WebExtensionPolicy* AddonPolicy();
nsCOMPtr<nsIURI> mDomain; nsCOMPtr<nsIURI> mDomain;
nsCOMPtr<nsIURI> mCodebase; nsCOMPtr<nsIURI> mCodebase;
// If mCodebaseImmutable is true, mCodebase is non-null and immutable // If mCodebaseImmutable is true, mCodebase is non-null and immutable
@ -61,7 +64,7 @@ protected:
bool MayLoadInternal(nsIURI* aURI) override; bool MayLoadInternal(nsIURI* aURI) override;
private: private:
mozilla::Maybe<nsString> mAddonIdCache; mozilla::Maybe<mozilla::WeakPtr<mozilla::extensions::WebExtensionPolicy>> mAddon;
}; };
#define NS_PRINCIPAL_CONTRACTID "@mozilla.org/principal;1" #define NS_PRINCIPAL_CONTRACTID "@mozilla.org/principal;1"

View file

@ -172,7 +172,7 @@ ExpandedPrincipal::GetAddonId(nsAString& aAddonId)
}; };
bool bool
ExpandedPrincipal::AddonHasPermission(const nsAString& aPerm) ExpandedPrincipal::AddonHasPermission(const nsIAtom* aPerm)
{ {
for (size_t i = 0; i < mPrincipals.Length(); ++i) { for (size_t i = 0; i < mPrincipals.Length(); ++i) {
if (BasePrincipal::Cast(mPrincipals[i])->AddonHasPermission(aPerm)) { if (BasePrincipal::Cast(mPrincipals[i])->AddonHasPermission(aPerm)) {

View file

@ -34,7 +34,7 @@ public:
NS_IMETHOD SetDomain(nsIURI* aDomain) override; NS_IMETHOD SetDomain(nsIURI* aDomain) override;
NS_IMETHOD GetBaseDomain(nsACString& aBaseDomain) override; NS_IMETHOD GetBaseDomain(nsACString& aBaseDomain) override;
NS_IMETHOD GetAddonId(nsAString& aAddonId) override; NS_IMETHOD GetAddonId(nsAString& aAddonId) override;
virtual bool AddonHasPermission(const nsAString& aPerm) override; virtual bool AddonHasPermission(const nsIAtom* aPerm) override;
virtual nsresult GetScriptLocation(nsACString &aStr) override; virtual nsresult GetScriptLocation(nsACString &aStr) override;
protected: protected:

View file

@ -274,6 +274,8 @@ interface nsIPrincipal : nsISerializable
*/ */
readonly attribute AString addonId; readonly attribute AString addonId;
readonly attribute nsISupports addonPolicy;
/** /**
* Gets the id of the user context this principal is inside. If this * Gets the id of the user context this principal is inside. If this
* principal is inside the default userContext, this returns * principal is inside the default userContext, this returns

View file

@ -769,13 +769,8 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
&hasFlags); &hasFlags);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
if (hasFlags) { if (hasFlags && BasePrincipal::Cast(aPrincipal)->AddonPolicy()) {
nsString addonId; return NS_OK;
aPrincipal->GetAddonId(addonId);
if (!addonId.IsEmpty()) {
return NS_OK;
}
} }
// If we get here, check all the schemes can link to each other, from the top down: // If we get here, check all the schemes can link to each other, from the top down:

View file

@ -9,9 +9,7 @@
#include "nsIScriptSecurityManager.h" #include "nsIScriptSecurityManager.h"
#include "nsIAddonPolicyService.h"
#include "mozilla/Maybe.h" #include "mozilla/Maybe.h"
#include "nsIAddonPolicyService.h"
#include "nsIPrincipal.h" #include "nsIPrincipal.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "nsIObserver.h" #include "nsIObserver.h"
@ -136,17 +134,6 @@ private:
// policy machinery will be removed soon. // policy machinery will be removed soon.
nsCOMPtr<nsIDomainPolicy> mDomainPolicy; nsCOMPtr<nsIDomainPolicy> mDomainPolicy;
// Cached addon policy service. We can't generate this in Init() because
// that's too early to get a service.
mozilla::Maybe<nsCOMPtr<nsIAddonPolicyService>> mAddonPolicyService;
nsIAddonPolicyService* GetAddonPolicyService()
{
if (mAddonPolicyService.isNothing()) {
mAddonPolicyService.emplace(do_GetService("@mozilla.org/addons/policy-service;1"));
}
return mAddonPolicyService.ref();
}
static bool sStrictFileOriginPolicy; static bool sStrictFileOriginPolicy;
static nsIIOService *sIOService; static nsIIOService *sIOService;

View file

@ -38,7 +38,7 @@ If it's the first time you add one of these, it's advised to follow the style of
New data types have been added over the years, so it's quite feasible that some of our probes are not the most suitable nowadays. New data types have been added over the years, so it's quite feasible that some of our probes are not the most suitable nowadays.
There's more information about types (and telemetry in general) on [this page](https://developer.mozilla.org/en-US/docs/Mozilla/Performance/Adding_a_new_Telemetry_probe) and [this other page](https://gecko.readthedocs.io/en/latest/toolkit/components/telemetry/telemetry/collection/index.html). There's more information about types (and telemetry in general) on [this page](https://developer.mozilla.org/en-US/docs/Mozilla/Performance/Adding_a_new_Telemetry_probe) and [this other page](https://firefox-source-docs.mozilla.org/toolkit/components/telemetry/telemetry/collection/index.html).
And of course, in case of doubt, ask! And of course, in case of doubt, ask!

View file

@ -121,8 +121,7 @@ ObjectActor.prototype = {
// Bug 1348761: getOwnPropertyNames is unecessary slow on TypedArrays // Bug 1348761: getOwnPropertyNames is unecessary slow on TypedArrays
let length = DevToolsUtils.getProperty(this.obj, "length"); let length = DevToolsUtils.getProperty(this.obj, "length");
g.ownPropertyLength = length; g.ownPropertyLength = length;
} else if (!["Function", "Proxy"].includes(g.class)) { } else if (g.class != "Proxy") {
// Bug 1163520: Assert on internal functions
g.ownPropertyLength = this.obj.getOwnPropertyNames().length; g.ownPropertyLength = this.obj.getOwnPropertyNames().length;
} }
} catch (e) { } catch (e) {

View file

@ -2331,7 +2331,7 @@ nsContentUtils::CanCallerAccess(nsPIDOMWindowInner* aWindow)
// static // static
bool bool
nsContentUtils::PrincipalHasPermission(nsIPrincipal* aPrincipal, const nsAString& aPerm) nsContentUtils::PrincipalHasPermission(nsIPrincipal* aPrincipal, const nsIAtom* aPerm)
{ {
// Chrome gets access by default. // Chrome gets access by default.
if (IsSystemPrincipal(aPrincipal)) { if (IsSystemPrincipal(aPrincipal)) {
@ -2344,7 +2344,7 @@ nsContentUtils::PrincipalHasPermission(nsIPrincipal* aPrincipal, const nsAString
// static // static
bool bool
nsContentUtils::CallerHasPermission(JSContext* aCx, const nsAString& aPerm) nsContentUtils::CallerHasPermission(JSContext* aCx, const nsIAtom* aPerm)
{ {
return PrincipalHasPermission(SubjectPrincipal(aCx), aPerm); return PrincipalHasPermission(SubjectPrincipal(aCx), aPerm);
} }
@ -7350,7 +7350,7 @@ nsContentUtils::IsCutCopyAllowed(nsIPrincipal* aSubjectPrincipal)
return true; return true;
} }
return PrincipalHasPermission(aSubjectPrincipal, NS_LITERAL_STRING("clipboardWrite")); return PrincipalHasPermission(aSubjectPrincipal, nsGkAtoms::clipboardWrite);
} }
/* static */ /* static */

View file

@ -57,6 +57,7 @@ class imgRequestProxy;
class nsAutoScriptBlockerSuppressNodeRemoved; class nsAutoScriptBlockerSuppressNodeRemoved;
class nsCacheableFuncStringHTMLCollection; class nsCacheableFuncStringHTMLCollection;
class nsHtml5StringParser; class nsHtml5StringParser;
class nsIAtom;
class nsIChannel; class nsIChannel;
class nsIConsoleService; class nsIConsoleService;
class nsIContent; class nsIContent;
@ -590,10 +591,10 @@ public:
static bool CanCallerAccess(nsPIDOMWindowInner* aWindow); static bool CanCallerAccess(nsPIDOMWindowInner* aWindow);
// Check if the principal is chrome or an addon with the permission. // Check if the principal is chrome or an addon with the permission.
static bool PrincipalHasPermission(nsIPrincipal* aPrincipal, const nsAString& aPerm); static bool PrincipalHasPermission(nsIPrincipal* aPrincipal, const nsIAtom* aPerm);
// Check if the JS caller is chrome or an addon with the permission. // Check if the JS caller is chrome or an addon with the permission.
static bool CallerHasPermission(JSContext* aCx, const nsAString& aPerm); static bool CallerHasPermission(JSContext* aCx, const nsIAtom* aPerm);
/** /**
* GetDocumentFromCaller gets its document by looking at the last called * GetDocumentFromCaller gets its document by looking at the last called

View file

@ -209,7 +209,6 @@
#include "imgRequestProxy.h" #include "imgRequestProxy.h"
#include "nsWrapperCacheInlines.h" #include "nsWrapperCacheInlines.h"
#include "nsSandboxFlags.h" #include "nsSandboxFlags.h"
#include "nsIAddonPolicyService.h"
#include "mozilla/dom/AnimatableBinding.h" #include "mozilla/dom/AnimatableBinding.h"
#include "mozilla/dom/AnonymousContent.h" #include "mozilla/dom/AnonymousContent.h"
#include "mozilla/dom/BindingUtils.h" #include "mozilla/dom/BindingUtils.h"
@ -227,6 +226,7 @@
#include "mozilla/dom/CustomElementRegistryBinding.h" #include "mozilla/dom/CustomElementRegistryBinding.h"
#include "mozilla/dom/CustomElementRegistry.h" #include "mozilla/dom/CustomElementRegistry.h"
#include "mozilla/dom/TimeoutManager.h" #include "mozilla/dom/TimeoutManager.h"
#include "mozilla/ExtensionPolicyService.h"
#include "nsFrame.h" #include "nsFrame.h"
#include "nsDOMCaretPosition.h" #include "nsDOMCaretPosition.h"
#include "nsIDOMHTMLTextAreaElement.h" #include "nsIDOMHTMLTextAreaElement.h"
@ -2940,10 +2940,8 @@ nsDocument::InitCSP(nsIChannel* aChannel)
NS_ConvertASCIItoUTF16 cspROHeaderValue(tCspROHeaderValue); NS_ConvertASCIItoUTF16 cspROHeaderValue(tCspROHeaderValue);
// Check if this is a document from a WebExtension. // Check if this is a document from a WebExtension.
nsString addonId;
nsCOMPtr<nsIPrincipal> principal = NodePrincipal(); nsCOMPtr<nsIPrincipal> principal = NodePrincipal();
principal->GetAddonId(addonId); auto addonPolicy = BasePrincipal::Cast(principal)->AddonPolicy();
bool applyAddonCSP = !addonId.IsEmpty();
// Check if this is a signed content to apply default CSP. // Check if this is a signed content to apply default CSP.
bool applySignedContentCSP = false; bool applySignedContentCSP = false;
@ -2953,7 +2951,7 @@ nsDocument::InitCSP(nsIChannel* aChannel)
} }
// If there's no CSP to apply, go ahead and return early // If there's no CSP to apply, go ahead and return early
if (!applyAddonCSP && if (!addonPolicy &&
!applySignedContentCSP && !applySignedContentCSP &&
cspHeaderValue.IsEmpty() && cspHeaderValue.IsEmpty() &&
cspROHeaderValue.IsEmpty()) { cspROHeaderValue.IsEmpty()) {
@ -2977,19 +2975,14 @@ nsDocument::InitCSP(nsIChannel* aChannel)
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
// ----- if the doc is an addon, apply its CSP. // ----- if the doc is an addon, apply its CSP.
if (applyAddonCSP) { if (addonPolicy) {
nsCOMPtr<nsIAddonPolicyService> aps = do_GetService("@mozilla.org/addons/policy-service;1"); nsCOMPtr<nsIAddonPolicyService> aps = do_GetService("@mozilla.org/addons/policy-service;1");
nsAutoString addonCSP; nsAutoString addonCSP;
rv = aps->GetBaseCSP(addonCSP); Unused << ExtensionPolicyService::GetSingleton().GetBaseCSP(addonCSP);
if (NS_SUCCEEDED(rv)) { csp->AppendPolicy(addonCSP, false, false);
csp->AppendPolicy(addonCSP, false, false);
}
rv = aps->GetAddonCSP(addonId, addonCSP); csp->AppendPolicy(addonPolicy->ContentSecurityPolicy(), false, false);
if (NS_SUCCEEDED(rv)) {
csp->AppendPolicy(addonCSP, false, false);
}
} }
// ----- if the doc is a signed content, apply the default CSP. // ----- if the doc is a signed content, apply the default CSP.
@ -13183,9 +13176,15 @@ nsDocument::UpdateIntersectionObservations()
time = perf->Now(); time = perf->Now();
} }
} }
nsTArray<RefPtr<DOMIntersectionObserver>> observers(mIntersectionObservers.Count());
for (auto iter = mIntersectionObservers.Iter(); !iter.Done(); iter.Next()) { for (auto iter = mIntersectionObservers.Iter(); !iter.Done(); iter.Next()) {
DOMIntersectionObserver* observer = iter.Get()->GetKey(); DOMIntersectionObserver* observer = iter.Get()->GetKey();
observer->Update(this, time); observers.AppendElement(observer);
}
for (const auto& observer : observers) {
if (observer) {
observer->Update(this, time);
}
} }
} }
@ -13212,7 +13211,9 @@ nsDocument::NotifyIntersectionObservers()
observers.AppendElement(observer); observers.AppendElement(observer);
} }
for (const auto& observer : observers) { for (const auto& observer : observers) {
observer->Notify(); if (observer) {
observer->Notify();
}
} }
} }

View file

@ -2069,6 +2069,11 @@ GK_ATOM(mozinputrangeignorepreventdefault, "mozinputrangeignorepreventdefault")
// WebExtensions // WebExtensions
GK_ATOM(moz_extension, "moz-extension") GK_ATOM(moz_extension, "moz-extension")
GK_ATOM(all_urlsPermission, "<all_urls>") GK_ATOM(all_urlsPermission, "<all_urls>")
GK_ATOM(clipboardRead, "clipboardRead")
GK_ATOM(clipboardWrite, "clipboardWrite")
GK_ATOM(debugger, "debugger")
GK_ATOM(tabs, "tabs")
GK_ATOM(webRequestBlocking, "webRequestBlocking")
GK_ATOM(http, "http") GK_ATOM(http, "http")
GK_ATOM(https, "https") GK_ATOM(https, "https")

View file

@ -3344,9 +3344,8 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
// it runs JS code for this compartment. We skip the check if this window is // it runs JS code for this compartment. We skip the check if this window is
// for chrome JS or an add-on. // for chrome JS or an add-on.
nsCOMPtr<nsIPrincipal> principal = mDoc->NodePrincipal(); nsCOMPtr<nsIPrincipal> principal = mDoc->NodePrincipal();
nsString addonId; if (GetDocGroup() && !nsContentUtils::IsSystemPrincipal(principal) &&
principal->GetAddonId(addonId); !BasePrincipal::Cast(principal)->AddonPolicy()) {
if (GetDocGroup() && !nsContentUtils::IsSystemPrincipal(principal) && addonId.IsEmpty()) {
js::SetCompartmentValidAccessPtr(cx, newInnerGlobal, js::SetCompartmentValidAccessPtr(cx, newInnerGlobal,
newInnerWindow->GetDocGroup()->GetValidAccessPtr()); newInnerWindow->GetDocGroup()->GetValidAccessPtr());
} }
@ -9827,8 +9826,7 @@ public:
JSCompartment* cpt = js::GetObjectCompartment(obj); JSCompartment* cpt = js::GetObjectCompartment(obj);
nsCOMPtr<nsIPrincipal> pc = nsJSPrincipals::get(JS_GetCompartmentPrincipals(cpt)); nsCOMPtr<nsIPrincipal> pc = nsJSPrincipals::get(JS_GetCompartmentPrincipals(cpt));
nsAutoString addonId; if (BasePrincipal::Cast(pc)->AddonPolicy()) {
if (NS_SUCCEEDED(pc->GetAddonId(addonId)) && !addonId.IsEmpty()) {
// We want to nuke all references to the add-on compartment. // We want to nuke all references to the add-on compartment.
xpc::NukeAllWrappersForCompartment(cx, cpt, xpc::NukeAllWrappersForCompartment(cx, cpt,
win->IsInnerWindow() ? js::DontNukeWindowReferences win->IsInnerWindow() ? js::DontNukeWindowReferences

View file

@ -5687,7 +5687,7 @@ CanvasRenderingContext2D::GetImageData(JSContext* aCx, double aSx,
// JSContext, and we're at least _somewhat_ perf-sensitive (so may not // JSContext, and we're at least _somewhat_ perf-sensitive (so may not
// want to compute the caller type in the common non-write-only case), so // want to compute the caller type in the common non-write-only case), so
// let's just use what we have. // let's just use what we have.
!nsContentUtils::CallerHasPermission(aCx, NS_LITERAL_STRING("<all_urls>"))) !nsContentUtils::CallerHasPermission(aCx, nsGkAtoms::all_urlsPermission))
{ {
// XXX ERRMSG we need to report an error to developers here! (bug 329026) // XXX ERRMSG we need to report an error to developers here! (bug 329026)
aError.Throw(NS_ERROR_DOM_SECURITY_ERR); aError.Throw(NS_ERROR_DOM_SECURITY_ERR);

View file

@ -118,7 +118,7 @@ CoerceDouble(const JS::Value& v, double* d)
bool bool
HasDrawWindowPrivilege(JSContext* aCx, JSObject* /* unused */) HasDrawWindowPrivilege(JSContext* aCx, JSObject* /* unused */)
{ {
return nsContentUtils::CallerHasPermission(aCx, NS_LITERAL_STRING("<all_urls>")); return nsContentUtils::CallerHasPermission(aCx, nsGkAtoms::all_urlsPermission);
} }
} // namespace CanvasUtils } // namespace CanvasUtils

View file

@ -652,7 +652,7 @@ HTMLCanvasElement::ToDataURL(JSContext* aCx, const nsAString& aType,
{ {
// do a trust check if this is a write-only canvas // do a trust check if this is a write-only canvas
if (mWriteOnly && if (mWriteOnly &&
!nsContentUtils::CallerHasPermission(aCx, NS_LITERAL_STRING("<all_urls>"))) { !nsContentUtils::CallerHasPermission(aCx, nsGkAtoms::all_urlsPermission)) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return; return;
} }
@ -835,7 +835,7 @@ HTMLCanvasElement::ToBlob(JSContext* aCx,
{ {
// do a trust check if this is a write-only canvas // do a trust check if this is a write-only canvas
if (mWriteOnly && if (mWriteOnly &&
!nsContentUtils::CallerHasPermission(aCx, NS_LITERAL_STRING("<all_urls>"))) { !nsContentUtils::CallerHasPermission(aCx, nsGkAtoms::all_urlsPermission)) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return; return;
} }

View file

@ -7570,9 +7570,8 @@ HTMLMediaElement::MarkAsTainted()
bool bool
HasDebuggerOrTabsPrivilege(JSContext* aCx, JSObject* aObj) HasDebuggerOrTabsPrivilege(JSContext* aCx, JSObject* aObj)
{ {
return nsContentUtils::CallerHasPermission(aCx, return nsContentUtils::CallerHasPermission(aCx, nsGkAtoms::debugger) ||
NS_LITERAL_STRING("debugger")) || nsContentUtils::CallerHasPermission(aCx, nsGkAtoms::tabs);
nsContentUtils::CallerHasPermission(aCx, NS_LITERAL_STRING("tabs"));
} }
void void

View file

@ -3290,7 +3290,7 @@ nsHTMLDocument::ExecCommand(const nsAString& commandID,
bool restricted = commandID.LowerCaseEqualsLiteral("paste"); bool restricted = commandID.LowerCaseEqualsLiteral("paste");
if (restricted && !nsContentUtils::PrincipalHasPermission(&aSubjectPrincipal, if (restricted && !nsContentUtils::PrincipalHasPermission(&aSubjectPrincipal,
NS_LITERAL_STRING("clipboardRead"))) { nsGkAtoms::clipboardRead)) {
return false; return false;
} }

View file

@ -38,23 +38,12 @@ nsSVGElement::StringInfo SVGAElement::sStringInfo[3] =
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// nsISupports methods // nsISupports methods
NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(SVGAElement) NS_INTERFACE_MAP_BEGIN(SVGAElement)
NS_INTERFACE_TABLE_INHERITED(SVGAElement, NS_INTERFACE_MAP_ENTRY(nsIDOMNode)
nsIDOMNode, NS_INTERFACE_MAP_ENTRY(nsIDOMElement)
nsIDOMElement, NS_INTERFACE_MAP_ENTRY(nsIDOMSVGElement)
nsIDOMSVGElement, NS_INTERFACE_MAP_ENTRY(Link)
Link) NS_INTERFACE_MAP_END_INHERITING(SVGAElementBase)
NS_INTERFACE_TABLE_TAIL_INHERITING(SVGAElementBase)
NS_IMPL_CYCLE_COLLECTION_CLASS(SVGAElement)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(SVGAElement,
SVGAElementBase)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(SVGAElement,
SVGAElementBase)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_ADDREF_INHERITED(SVGAElement, SVGAElementBase) NS_IMPL_ADDREF_INHERITED(SVGAElement, SVGAElementBase)
NS_IMPL_RELEASE_INHERITED(SVGAElement, SVGAElementBase) NS_IMPL_RELEASE_INHERITED(SVGAElement, SVGAElementBase)

View file

@ -34,7 +34,6 @@ protected:
public: public:
NS_DECL_ISUPPORTS_INHERITED NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(SVGAElement, SVGAElementBase)
// nsINode interface methods // nsINode interface methods
virtual nsresult GetEventTargetParent( virtual nsresult GetEventTargetParent(

View file

@ -8,6 +8,7 @@ support-files = beacon-frame.html
[test_beacon.html] [test_beacon.html]
[test_beaconFrame.html] [test_beaconFrame.html]
[test_beaconPreflightWithCustomContentType.html] [test_beaconPreflightWithCustomContentType.html]
skip-if = toolkit == 'android' # Bug 1373945
[test_beaconContentPolicy.html] [test_beaconContentPolicy.html]
[test_beaconOriginHeader.html] [test_beaconOriginHeader.html]
[test_beaconRedirect.html] [test_beaconRedirect.html]

View file

@ -5,7 +5,7 @@
#include "domstubs.idl" #include "domstubs.idl"
interface nsIAtom; interface nsIAtom; // used in [noscript] methods only
interface nsIContent; interface nsIContent;
interface nsIXULBuilderListener; interface nsIXULBuilderListener;
interface nsIXULTemplateResult; interface nsIXULTemplateResult;
@ -267,7 +267,8 @@ interface nsIXULTemplateBuilder : nsISupports
* @param aNode node to check * @param aNode node to check
* @param aTag tag that must match * @param aTag tag that must match
*/ */
boolean hasGeneratedContent(in nsIRDFResource aNode, in nsIAtom aTag); [noscript] boolean hasGeneratedContent(in nsIRDFResource aNode,
in nsIAtom aTag);
/** /**
* Adds a rule filter for a given rule, which may be used for specialized * Adds a rule filter for a given rule, which may be used for specialized

View file

@ -5,7 +5,7 @@
#include "domstubs.idl" #include "domstubs.idl"
interface nsIAtom; interface nsIAtom; // used in [noscript] methods only
interface nsIArray; interface nsIArray;
interface nsISimpleEnumerator; interface nsISimpleEnumerator;
interface nsIXULTemplateResult; interface nsIXULTemplateResult;
@ -162,10 +162,10 @@ interface nsIXULTemplateQueryProcessor : nsISupports
* *
* @returns a compiled query object * @returns a compiled query object
*/ */
nsISupports compileQuery(in nsIXULTemplateBuilder aBuilder, [noscript] nsISupports compileQuery(in nsIXULTemplateBuilder aBuilder,
in nsIDOMNode aQuery, in nsIDOMNode aQuery,
in nsIAtom aRefVariable, in nsIAtom aRefVariable,
in nsIAtom aMemberVariable); in nsIAtom aMemberVariable);
/** /**
* Generate the results of a query and return them in an enumerator. The * Generate the results of a query and return them in an enumerator. The
@ -222,10 +222,10 @@ interface nsIXULTemplateQueryProcessor : nsISupports
* @param aRef variable that holds reference value * @param aRef variable that holds reference value
* @param aExpr expression used to compute the value to assign * @param aExpr expression used to compute the value to assign
*/ */
void addBinding(in nsIDOMNode aRuleNode, [noscript] void addBinding(in nsIDOMNode aRuleNode,
in nsIAtom aVar, in nsIAtom aVar,
in nsIAtom aRef, in nsIAtom aRef,
in AString aExpr); in AString aExpr);
/** /**
* Translate a ref attribute string into a result. This is used as the * Translate a ref attribute string into a result. This is used as the
@ -269,8 +269,8 @@ interface nsIXULTemplateQueryProcessor : nsISupports
* *
* @param returns -1 if less, 0 if equal, or 1 if greater * @param returns -1 if less, 0 if equal, or 1 if greater
*/ */
int32_t compareResults(in nsIXULTemplateResult aLeft, [noscript] int32_t compareResults(in nsIXULTemplateResult aLeft,
in nsIXULTemplateResult aRight, in nsIXULTemplateResult aRight,
in nsIAtom aVar, in nsIAtom aVar,
in unsigned long aSortHints); in unsigned long aSortHints);
}; };

View file

@ -5,7 +5,7 @@
#include "nsISupports.idl" #include "nsISupports.idl"
interface nsIAtom; interface nsIAtom; // used in [noscript] methods only
interface nsIDOMNode; interface nsIDOMNode;
interface nsIRDFResource; interface nsIRDFResource;
@ -80,7 +80,7 @@ interface nsIXULTemplateResult : nsISupports
* *
* @return the value for the variable or a null string if it has no value * @return the value for the variable or a null string if it has no value
*/ */
AString getBindingFor(in nsIAtom aVar); [noscript] AString getBindingFor(in nsIAtom aVar);
/** /**
* Get an object value for a variable such as ?name for this result. * Get an object value for a variable such as ?name for this result.
@ -93,7 +93,7 @@ interface nsIXULTemplateResult : nsISupports
* *
* @return the value for the variable or null if it has no value * @return the value for the variable or null if it has no value
*/ */
nsISupports getBindingObjectFor(in nsIAtom aVar); [noscript] nsISupports getBindingObjectFor(in nsIAtom aVar);
/** /**
* Indicate that a particular rule of a query has matched and that output * Indicate that a particular rule of a query has matched and that output

View file

@ -11,11 +11,13 @@
#include "Logging.h" #include "Logging.h"
#include "mozilla/RefPtr.h" #include "mozilla/RefPtr.h"
#include "mozilla/StaticMutex.h"
namespace mozilla { namespace mozilla {
namespace gfx { namespace gfx {
static Atomic<uint64_t> sNextFontFileKey; static StaticMutex sFontFileStreamsMutex;
static uint64_t sNextFontFileKey = 0;
static std::unordered_map<uint64_t, IDWriteFontFileStream*> sFontFileStreams; static std::unordered_map<uint64_t, IDWriteFontFileStream*> sFontFileStreams;
class DWriteFontFileLoader : public IDWriteFontFileLoader class DWriteFontFileLoader : public IDWriteFontFileLoader
@ -109,18 +111,16 @@ public:
IFACEMETHOD_(ULONG, AddRef)() IFACEMETHOD_(ULONG, AddRef)()
{ {
++mRefCnt; return ++mRefCnt;
return mRefCnt;
} }
IFACEMETHOD_(ULONG, Release)() IFACEMETHOD_(ULONG, Release)()
{ {
--mRefCnt; uint32_t count = --mRefCnt;
if (mRefCnt == 0) { if (count == 0) {
delete this; delete this;
return 0;
} }
return mRefCnt; return count;
} }
// IDWriteFontFileStream methods // IDWriteFontFileStream methods
@ -137,7 +137,7 @@ public:
private: private:
std::vector<uint8_t> mData; std::vector<uint8_t> mData;
uint32_t mRefCnt; Atomic<uint32_t> mRefCnt;
uint64_t mFontFileKey; uint64_t mFontFileKey;
}; };
@ -152,6 +152,7 @@ DWriteFontFileLoader::CreateStreamFromKey(const void *fontFileReferenceKey,
return E_POINTER; return E_POINTER;
} }
StaticMutexAutoLock lock(sFontFileStreamsMutex);
uint64_t fontFileKey = *static_cast<const uint64_t*>(fontFileReferenceKey); uint64_t fontFileKey = *static_cast<const uint64_t*>(fontFileReferenceKey);
auto found = sFontFileStreams.find(fontFileKey); auto found = sFontFileStreams.find(fontFileKey);
if (found == sFontFileStreams.end()) { if (found == sFontFileStreams.end()) {
@ -175,6 +176,7 @@ DWriteFontFileStream::DWriteFontFileStream(uint8_t *aData, uint32_t aSize,
DWriteFontFileStream::~DWriteFontFileStream() DWriteFontFileStream::~DWriteFontFileStream()
{ {
StaticMutexAutoLock lock(sFontFileStreamsMutex);
sFontFileStreams.erase(mFontFileKey); sFontFileStreams.erase(mFontFileKey);
} }
@ -227,10 +229,12 @@ NativeFontResourceDWrite::Create(uint8_t *aFontData, uint32_t aDataLength,
return nullptr; return nullptr;
} }
sFontFileStreamsMutex.Lock();
uint64_t fontFileKey = sNextFontFileKey++; uint64_t fontFileKey = sNextFontFileKey++;
RefPtr<IDWriteFontFileStream> ffsRef = RefPtr<IDWriteFontFileStream> ffsRef =
new DWriteFontFileStream(aFontData, aDataLength, fontFileKey); new DWriteFontFileStream(aFontData, aDataLength, fontFileKey);
sFontFileStreams[fontFileKey] = ffsRef; sFontFileStreams[fontFileKey] = ffsRef;
sFontFileStreamsMutex.Unlock();
RefPtr<IDWriteFontFile> fontFile; RefPtr<IDWriteFontFile> fontFile;
HRESULT hr = HRESULT hr =

View file

@ -185,27 +185,6 @@ public:
// -- // --
class ScopedBindVAO final
{
GLContext& mGL;
const GLuint mOldVAO;
public:
ScopedBindVAO(GLContext* const gl, const GLuint vao)
: mGL(*gl)
, mOldVAO(mGL.GetIntAs<GLuint>(LOCAL_GL_VERTEX_ARRAY_BINDING))
{
mGL.fBindVertexArray(vao);
}
~ScopedBindVAO()
{
mGL.fBindVertexArray(mOldVAO);
}
};
// --
class ScopedShader final class ScopedShader final
{ {
GLContext& mGL; GLContext& mGL;
@ -367,8 +346,43 @@ DrawBlitProg::Draw(const BaseArgs& args, const YUVArgs* const argsYUV) const
// -- // --
const ScopedDrawBlitState drawState(gl, args.destSize); const ScopedDrawBlitState drawState(gl, args.destSize);
const ScopedBindVAO bindVAO(gl, mParent.mQuadVAO);
GLuint oldVAO;
GLint vaa0Enabled;
GLint vaa0Size;
GLenum vaa0Type;
GLint vaa0Normalized;
GLsizei vaa0Stride;
GLvoid* vaa0Pointer;
if (mParent.mQuadVAO) {
oldVAO = gl->GetIntAs<GLuint>(LOCAL_GL_VERTEX_ARRAY_BINDING);
gl->fBindVertexArray(mParent.mQuadVAO);
} else {
gl->fGetVertexAttribiv(0, LOCAL_GL_VERTEX_ATTRIB_ARRAY_ENABLED, &vaa0Enabled);
gl->fGetVertexAttribiv(0, LOCAL_GL_VERTEX_ATTRIB_ARRAY_SIZE, &vaa0Size);
gl->fGetVertexAttribiv(0, LOCAL_GL_VERTEX_ATTRIB_ARRAY_TYPE, (GLint*)&vaa0Type);
gl->fGetVertexAttribiv(0, LOCAL_GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &vaa0Normalized);
gl->fGetVertexAttribiv(0, LOCAL_GL_VERTEX_ATTRIB_ARRAY_STRIDE, (GLint*)&vaa0Stride);
gl->fGetVertexAttribPointerv(0, LOCAL_GL_VERTEX_ATTRIB_ARRAY_POINTER, &vaa0Pointer);
gl->fEnableVertexAttribArray(0);
const ScopedBindArrayBuffer bindVBO(gl, mParent.mQuadVBO);
gl->fVertexAttribPointer(0, 2, LOCAL_GL_FLOAT, false, 0, 0);
}
gl->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4); gl->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4);
if (mParent.mQuadVAO) {
gl->fBindVertexArray(oldVAO);
} else {
if (vaa0Enabled) {
gl->fEnableVertexAttribArray(0);
} else {
gl->fDisableVertexAttribArray(0);
}
gl->fVertexAttribPointer(0, vaa0Size, vaa0Type, bool(vaa0Normalized), vaa0Stride,
vaa0Pointer);
}
} }
// -- // --
@ -376,6 +390,7 @@ DrawBlitProg::Draw(const BaseArgs& args, const YUVArgs* const argsYUV) const
GLBlitHelper::GLBlitHelper(GLContext* const gl) GLBlitHelper::GLBlitHelper(GLContext* const gl)
: mGL(gl) : mGL(gl)
, mQuadVAO(0) , mQuadVAO(0)
, mQuadVBO(0)
, mDrawBlitProg_VertShader(mGL->fCreateShader(LOCAL_GL_VERTEX_SHADER)) , mDrawBlitProg_VertShader(mGL->fCreateShader(LOCAL_GL_VERTEX_SHADER))
, mYuvUploads{0} , mYuvUploads{0}
, mYuvUploads_YSize(0, 0) , mYuvUploads_YSize(0, 0)
@ -386,10 +401,9 @@ GLBlitHelper::GLBlitHelper(GLContext* const gl)
return; return;
} }
GLuint vbo = 0; mGL->fGenBuffers(1, &mQuadVBO);
mGL->fGenBuffers(1, &vbo);
{ {
const ScopedBindArrayBuffer bindVBO(mGL, vbo); const ScopedBindArrayBuffer bindVBO(mGL, mQuadVBO);
const float quadData[] = { const float quadData[] = {
0, 0, 0, 0,
@ -401,12 +415,17 @@ GLBlitHelper::GLBlitHelper(GLContext* const gl)
mGL->fBufferData(LOCAL_GL_ARRAY_BUFFER, heapQuadData.ByteLength(), mGL->fBufferData(LOCAL_GL_ARRAY_BUFFER, heapQuadData.ByteLength(),
heapQuadData.Data(), LOCAL_GL_STATIC_DRAW); heapQuadData.Data(), LOCAL_GL_STATIC_DRAW);
mGL->fGenVertexArrays(1, &mQuadVAO); if (mGL->IsSupported(GLFeature::vertex_array_object)) {
const ScopedBindVAO bindVAO(mGL, mQuadVAO); const auto prev = mGL->GetIntAs<GLuint>(LOCAL_GL_VERTEX_ARRAY_BINDING);
mGL->fEnableVertexAttribArray(0);
mGL->fVertexAttribPointer(0, 2, LOCAL_GL_FLOAT, false, 0, 0); mGL->fGenVertexArrays(1, &mQuadVAO);
mGL->fBindVertexArray(mQuadVAO);
mGL->fEnableVertexAttribArray(0);
mGL->fVertexAttribPointer(0, 2, LOCAL_GL_FLOAT, false, 0, 0);
mGL->fBindVertexArray(prev);
}
} }
mGL->fDeleteBuffers(1, &vbo);
// -- // --
@ -471,7 +490,11 @@ GLBlitHelper::~GLBlitHelper()
return; return;
mGL->fDeleteShader(mDrawBlitProg_VertShader); mGL->fDeleteShader(mDrawBlitProg_VertShader);
mGL->fDeleteVertexArrays(1, &mQuadVAO); mGL->fDeleteBuffers(1, &mQuadVBO);
if (mQuadVAO) {
mGL->fDeleteVertexArrays(1, &mQuadVAO);
}
} }
// -- // --

View file

@ -108,6 +108,7 @@ class GLBlitHelper final
mutable std::map<DrawBlitProg::Key, const DrawBlitProg*> mDrawBlitProgs; mutable std::map<DrawBlitProg::Key, const DrawBlitProg*> mDrawBlitProgs;
GLuint mQuadVAO; GLuint mQuadVAO;
GLuint mQuadVBO;
nsCString mDrawBlitProg_VersionLine; nsCString mDrawBlitProg_VersionLine;
const GLuint mDrawBlitProg_VertShader; const GLuint mDrawBlitProg_VertShader;

View file

@ -24,6 +24,12 @@ StreamFromD3DTexture(ID3D11Texture2D* const texD3D,
const EGLAttrib* const postAttribs) const EGLAttrib* const postAttribs)
{ {
auto& egl = sEGLLibrary; auto& egl = sEGLLibrary;
if (!egl.IsExtensionSupported(GLLibraryEGL::NV_stream_consumer_gltexture_yuv) ||
!egl.IsExtensionSupported(GLLibraryEGL::ANGLE_stream_producer_d3d_texture_nv12))
{
return 0;
}
const auto& display = egl.Display(); const auto& display = egl.Display();
const auto stream = egl.fCreateStreamKHR(display, nullptr); const auto stream = egl.fCreateStreamKHR(display, nullptr);
MOZ_ASSERT(stream); MOZ_ASSERT(stream);

View file

@ -210,7 +210,10 @@ FPSCounter::WriteFrameTimeStamps(PRFileDesc* fd)
const int bufferSize = 256; const int bufferSize = 256;
char buffer[bufferSize]; char buffer[bufferSize];
int writtenCount = SprintfLiteral(buffer, "FPS Data for: %s\n", mFPSName); int writtenCount = SprintfLiteral(buffer, "FPS Data for: %s\n", mFPSName);
MOZ_ASSERT(writtenCount >= 0); MOZ_ASSERT(writtenCount < bufferSize);
if (writtenCount >= bufferSize) {
return;
}
PR_Write(fd, buffer, writtenCount); PR_Write(fd, buffer, writtenCount);
ResetReverseIterator(); ResetReverseIterator();
@ -225,8 +228,10 @@ FPSCounter::WriteFrameTimeStamps(PRFileDesc* fd)
while (HasNext(startTimeStamp)) { while (HasNext(startTimeStamp)) {
TimeDuration duration = previousSample - nextTimeStamp; TimeDuration duration = previousSample - nextTimeStamp;
writtenCount = SprintfLiteral(buffer, "%f,\n", duration.ToMilliseconds()); writtenCount = SprintfLiteral(buffer, "%f,\n", duration.ToMilliseconds());
MOZ_ASSERT(writtenCount < bufferSize);
MOZ_ASSERT(writtenCount >= 0); if (writtenCount >= bufferSize) {
continue;
}
PR_Write(fd, buffer, writtenCount); PR_Write(fd, buffer, writtenCount);
previousSample = nextTimeStamp; previousSample = nextTimeStamp;
@ -299,8 +304,13 @@ FPSCounter::PrintFPS()
void void
FPSCounter::PrintHistogram(std::map<int, int>& aHistogram) FPSCounter::PrintHistogram(std::map<int, int>& aHistogram)
{ {
if (aHistogram.size() == 0) {
return;
}
int length = 0; int length = 0;
const int kBufferLength = 512; const int kBufferLength = 512;
int availableSpace = kBufferLength;
char buffer[kBufferLength]; char buffer[kBufferLength];
for (std::map<int, int>::iterator iter = aHistogram.begin(); for (std::map<int, int>::iterator iter = aHistogram.begin();
@ -309,9 +319,14 @@ FPSCounter::PrintHistogram(std::map<int, int>& aHistogram)
int fps = iter->first; int fps = iter->first;
int count = iter->second; int count = iter->second;
length += snprintf(buffer + length, kBufferLength - length, int lengthRequired = snprintf(buffer + length, availableSpace,
"FPS: %d = %d. ", fps, count); "FPS: %d = %d. ", fps, count);
NS_ASSERTION(length >= kBufferLength, "Buffer overrun while printing FPS histogram."); // Ran out of buffer space. Oh well - just print what we have.
if (lengthRequired > availableSpace) {
break;
}
length += lengthRequired;
availableSpace -= lengthRequired;
} }
printf_stderr("%s\n", buffer); printf_stderr("%s\n", buffer);

View file

@ -757,6 +757,11 @@ gfxMacPlatformFontList::gfxMacPlatformFontList() :
gfxMacPlatformFontList::~gfxMacPlatformFontList() gfxMacPlatformFontList::~gfxMacPlatformFontList()
{ {
::CFNotificationCenterRemoveObserver(::CFNotificationCenterGetLocalCenter(),
this,
kCTFontManagerRegisteredFontsChangedNotification,
0);
if (mDefaultFont) { if (mDefaultFont) {
::CFRelease(mDefaultFont); ::CFRelease(mDefaultFont);
} }

View file

@ -975,12 +975,38 @@ using namespace std;
void void
imgCacheQueue::Remove(imgCacheEntry* entry) imgCacheQueue::Remove(imgCacheEntry* entry)
{ {
auto it = find(mQueue.begin(), mQueue.end(), entry); uint64_t index = mQueue.IndexOf(entry);
if (it != mQueue.end()) { if (index == queueContainer::NoIndex) {
mSize -= (*it)->GetDataSize(); return;
mQueue.erase(it);
MarkDirty();
} }
mSize -= mQueue[index]->GetDataSize();
// If the queue is clean and this is the first entry,
// then we can efficiently remove the entry without
// dirtying the sort order.
if (!IsDirty() && index == 0) {
std::pop_heap(mQueue.begin(), mQueue.end(),
imgLoader::CompareCacheEntries);
mQueue.RemoveElementAt(mQueue.Length() - 1);
return;
}
// Remove from the middle of the list. This potentially
// breaks the binary heap sort order.
mQueue.RemoveElementAt(index);
// If we only have one entry or the queue is empty, though,
// then the sort order is still effectively good. Simply
// refresh the list to clear the dirty flag.
if (mQueue.Length() <= 1) {
Refresh();
return;
}
// Otherwise we must mark the queue dirty and potentially
// trigger an expensive sort later.
MarkDirty();
} }
void void
@ -989,23 +1015,27 @@ imgCacheQueue::Push(imgCacheEntry* entry)
mSize += entry->GetDataSize(); mSize += entry->GetDataSize();
RefPtr<imgCacheEntry> refptr(entry); RefPtr<imgCacheEntry> refptr(entry);
mQueue.push_back(refptr); mQueue.AppendElement(Move(refptr));
MarkDirty(); // If we're not dirty already, then we can efficiently add this to the
// binary heap immediately. This is only O(log n).
if (!IsDirty()) {
std::push_heap(mQueue.begin(), mQueue.end(), imgLoader::CompareCacheEntries);
}
} }
already_AddRefed<imgCacheEntry> already_AddRefed<imgCacheEntry>
imgCacheQueue::Pop() imgCacheQueue::Pop()
{ {
if (mQueue.empty()) { if (mQueue.IsEmpty()) {
return nullptr; return nullptr;
} }
if (IsDirty()) { if (IsDirty()) {
Refresh(); Refresh();
} }
RefPtr<imgCacheEntry> entry = mQueue[0];
std::pop_heap(mQueue.begin(), mQueue.end(), imgLoader::CompareCacheEntries); std::pop_heap(mQueue.begin(), mQueue.end(), imgLoader::CompareCacheEntries);
mQueue.pop_back(); RefPtr<imgCacheEntry> entry = Move(mQueue.LastElement());
mQueue.RemoveElementAt(mQueue.Length() - 1);
mSize -= entry->GetDataSize(); mSize -= entry->GetDataSize();
return entry.forget(); return entry.forget();
@ -1014,6 +1044,8 @@ imgCacheQueue::Pop()
void void
imgCacheQueue::Refresh() imgCacheQueue::Refresh()
{ {
// Resort the list. This is an O(3 * n) operation and best avoided
// if possible.
std::make_heap(mQueue.begin(), mQueue.end(), imgLoader::CompareCacheEntries); std::make_heap(mQueue.begin(), mQueue.end(), imgLoader::CompareCacheEntries);
mDirty = false; mDirty = false;
} }
@ -1033,7 +1065,7 @@ imgCacheQueue::IsDirty()
uint32_t uint32_t
imgCacheQueue::GetNumElements() const imgCacheQueue::GetNumElements() const
{ {
return mQueue.size(); return mQueue.Length();
} }
imgCacheQueue::iterator imgCacheQueue::iterator
@ -1614,7 +1646,12 @@ void
imgLoader::CacheEntriesChanged(bool aForChrome, int32_t aSizeDiff /* = 0 */) imgLoader::CacheEntriesChanged(bool aForChrome, int32_t aSizeDiff /* = 0 */)
{ {
imgCacheQueue& queue = GetCacheQueue(aForChrome); imgCacheQueue& queue = GetCacheQueue(aForChrome);
queue.MarkDirty(); // We only need to dirty the queue if there is any sorting
// taking place. Empty or single-entry lists can't become
// dirty.
if (queue.GetNumElements() > 1) {
queue.MarkDirty();
}
queue.UpdateSize(aSizeDiff); queue.UpdateSize(aSizeDiff);
} }
@ -2009,13 +2046,13 @@ imgLoader::EvictEntries(imgCacheQueue& aQueueToClear)
// We have to make a temporary, since RemoveFromCache removes the element // We have to make a temporary, since RemoveFromCache removes the element
// from the queue, invalidating iterators. // from the queue, invalidating iterators.
nsTArray<RefPtr<imgCacheEntry> > entries(aQueueToClear.GetNumElements()); nsTArray<RefPtr<imgCacheEntry> > entries(aQueueToClear.GetNumElements());
for (imgCacheQueue::const_iterator i = aQueueToClear.begin(); for (auto i = aQueueToClear.begin(); i != aQueueToClear.end(); ++i) {
i != aQueueToClear.end(); ++i) {
entries.AppendElement(*i); entries.AppendElement(*i);
} }
for (uint32_t i = 0; i < entries.Length(); ++i) { // Iterate in reverse order to minimize array copying.
if (!RemoveFromCache(entries[i])) { for (auto& entry : entries) {
if (!RemoveFromCache(entry)) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
} }

View file

@ -201,7 +201,7 @@ public:
uint32_t GetSize() const; uint32_t GetSize() const;
void UpdateSize(int32_t diff); void UpdateSize(int32_t diff);
uint32_t GetNumElements() const; uint32_t GetNumElements() const;
typedef std::vector<RefPtr<imgCacheEntry> > queueContainer; typedef nsTArray<RefPtr<imgCacheEntry> > queueContainer;
typedef queueContainer::iterator iterator; typedef queueContainer::iterator iterator;
typedef queueContainer::const_iterator const_iterator; typedef queueContainer::const_iterator const_iterator;

View file

@ -559,8 +559,7 @@ XPCJSContext::ActivityCallback(void* arg, bool active)
static inline bool static inline bool
IsWebExtensionPrincipal(nsIPrincipal* principal, nsAString& addonId) IsWebExtensionPrincipal(nsIPrincipal* principal, nsAString& addonId)
{ {
return (NS_SUCCEEDED(principal->GetAddonId(addonId)) && return BasePrincipal::Cast(principal)->AddonPolicy();
!addonId.IsEmpty());
} }
static bool static bool

View file

@ -2220,10 +2220,10 @@ RecreateLostWaivers(JSContext* cx, const PropertyDescriptor* orig,
orig->value.isObject() && orig->value.isObject() &&
WrapperFactory::HasWaiveXrayFlag(&orig->value.toObject()); WrapperFactory::HasWaiveXrayFlag(&orig->value.toObject());
bool getterWasWaived = bool getterWasWaived =
(orig->attrs & JSPROP_GETTER) && (orig->attrs & JSPROP_GETTER) && orig->getter &&
WrapperFactory::HasWaiveXrayFlag(JS_FUNC_TO_DATA_PTR(JSObject*, orig->getter)); WrapperFactory::HasWaiveXrayFlag(JS_FUNC_TO_DATA_PTR(JSObject*, orig->getter));
bool setterWasWaived = bool setterWasWaived =
(orig->attrs & JSPROP_SETTER) && (orig->attrs & JSPROP_SETTER) && orig->setter &&
WrapperFactory::HasWaiveXrayFlag(JS_FUNC_TO_DATA_PTR(JSObject*, orig->setter)); WrapperFactory::HasWaiveXrayFlag(JS_FUNC_TO_DATA_PTR(JSObject*, orig->setter));
// Recreate waivers. Note that for value, we need an extra UncheckedUnwrap // Recreate waivers. Note that for value, we need an extra UncheckedUnwrap

View file

@ -169,7 +169,7 @@ fuzzy(50,500) fuzzy-if(skiaContent,51,320) fails-if(webrender) == attachment-loc
# The next three tests are fuzzy due to bug 1128229. # The next three tests are fuzzy due to bug 1128229.
fuzzy(16,69) fuzzy-if(skiaContent,95,2200) == attachment-local-clipping-image-4.html attachment-local-clipping-image-4-ref.html fuzzy(16,69) fuzzy-if(skiaContent,95,2200) == attachment-local-clipping-image-4.html attachment-local-clipping-image-4-ref.html
fuzzy(16,69) fuzzy-if(skiaContent,95,2200) == attachment-local-clipping-image-5.html attachment-local-clipping-image-4-ref.html fuzzy(16,69) fuzzy-if(skiaContent,95,2200) == attachment-local-clipping-image-5.html attachment-local-clipping-image-4-ref.html
fuzzy(80,500) fuzzy-if(skiaContent,100,908) fails-if(webrender) == attachment-local-clipping-image-6.html attachment-local-clipping-image-6-ref.html fuzzy(80,500) fuzzy-if(skiaContent,109,908) fails-if(webrender) == attachment-local-clipping-image-6.html attachment-local-clipping-image-6-ref.html
fuzzy-if(skiaContent,1,8) fuzzy-if(webrender,1,84) == background-multiple-with-border-radius.html background-multiple-with-border-radius-ref.html fuzzy-if(skiaContent,1,8) fuzzy-if(webrender,1,84) == background-multiple-with-border-radius.html background-multiple-with-border-radius-ref.html
== background-repeat-large-area.html background-repeat-large-area-ref.html == background-repeat-large-area.html background-repeat-large-area-ref.html

View file

@ -251,6 +251,16 @@ class ReftestArgumentsParser(argparse.ArgumentParser):
dest="objPath", dest="objPath",
help="Path to the base dir of all object files.") help="Path to the base dir of all object files.")
self.add_argument("--verify",
action="store_true",
default=False,
help="Test verification mode.")
self.add_argument("--verify-max-time",
type=int,
default=3600,
help="Maximum time, in seconds, to run in --verify mode..")
mozlog.commandline.add_logging_group(self) mozlog.commandline.add_logging_group(self)
def get_ip(self): def get_ip(self):

View file

@ -7,6 +7,7 @@ Runs the reftest test harness.
""" """
import collections import collections
import copy
import itertools import itertools
import json import json
import multiprocessing import multiprocessing
@ -18,6 +19,7 @@ import signal
import subprocess import subprocess
import sys import sys
import threading import threading
from datetime import datetime, timedelta
SCRIPT_DIRECTORY = os.path.abspath( SCRIPT_DIRECTORY = os.path.abspath(
os.path.realpath(os.path.dirname(__file__))) os.path.realpath(os.path.dirname(__file__)))
@ -415,6 +417,79 @@ class RefTest(object):
if profileDir: if profileDir:
shutil.rmtree(profileDir, True) shutil.rmtree(profileDir, True)
def verifyTests(self, tests, options):
"""
Support --verify mode: Run test(s) many times in a variety of
configurations/environments in an effort to find intermittent
failures.
"""
self._populate_logger(options)
# Number of times to repeat test(s) when running with --repeat
VERIFY_REPEAT = 20
# Number of times to repeat test(s) when running test in separate browser
VERIFY_REPEAT_SINGLE_BROWSER = 10
def step1():
stepOptions = copy.deepcopy(options)
stepOptions.repeat = VERIFY_REPEAT
stepOptions.runUntilFailure = True
result = self.runTests(tests, stepOptions)
return result
def step2():
stepOptions = copy.deepcopy(options)
for i in xrange(VERIFY_REPEAT_SINGLE_BROWSER):
result = self.runTests(tests, stepOptions)
if result != 0:
break
return result
steps = [
("1. Run each test %d times in one browser." % VERIFY_REPEAT,
step1),
("2. Run each test %d times in a new browser each time." %
VERIFY_REPEAT_SINGLE_BROWSER,
step2),
]
stepResults = {}
for (descr, step) in steps:
stepResults[descr] = "not run / incomplete"
startTime = datetime.now()
maxTime = timedelta(seconds=options.verify_max_time)
finalResult = "PASSED"
for (descr, step) in steps:
if (datetime.now() - startTime) > maxTime:
self.log.info("::: Test verification is taking too long: Giving up!")
self.log.info("::: So far, all checks passed, but not all checks were run.")
break
self.log.info(':::')
self.log.info('::: Running test verification step "%s"...' % descr)
self.log.info(':::')
result = step()
if result != 0:
stepResults[descr] = "FAIL"
finalResult = "FAILED!"
break
stepResults[descr] = "Pass"
self.log.info(':::')
self.log.info('::: Test verification summary for:')
self.log.info(':::')
for test in tests:
self.log.info('::: '+test)
self.log.info(':::')
for descr in sorted(stepResults.keys()):
self.log.info('::: %s : %s' % (descr, stepResults[descr]))
self.log.info(':::')
self.log.info('::: Test verification %s' % finalResult)
self.log.info(':::')
return result
def runTests(self, tests, options, cmdargs=None): def runTests(self, tests, options, cmdargs=None):
cmdargs = cmdargs or [] cmdargs = cmdargs or []
self._populate_logger(options) self._populate_logger(options)
@ -763,7 +838,12 @@ def run_test_harness(parser, options):
if options.xrePath is None: if options.xrePath is None:
options.xrePath = os.path.dirname(options.app) options.xrePath = os.path.dirname(options.app)
return reftest.runTests(options.tests, options) if options.verify:
result = reftest.verifyTests(options.tests, options)
else:
result = reftest.runTests(options.tests, options)
return result
if __name__ == "__main__": if __name__ == "__main__":

View file

@ -6,7 +6,6 @@
interface nsITreeColumns; interface nsITreeColumns;
interface nsIDOMElement; interface nsIDOMElement;
interface nsIAtom;
[scriptable, uuid(ae835ecf-6b32-4660-9b43-8a270df56e02)] [scriptable, uuid(ae835ecf-6b32-4660-9b43-8a270df56e02)]
interface nsITreeColumn : nsISupports interface nsITreeColumn : nsISupports
@ -20,7 +19,6 @@ interface nsITreeColumn : nsISupports
readonly attribute AString id; readonly attribute AString id;
[noscript] void getIdConst([shared] out wstring idConst); [noscript] void getIdConst([shared] out wstring idConst);
[noscript] readonly attribute nsIAtom atom;
readonly attribute long index; readonly attribute long index;

View file

@ -201,13 +201,6 @@ nsTreeColumn::GetIdConst(const char16_t** aIdConst)
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
nsTreeColumn::GetAtom(nsIAtom** aAtom)
{
NS_IF_ADDREF(*aAtom = GetAtom());
return NS_OK;
}
NS_IMETHODIMP NS_IMETHODIMP
nsTreeColumn::GetIndex(int32_t* aIndex) nsTreeColumn::GetIndex(int32_t* aIndex)
{ {

View file

@ -38,7 +38,7 @@ import java.util.Set;
/** /**
* Receives and processes telemetry broadcasts from background services, namely Sync. * Receives and processes telemetry broadcasts from background services, namely Sync.
* Nomenclature: * Nomenclature:
* - Bundled Sync Ping: a Sync Ping as documented at http://gecko.readthedocs.io/en/latest/toolkit/components/telemetry/telemetry/data/sync-ping.html * - Bundled Sync Ping: a Sync Ping as documented at https://firefox-source-docs.mozilla.org/toolkit/components/telemetry/telemetry/data/sync-ping.html
* as of commit https://github.com/mozilla-services/docs/commit/7eb4b412d3ab5ec46b280eff312ace32e7cf27e6 * as of commit https://github.com/mozilla-services/docs/commit/7eb4b412d3ab5ec46b280eff312ace32e7cf27e6
* - Telemetry data: incoming background telemetry, of two types: "sync" and "sync event" * - Telemetry data: incoming background telemetry, of two types: "sync" and "sync event"
* - Local Sync Ping: a persistable representation of incoming telemetry data. Not intended for upload. * - Local Sync Ping: a persistable representation of incoming telemetry data. Not intended for upload.

View file

@ -36,7 +36,7 @@ import java.util.concurrent.TimeUnit;
/** /**
* Builds a {@link TelemetryOutgoingPing} representing a core ping. * Builds a {@link TelemetryOutgoingPing} representing a core ping.
* *
* See https://gecko.readthedocs.org/en/latest/toolkit/components/telemetry/telemetry/core-ping.html * See https://firefox-source-docs.mozilla.org/toolkit/components/telemetry/telemetry/data/core-ping.html
* for details on the core ping. * for details on the core ping.
*/ */
public class TelemetryCorePingBuilder extends TelemetryPingBuilder { public class TelemetryCorePingBuilder extends TelemetryPingBuilder {

View file

@ -26,7 +26,7 @@ import java.util.TimeZone;
/** /**
* Responsible for building a Sync Ping, based on the telemetry docs: * Responsible for building a Sync Ping, based on the telemetry docs:
* http://gecko.readthedocs.io/en/latest/toolkit/components/telemetry/telemetry/data/sync-ping.html * https://firefox-source-docs.mozilla.org/toolkit/components/telemetry/telemetry/data/sync-ping.html
* *
* This builder takes two stores ('sync' and 'event') and produces a single "sync ping". * This builder takes two stores ('sync' and 'event') and produces a single "sync ping".
* *

2
mobile/android/mach_commands.py Normal file → Executable file
View file

@ -262,7 +262,7 @@ class MachCommands(MachCommandBase):
@SubCommand('android', 'gradle-dependencies', @SubCommand('android', 'gradle-dependencies',
"""Collect Android Gradle dependencies. """Collect Android Gradle dependencies.
See https://gecko.readthedocs.io/en/latest/build/buildsystem/toolchains.html#firefox-for-android-with-gradle""") See http://firefox-source-docs.mozilla.org/build/buildsystem/toolchains.html#firefox-for-android-with-gradle""")
@CommandArgument('args', nargs=argparse.REMAINDER) @CommandArgument('args', nargs=argparse.REMAINDER)
def android_gradle_dependencies(self, args): def android_gradle_dependencies(self, args):
# The union, plus a bit more, of all of the Gradle tasks # The union, plus a bit more, of all of the Gradle tasks

View file

@ -7,6 +7,7 @@
#include "mozilla/net/NeckoChannelParams.h" #include "mozilla/net/NeckoChannelParams.h"
#include "mozilla/LoadInfo.h" #include "mozilla/LoadInfo.h"
#include "mozilla/BasePrincipal.h" #include "mozilla/BasePrincipal.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/dom/ContentChild.h" #include "mozilla/dom/ContentChild.h"
#include "mozilla/ipc/URIUtils.h" #include "mozilla/ipc/URIUtils.h"
#include "mozilla/net/NeckoChild.h" #include "mozilla/net/NeckoChild.h"
@ -36,16 +37,17 @@ static const char kPrefThirdPartySession[] =
static const char kPrefCookieIPCSync[] = "network.cookie.ipc.sync"; static const char kPrefCookieIPCSync[] = "network.cookie.ipc.sync";
static const char kCookieLeaveSecurityAlone[] = "network.cookie.leave-secure-alone"; static const char kCookieLeaveSecurityAlone[] = "network.cookie.leave-secure-alone";
static CookieServiceChild *gCookieService; static StaticRefPtr<CookieServiceChild> gCookieService;
CookieServiceChild* already_AddRefed<CookieServiceChild>
CookieServiceChild::GetSingleton() CookieServiceChild::GetSingleton()
{ {
if (!gCookieService) if (!gCookieService) {
gCookieService = new CookieServiceChild(); gCookieService = new CookieServiceChild();
ClearOnShutdown(&gCookieService);
}
NS_ADDREF(gCookieService); return do_AddRef(gCookieService);
return gCookieService;
} }
NS_IMPL_ISUPPORTS(CookieServiceChild, NS_IMPL_ISUPPORTS(CookieServiceChild,

View file

@ -40,7 +40,7 @@ public:
CookieServiceChild(); CookieServiceChild();
static CookieServiceChild* GetSingleton(); static already_AddRefed<CookieServiceChild> GetSingleton();
void void
TrackCookieLoad(nsIChannel *aChannel); TrackCookieLoad(nsIChannel *aChannel);

View file

@ -70,8 +70,7 @@ CookieServiceParent::CookieServiceParent()
nsCOMPtr<nsICookieService> cs = do_GetService(NS_COOKIESERVICE_CONTRACTID); nsCOMPtr<nsICookieService> cs = do_GetService(NS_COOKIESERVICE_CONTRACTID);
// Get the nsCookieService instance directly, so we can call internal methods. // Get the nsCookieService instance directly, so we can call internal methods.
mCookieService = mCookieService = nsCookieService::GetSingleton();
already_AddRefed<nsCookieService>(nsCookieService::GetSingleton());
NS_ASSERTION(mCookieService, "couldn't get nsICookieService"); NS_ASSERTION(mCookieService, "couldn't get nsICookieService");
} }

View file

@ -5,6 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/Attributes.h" #include "mozilla/Attributes.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/DebugOnly.h" #include "mozilla/DebugOnly.h"
#include "mozilla/Likely.h" #include "mozilla/Likely.h"
#include "mozilla/Printf.h" #include "mozilla/Printf.h"
@ -72,7 +73,7 @@ using namespace mozilla::net;
* useful types & constants * useful types & constants
******************************************************************************/ ******************************************************************************/
static nsCookieService *gCookieService; static StaticRefPtr<nsCookieService> gCookieService;
// XXX_hack. See bug 178993. // XXX_hack. See bug 178993.
// This is a hack to hide HttpOnly cookies from older browsers // This is a hack to hide HttpOnly cookies from older browsers
@ -638,7 +639,7 @@ DBState::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
* singleton instance ctor/dtor methods * singleton instance ctor/dtor methods
******************************************************************************/ ******************************************************************************/
nsICookieService* already_AddRefed<nsICookieService>
nsCookieService::GetXPCOMSingleton() nsCookieService::GetXPCOMSingleton()
{ {
if (IsNeckoChild()) if (IsNeckoChild())
@ -647,14 +648,13 @@ nsCookieService::GetXPCOMSingleton()
return GetSingleton(); return GetSingleton();
} }
nsCookieService* already_AddRefed<nsCookieService>
nsCookieService::GetSingleton() nsCookieService::GetSingleton()
{ {
NS_ASSERTION(!IsNeckoChild(), "not a parent process"); NS_ASSERTION(!IsNeckoChild(), "not a parent process");
if (gCookieService) { if (gCookieService) {
NS_ADDREF(gCookieService); return do_AddRef(gCookieService);
return gCookieService;
} }
// Create a new singleton nsCookieService. // Create a new singleton nsCookieService.
@ -665,13 +665,14 @@ nsCookieService::GetSingleton()
// See bug 209571. // See bug 209571.
gCookieService = new nsCookieService(); gCookieService = new nsCookieService();
if (gCookieService) { if (gCookieService) {
NS_ADDREF(gCookieService); if (NS_SUCCEEDED(gCookieService->Init())) {
if (NS_FAILED(gCookieService->Init())) { ClearOnShutdown(&gCookieService);
NS_RELEASE(gCookieService); } else {
gCookieService = nullptr;
} }
} }
return gCookieService; return do_AddRef(gCookieService);
} }
/* static */ void /* static */ void

View file

@ -215,8 +215,8 @@ class nsCookieService final : public nsICookieService
NS_DECL_NSIMEMORYREPORTER NS_DECL_NSIMEMORYREPORTER
nsCookieService(); nsCookieService();
static nsICookieService* GetXPCOMSingleton(); static already_AddRefed<nsICookieService> GetXPCOMSingleton();
nsresult Init(); nsresult Init();
/** /**
* Start watching the observer service for messages indicating that an app has * Start watching the observer service for messages indicating that an app has
@ -330,7 +330,7 @@ class nsCookieService final : public nsICookieService
friend class ReadCookieDBListener; friend class ReadCookieDBListener;
friend class CloseCookieDBListener; friend class CloseCookieDBListener;
static nsCookieService* GetSingleton(); static already_AddRefed<nsCookieService> GetSingleton();
friend class mozilla::net::CookieServiceParent; friend class mozilla::net::CookieServiceParent;
}; };

View file

@ -203,7 +203,7 @@ HttpChannelChild::HttpChannelChild()
// IPC HTTP channel is created. // IPC HTTP channel is created.
// We require that the parent cookie service actor exists while // We require that the parent cookie service actor exists while
// processing HTTP responses. // processing HTTP responses.
CookieServiceChild::GetSingleton(); RefPtr<CookieServiceChild> cookieService = CookieServiceChild::GetSingleton();
} }
HttpChannelChild::~HttpChannelChild() HttpChannelChild::~HttpChannelChild()

View file

@ -461,16 +461,12 @@ nsHttpHandler::Init()
mAppVersion.AssignLiteral(MOZ_APP_UA_VERSION); mAppVersion.AssignLiteral(MOZ_APP_UA_VERSION);
} }
// Generating the spoofed userAgent for fingerprinting resistance. // Generating the spoofed User Agent for fingerprinting resistance.
// The browser version will be rounded down to a multiple of 10. rv = nsRFPService::GetSpoofedUserAgent(mSpoofedUserAgent);
// By doing so, the anonymity group will cover more versions instead of one if (NS_FAILED(rv)) {
// version. // Empty mSpoofedUserAgent to make sure the unsuccessful spoofed UA string
uint32_t spoofedVersion = mAppVersion.ToInteger(&rv); // will not be used anywhere.
if (NS_SUCCEEDED(rv)) { mSpoofedUserAgent.Truncate();
spoofedVersion = spoofedVersion - (spoofedVersion % 10);
mSpoofedUserAgent.Assign(nsPrintfCString(
"Mozilla/5.0 (%s; rv:%d.0) Gecko/%s Firefox/%d.0",
SPOOFED_OSCPU, spoofedVersion, LEGACY_BUILD_ID, spoofedVersion));
} }
mSessionStartTime = NowInSeconds(); mSessionStartTime = NowInSeconds();

View file

@ -65,7 +65,7 @@ class ManifestParser(object):
:param finder: If provided, this finder object will be used for filesystem :param finder: If provided, this finder object will be used for filesystem
interactions. Finder objects are part of the mozpack package, interactions. Finder objects are part of the mozpack package,
documented at documented at
http://gecko.readthedocs.org/en/latest/python/mozpack.html#module-mozpack.files http://firefox-source-docs.mozilla.org/python/mozpack.html#module-mozpack.files
:param handle_defaults: If not set, do not propagate manifest defaults to individual :param handle_defaults: If not set, do not propagate manifest defaults to individual
test objects. Callers are expected to manage per-manifest test objects. Callers are expected to manage per-manifest
defaults themselves via the manifest_defaults member defaults themselves via the manifest_defaults member

2
testing/mozharness/manifestparser/manifestparser.py Normal file → Executable file
View file

@ -65,7 +65,7 @@ class ManifestParser(object):
:param finder: If provided, this finder object will be used for filesystem :param finder: If provided, this finder object will be used for filesystem
interactions. Finder objects are part of the mozpack package, interactions. Finder objects are part of the mozpack package,
documented at documented at
http://gecko.readthedocs.org/en/latest/python/mozpack.html#module-mozpack.files http://firefox-source-docs.mozilla.org/python/mozpack.html#module-mozpack.files
:param handle_defaults: If not set, do not propagate manifest defaults to individual :param handle_defaults: If not set, do not propagate manifest defaults to individual
test objects. Callers are expected to manage per-manifest test objects. Callers are expected to manage per-manifest
defaults themselves via the manifest_defaults member defaults themselves via the manifest_defaults member

View file

@ -250,10 +250,7 @@ ExtensionPolicyService::CheckDocument(nsIDocument* aDocument)
nsIPrincipal* principal = aDocument->NodePrincipal(); nsIPrincipal* principal = aDocument->NodePrincipal();
nsAutoString addonId; RefPtr<WebExtensionPolicy> policy = BasePrincipal::Cast(principal)->AddonPolicy();
Unused << principal->GetAddonId(addonId);
RefPtr<WebExtensionPolicy> policy = GetByID(addonId);
if (policy) { if (policy) {
nsCOMPtr<nsIDOMDocument> doc = do_QueryInterface(aDocument); nsCOMPtr<nsIDOMDocument> doc = do_QueryInterface(aDocument);
ProcessScript().InitExtensionDocument(policy, doc); ProcessScript().InitExtensionDocument(policy, doc);

View file

@ -261,7 +261,7 @@ StreamFilter::FireErrorEvent(const nsAString& aError)
/* static */ bool /* static */ bool
StreamFilter::IsAllowedInContext(JSContext* aCx, JSObject* /* unused */) StreamFilter::IsAllowedInContext(JSContext* aCx, JSObject* /* unused */)
{ {
return nsContentUtils::CallerHasPermission(aCx, NS_LITERAL_STRING("webRequestBlocking")); return nsContentUtils::CallerHasPermission(aCx, nsGkAtoms::webRequestBlocking);
} }
JSObject* JSObject*

View file

@ -18,10 +18,13 @@
#include "nsServiceManagerUtils.h" #include "nsServiceManagerUtils.h"
#include "nsString.h" #include "nsString.h"
#include "nsXULAppAPI.h" #include "nsXULAppAPI.h"
#include "nsPrintfCString.h"
#include "nsIObserverService.h" #include "nsIObserverService.h"
#include "nsIPrefBranch.h" #include "nsIPrefBranch.h"
#include "nsIPrefService.h" #include "nsIPrefService.h"
#include "nsIXULAppInfo.h"
#include "nsIXULRuntime.h"
#include "nsJSUtils.h" #include "nsJSUtils.h"
#include "prenv.h" #include "prenv.h"
@ -162,6 +165,59 @@ nsRFPService::GetSpoofedPresentedFrames(double aTime, uint32_t aWidth, uint32_t
return NSToIntFloor(time * sVideoFramesPerSec * ((100 - boundedDroppedRatio) / 100.0)); return NSToIntFloor(time * sVideoFramesPerSec * ((100 - boundedDroppedRatio) / 100.0));
} }
/* static */
nsresult
nsRFPService::GetSpoofedUserAgent(nsACString &userAgent)
{
// This function generates the spoofed value of User Agent.
// We spoof the values of the platform and Firefox version, which could be
// used as fingerprinting sources to identify individuals.
// Reference of the format of User Agent:
// https://developer.mozilla.org/en-US/docs/Web/API/NavigatorID/userAgent
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent
nsresult rv;
nsCOMPtr<nsIXULAppInfo> appInfo =
do_GetService("@mozilla.org/xre/app-info;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoCString appVersion;
rv = appInfo->GetVersion(appVersion);
NS_ENSURE_SUCCESS(rv, rv);
// The browser version will be spoofed as the last ESR version.
// By doing so, the anonymity group will cover more versions instead of one
// version.
uint32_t firefoxVersion = appVersion.ToInteger(&rv);
NS_ENSURE_SUCCESS(rv, rv);
// Starting from Firefox 10, Firefox ESR was released once every seven
// Firefox releases, e.g. Firefox 10, 17, 24, 31, and so on.
// We infer the last and closest ESR version based on this rule.
nsCOMPtr<nsIXULRuntime> runtime =
do_GetService("@mozilla.org/xre/runtime;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoCString updateChannel;
rv = runtime->GetDefaultUpdateChannel(updateChannel);
NS_ENSURE_SUCCESS(rv, rv);
// If we are running in Firefox ESR, determine whether the formula of ESR
// version has changed. Once changed, we must update the formula in this
// function.
if (updateChannel.Equals("esr")) {
MOZ_ASSERT(((firefoxVersion % 7) == 3),
"Please udpate ESR version formula in nsRFPService.cpp");
}
uint32_t spoofedVersion = firefoxVersion - ((firefoxVersion - 3) % 7);
userAgent.Assign(nsPrintfCString(
"Mozilla/5.0 (%s; rv:%d.0) Gecko/%s Firefox/%d.0",
SPOOFED_OSCPU, spoofedVersion, LEGACY_BUILD_ID, spoofedVersion));
return rv;
}
nsresult nsresult
nsRFPService::Init() nsRFPService::Init()
{ {

View file

@ -49,6 +49,9 @@ public:
static uint32_t GetSpoofedDroppedFrames(double aTime, uint32_t aWidth, uint32_t aHeight); static uint32_t GetSpoofedDroppedFrames(double aTime, uint32_t aWidth, uint32_t aHeight);
static uint32_t GetSpoofedPresentedFrames(double aTime, uint32_t aWidth, uint32_t aHeight); static uint32_t GetSpoofedPresentedFrames(double aTime, uint32_t aWidth, uint32_t aHeight);
// This method generates the spoofed value of User Agent.
static nsresult GetSpoofedUserAgent(nsACString &userAgent);
private: private:
nsresult Init(); nsresult Init();

View file

@ -1,7 +1,7 @@
# This lists the known child processes we collect Telemetry for. # This lists the known child processes we collect Telemetry for.
# The entries are keyed with the names used in Telemetry internally, the same name that is used # The entries are keyed with the names used in Telemetry internally, the same name that is used
# in the main pings payload, i.e. "payload/processes/<process name>". See: # in the main pings payload, i.e. "payload/processes/<process name>". See:
# https://gecko.readthedocs.io/en/latest/toolkit/components/telemetry/telemetry/data/main-ping.html#processes # https://firefox-source-docs.mozilla.org/toolkit/components/telemetry/telemetry/data/main-ping.html#processes
# #
# For now this is only used to inform the data pipeline about new processes, but will be used to # For now this is only used to inform the data pipeline about new processes, but will be used to
# generate headers with C++ data later (enums, strings, ...). # generate headers with C++ data later (enums, strings, ...).

2
toolkit/components/telemetry/histogram_tools.py Normal file → Executable file
View file

@ -35,7 +35,7 @@ ALWAYS_ALLOWED_KEYS = [
'record_in_processes', 'record_in_processes',
] ]
BASE_DOC_URL = ("https://gecko.readthedocs.io/en/latest/toolkit/components/" BASE_DOC_URL = ("https://firefox-source-docs.mozilla.org/toolkit/components/"
"telemetry/telemetry/") "telemetry/telemetry/")
HISTOGRAMS_DOC_URL = (BASE_DOC_URL + "collection/histograms.html") HISTOGRAMS_DOC_URL = (BASE_DOC_URL + "collection/histograms.html")
SCALARS_DOC_URL = (BASE_DOC_URL + "collection/scalars.html") SCALARS_DOC_URL = (BASE_DOC_URL + "collection/scalars.html")

2
toolkit/components/telemetry/parse_scalars.py Normal file → Executable file
View file

@ -11,7 +11,7 @@ from shared_telemetry_utils import ParserError
# The map of containing the allowed scalar types and their mapping to # The map of containing the allowed scalar types and their mapping to
# nsITelemetry::SCALAR_* type constants. # nsITelemetry::SCALAR_* type constants.
BASE_DOC_URL = 'https://gecko.readthedocs.io/en/latest/toolkit/components/' + \ BASE_DOC_URL = 'https://firefox-source-docs.mozilla.org/toolkit/components/' + \
'telemetry/telemetry/collection/scalars.html' 'telemetry/telemetry/collection/scalars.html'
SCALAR_TYPES_MAP = { SCALAR_TYPES_MAP = {

2
toolkit/content/aboutTelemetry.js Normal file → Executable file
View file

@ -307,7 +307,7 @@ var PingPicker = {
render() { render() {
let pings = bundle.GetStringFromName("pingExplanationLink"); let pings = bundle.GetStringFromName("pingExplanationLink");
let pingLink = "<a href=\"http://gecko.readthedocs.io/en/latest/toolkit/components/telemetry/telemetry/concepts/pings.html\">" + pings + "</a>"; let pingLink = "<a href=\"https://firefox-source-docs.mozilla.org/toolkit/components/telemetry/telemetry/concepts/pings.html\">" + pings + "</a>";
let pingName = this._getSelectedPingName(); let pingName = this._getSelectedPingName();
// Display the type and controls if the ping is not current // Display the type and controls if the ping is not current

View file

@ -50,4 +50,4 @@ skip-if = toolkit == 'android'
[test_bug898940.html] [test_bug898940.html]
[test_videocontrols_error.html] [test_videocontrols_error.html]
[test_videocontrols_orientation.html] [test_videocontrols_orientation.html]
run-if = toolkit == 'android' run-if = toolkit == 'android'

View file

@ -22,7 +22,6 @@ var video = document.getElementById("video");
let onLoaded = event => { let onLoaded = event => {
SpecialPowers.pushPrefEnv( SpecialPowers.pushPrefEnv(
{"set": [["full-screen-api.allow-trusted-requests-only", false], {"set": [["full-screen-api.allow-trusted-requests-only", false],
["full-screen-api.unprefix.enabled", true],
["media.videocontrols.lock-video-orientation", true]]}, ["media.videocontrols.lock-video-orientation", true]]},
startMediaLoad); startMediaLoad);
} }
@ -35,14 +34,14 @@ let startMediaLoad = () => {
} }
function runTest() { function runTest() {
is(document.fullscreenElement, null, "should not be in fullscreen initially"); is(document.mozFullScreenElement, null, "should not be in fullscreen initially");
isnot(window.screen.orientation.type, "landscape-primary", "should not be in landscape"); isnot(window.screen.orientation.type, "landscape-primary", "should not be in landscape");
isnot(window.screen.orientation.type, "landscape-secondary", "should not be in landscape"); isnot(window.screen.orientation.type, "landscape-secondary", "should not be in landscape");
let originalOnChange = window.screen.orientation.onchange; let originalOnChange = window.screen.orientation.onchange;
window.screen.orientation.onchange = () => { window.screen.orientation.onchange = () => {
is(document.fullscreenElement, video); is(document.mozFullScreenElement, video, "should be in fullscreen");
ok(window.screen.orientation.type === "landscape-primary" || ok(window.screen.orientation.type === "landscape-primary" ||
window.screen.orientation.type === "landscape-secondary", "should be in landscape"); window.screen.orientation.type === "landscape-secondary", "should be in landscape");

View file

@ -47,7 +47,7 @@ currentPingSidebar = current ping
resultsForSearch = Results for “%1$S” resultsForSearch = Results for “%1$S”
# Note to translators: # Note to translators:
# - %1$S will be replaced by the section name from the structure of the ping. More info about it can be found here : http://gecko.readthedocs.io/en/latest/toolkit/components/telemetry/telemetry/data/main-ping.html # - %1$S will be replaced by the section name from the structure of the ping. More info about it can be found here : https://firefox-source-docs.mozilla.org/toolkit/components/telemetry/telemetry/data/main-ping.html
# - %2$S will be replaced by the current text in the search input # - %2$S will be replaced by the current text in the search input
noSearchResults = Sorry! There are no results in %1$S for “%2$S” noSearchResults = Sorry! There are no results in %1$S for “%2$S”
@ -62,7 +62,8 @@ telemetryLogHeadingTimestamp = Timestamp
telemetryLogHeadingData = Data telemetryLogHeadingData = Data
# Note to translators: # Note to translators:
# - %1$S will be replaced by the section name from the structure of the ping. More info about it can be found here : http://gecko.readthedocs.io/en/latest/toolkit/components/telemetry/telemetry/data/main-ping.html # - %1$S will be replaced by the section name from the structure of the ping. More info about it can be found here : https://firefox-source-docs.mozilla.org/toolkit/components/telemetry/telemetry/data/main-ping.html
filterPlaceholder = Find in %1$S filterPlaceholder = Find in %1$S
allSections = all sections allSections = all sections

View file

@ -29,7 +29,7 @@ $ npm install eslint-plugin-mozilla --save-dev
## Documentation ## Documentation
For details about the rules, please see the [gecko documentation page](http://gecko.readthedocs.io/en/latest/tools/lint/linters/eslint-plugin-mozilla.html). For details about the rules, please see the [firefox documentation page](http://firefox-source-docs.mozilla.org/tools/lint/linters/eslint-plugin-mozilla.html).
## Source Code ## Source Code

View file

@ -12,7 +12,7 @@
"bugs": { "bugs": {
"url": "https://bugzilla.mozilla.org/enter_bug.cgi?product=Testing&component=Lint" "url": "https://bugzilla.mozilla.org/enter_bug.cgi?product=Testing&component=Lint"
}, },
"homepage": "http://gecko.readthedocs.io/en/latest/tools/lint/linters/eslint-plugin-mozilla.html", "homepage": "http://firefox-source-docs.mozilla.org/tools/lint/linters/eslint-plugin-mozilla.html",
"repository": { "repository": {
"type": "hg", "type": "hg",
"url": "https://hg.mozilla.org/mozilla-central/" "url": "https://hg.mozilla.org/mozilla-central/"

View file

@ -12,7 +12,7 @@
"bugs": { "bugs": {
"url": "https://bugzilla.mozilla.org/enter_bug.cgi?product=Testing&component=Lint" "url": "https://bugzilla.mozilla.org/enter_bug.cgi?product=Testing&component=Lint"
}, },
"homepage": "http://gecko.readthedocs.io/en/latest/tools/lint/linters/eslint-plugin-spidermonkey-js.html", "homepage": "http://firefox-source-docs.mozilla.org/tools/lint/linters/eslint-plugin-spidermonkey-js.html",
"repository": { "repository": {
"type": "hg", "type": "hg",
"url": "https://hg.mozilla.org/mozilla-central/" "url": "https://hg.mozilla.org/mozilla-central/"

View file

@ -274,4 +274,12 @@ RefPtr<T>::operator=(const mozilla::StaticRefPtr<U>& aOther)
return operator=(aOther.get()); return operator=(aOther.get());
} }
template <class T>
inline already_AddRefed<T>
do_AddRef(const mozilla::StaticRefPtr<T>& aObj)
{
RefPtr<T> ref(aObj);
return ref.forget();
}
#endif #endif

View file

@ -42,6 +42,8 @@ do_QueryReferent(nsIWeakReference* aRawPtr, nsresult* aError = 0)
*/ */
extern nsIWeakReference* NS_GetWeakReference(nsISupports*, extern nsIWeakReference* NS_GetWeakReference(nsISupports*,
nsresult* aResult = 0); nsresult* aResult = 0);
extern nsIWeakReference* NS_GetWeakReference(nsISupportsWeakReference*,
nsresult* aResult = 0);
/** /**
* |do_GetWeakReference| is a convenience function that bundles up all the work needed * |do_GetWeakReference| is a convenience function that bundles up all the work needed
@ -56,6 +58,12 @@ do_GetWeakReference(nsISupports* aRawPtr, nsresult* aError = 0)
return dont_AddRef(NS_GetWeakReference(aRawPtr, aError)); return dont_AddRef(NS_GetWeakReference(aRawPtr, aError));
} }
inline already_AddRefed<nsIWeakReference>
do_GetWeakReference(nsISupportsWeakReference* aRawPtr, nsresult* aError = 0)
{
return dont_AddRef(NS_GetWeakReference(aRawPtr, aError));
}
inline void inline void
do_GetWeakReference(nsIWeakReference* aRawPtr, nsresult* aError = 0) do_GetWeakReference(nsIWeakReference* aRawPtr, nsresult* aError = 0)
{ {

View file

@ -67,6 +67,26 @@ nsQueryReferent::operator()(const nsIID& aIID, void** aAnswer) const
return status; return status;
} }
nsIWeakReference*
NS_GetWeakReference(nsISupportsWeakReference* aInstancePtr, nsresult* aErrorPtr)
{
nsresult status;
nsIWeakReference* result = nullptr;
if (aInstancePtr) {
status = aInstancePtr->GetWeakReference(&result);
} else {
status = NS_ERROR_NULL_POINTER;
}
if (aErrorPtr) {
*aErrorPtr = status;
}
return result;
}
nsIWeakReference* // or else |already_AddRefed<nsIWeakReference>| nsIWeakReference* // or else |already_AddRefed<nsIWeakReference>|
NS_GetWeakReference(nsISupports* aInstancePtr, nsresult* aErrorPtr) NS_GetWeakReference(nsISupports* aInstancePtr, nsresult* aErrorPtr)
{ {