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

MozReview-Commit-ID: KLssMPhSQ0O
This commit is contained in:
Sebastian Hengst 2017-09-06 11:26:13 +02:00
commit 9c8a09d458
73 changed files with 525 additions and 289 deletions

View File

@ -91,7 +91,7 @@ add_task(async function setup() {
let appInfo = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo);
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`;
});

View File

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

View File

@ -12,6 +12,7 @@
#include "mozilla/Attributes.h"
#include "mozilla/OriginAttributes.h"
class nsIAtom;
class nsIContentSecurityPolicy;
class nsIObjectOutputStream;
class nsIObjectInputStream;
@ -20,6 +21,9 @@ class nsIURI;
class ExpandedPrincipal;
namespace mozilla {
namespace extensions {
class WebExtensionPolicy;
}
/*
* 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 SubsumesConsideringDomainIgnoringFPD(nsIPrincipal* other, bool* _retval) 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 SetCsp(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 GetPrivateBrowsingId(uint32_t* aPrivateBrowsingId) final;
virtual bool AddonHasPermission(const nsAString& aPerm);
virtual bool AddonHasPermission(const nsIAtom* aPerm);
virtual bool IsCodebasePrincipal() const { return false; };
@ -99,6 +104,7 @@ public:
const OriginAttributes& OriginAttributesRef() final { return mOriginAttributes; }
uint32_t AppId() const { return mOriginAttributes.mAppId; }
extensions::WebExtensionPolicy* AddonPolicy();
uint32_t UserContextId() const { return mOriginAttributes.mUserContextId; }
uint32_t PrivateBrowsingId() const { return mOriginAttributes.mPrivateBrowsingId; }
bool IsInIsolatedMozBrowserElement() const { return mOriginAttributes.mInIsolatedMozBrowser; }

View File

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

View File

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

View File

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

View File

@ -34,7 +34,7 @@ public:
NS_IMETHOD SetDomain(nsIURI* aDomain) override;
NS_IMETHOD GetBaseDomain(nsACString& aBaseDomain) 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;
protected:

View File

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

View File

@ -769,13 +769,8 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
&hasFlags);
NS_ENSURE_SUCCESS(rv, rv);
if (hasFlags) {
nsString addonId;
aPrincipal->GetAddonId(addonId);
if (!addonId.IsEmpty()) {
return NS_OK;
}
if (hasFlags && BasePrincipal::Cast(aPrincipal)->AddonPolicy()) {
return NS_OK;
}
// 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 "nsIAddonPolicyService.h"
#include "mozilla/Maybe.h"
#include "nsIAddonPolicyService.h"
#include "nsIPrincipal.h"
#include "nsCOMPtr.h"
#include "nsIObserver.h"
@ -136,17 +134,6 @@ private:
// policy machinery will be removed soon.
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 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.
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!

View File

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

View File

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

View File

@ -57,6 +57,7 @@ class imgRequestProxy;
class nsAutoScriptBlockerSuppressNodeRemoved;
class nsCacheableFuncStringHTMLCollection;
class nsHtml5StringParser;
class nsIAtom;
class nsIChannel;
class nsIConsoleService;
class nsIContent;
@ -590,10 +591,10 @@ public:
static bool CanCallerAccess(nsPIDOMWindowInner* aWindow);
// 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.
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

View File

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

View File

@ -2069,6 +2069,11 @@ GK_ATOM(mozinputrangeignorepreventdefault, "mozinputrangeignorepreventdefault")
// WebExtensions
GK_ATOM(moz_extension, "moz-extension")
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(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
// for chrome JS or an add-on.
nsCOMPtr<nsIPrincipal> principal = mDoc->NodePrincipal();
nsString addonId;
principal->GetAddonId(addonId);
if (GetDocGroup() && !nsContentUtils::IsSystemPrincipal(principal) && addonId.IsEmpty()) {
if (GetDocGroup() && !nsContentUtils::IsSystemPrincipal(principal) &&
!BasePrincipal::Cast(principal)->AddonPolicy()) {
js::SetCompartmentValidAccessPtr(cx, newInnerGlobal,
newInnerWindow->GetDocGroup()->GetValidAccessPtr());
}
@ -9827,8 +9826,7 @@ public:
JSCompartment* cpt = js::GetObjectCompartment(obj);
nsCOMPtr<nsIPrincipal> pc = nsJSPrincipals::get(JS_GetCompartmentPrincipals(cpt));
nsAutoString addonId;
if (NS_SUCCEEDED(pc->GetAddonId(addonId)) && !addonId.IsEmpty()) {
if (BasePrincipal::Cast(pc)->AddonPolicy()) {
// We want to nuke all references to the add-on compartment.
xpc::NukeAllWrappersForCompartment(cx, cpt,
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
// want to compute the caller type in the common non-write-only case), so
// 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)
aError.Throw(NS_ERROR_DOM_SECURITY_ERR);

View File

@ -118,7 +118,7 @@ CoerceDouble(const JS::Value& v, double* d)
bool
HasDrawWindowPrivilege(JSContext* aCx, JSObject* /* unused */)
{
return nsContentUtils::CallerHasPermission(aCx, NS_LITERAL_STRING("<all_urls>"));
return nsContentUtils::CallerHasPermission(aCx, nsGkAtoms::all_urlsPermission);
}
} // 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
if (mWriteOnly &&
!nsContentUtils::CallerHasPermission(aCx, NS_LITERAL_STRING("<all_urls>"))) {
!nsContentUtils::CallerHasPermission(aCx, nsGkAtoms::all_urlsPermission)) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return;
}
@ -835,7 +835,7 @@ HTMLCanvasElement::ToBlob(JSContext* aCx,
{
// do a trust check if this is a write-only canvas
if (mWriteOnly &&
!nsContentUtils::CallerHasPermission(aCx, NS_LITERAL_STRING("<all_urls>"))) {
!nsContentUtils::CallerHasPermission(aCx, nsGkAtoms::all_urlsPermission)) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return;
}

View File

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

View File

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

View File

@ -38,23 +38,12 @@ nsSVGElement::StringInfo SVGAElement::sStringInfo[3] =
//----------------------------------------------------------------------
// nsISupports methods
NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(SVGAElement)
NS_INTERFACE_TABLE_INHERITED(SVGAElement,
nsIDOMNode,
nsIDOMElement,
nsIDOMSVGElement,
Link)
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_INTERFACE_MAP_BEGIN(SVGAElement)
NS_INTERFACE_MAP_ENTRY(nsIDOMNode)
NS_INTERFACE_MAP_ENTRY(nsIDOMElement)
NS_INTERFACE_MAP_ENTRY(nsIDOMSVGElement)
NS_INTERFACE_MAP_ENTRY(Link)
NS_INTERFACE_MAP_END_INHERITING(SVGAElementBase)
NS_IMPL_ADDREF_INHERITED(SVGAElement, SVGAElementBase)
NS_IMPL_RELEASE_INHERITED(SVGAElement, SVGAElementBase)

View File

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

View File

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

View File

@ -5,7 +5,7 @@
#include "domstubs.idl"
interface nsIAtom;
interface nsIAtom; // used in [noscript] methods only
interface nsIContent;
interface nsIXULBuilderListener;
interface nsIXULTemplateResult;
@ -267,7 +267,8 @@ interface nsIXULTemplateBuilder : nsISupports
* @param aNode node to check
* @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

View File

@ -5,7 +5,7 @@
#include "domstubs.idl"
interface nsIAtom;
interface nsIAtom; // used in [noscript] methods only
interface nsIArray;
interface nsISimpleEnumerator;
interface nsIXULTemplateResult;
@ -162,10 +162,10 @@ interface nsIXULTemplateQueryProcessor : nsISupports
*
* @returns a compiled query object
*/
nsISupports compileQuery(in nsIXULTemplateBuilder aBuilder,
in nsIDOMNode aQuery,
in nsIAtom aRefVariable,
in nsIAtom aMemberVariable);
[noscript] nsISupports compileQuery(in nsIXULTemplateBuilder aBuilder,
in nsIDOMNode aQuery,
in nsIAtom aRefVariable,
in nsIAtom aMemberVariable);
/**
* 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 aExpr expression used to compute the value to assign
*/
void addBinding(in nsIDOMNode aRuleNode,
in nsIAtom aVar,
in nsIAtom aRef,
in AString aExpr);
[noscript] void addBinding(in nsIDOMNode aRuleNode,
in nsIAtom aVar,
in nsIAtom aRef,
in AString aExpr);
/**
* 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
*/
int32_t compareResults(in nsIXULTemplateResult aLeft,
in nsIXULTemplateResult aRight,
in nsIAtom aVar,
in unsigned long aSortHints);
[noscript] int32_t compareResults(in nsIXULTemplateResult aLeft,
in nsIXULTemplateResult aRight,
in nsIAtom aVar,
in unsigned long aSortHints);
};

View File

@ -5,7 +5,7 @@
#include "nsISupports.idl"
interface nsIAtom;
interface nsIAtom; // used in [noscript] methods only
interface nsIDOMNode;
interface nsIRDFResource;
@ -80,7 +80,7 @@ interface nsIXULTemplateResult : nsISupports
*
* @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.
@ -93,7 +93,7 @@ interface nsIXULTemplateResult : nsISupports
*
* @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

View File

@ -11,11 +11,13 @@
#include "Logging.h"
#include "mozilla/RefPtr.h"
#include "mozilla/StaticMutex.h"
namespace mozilla {
namespace gfx {
static Atomic<uint64_t> sNextFontFileKey;
static StaticMutex sFontFileStreamsMutex;
static uint64_t sNextFontFileKey = 0;
static std::unordered_map<uint64_t, IDWriteFontFileStream*> sFontFileStreams;
class DWriteFontFileLoader : public IDWriteFontFileLoader
@ -109,18 +111,16 @@ public:
IFACEMETHOD_(ULONG, AddRef)()
{
++mRefCnt;
return mRefCnt;
return ++mRefCnt;
}
IFACEMETHOD_(ULONG, Release)()
{
--mRefCnt;
if (mRefCnt == 0) {
uint32_t count = --mRefCnt;
if (count == 0) {
delete this;
return 0;
}
return mRefCnt;
return count;
}
// IDWriteFontFileStream methods
@ -137,7 +137,7 @@ public:
private:
std::vector<uint8_t> mData;
uint32_t mRefCnt;
Atomic<uint32_t> mRefCnt;
uint64_t mFontFileKey;
};
@ -152,6 +152,7 @@ DWriteFontFileLoader::CreateStreamFromKey(const void *fontFileReferenceKey,
return E_POINTER;
}
StaticMutexAutoLock lock(sFontFileStreamsMutex);
uint64_t fontFileKey = *static_cast<const uint64_t*>(fontFileReferenceKey);
auto found = sFontFileStreams.find(fontFileKey);
if (found == sFontFileStreams.end()) {
@ -175,6 +176,7 @@ DWriteFontFileStream::DWriteFontFileStream(uint8_t *aData, uint32_t aSize,
DWriteFontFileStream::~DWriteFontFileStream()
{
StaticMutexAutoLock lock(sFontFileStreamsMutex);
sFontFileStreams.erase(mFontFileKey);
}
@ -227,10 +229,12 @@ NativeFontResourceDWrite::Create(uint8_t *aFontData, uint32_t aDataLength,
return nullptr;
}
sFontFileStreamsMutex.Lock();
uint64_t fontFileKey = sNextFontFileKey++;
RefPtr<IDWriteFontFileStream> ffsRef =
new DWriteFontFileStream(aFontData, aDataLength, fontFileKey);
sFontFileStreams[fontFileKey] = ffsRef;
sFontFileStreamsMutex.Unlock();
RefPtr<IDWriteFontFile> fontFile;
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
{
GLContext& mGL;
@ -367,8 +346,43 @@ DrawBlitProg::Draw(const BaseArgs& args, const YUVArgs* const argsYUV) const
// --
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);
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)
: mGL(gl)
, mQuadVAO(0)
, mQuadVBO(0)
, mDrawBlitProg_VertShader(mGL->fCreateShader(LOCAL_GL_VERTEX_SHADER))
, mYuvUploads{0}
, mYuvUploads_YSize(0, 0)
@ -386,10 +401,9 @@ GLBlitHelper::GLBlitHelper(GLContext* const gl)
return;
}
GLuint vbo = 0;
mGL->fGenBuffers(1, &vbo);
mGL->fGenBuffers(1, &mQuadVBO);
{
const ScopedBindArrayBuffer bindVBO(mGL, vbo);
const ScopedBindArrayBuffer bindVBO(mGL, mQuadVBO);
const float quadData[] = {
0, 0,
@ -401,12 +415,17 @@ GLBlitHelper::GLBlitHelper(GLContext* const gl)
mGL->fBufferData(LOCAL_GL_ARRAY_BUFFER, heapQuadData.ByteLength(),
heapQuadData.Data(), LOCAL_GL_STATIC_DRAW);
mGL->fGenVertexArrays(1, &mQuadVAO);
const ScopedBindVAO bindVAO(mGL, mQuadVAO);
mGL->fEnableVertexAttribArray(0);
mGL->fVertexAttribPointer(0, 2, LOCAL_GL_FLOAT, false, 0, 0);
if (mGL->IsSupported(GLFeature::vertex_array_object)) {
const auto prev = mGL->GetIntAs<GLuint>(LOCAL_GL_VERTEX_ARRAY_BINDING);
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;
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;
GLuint mQuadVAO;
GLuint mQuadVBO;
nsCString mDrawBlitProg_VersionLine;
const GLuint mDrawBlitProg_VertShader;

View File

@ -24,6 +24,12 @@ StreamFromD3DTexture(ID3D11Texture2D* const texD3D,
const EGLAttrib* const postAttribs)
{
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 stream = egl.fCreateStreamKHR(display, nullptr);
MOZ_ASSERT(stream);

View File

@ -210,7 +210,10 @@ FPSCounter::WriteFrameTimeStamps(PRFileDesc* fd)
const int bufferSize = 256;
char buffer[bufferSize];
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);
ResetReverseIterator();
@ -225,8 +228,10 @@ FPSCounter::WriteFrameTimeStamps(PRFileDesc* fd)
while (HasNext(startTimeStamp)) {
TimeDuration duration = previousSample - nextTimeStamp;
writtenCount = SprintfLiteral(buffer, "%f,\n", duration.ToMilliseconds());
MOZ_ASSERT(writtenCount >= 0);
MOZ_ASSERT(writtenCount < bufferSize);
if (writtenCount >= bufferSize) {
continue;
}
PR_Write(fd, buffer, writtenCount);
previousSample = nextTimeStamp;
@ -299,8 +304,13 @@ FPSCounter::PrintFPS()
void
FPSCounter::PrintHistogram(std::map<int, int>& aHistogram)
{
if (aHistogram.size() == 0) {
return;
}
int length = 0;
const int kBufferLength = 512;
int availableSpace = kBufferLength;
char buffer[kBufferLength];
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 count = iter->second;
length += snprintf(buffer + length, kBufferLength - length,
"FPS: %d = %d. ", fps, count);
NS_ASSERTION(length >= kBufferLength, "Buffer overrun while printing FPS histogram.");
int lengthRequired = snprintf(buffer + length, availableSpace,
"FPS: %d = %d. ", fps, count);
// 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);

View File

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

View File

@ -975,12 +975,38 @@ using namespace std;
void
imgCacheQueue::Remove(imgCacheEntry* entry)
{
auto it = find(mQueue.begin(), mQueue.end(), entry);
if (it != mQueue.end()) {
mSize -= (*it)->GetDataSize();
mQueue.erase(it);
MarkDirty();
uint64_t index = mQueue.IndexOf(entry);
if (index == queueContainer::NoIndex) {
return;
}
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
@ -989,23 +1015,27 @@ imgCacheQueue::Push(imgCacheEntry* entry)
mSize += entry->GetDataSize();
RefPtr<imgCacheEntry> refptr(entry);
mQueue.push_back(refptr);
MarkDirty();
mQueue.AppendElement(Move(refptr));
// 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>
imgCacheQueue::Pop()
{
if (mQueue.empty()) {
if (mQueue.IsEmpty()) {
return nullptr;
}
if (IsDirty()) {
Refresh();
}
RefPtr<imgCacheEntry> entry = mQueue[0];
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();
return entry.forget();
@ -1014,6 +1044,8 @@ imgCacheQueue::Pop()
void
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);
mDirty = false;
}
@ -1033,7 +1065,7 @@ imgCacheQueue::IsDirty()
uint32_t
imgCacheQueue::GetNumElements() const
{
return mQueue.size();
return mQueue.Length();
}
imgCacheQueue::iterator
@ -1614,7 +1646,12 @@ void
imgLoader::CacheEntriesChanged(bool aForChrome, int32_t aSizeDiff /* = 0 */)
{
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);
}
@ -2009,13 +2046,13 @@ imgLoader::EvictEntries(imgCacheQueue& aQueueToClear)
// We have to make a temporary, since RemoveFromCache removes the element
// from the queue, invalidating iterators.
nsTArray<RefPtr<imgCacheEntry> > entries(aQueueToClear.GetNumElements());
for (imgCacheQueue::const_iterator i = aQueueToClear.begin();
i != aQueueToClear.end(); ++i) {
for (auto i = aQueueToClear.begin(); i != aQueueToClear.end(); ++i) {
entries.AppendElement(*i);
}
for (uint32_t i = 0; i < entries.Length(); ++i) {
if (!RemoveFromCache(entries[i])) {
// Iterate in reverse order to minimize array copying.
for (auto& entry : entries) {
if (!RemoveFromCache(entry)) {
return NS_ERROR_FAILURE;
}
}

View File

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

View File

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

View File

@ -2220,10 +2220,10 @@ RecreateLostWaivers(JSContext* cx, const PropertyDescriptor* orig,
orig->value.isObject() &&
WrapperFactory::HasWaiveXrayFlag(&orig->value.toObject());
bool getterWasWaived =
(orig->attrs & JSPROP_GETTER) &&
(orig->attrs & JSPROP_GETTER) && orig->getter &&
WrapperFactory::HasWaiveXrayFlag(JS_FUNC_TO_DATA_PTR(JSObject*, orig->getter));
bool setterWasWaived =
(orig->attrs & JSPROP_SETTER) &&
(orig->attrs & JSPROP_SETTER) && orig->setter &&
WrapperFactory::HasWaiveXrayFlag(JS_FUNC_TO_DATA_PTR(JSObject*, orig->setter));
// 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.
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(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
== background-repeat-large-area.html background-repeat-large-area-ref.html

View File

@ -251,6 +251,16 @@ class ReftestArgumentsParser(argparse.ArgumentParser):
dest="objPath",
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)
def get_ip(self):

View File

@ -7,6 +7,7 @@ Runs the reftest test harness.
"""
import collections
import copy
import itertools
import json
import multiprocessing
@ -18,6 +19,7 @@ import signal
import subprocess
import sys
import threading
from datetime import datetime, timedelta
SCRIPT_DIRECTORY = os.path.abspath(
os.path.realpath(os.path.dirname(__file__)))
@ -415,6 +417,79 @@ class RefTest(object):
if profileDir:
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):
cmdargs = cmdargs or []
self._populate_logger(options)
@ -763,7 +838,12 @@ def run_test_harness(parser, options):
if options.xrePath is None:
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__":

View File

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

View File

@ -201,13 +201,6 @@ nsTreeColumn::GetIdConst(const char16_t** aIdConst)
return NS_OK;
}
NS_IMETHODIMP
nsTreeColumn::GetAtom(nsIAtom** aAtom)
{
NS_IF_ADDREF(*aAtom = GetAtom());
return NS_OK;
}
NS_IMETHODIMP
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.
* 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
* - 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.

View File

@ -36,7 +36,7 @@ import java.util.concurrent.TimeUnit;
/**
* 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.
*/
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:
* 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".
*

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

@ -262,7 +262,7 @@ class MachCommands(MachCommandBase):
@SubCommand('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)
def android_gradle_dependencies(self, args):
# 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/LoadInfo.h"
#include "mozilla/BasePrincipal.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/ipc/URIUtils.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 kCookieLeaveSecurityAlone[] = "network.cookie.leave-secure-alone";
static CookieServiceChild *gCookieService;
static StaticRefPtr<CookieServiceChild> gCookieService;
CookieServiceChild*
already_AddRefed<CookieServiceChild>
CookieServiceChild::GetSingleton()
{
if (!gCookieService)
if (!gCookieService) {
gCookieService = new CookieServiceChild();
ClearOnShutdown(&gCookieService);
}
NS_ADDREF(gCookieService);
return gCookieService;
return do_AddRef(gCookieService);
}
NS_IMPL_ISUPPORTS(CookieServiceChild,

View File

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

View File

@ -70,8 +70,7 @@ CookieServiceParent::CookieServiceParent()
nsCOMPtr<nsICookieService> cs = do_GetService(NS_COOKIESERVICE_CONTRACTID);
// Get the nsCookieService instance directly, so we can call internal methods.
mCookieService =
already_AddRefed<nsCookieService>(nsCookieService::GetSingleton());
mCookieService = nsCookieService::GetSingleton();
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/. */
#include "mozilla/Attributes.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/Likely.h"
#include "mozilla/Printf.h"
@ -72,7 +73,7 @@ using namespace mozilla::net;
* useful types & constants
******************************************************************************/
static nsCookieService *gCookieService;
static StaticRefPtr<nsCookieService> gCookieService;
// XXX_hack. See bug 178993.
// 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
******************************************************************************/
nsICookieService*
already_AddRefed<nsICookieService>
nsCookieService::GetXPCOMSingleton()
{
if (IsNeckoChild())
@ -647,14 +648,13 @@ nsCookieService::GetXPCOMSingleton()
return GetSingleton();
}
nsCookieService*
already_AddRefed<nsCookieService>
nsCookieService::GetSingleton()
{
NS_ASSERTION(!IsNeckoChild(), "not a parent process");
if (gCookieService) {
NS_ADDREF(gCookieService);
return gCookieService;
return do_AddRef(gCookieService);
}
// Create a new singleton nsCookieService.
@ -665,13 +665,14 @@ nsCookieService::GetSingleton()
// See bug 209571.
gCookieService = new nsCookieService();
if (gCookieService) {
NS_ADDREF(gCookieService);
if (NS_FAILED(gCookieService->Init())) {
NS_RELEASE(gCookieService);
if (NS_SUCCEEDED(gCookieService->Init())) {
ClearOnShutdown(&gCookieService);
} else {
gCookieService = nullptr;
}
}
return gCookieService;
return do_AddRef(gCookieService);
}
/* static */ void

View File

@ -215,8 +215,8 @@ class nsCookieService final : public nsICookieService
NS_DECL_NSIMEMORYREPORTER
nsCookieService();
static nsICookieService* GetXPCOMSingleton();
nsresult Init();
static already_AddRefed<nsICookieService> GetXPCOMSingleton();
nsresult Init();
/**
* 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 CloseCookieDBListener;
static nsCookieService* GetSingleton();
static already_AddRefed<nsCookieService> GetSingleton();
friend class mozilla::net::CookieServiceParent;
};

View File

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

View File

@ -461,16 +461,12 @@ nsHttpHandler::Init()
mAppVersion.AssignLiteral(MOZ_APP_UA_VERSION);
}
// Generating the spoofed userAgent for fingerprinting resistance.
// The browser version will be rounded down to a multiple of 10.
// By doing so, the anonymity group will cover more versions instead of one
// version.
uint32_t spoofedVersion = mAppVersion.ToInteger(&rv);
if (NS_SUCCEEDED(rv)) {
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));
// Generating the spoofed User Agent for fingerprinting resistance.
rv = nsRFPService::GetSpoofedUserAgent(mSpoofedUserAgent);
if (NS_FAILED(rv)) {
// Empty mSpoofedUserAgent to make sure the unsuccessful spoofed UA string
// will not be used anywhere.
mSpoofedUserAgent.Truncate();
}
mSessionStartTime = NowInSeconds();

View File

@ -65,7 +65,7 @@ class ManifestParser(object):
:param finder: If provided, this finder object will be used for filesystem
interactions. Finder objects are part of the mozpack package,
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
test objects. Callers are expected to manage per-manifest
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
interactions. Finder objects are part of the mozpack package,
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
test objects. Callers are expected to manage per-manifest
defaults themselves via the manifest_defaults member

View File

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

View File

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

View File

@ -18,10 +18,13 @@
#include "nsServiceManagerUtils.h"
#include "nsString.h"
#include "nsXULAppAPI.h"
#include "nsPrintfCString.h"
#include "nsIObserverService.h"
#include "nsIPrefBranch.h"
#include "nsIPrefService.h"
#include "nsIXULAppInfo.h"
#include "nsIXULRuntime.h"
#include "nsJSUtils.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));
}
/* 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
nsRFPService::Init()
{

View File

@ -49,6 +49,9 @@ public:
static uint32_t GetSpoofedDroppedFrames(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:
nsresult Init();

View File

@ -1,7 +1,7 @@
# 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
# 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
# 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',
]
BASE_DOC_URL = ("https://gecko.readthedocs.io/en/latest/toolkit/components/"
BASE_DOC_URL = ("https://firefox-source-docs.mozilla.org/toolkit/components/"
"telemetry/telemetry/")
HISTOGRAMS_DOC_URL = (BASE_DOC_URL + "collection/histograms.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
# 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'
SCALAR_TYPES_MAP = {

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

@ -307,7 +307,7 @@ var PingPicker = {
render() {
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();
// 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_videocontrols_error.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 => {
SpecialPowers.pushPrefEnv(
{"set": [["full-screen-api.allow-trusted-requests-only", false],
["full-screen-api.unprefix.enabled", true],
["media.videocontrols.lock-video-orientation", true]]},
startMediaLoad);
}
@ -35,14 +34,14 @@ let startMediaLoad = () => {
}
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-secondary", "should not be in landscape");
let originalOnChange = 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" ||
window.screen.orientation.type === "landscape-secondary", "should be in landscape");

View File

@ -47,7 +47,7 @@ currentPingSidebar = current ping
resultsForSearch = Results for “%1$S”
# 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
noSearchResults = Sorry! There are no results in %1$S for “%2$S”
@ -62,7 +62,8 @@ telemetryLogHeadingTimestamp = Timestamp
telemetryLogHeadingData = Data
# 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
allSections = all sections

View File

@ -29,7 +29,7 @@ $ npm install eslint-plugin-mozilla --save-dev
## 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

View File

@ -12,7 +12,7 @@
"bugs": {
"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": {
"type": "hg",
"url": "https://hg.mozilla.org/mozilla-central/"

View File

@ -12,7 +12,7 @@
"bugs": {
"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": {
"type": "hg",
"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());
}
template <class T>
inline already_AddRefed<T>
do_AddRef(const mozilla::StaticRefPtr<T>& aObj)
{
RefPtr<T> ref(aObj);
return ref.forget();
}
#endif

View File

@ -42,6 +42,8 @@ do_QueryReferent(nsIWeakReference* aRawPtr, nsresult* aError = 0)
*/
extern nsIWeakReference* NS_GetWeakReference(nsISupports*,
nsresult* aResult = 0);
extern nsIWeakReference* NS_GetWeakReference(nsISupportsWeakReference*,
nsresult* aResult = 0);
/**
* |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));
}
inline already_AddRefed<nsIWeakReference>
do_GetWeakReference(nsISupportsWeakReference* aRawPtr, nsresult* aError = 0)
{
return dont_AddRef(NS_GetWeakReference(aRawPtr, aError));
}
inline void
do_GetWeakReference(nsIWeakReference* aRawPtr, nsresult* aError = 0)
{

View File

@ -67,6 +67,26 @@ nsQueryReferent::operator()(const nsIID& aIID, void** aAnswer) const
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>|
NS_GetWeakReference(nsISupports* aInstancePtr, nsresult* aErrorPtr)
{