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

This commit is contained in:
Cosmin Sabou 2019-01-09 18:05:44 +02:00
Родитель 8519596937 7de2c5899e
Коммит ad04ab5446
89 изменённых файлов: 2594 добавлений и 2399 удалений

Просмотреть файл

@ -339,7 +339,7 @@ function openLinkIn(url, where, params) {
userContextId: aUserContextId,
privateBrowsingId: aIsPrivate || (w && PrivateBrowsingUtils.isWindowPrivate(w)),
};
return Services.scriptSecurityManager.createCodebasePrincipal(principal.URI, attrs);
return Services.scriptSecurityManager.principalWithOA(principal, attrs);
}
return principal;
}

Просмотреть файл

@ -23,6 +23,7 @@
#include "mozilla/dom/BlobURLProtocolHandler.h"
#include "mozilla/dom/ChromeUtils.h"
#include "mozilla/dom/CSPDictionariesBinding.h"
#include "mozilla/dom/nsCSPContext.h"
#include "mozilla/dom/ToJSValue.h"
namespace mozilla {
@ -494,6 +495,34 @@ void BasePrincipal::FinishInit(const nsACString& aOriginNoSuffix,
mOriginNoSuffix = NS_Atomize(aOriginNoSuffix);
}
void BasePrincipal::FinishInit(BasePrincipal* aOther,
const OriginAttributes& aOriginAttributes) {
mInitialized = true;
mOriginAttributes = aOriginAttributes;
// First compute the origin suffix since it's infallible.
nsAutoCString originSuffix;
mOriginAttributes.CreateSuffix(originSuffix);
mOriginSuffix = NS_Atomize(originSuffix);
mOriginNoSuffix = aOther->mOriginNoSuffix;
mHasExplicitDomain = aOther->mHasExplicitDomain;
if (aOther->mPreloadCSP) {
mPreloadCSP = do_CreateInstance("@mozilla.org/cspcontext;1");
nsCSPContext* preloadCSP = static_cast<nsCSPContext*>(mPreloadCSP.get());
preloadCSP->InitFromOther(
static_cast<nsCSPContext*>(aOther->mPreloadCSP.get()), nullptr, this);
}
if (aOther->mCSP) {
mCSP = do_CreateInstance("@mozilla.org/cspcontext;1");
nsCSPContext* csp = static_cast<nsCSPContext*>(mCSP.get());
csp->InitFromOther(static_cast<nsCSPContext*>(aOther->mCSP.get()), nullptr,
this);
}
}
bool SiteIdentifier::Equals(const SiteIdentifier& aOther) const {
MOZ_ASSERT(IsInitialized());
MOZ_ASSERT(aOther.IsInitialized());

Просмотреть файл

@ -241,11 +241,13 @@ class BasePrincipal : public nsJSPrincipals {
void SetHasExplicitDomain() { mHasExplicitDomain = true; }
// This function should be called as the last step of the initialization of
// the principal objects. It's typically called as the last step from the
// Init() method of the child classes.
// Either of these functions should be called as the last step of the
// initialization of the principal objects. It's typically called as the
// last step from the Init() method of the child classes.
void FinishInit(const nsACString& aOriginNoSuffix,
const OriginAttributes& aOriginAttributes);
void FinishInit(BasePrincipal* aOther,
const OriginAttributes& aOriginAttributes);
nsCOMPtr<nsIContentSecurityPolicy> mCSP;
nsCOMPtr<nsIContentSecurityPolicy> mPreloadCSP;

Просмотреть файл

@ -81,6 +81,18 @@ nsresult ContentPrincipal::Init(nsIURI* aCodebase,
return NS_OK;
}
nsresult ContentPrincipal::Init(ContentPrincipal* aOther,
const OriginAttributes& aOriginAttributes) {
NS_ENSURE_ARG(aOther);
mCodebase = aOther->mCodebase;
FinishInit(aOther, aOriginAttributes);
mDomain = aOther->mDomain;
mAddon = aOther->mAddon;
return NS_OK;
}
nsresult ContentPrincipal::GetScriptLocation(nsACString& aStr) {
return mCodebase->GetSpec(aStr);
}

Просмотреть файл

@ -38,6 +38,8 @@ class ContentPrincipal final : public BasePrincipal {
// Init() must be called before the principal is in a usable state.
nsresult Init(nsIURI* aCodebase, const OriginAttributes& aOriginAttributes,
const nsACString& aOriginNoSuffix);
nsresult Init(ContentPrincipal* aOther,
const OriginAttributes& aOriginAttributes);
virtual nsresult GetScriptLocation(nsACString& aStr) override;

Просмотреть файл

@ -154,6 +154,14 @@ interface nsIScriptSecurityManager : nsISupports
nsIPrincipal getDocShellCodebasePrincipal(in nsIURI uri,
in nsIDocShell docShell);
/**
* If this is a codebase principal, return a copy with different
* origin attributes.
*/
[implicit_jscontext]
nsIPrincipal principalWithOA(in nsIPrincipal principal,
in jsval originAttributes);
/**
* Returns a principal whose origin is composed of |uri| and |originAttributes|.
* See nsIPrincipal.idl for a description of origin attributes, and

Просмотреть файл

@ -120,9 +120,10 @@ JS_PUBLIC_API void JSPrincipals::dump() {
return ReadKnownPrincipalType(aCx, aReader, tag, aOutPrincipals);
}
static bool ReadPrincipalInfo(JSStructuredCloneReader* aReader,
OriginAttributes& aAttrs, nsACString& aSpec,
nsACString& aOriginNoSuffix) {
static bool ReadPrincipalInfo(
JSStructuredCloneReader* aReader, OriginAttributes& aAttrs,
nsACString& aSpec, nsACString& aOriginNoSuffix,
nsTArray<ContentSecurityPolicy>* aPolicies = nullptr) {
uint32_t suffixLength, specLength;
if (!JS_ReadUint32Pair(aReader, &suffixLength, &specLength)) {
return false;
@ -149,12 +150,14 @@ static bool ReadPrincipalInfo(JSStructuredCloneReader* aReader,
return false;
}
uint32_t originNoSuffixLength, dummy;
if (!JS_ReadUint32Pair(aReader, &originNoSuffixLength, &dummy)) {
uint32_t originNoSuffixLength, policyCount;
if (!JS_ReadUint32Pair(aReader, &originNoSuffixLength, &policyCount)) {
return false;
}
MOZ_ASSERT(dummy == 0);
if (!aPolicies) {
MOZ_ASSERT(policyCount == 0);
}
if (!aOriginNoSuffix.SetLength(originNoSuffixLength, fallible)) {
return false;
@ -165,6 +168,29 @@ static bool ReadPrincipalInfo(JSStructuredCloneReader* aReader,
return false;
}
for (uint32_t i = 0; i < policyCount; i++) {
uint32_t policyLength, reportAndMeta;
if (!JS_ReadUint32Pair(aReader, &policyLength, &reportAndMeta)) {
return false;
}
bool reportOnly = reportAndMeta & 1;
bool deliveredViaMetaTag = reportAndMeta & 2;
nsAutoCString policyStr;
if (!policyStr.SetLength(policyLength, fallible)) {
return false;
}
if (!JS_ReadBytes(aReader, policyStr.BeginWriting(), policyLength)) {
return false;
}
if (aPolicies) {
aPolicies->AppendElement(ContentSecurityPolicy(
NS_ConvertUTF8toUTF16(policyStr), reportOnly, deliveredViaMetaTag));
}
}
return true;
}
@ -206,7 +232,8 @@ static bool ReadPrincipalInfo(JSStructuredCloneReader* aReader, uint32_t aTag,
OriginAttributes attrs;
nsAutoCString spec;
nsAutoCString originNoSuffix;
if (!ReadPrincipalInfo(aReader, attrs, spec, originNoSuffix)) {
nsTArray<ContentSecurityPolicy> policies;
if (!ReadPrincipalInfo(aReader, attrs, spec, originNoSuffix, &policies)) {
return false;
}
@ -218,7 +245,8 @@ static bool ReadPrincipalInfo(JSStructuredCloneReader* aReader, uint32_t aTag,
MOZ_DIAGNOSTIC_ASSERT(!originNoSuffix.IsEmpty());
aInfo = ContentPrincipalInfo(attrs, originNoSuffix, spec);
aInfo =
ContentPrincipalInfo(attrs, originNoSuffix, spec, std::move(policies));
} else {
#ifdef FUZZING
return false;
@ -259,19 +287,37 @@ static bool ReadPrincipalInfo(JSStructuredCloneReader* aReader, uint32_t aTag,
return true;
}
static bool WritePrincipalInfo(JSStructuredCloneWriter* aWriter,
const OriginAttributes& aAttrs,
const nsCString& aSpec,
const nsCString& aOriginNoSuffix) {
static bool WritePrincipalInfo(
JSStructuredCloneWriter* aWriter, const OriginAttributes& aAttrs,
const nsCString& aSpec, const nsCString& aOriginNoSuffix,
const nsTArray<ContentSecurityPolicy>* aPolicies = nullptr) {
nsAutoCString suffix;
aAttrs.CreateSuffix(suffix);
size_t policyCount = aPolicies ? aPolicies->Length() : 0;
return JS_WriteUint32Pair(aWriter, suffix.Length(), aSpec.Length()) &&
JS_WriteBytes(aWriter, suffix.get(), suffix.Length()) &&
JS_WriteBytes(aWriter, aSpec.get(), aSpec.Length()) &&
JS_WriteUint32Pair(aWriter, aOriginNoSuffix.Length(), 0) &&
JS_WriteBytes(aWriter, aOriginNoSuffix.get(),
aOriginNoSuffix.Length());
if (!(JS_WriteUint32Pair(aWriter, suffix.Length(), aSpec.Length()) &&
JS_WriteBytes(aWriter, suffix.get(), suffix.Length()) &&
JS_WriteBytes(aWriter, aSpec.get(), aSpec.Length()) &&
JS_WriteUint32Pair(aWriter, aOriginNoSuffix.Length(), policyCount) &&
JS_WriteBytes(aWriter, aOriginNoSuffix.get(),
aOriginNoSuffix.Length()))) {
return false;
}
for (uint32_t i = 0; i < policyCount; i++) {
nsCString policy;
CopyUTF16toUTF8((*aPolicies)[i].policy(), policy);
uint32_t reportAndMeta =
((*aPolicies)[i].reportOnlyFlag() ? 1 : 0) |
((*aPolicies)[i].deliveredViaMetaTagFlag() ? 2 : 0);
if (!(JS_WriteUint32Pair(aWriter, policy.Length(), reportAndMeta) &&
JS_WriteBytes(aWriter, PromiseFlatCString(policy).get(),
policy.Length()))) {
return false;
}
}
return true;
}
static bool WritePrincipalInfo(JSStructuredCloneWriter* aWriter,
@ -304,7 +350,8 @@ static bool WritePrincipalInfo(JSStructuredCloneWriter* aWriter,
const ContentPrincipalInfo& cInfo = aInfo;
return JS_WriteUint32Pair(aWriter, SCTAG_DOM_CONTENT_PRINCIPAL, 0) &&
WritePrincipalInfo(aWriter, cInfo.attrs(), cInfo.spec(),
cInfo.originNoSuffix());
cInfo.originNoSuffix(),
&(cInfo.securityPolicies()));
}
bool nsJSPrincipals::write(JSContext* aCx, JSStructuredCloneWriter* aWriter) {

Просмотреть файл

@ -1257,6 +1257,35 @@ nsScriptSecurityManager::GetDocShellCodebasePrincipal(
return *aPrincipal ? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsScriptSecurityManager::PrincipalWithOA(
nsIPrincipal* aPrincipal, JS::Handle<JS::Value> aOriginAttributes,
JSContext* aCx, nsIPrincipal** aReturnPrincipal) {
if (!aPrincipal) {
return NS_OK;
}
if (aPrincipal->GetIsCodebasePrincipal()) {
OriginAttributes attrs;
if (!aOriginAttributes.isObject() || !attrs.Init(aCx, aOriginAttributes)) {
return NS_ERROR_INVALID_ARG;
}
RefPtr<ContentPrincipal> copy = new ContentPrincipal();
ContentPrincipal* contentPrincipal =
static_cast<ContentPrincipal*>(aPrincipal);
nsresult rv = copy->Init(contentPrincipal, attrs);
NS_ENSURE_SUCCESS(rv, rv);
copy.forget(aReturnPrincipal);
} else {
// We do this for null principals, system principals (both fine)
// ... and expanded principals, where we should probably do something
// cleverer, but I also don't think we care too much.
nsCOMPtr<nsIPrincipal> prin = aPrincipal;
prin.forget(aReturnPrincipal);
}
return *aReturnPrincipal ? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsScriptSecurityManager::CanCreateWrapper(JSContext* cx, const nsIID& aIID,
nsISupports* aObj,

Двоичные данные
config/external/icu/data/icudt63l.dat поставляемый

Двоичный файл не отображается.

Просмотреть файл

@ -54,6 +54,7 @@ support-files =
browser_timelineMarkers-frame-05.js
head.js
frame-head.js
file_data_load_inherit_csp.html
file_click_link_within_view_source.html
onload_message.html
onpageshow_message.html
@ -92,6 +93,7 @@ skip-if = verify
[browser_bug852909.js]
skip-if = (verify && debug && (os == 'win'))
[browser_bug92473.js]
[browser_data_load_inherit_csp.js]
[browser_dataURI_unique_opaque_origin.js]
[browser_uriFixupIntegration.js]
[browser_uriFixupAlternateRedirects.js]

Просмотреть файл

@ -0,0 +1,82 @@
"use strict";
const TEST_PATH = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "http://example.com");
const HTML_URI = TEST_PATH + "file_data_load_inherit_csp.html";
const DATA_URI = "data:text/html;html,<html><body>foo</body></html>";
function setDataHrefOnLink(aBrowser, aDataURI) {
return ContentTask.spawn(aBrowser, aDataURI, function(uri) {
let link = content.document.getElementById("testlink");
link.href = uri;
});
};
function verifyCSP(aTestName, aBrowser, aDataURI) {
return ContentTask.spawn(aBrowser, {aTestName, aDataURI}, async function ({aTestName, aDataURI}) {
let channel = content.docShell.currentDocumentChannel;
is(channel.URI.spec, aDataURI, "testing CSP for " + aTestName);
let principal = channel.loadInfo.triggeringPrincipal;
let cspJSON = principal.cspJSON;
let cspOBJ = JSON.parse(cspJSON);
let policies = cspOBJ["csp-policies"];
is(policies.length, 1, "should be one policy");
let policy = policies[0];
is(policy['script-src'], "'unsafe-inline'", "script-src directive matches");
});
};
add_task(async function setup() {
// allow top level data: URI navigations, otherwise clicking data: link fails
await SpecialPowers.pushPrefEnv({
"set": [["security.data_uri.block_toplevel_data_uri_navigations", false]],
});
});
add_task(async function test_data_csp_inheritance_regular_click() {
await BrowserTestUtils.withNewTab(HTML_URI, async function(browser) {
let loadPromise = BrowserTestUtils.browserLoaded(browser, false, DATA_URI);
// set the data href + simulate click
await setDataHrefOnLink(gBrowser.selectedBrowser, DATA_URI);
BrowserTestUtils.synthesizeMouseAtCenter("#testlink", {},
gBrowser.selectedBrowser);
await loadPromise;
await verifyCSP("click()", gBrowser.selectedBrowser, DATA_URI);
});
});
add_task(async function test_data_csp_inheritance_ctrl_click() {
await BrowserTestUtils.withNewTab(HTML_URI, async function(browser) {
let loadPromise = BrowserTestUtils.waitForNewTab(gBrowser, DATA_URI);
// set the data href + simulate ctrl+click
await setDataHrefOnLink(gBrowser.selectedBrowser, DATA_URI);
BrowserTestUtils.synthesizeMouseAtCenter("#testlink",
{ ctrlKey: true, metaKey: true },
gBrowser.selectedBrowser);
let tab = await loadPromise;
gBrowser.selectTabAtIndex(2);
await verifyCSP("ctrl-click()", gBrowser.selectedBrowser, DATA_URI);
await BrowserTestUtils.removeTab(tab);
});
});
add_task(async function test_data_csp_inheritance_right_click_open_link_in_new_tab() {
await BrowserTestUtils.withNewTab(HTML_URI, async function(browser) {
let loadPromise = BrowserTestUtils.waitForNewTab(gBrowser, DATA_URI);
// set the data href + simulate right-click open link in tab
await setDataHrefOnLink(gBrowser.selectedBrowser, DATA_URI);
BrowserTestUtils.waitForEvent(document, "popupshown", false, event => {
// These are operations that must be executed synchronously with the event.
document.getElementById("context-openlinkintab").doCommand();
event.target.hidePopup();
return true;
});
BrowserTestUtils.synthesizeMouseAtCenter("#testlink",
{ type: "contextmenu", button: 2 },
gBrowser.selectedBrowser);
let tab = await loadPromise;
gBrowser.selectTabAtIndex(2);
await verifyCSP("right-click-open-in-new-tab()", gBrowser.selectedBrowser, DATA_URI);
await BrowserTestUtils.removeTab(tab);
});
});

Просмотреть файл

@ -0,0 +1,11 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Bug 1358009 - Inherit CSP into data URI</title>
<meta http-equiv="Content-Security-Policy" content="script-src 'unsafe-inline'">
</head>
<body>
<a id="testlink">testlink</a>
</body>
</html>

5
dom/cache/DBSchema.cpp поставляемый
Просмотреть файл

@ -2490,8 +2490,11 @@ nsresult ReadResponse(mozIStorageConnection* aConn, EntryId aEntryId,
nsCString origin;
url->Origin(origin);
// CSP is recovered from the headers, no need to initialise it here.
nsTArray<mozilla::ipc::ContentSecurityPolicy> policies;
aSavedResponseOut->mValue.principalInfo() =
mozilla::ipc::ContentPrincipalInfo(attrs, origin, specNoSuffix);
mozilla::ipc::ContentPrincipalInfo(attrs, origin, specNoSuffix,
std::move(policies));
}
bool nullPadding = false;

Просмотреть файл

@ -261,6 +261,22 @@ nsCSPContext::~nsCSPContext() {
}
}
nsresult nsCSPContext::InitFromOther(nsCSPContext* aOtherContext,
Document* aDoc, nsIPrincipal* aPrincipal) {
NS_ENSURE_ARG(aOtherContext);
nsresult rv = SetRequestContext(aDoc, aPrincipal);
NS_ENSURE_SUCCESS(rv, rv);
for (auto policy : aOtherContext->mPolicies) {
nsAutoString policyStr;
policy->toString(policyStr);
AppendPolicy(policyStr, policy->getReportOnlyFlag(),
policy->getDeliveredViaMetaTagFlag());
}
return NS_OK;
}
NS_IMETHODIMP
nsCSPContext::GetPolicyString(uint32_t aIndex, nsAString& outStr) {
outStr.Truncate();

Просмотреть файл

@ -51,6 +51,10 @@ class nsCSPContext : public nsIContentSecurityPolicy {
public:
nsCSPContext();
nsresult InitFromOther(nsCSPContext* otherContext,
mozilla::dom::Document* aDoc,
nsIPrincipal* aPrincipal);
/**
* SetRequestContext() needs to be called before the innerWindowID
* is initialized on the document. Use this function to call back to

Просмотреть файл

@ -21,6 +21,7 @@
#include "nsIScriptError.h"
#include "nsContentUtils.h"
#include "nsContentPolicyUtils.h"
#include "nsNetUtil.h"
using namespace mozilla;
@ -250,6 +251,17 @@ CSPService::AsyncOnChannelRedirect(nsIChannel *oldChannel,
nsIAsyncVerifyRedirectCallback *callback) {
net::nsAsyncRedirectAutoCallback autoCallback(callback);
if (XRE_IsE10sParentProcess()) {
nsCOMPtr<nsIParentChannel> parentChannel;
NS_QueryNotificationCallbacks(oldChannel, parentChannel);
if (parentChannel) {
// This is an IPC'd channel. Don't check it here, because we won't have
// access to the request context; we'll check them in the content
// process instead. Bug 1509738 covers fixing this.
return NS_OK;
}
}
nsCOMPtr<nsIURI> newUri;
nsresult rv = newChannel->GetURI(getter_AddRefs(newUri));
NS_ENSURE_SUCCESS(rv, rv);

Просмотреть файл

@ -10,4 +10,7 @@ support-files =
!/dom/security/test/csp/file_web_manifest_remote.html
[browser_test_web_manifest.js]
[browser_test_web_manifest_mixed_content.js]
[browser_test_uir_optional_clicks.js]
support-files =
file_csp_meta_uir.html
[browser_manifest-src-override-default-src.js]

Просмотреть файл

@ -0,0 +1,14 @@
"use strict"
const TEST_PATH_HTTP = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "http://example.com");
const TEST_PATH_HTTPS = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "https://example.com");
add_task(async function() {
await BrowserTestUtils.withNewTab(TEST_PATH_HTTPS + "file_csp_meta_uir.html", async function(browser) {
let newTabPromise = BrowserTestUtils.waitForNewTab(gBrowser, null, true);
BrowserTestUtils.synthesizeMouse("#mylink", 2, 2, {accelKey: true}, browser);
let tab = await newTabPromise;
is(tab.linkedBrowser.currentURI.scheme, "https", "Should have opened https page.");
BrowserTestUtils.removeTab(tab);
});
});

Просмотреть файл

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World</title>
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
</head>
<body>
<script>
document.write("<a href='" + document.location.href.replace(/^https/, "http") + "' id='mylink'>Click me</a>");
</script>
</body>
</html>

Просмотреть файл

@ -111,8 +111,10 @@ nsresult CreatePrincipalInfo(nsILineInputStream* aStream,
return rv;
}
aEntry->principal() =
mozilla::ipc::ContentPrincipalInfo(attrs, origin, aEntry->scope());
// CSP will be applied during the script load.
nsTArray<mozilla::ipc::ContentSecurityPolicy> policies;
aEntry->principal() = mozilla::ipc::ContentPrincipalInfo(
attrs, origin, aEntry->scope(), std::move(policies));
return NS_OK;
}

Просмотреть файл

@ -271,8 +271,10 @@ TEST(ServiceWorkerRegistrar, TestWriteData) {
nsAutoCString spec;
spec.AppendPrintf("spec write %d", i);
nsTArray<mozilla::ipc::ContentSecurityPolicy> policies;
reg.principal() = mozilla::ipc::ContentPrincipalInfo(
mozilla::OriginAttributes(i, i % 2), spec, spec);
mozilla::OriginAttributes(i, i % 2), spec, spec, std::move(policies));
swr->TestRegisterServiceWorker(reg);
}
@ -858,8 +860,10 @@ TEST(ServiceWorkerRegistrar, TestDedupeWrite) {
nsAutoCString spec;
spec.AppendPrintf("spec write dedupe/%d", i);
nsTArray<mozilla::ipc::ContentSecurityPolicy> policies;
reg.principal() = mozilla::ipc::ContentPrincipalInfo(
mozilla::OriginAttributes(0, false), spec, spec);
mozilla::OriginAttributes(0, false), spec, spec, std::move(policies));
swr->TestRegisterServiceWorker(reg);
}

Просмотреть файл

@ -11,13 +11,6 @@ using struct mozilla::void_t from "ipc/IPCMessageUtils.h";
namespace mozilla {
namespace dom {
struct ContentSecurityPolicy
{
nsString policy;
bool reportOnlyFlag;
bool deliveredViaMetaTagFlag;
};
struct RemoteWorkerData
{
// This should only be used for devtools.

Просмотреть файл

@ -38,34 +38,6 @@ using namespace mozilla::ipc;
namespace {
nsresult PopulateContentSecurityPolicies(
nsIContentSecurityPolicy* aCSP,
nsTArray<ContentSecurityPolicy>& aPolicies) {
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aCSP);
MOZ_ASSERT(aPolicies.IsEmpty());
uint32_t count = 0;
nsresult rv = aCSP->GetPolicyCount(&count);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
for (uint32_t i = 0; i < count; ++i) {
const nsCSPPolicy* policy = aCSP->GetPolicy(i);
MOZ_ASSERT(policy);
nsAutoString policyString;
policy->toString(policyString);
aPolicies.AppendElement(
ContentSecurityPolicy(policyString, policy->getReportOnlyFlag(),
policy->getDeliveredViaMetaTagFlag()));
}
return NS_OK;
}
nsresult PopulateContentSecurityPolicyArray(
nsIPrincipal* aPrincipal, nsTArray<ContentSecurityPolicy>& policies,
nsTArray<ContentSecurityPolicy>& preloadPolicies) {

Просмотреть файл

@ -1,5 +1,5 @@
commit 6e82c7c389888603f0de84ffe5c60f43f11ee844
commit 26eea4948c743417c8aa9d1e7fd900d1fb57fbdc
Author: Yoshito Umaoka <yoshito_umaoka@us.ibm.com>
Date: Wed Nov 7 19:23:35 2018 -0500
Date: Wed Jan 2 17:39:20 2019 -0500
ICU-20260 Fix CR/LF issue
ICU time zone data updates for tzdata 2018i (including 2018h changes)

Просмотреть файл

@ -1 +1 @@
2018g
2018i

Двоичные данные
intl/tzdata/source/be/metaZones.res

Двоичный файл не отображается.

Двоичные данные
intl/tzdata/source/be/timezoneTypes.res

Двоичный файл не отображается.

Двоичные данные
intl/tzdata/source/be/windowsZones.res

Двоичный файл не отображается.

Двоичные данные
intl/tzdata/source/be/zoneinfo64.res

Двоичный файл не отображается.

Двоичные данные
intl/tzdata/source/ee/metaZones.res

Двоичный файл не отображается.

Двоичные данные
intl/tzdata/source/ee/timezoneTypes.res

Двоичный файл не отображается.

Двоичные данные
intl/tzdata/source/ee/windowsZones.res

Двоичный файл не отображается.

Двоичные данные
intl/tzdata/source/ee/zoneinfo64.res

Двоичный файл не отображается.

Двоичные данные
intl/tzdata/source/le/metaZones.res

Двоичный файл не отображается.

Двоичные данные
intl/tzdata/source/le/timezoneTypes.res

Двоичный файл не отображается.

Двоичные данные
intl/tzdata/source/le/windowsZones.res

Двоичный файл не отображается.

Двоичные данные
intl/tzdata/source/le/zoneinfo64.res

Двоичный файл не отображается.

Просмотреть файл

@ -813,12 +813,7 @@ metaZones:table(nofallback){
{
"Europe_Western",
"1985-12-31 23:00",
"2018-10-26 23:00",
}
{
"Europe_Central",
"2018-10-26 23:00",
"9999-12-31 23:59",
"2018-10-28 02:00",
}
}
"Africa:Ceuta"{
@ -867,12 +862,7 @@ metaZones:table(nofallback){
{
"Europe_Western",
"1976-04-14 01:00",
"2018-10-26 23:00",
}
{
"Europe_Central",
"2018-10-26 23:00",
"9999-12-31 23:59",
"2018-10-28 02:00",
}
}
"Africa:Freetown"{
@ -1045,6 +1035,11 @@ metaZones:table(nofallback){
{
"Africa_Western",
"2018-01-01 01:00",
"2019-01-01 01:00",
}
{
"GMT",
"2019-01-01 01:00",
"9999-12-31 23:59",
}
}
@ -2086,6 +2081,16 @@ metaZones:table(nofallback){
{
"Alaska",
"2015-11-01 10:00",
"2018-11-04 10:00",
}
{
"America_Pacific",
"2018-11-04 10:00",
"2019-03-10 11:00",
}
{
"Alaska",
"2019-03-10 11:00",
"9999-12-31 23:59",
}
}
@ -3162,6 +3167,13 @@ metaZones:table(nofallback){
"9999-12-31 23:59",
}
}
"Asia:Qostanay"{
{
"Kazakhstan_Eastern",
"2004-10-30 21:00",
"9999-12-31 23:59",
}
}
"Asia:Qyzylorda"{
{
"Kizilorda",
@ -3176,6 +3188,11 @@ metaZones:table(nofallback){
{
"Kazakhstan_Eastern",
"2004-10-30 21:00",
"2018-12-20 18:00",
}
{
"Kazakhstan_Western",
"2018-12-20 18:00",
"9999-12-31 23:59",
}
}
@ -4226,11 +4243,11 @@ metaZones:table(nofallback){
{
"Kwajalein",
"1970-01-01 00:00",
"1993-08-20 12:00",
"1993-08-21 12:00",
}
{
"Marshall_Islands",
"1993-08-20 12:00",
"1993-08-21 12:00",
"9999-12-31 23:59",
}
}

Просмотреть файл

@ -416,6 +416,7 @@ timezoneTypes:table(nofallback){
"Asia:Pontianak"{"idpnk"}
"Asia:Pyongyang"{"kpfnj"}
"Asia:Qatar"{"qadoh"}
"Asia:Qostanay"{"kzksn"}
"Asia:Qyzylorda"{"kzkzo"}
"Asia:Rangoon"{"mmrgn"}
"Asia:Riyadh"{"saruh"}

Просмотреть файл

@ -17,8 +17,8 @@ windowsZones:table(nofallback){
"Alaskan Standard Time"{
001{"America/Anchorage"}
US{
"America/Anchorage America/Juneau America/Metlakatla America/Nome Ame"
"rica/Sitka America/Yakutat"
"America/Anchorage America/Juneau America/Nome America/Sitka America/"
"Yakutat"
}
}
"Aleutian Standard Time"{
@ -130,7 +130,7 @@ windowsZones:table(nofallback){
CN{"Asia/Urumqi"}
IO{"Indian/Chagos"}
KG{"Asia/Bishkek"}
KZ{"Asia/Almaty Asia/Qyzylorda"}
KZ{"Asia/Almaty Asia/Qostanay"}
ZZ{"Etc/GMT-6"}
}
"Central Brazilian Standard Time"{
@ -468,7 +468,7 @@ windowsZones:table(nofallback){
"Pacific Standard Time"{
001{"America/Los_Angeles"}
CA{"America/Vancouver America/Dawson America/Whitehorse"}
US{"America/Los_Angeles"}
US{"America/Los_Angeles America/Metlakatla"}
ZZ{"PST8PDT"}
}
"Pakistan Standard Time"{
@ -779,7 +779,7 @@ windowsZones:table(nofallback){
"West Asia Standard Time"{
001{"Asia/Tashkent"}
AQ{"Antarctica/Mawson"}
KZ{"Asia/Oral Asia/Aqtau Asia/Aqtobe Asia/Atyrau"}
KZ{"Asia/Oral Asia/Aqtau Asia/Aqtobe Asia/Atyrau Asia/Qyzylorda"}
MV{"Indian/Maldives"}
TF{"Indian/Kerguelen"}
TJ{"Asia/Dushanbe"}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -8,7 +8,6 @@
#include "MainThreadUtils.h"
#include "mozilla/Assertions.h"
#include "mozilla/BasePrincipal.h"
#include "mozilla/ContentPrincipal.h"
#include "mozilla/NullPrincipal.h"
#include "mozilla/ipc/PBackgroundSharedTypes.h"
@ -24,6 +23,8 @@
#include "nsTArray.h"
#include "mozilla/nsRedirectHistoryEntry.h"
#include "URIUtils.h"
#include "mozilla/dom/nsCSPUtils.h"
#include "mozilla/dom/nsCSPContext.h"
namespace mozilla {
namespace net {
@ -103,6 +104,29 @@ already_AddRefed<nsIPrincipal> PrincipalInfoToPrincipal(
MOZ_CRASH("Origin must be available when deserialized");
}
if (info.securityPolicies().Length() > 0) {
nsCOMPtr<nsIContentSecurityPolicy> csp =
do_CreateInstance(NS_CSPCONTEXT_CONTRACTID, &rv);
if (NS_WARN_IF(NS_FAILED(rv))) {
return nullptr;
}
rv = csp->SetRequestContext(nullptr, principal);
if (NS_WARN_IF(NS_FAILED(rv))) {
return nullptr;
}
for (auto policy : info.securityPolicies()) {
rv = csp->AppendPolicy(policy.policy(), policy.reportOnlyFlag(),
policy.deliveredViaMetaTagFlag());
if (NS_WARN_IF(NS_FAILED(rv))) {
return nullptr;
}
}
principal->SetCsp(csp);
}
return principal.forget();
}
@ -140,6 +164,34 @@ already_AddRefed<nsIPrincipal> PrincipalInfoToPrincipal(
MOZ_CRASH("Should never get here!");
}
nsresult PopulateContentSecurityPolicies(
nsIContentSecurityPolicy* aCSP,
nsTArray<ContentSecurityPolicy>& aPolicies) {
MOZ_ASSERT(aCSP);
MOZ_ASSERT(aPolicies.IsEmpty());
MOZ_ASSERT(NS_IsMainThread());
uint32_t count = 0;
nsresult rv = aCSP->GetPolicyCount(&count);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
for (uint32_t i = 0; i < count; ++i) {
const nsCSPPolicy* policy = aCSP->GetPolicy(i);
MOZ_ASSERT(policy);
nsAutoString policyString;
policy->toString(policyString);
aPolicies.AppendElement(
ContentSecurityPolicy(policyString, policy->getReportOnlyFlag(),
policy->getDeliveredViaMetaTagFlag()));
}
return NS_OK;
}
nsresult PrincipalToPrincipalInfo(nsIPrincipal* aPrincipal,
PrincipalInfo* aPrincipalInfo) {
MOZ_ASSERT(NS_IsMainThread());
@ -231,8 +283,20 @@ nsresult PrincipalToPrincipalInfo(nsIPrincipal* aPrincipal,
return rv;
}
*aPrincipalInfo = ContentPrincipalInfo(aPrincipal->OriginAttributesRef(),
originNoSuffix, spec);
nsCOMPtr<nsIContentSecurityPolicy> csp;
rv = aPrincipal->GetCsp(getter_AddRefs(csp));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
nsTArray<ContentSecurityPolicy> policies;
if (csp) {
PopulateContentSecurityPolicies(csp, policies);
}
*aPrincipalInfo =
ContentPrincipalInfo(aPrincipal->OriginAttributesRef(), originNoSuffix,
spec, std::move(policies));
return NS_OK;
}

Просмотреть файл

@ -55,6 +55,7 @@ class RedirectHistoryEntryInfo;
namespace ipc {
class ContentSecurityPolicy;
class PrincipalInfo;
/**
@ -65,6 +66,14 @@ class PrincipalInfo;
already_AddRefed<nsIPrincipal> PrincipalInfoToPrincipal(
const PrincipalInfo& aPrincipalInfo, nsresult* aOptionalResult = nullptr);
/**
* Populate an array of ContentSecurityPolicy objects from a CSP object.
*
* MUST be called on the main thread only.
*/
nsresult PopulateContentSecurityPolicies(
nsIContentSecurityPolicy* aCSP, nsTArray<ContentSecurityPolicy>& aPolicies);
/**
* Convert an nsIPrincipal to a PrincipalInfo.
*

Просмотреть файл

@ -8,6 +8,13 @@ using struct mozilla::void_t from "ipc/IPCMessageUtils.h";
namespace mozilla {
namespace ipc {
struct ContentSecurityPolicy
{
nsString policy;
bool reportOnlyFlag;
bool deliveredViaMetaTagFlag;
};
struct ContentPrincipalInfo
{
OriginAttributes attrs;
@ -22,6 +29,8 @@ struct ContentPrincipalInfo
nsCString originNoSuffix;
nsCString spec;
ContentSecurityPolicy[] securityPolicies;
};
struct SystemPrincipalInfo

Просмотреть файл

@ -1,5 +1,5 @@
// Generated by make_intl_data.py. DO NOT EDIT.
// tzdata version = 2018g
// tzdata version = 2018i
#ifndef builtin_intl_TimeZoneDataGenerated_h
#define builtin_intl_TimeZoneDataGenerated_h

Просмотреть файл

@ -256,6 +256,33 @@ void LIRGenerator::visitWasmUnsignedToFloat32(MWasmUnsignedToFloat32* ins) {
define(lir, ins);
}
// If the base is a constant, and it is zero or its offset is zero, then
// code generation will fold the values into the access. Allocate the
// pointer to a register only if that can't happen.
static bool OptimizableConstantAccess(MDefinition* base,
const wasm::MemoryAccessDesc& access) {
MOZ_ASSERT(base->isConstant());
MOZ_ASSERT(base->type() == MIRType::Int32);
if (!(base->toConstant()->isInt32(0) || access.offset() == 0)) {
return false;
}
if (access.type() == Scalar::Int64) {
// For int64 accesses on 32-bit systems we will need to add another offset
// of 4 to access the high part of the value; make sure this does not
// overflow the value.
int32_t v;
if (base->toConstant()->isInt32(0)) {
v = access.offset();
} else {
v = base->toConstant()->toInt32();
}
return v <= int32_t(INT32_MAX - INT64HIGH_OFFSET);
}
return true;
}
void LIRGenerator::visitWasmLoad(MWasmLoad* ins) {
MDefinition* base = ins->base();
MOZ_ASSERT(base->type() == MIRType::Int32);
@ -273,13 +300,8 @@ void LIRGenerator::visitWasmLoad(MWasmLoad* ins) {
return;
}
// If the base is a constant, and it is zero or its offset is zero, then
// code generation will fold the values into the access. Allocate the
// pointer to a register only if that can't happen.
LAllocation baseAlloc;
if (!base->isConstant() ||
!(base->toConstant()->isInt32(0) || ins->access().offset() == 0)) {
if (!base->isConstant() || !OptimizableConstantAccess(base, ins->access())) {
baseAlloc = ins->type() == MIRType::Int64 ? useRegister(base)
: useRegisterAtStart(base);
}
@ -326,13 +348,8 @@ void LIRGenerator::visitWasmStore(MWasmStore* ins) {
return;
}
// If the base is a constant, and it is zero or its offset is zero, then
// code generation will fold the values into the access. Allocate the
// pointer to a register only if that can't happen.
LAllocation baseAlloc;
if (!base->isConstant() ||
!(base->toConstant()->isInt32(0) || ins->access().offset() == 0)) {
if (!base->isConstant() || !OptimizableConstantAccess(base, ins->access())) {
baseAlloc = useRegisterAtStart(base);
}

Просмотреть файл

@ -1,7 +1,7 @@
// |reftest| skip-if(!this.hasOwnProperty("Intl"))
// Generated by make_intl_data.py. DO NOT EDIT.
// tzdata version = 2018g
// tzdata version = 2018i
const tzMapper = [
x => x,

Просмотреть файл

@ -1,7 +1,7 @@
// |reftest| skip-if(!this.hasOwnProperty("Intl"))
// Generated by make_intl_data.py. DO NOT EDIT.
// tzdata version = 2018g
// tzdata version = 2018i
const tzMapper = [
x => x,

Просмотреть файл

@ -1,7 +1,7 @@
// |reftest| skip-if(!this.hasOwnProperty("Intl"))
// Generated by make_intl_data.py. DO NOT EDIT.
// tzdata version = 2018g
// tzdata version = 2018i
const tzMapper = [
x => x,

Просмотреть файл

@ -1,7 +1,7 @@
// |reftest| skip-if(!this.hasOwnProperty("Intl"))
// Generated by make_intl_data.py. DO NOT EDIT.
// tzdata version = 2018g
// tzdata version = 2018i
const tzMapper = [
x => x,

Просмотреть файл

@ -164,8 +164,8 @@ struct JSContext : public JS::RootingContext,
return thing->compartment() == compartment();
}
void* onOutOfMemory(js::AllocFunction allocFunc, size_t nbytes,
arena_id_t arena, void* reallocPtr = nullptr) {
void* onOutOfMemory(js::AllocFunction allocFunc, arena_id_t arena,
size_t nbytes, void* reallocPtr = nullptr) {
if (helperThread()) {
addPendingOutOfMemory();
return nullptr;

Просмотреть файл

@ -162,7 +162,10 @@ static SystemClass ClassifySystem() {
}
// Code sizes in machine code bytes per bytecode byte, again empirical except
// where marked as "Guess".
// where marked.
//
// The Ion estimate for ARM64 is the measured Baseline value scaled by a
// plausible factor for optimized code.
static const double x64Tox86Inflation = 1.25;
@ -170,15 +173,14 @@ static const double x64IonBytesPerBytecode = 2.45;
static const double x86IonBytesPerBytecode =
x64IonBytesPerBytecode * x64Tox86Inflation;
static const double arm32IonBytesPerBytecode = 3.3;
static const double arm64IonBytesPerBytecode = 3.0; // Guess
static const double arm64IonBytesPerBytecode = 3.0 / 1.4; // Estimate
static const double x64BaselineBytesPerBytecode = x64IonBytesPerBytecode * 1.43;
static const double x86BaselineBytesPerBytecode =
x64BaselineBytesPerBytecode * x64Tox86Inflation;
static const double arm32BaselineBytesPerBytecode =
arm32IonBytesPerBytecode * 1.39;
static const double arm64BaselineBytesPerBytecode =
arm64IonBytesPerBytecode * 1.39; // Guess
static const double arm64BaselineBytesPerBytecode = 3.0;
static double OptimizedBytesPerBytecode(SystemClass cls) {
switch (cls) {
@ -239,25 +241,32 @@ static const double tierCutoffMs = 250;
// Compilation rate values are empirical except when noted, the reference
// systems are:
//
// Late-2013 MacBook Pro (2.6GHz quad hyperthreaded Haswell)
// Late-2015 Nexus 5X (1.4GHz quad Cortex-A53 + 1.8GHz dual Cortex-A57)
// Late-2013 MacBook Pro (2.6GHz 4 x hyperthreaded Haswell, Mac OS X)
// Late-2015 Nexus 5X (1.4GHz 4 x Cortex-A53 + 1.8GHz 2 x Cortex-A57, Android)
// Ca-2016 SoftIron Overdrive 1000 (1.7GHz 4 x Cortex-A57, Fedora)
//
// The rates are always per core.
//
// The estimate for ARM64 is the Baseline compilation rate on the SoftIron
// (because we have no Ion yet), divided by 5 to estimate Ion compile rate and
// then divided by 2 to make it more reasonable for consumer ARM64 systems.
static const double x64BytecodesPerMs = 2100;
static const double x86BytecodesPerMs = 1500;
static const double arm32BytecodesPerMs = 450;
static const double arm64BytecodesPerMs = 650; // Guess
static const double x64IonBytecodesPerMs = 2100;
static const double x86IonBytecodesPerMs = 1500;
static const double arm32IonBytecodesPerMs = 450;
static const double arm64IonBytecodesPerMs = 750; // Estimate
// Tiering cutoff values: if code section sizes are below these values (when
// divided by the effective number of cores) we do not tier, because we guess
// that parallel Ion compilation will be fast enough.
static const double x64DesktopTierCutoff = x64BytecodesPerMs * tierCutoffMs;
static const double x86DesktopTierCutoff = x86BytecodesPerMs * tierCutoffMs;
static const double x64DesktopTierCutoff = x64IonBytecodesPerMs * tierCutoffMs;
static const double x86DesktopTierCutoff = x86IonBytecodesPerMs * tierCutoffMs;
static const double x86MobileTierCutoff = x86DesktopTierCutoff / 2; // Guess
static const double arm32MobileTierCutoff = arm32BytecodesPerMs * tierCutoffMs;
static const double arm64MobileTierCutoff = arm64BytecodesPerMs * tierCutoffMs;
static const double arm32MobileTierCutoff = arm32IonBytecodesPerMs * tierCutoffMs;
static const double arm64MobileTierCutoff = arm64IonBytecodesPerMs * tierCutoffMs;
static double CodesizeCutoff(SystemClass cls, uint32_t codeSize) {
static double CodesizeCutoff(SystemClass cls) {
switch (cls) {
case SystemClass::DesktopX86:
case SystemClass::DesktopUnknown32:
@ -335,7 +344,7 @@ static bool TieringBeneficial(uint32_t codeSize) {
// Ion compilation on available cores must take long enough to be worth the
// bother.
double cutoffSize = CodesizeCutoff(cls, codeSize);
double cutoffSize = CodesizeCutoff(cls);
double effectiveCores = EffectiveCores(cls, cores);
if ((codeSize / effectiveCores) < cutoffSize) {

Просмотреть файл

@ -7814,7 +7814,10 @@ static bool IsAcceptableCaretPosition(const gfxSkipCharsIterator& aIter,
(NS_IS_LOW_SURROGATE(ch) && offs > 0 &&
NS_IS_HIGH_SURROGATE(frag->CharAt(offs - 1))) ||
(!aTextRun->IsLigatureGroupStart(index) &&
unicode::GetEmojiPresentation(ch) == unicode::EmojiDefault)) {
(unicode::GetEmojiPresentation(ch) == unicode::EmojiDefault ||
(unicode::GetEmojiPresentation(ch) == unicode::TextDefault &&
offs + 1 < frag->GetLength() &&
frag->CharAt(offs + 1) == gfxFontUtils::kUnicodeVS16)))) {
return false;
}

Просмотреть файл

@ -1784,6 +1784,20 @@ VARCACHE_PREF(
bool, true
)
// Block 3rd party fingerprinting resources.
VARCACHE_PREF(
"privacy.trackingprotection.fingerprinting.enabled",
privacy_trackingprotection_fingerprinting_enabled,
bool, true
)
// Block 3rd party cryptomining resources.
VARCACHE_PREF(
"privacy.trackingprotection.cryptomining.enabled",
privacy_trackingprotection_cryptomining_enabled,
bool, true
)
// Lower the priority of network loads for resources on the tracking protection
// list. Note that this requires the
// privacy.trackingprotection.annotate_channels pref to be on in order to have

Просмотреть файл

@ -87,13 +87,14 @@ LazyLogModule UrlClassifierCommon::sLog("nsChannelClassifier");
pwin->NotifyContentBlockingState(aBlockedReason, aChannel, true, uri);
}
/* static */ bool
UrlClassifierCommon::ShouldEnableTrackingProtectionOrAnnotation(
/* static */ bool UrlClassifierCommon::ShouldEnableClassifier(
nsIChannel* aChannel,
AntiTrackingCommon::ContentBlockingAllowListPurpose aBlockingPurpose) {
MOZ_ASSERT(aChannel);
MOZ_ASSERT(aBlockingPurpose == AntiTrackingCommon::eTrackingProtection ||
aBlockingPurpose == AntiTrackingCommon::eTrackingAnnotations);
aBlockingPurpose == AntiTrackingCommon::eTrackingAnnotations ||
aBlockingPurpose == AntiTrackingCommon::eFingerprinting ||
aBlockingPurpose == AntiTrackingCommon::eCryptomining);
nsCOMPtr<nsIHttpChannelInternal> channel = do_QueryInterface(aChannel);
if (!channel) {

Просмотреть файл

@ -33,7 +33,7 @@ class UrlClassifierCommon final {
static void NotifyChannelBlocked(nsIChannel* aChannel,
unsigned aBlockedReason);
static bool ShouldEnableTrackingProtectionOrAnnotation(
static bool ShouldEnableClassifier(
nsIChannel* aChannel,
AntiTrackingCommon::ContentBlockingAllowListPurpose aBlockingPurpose);

Просмотреть файл

@ -0,0 +1,175 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "UrlClassifierFeatureCryptomining.h"
#include "mozilla/AntiTrackingCommon.h"
#include "mozilla/net/UrlClassifierCommon.h"
#include "mozilla/StaticPrefs.h"
#include "nsContentUtils.h"
#include "nsNetUtil.h"
namespace mozilla {
namespace net {
namespace {
#define CRYPTOMINING_FEATURE_NAME "cryptomining"
#define URLCLASSIFIER_CRYPTOMINING_BLACKLIST \
"urlclassifier.features.cryptomining.blacklistTables"
#define URLCLASSIFIER_CRYPTOMINING_BLACKLIST_TEST_ENTRIES \
"urlclassifier.features.cryptomining.blacklistHosts"
#define URLCLASSIFIER_CRYPTOMINING_WHITELIST \
"urlclassifier.features.cryptomining.whitelistTables"
#define URLCLASSIFIER_CRYPTOMINING_WHITELIST_TEST_ENTRIES \
"urlclassifier.features.cryptomining.whitelistHosts"
#define TABLE_CRYPTOMINING_BLACKLIST_PREF "cryptomining-blacklist-pref"
#define TABLE_CRYPTOMINING_WHITELIST_PREF "cryptomining-whitelist-pref"
StaticRefPtr<UrlClassifierFeatureCryptomining> gFeatureCryptomining;
} // namespace
UrlClassifierFeatureCryptomining::UrlClassifierFeatureCryptomining()
: UrlClassifierFeatureBase(
NS_LITERAL_CSTRING(CRYPTOMINING_FEATURE_NAME),
NS_LITERAL_CSTRING(URLCLASSIFIER_CRYPTOMINING_BLACKLIST),
NS_LITERAL_CSTRING(URLCLASSIFIER_CRYPTOMINING_WHITELIST),
NS_LITERAL_CSTRING(URLCLASSIFIER_CRYPTOMINING_BLACKLIST_TEST_ENTRIES),
NS_LITERAL_CSTRING(URLCLASSIFIER_CRYPTOMINING_WHITELIST_TEST_ENTRIES),
NS_LITERAL_CSTRING(TABLE_CRYPTOMINING_BLACKLIST_PREF),
NS_LITERAL_CSTRING(TABLE_CRYPTOMINING_WHITELIST_PREF),
EmptyCString()) {}
/* static */ const char* UrlClassifierFeatureCryptomining::Name() {
return CRYPTOMINING_FEATURE_NAME;
}
/* static */ void UrlClassifierFeatureCryptomining::MaybeInitialize() {
UC_LOG(("UrlClassifierFeatureCryptomining: MaybeInitialize"));
if (!gFeatureCryptomining) {
gFeatureCryptomining = new UrlClassifierFeatureCryptomining();
gFeatureCryptomining->InitializePreferences();
}
}
/* static */ void UrlClassifierFeatureCryptomining::MaybeShutdown() {
UC_LOG(("UrlClassifierFeatureCryptomining: MaybeShutdown"));
if (gFeatureCryptomining) {
gFeatureCryptomining->ShutdownPreferences();
gFeatureCryptomining = nullptr;
}
}
/* static */ already_AddRefed<UrlClassifierFeatureCryptomining>
UrlClassifierFeatureCryptomining::MaybeCreate(nsIChannel* aChannel) {
MOZ_ASSERT(aChannel);
UC_LOG(("UrlClassifierFeatureCryptomining: MaybeCreate for channel %p",
aChannel));
if (!StaticPrefs::privacy_trackingprotection_cryptomining_enabled()) {
return nullptr;
}
nsCOMPtr<nsIURI> chanURI;
nsresult rv = aChannel->GetURI(getter_AddRefs(chanURI));
if (NS_WARN_IF(NS_FAILED(rv))) {
return nullptr;
}
bool isThirdParty =
nsContentUtils::IsThirdPartyWindowOrChannel(nullptr, aChannel, chanURI);
if (!isThirdParty) {
if (UC_LOG_ENABLED()) {
nsCString spec = chanURI->GetSpecOrDefault();
spec.Truncate(
std::min(spec.Length(), UrlClassifierCommon::sMaxSpecLength));
UC_LOG(
("UrlClassifierFeatureCryptomining: Skipping cryptomining checks "
"for first party or top-level load channel[%p] "
"with uri %s",
aChannel, spec.get()));
}
return nullptr;
}
if (!UrlClassifierCommon::ShouldEnableClassifier(
aChannel, AntiTrackingCommon::eCryptomining)) {
return nullptr;
}
MaybeInitialize();
MOZ_ASSERT(gFeatureCryptomining);
RefPtr<UrlClassifierFeatureCryptomining> self = gFeatureCryptomining;
return self.forget();
}
/* static */ already_AddRefed<nsIUrlClassifierFeature>
UrlClassifierFeatureCryptomining::GetIfNameMatches(const nsACString& aName) {
if (!aName.EqualsLiteral(CRYPTOMINING_FEATURE_NAME)) {
return nullptr;
}
MaybeInitialize();
MOZ_ASSERT(gFeatureCryptomining);
RefPtr<UrlClassifierFeatureCryptomining> self = gFeatureCryptomining;
return self.forget();
}
NS_IMETHODIMP
UrlClassifierFeatureCryptomining::ProcessChannel(nsIChannel* aChannel,
const nsACString& aList,
bool* aShouldContinue) {
NS_ENSURE_ARG_POINTER(aChannel);
NS_ENSURE_ARG_POINTER(aShouldContinue);
// This is a blocking feature.
*aShouldContinue = false;
UrlClassifierCommon::SetBlockedContent(aChannel, NS_ERROR_TRACKING_URI, aList,
EmptyCString(), EmptyCString());
UC_LOG(
("UrlClassifierFeatureCryptomining::ProcessChannel, cancelling "
"channel[%p]",
aChannel));
nsCOMPtr<nsIHttpChannelInternal> httpChannel = do_QueryInterface(aChannel);
// FIXME: the way we cancel the channel depends on what the UI wants to show.
// This needs to change, at some point.
if (httpChannel) {
Unused << httpChannel->CancelForTrackingProtection();
} else {
Unused << aChannel->Cancel(NS_ERROR_TRACKING_URI);
}
return NS_OK;
}
NS_IMETHODIMP
UrlClassifierFeatureCryptomining::GetURIByListType(
nsIChannel* aChannel, nsIUrlClassifierFeature::listType aListType,
nsIURI** aURI) {
NS_ENSURE_ARG_POINTER(aChannel);
NS_ENSURE_ARG_POINTER(aURI);
if (aListType == nsIUrlClassifierFeature::blacklist) {
return aChannel->GetURI(aURI);
}
MOZ_ASSERT(aListType == nsIUrlClassifierFeature::whitelist);
return UrlClassifierCommon::CreatePairwiseWhiteListURI(aChannel, aURI);
}
} // namespace net
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,45 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_net_UrlClassifierFeatureCryptomining_h
#define mozilla_net_UrlClassifierFeatureCryptomining_h
#include "UrlClassifierFeatureBase.h"
class nsIChannel;
namespace mozilla {
namespace net {
class UrlClassifierFeatureCryptomining final : public UrlClassifierFeatureBase {
public:
static const char* Name();
static void MaybeShutdown();
static already_AddRefed<UrlClassifierFeatureCryptomining> MaybeCreate(
nsIChannel* aChannel);
static already_AddRefed<nsIUrlClassifierFeature> GetIfNameMatches(
const nsACString& aName);
NS_IMETHOD ProcessChannel(nsIChannel* aChannel, const nsACString& aList,
bool* aShouldContinue) override;
NS_IMETHOD GetURIByListType(nsIChannel* aChannel,
nsIUrlClassifierFeature::listType aListType,
nsIURI** aURI) override;
private:
UrlClassifierFeatureCryptomining();
static void MaybeInitialize();
};
} // namespace net
} // namespace mozilla
#endif // mozilla_net_UrlClassifierFeatureCryptomining_h

Просмотреть файл

@ -7,6 +7,8 @@
#include "mozilla/net/UrlClassifierFeatureFactory.h"
// List of Features
#include "UrlClassifierFeatureCryptomining.h"
#include "UrlClassifierFeatureFingerprinting.h"
#include "UrlClassifierFeatureFlash.h"
#include "UrlClassifierFeatureLoginReputation.h"
#include "UrlClassifierFeatureTrackingProtection.h"
@ -24,6 +26,8 @@ namespace net {
return;
}
UrlClassifierFeatureCryptomining::MaybeShutdown();
UrlClassifierFeatureFingerprinting::MaybeShutdown();
UrlClassifierFeatureFlash::MaybeShutdown();
UrlClassifierFeatureLoginReputation::MaybeShutdown();
UrlClassifierFeatureTrackingAnnotation::MaybeShutdown();
@ -43,6 +47,18 @@ namespace net {
// feature order, and this could produce different results with a different
// feature ordering.
// Cryptomining
feature = UrlClassifierFeatureCryptomining::MaybeCreate(aChannel);
if (feature) {
aFeatures.AppendElement(feature);
}
// Fingerprinting
feature = UrlClassifierFeatureFingerprinting::MaybeCreate(aChannel);
if (feature) {
aFeatures.AppendElement(feature);
}
// Tracking Protection
feature = UrlClassifierFeatureTrackingProtection::MaybeCreate(aChannel);
if (feature) {
@ -75,6 +91,18 @@ UrlClassifierFeatureFactory::GetFeatureByName(const nsACString& aName) {
nsCOMPtr<nsIUrlClassifierFeature> feature;
// Cryptomining
feature = UrlClassifierFeatureCryptomining::GetIfNameMatches(aName);
if (feature) {
return feature.forget();
}
// Fingerprinting
feature = UrlClassifierFeatureFingerprinting::GetIfNameMatches(aName);
if (feature) {
return feature.forget();
}
// Tracking Protection
feature = UrlClassifierFeatureTrackingProtection::GetIfNameMatches(aName);
if (feature) {
@ -102,6 +130,49 @@ UrlClassifierFeatureFactory::GetFeatureByName(const nsACString& aName) {
return nullptr;
}
/* static */ void UrlClassifierFeatureFactory::GetFeatureNames(
nsTArray<nsCString>& aArray) {
if (!XRE_IsParentProcess()) {
return;
}
// Cryptomining
nsAutoCString name;
name.Assign(UrlClassifierFeatureCryptomining::Name());
if (!name.IsEmpty()) {
aArray.AppendElement(name);
}
// Fingerprinting
name.Assign(UrlClassifierFeatureFingerprinting::Name());
if (!name.IsEmpty()) {
aArray.AppendElement(name);
}
// Tracking Protection
name.Assign(UrlClassifierFeatureTrackingProtection::Name());
if (!name.IsEmpty()) {
aArray.AppendElement(name);
}
// Tracking Annotation
name.Assign(UrlClassifierFeatureTrackingAnnotation::Name());
if (!name.IsEmpty()) {
aArray.AppendElement(name);
}
// Login reputation
name.Assign(UrlClassifierFeatureLoginReputation::Name());
if (!name.IsEmpty()) {
aArray.AppendElement(name);
}
// Flash features
nsTArray<nsCString> features;
UrlClassifierFeatureFlash::GetFeatureNames(features);
aArray.AppendElements(features);
}
/* static */ already_AddRefed<nsIUrlClassifierFeature>
UrlClassifierFeatureFactory::CreateFeatureWithTables(
const nsACString& aName, const nsTArray<nsCString>& aBlacklistTables,

Просмотреть файл

@ -29,6 +29,8 @@ class UrlClassifierFeatureFactory final {
static already_AddRefed<nsIUrlClassifierFeature> GetFeatureByName(
const nsACString& aFeatureName);
static void GetFeatureNames(nsTArray<nsCString>& aArray);
static already_AddRefed<nsIUrlClassifierFeature> CreateFeatureWithTables(
const nsACString& aName, const nsTArray<nsCString>& aBlacklistTables,
const nsTArray<nsCString>& aWhitelistTables);

Просмотреть файл

@ -0,0 +1,177 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "UrlClassifierFeatureFingerprinting.h"
#include "mozilla/AntiTrackingCommon.h"
#include "mozilla/net/UrlClassifierCommon.h"
#include "mozilla/StaticPrefs.h"
#include "nsContentUtils.h"
#include "nsNetUtil.h"
namespace mozilla {
namespace net {
namespace {
#define FINGERPRINTING_FEATURE_NAME "fingerprinting"
#define URLCLASSIFIER_FINGERPRINTING_BLACKLIST \
"urlclassifier.features.fingerprinting.blacklistTables"
#define URLCLASSIFIER_FINGERPRINTING_BLACKLIST_TEST_ENTRIES \
"urlclassifier.features.fingerprinting.blacklistHosts"
#define URLCLASSIFIER_FINGERPRINTING_WHITELIST \
"urlclassifier.features.fingerprinting.whitelistTables"
#define URLCLASSIFIER_FINGERPRINTING_WHITELIST_TEST_ENTRIES \
"urlclassifier.features.fingerprinting.whitelistHosts"
#define TABLE_FINGERPRINTING_BLACKLIST_PREF "fingerprinting-blacklist-pref"
#define TABLE_FINGERPRINTING_WHITELIST_PREF "fingerprinting-whitelist-pref"
StaticRefPtr<UrlClassifierFeatureFingerprinting> gFeatureFingerprinting;
} // namespace
UrlClassifierFeatureFingerprinting::UrlClassifierFeatureFingerprinting()
: UrlClassifierFeatureBase(
NS_LITERAL_CSTRING(FINGERPRINTING_FEATURE_NAME),
NS_LITERAL_CSTRING(URLCLASSIFIER_FINGERPRINTING_BLACKLIST),
NS_LITERAL_CSTRING(URLCLASSIFIER_FINGERPRINTING_WHITELIST),
NS_LITERAL_CSTRING(
URLCLASSIFIER_FINGERPRINTING_BLACKLIST_TEST_ENTRIES),
NS_LITERAL_CSTRING(
URLCLASSIFIER_FINGERPRINTING_WHITELIST_TEST_ENTRIES),
NS_LITERAL_CSTRING(TABLE_FINGERPRINTING_BLACKLIST_PREF),
NS_LITERAL_CSTRING(TABLE_FINGERPRINTING_WHITELIST_PREF),
EmptyCString()) {}
/* static */ const char* UrlClassifierFeatureFingerprinting::Name() {
return FINGERPRINTING_FEATURE_NAME;
}
/* static */ void UrlClassifierFeatureFingerprinting::MaybeInitialize() {
UC_LOG(("UrlClassifierFeatureFingerprinting: MaybeInitialize"));
if (!gFeatureFingerprinting) {
gFeatureFingerprinting = new UrlClassifierFeatureFingerprinting();
gFeatureFingerprinting->InitializePreferences();
}
}
/* static */ void UrlClassifierFeatureFingerprinting::MaybeShutdown() {
UC_LOG(("UrlClassifierFeatureFingerprinting: MaybeShutdown"));
if (gFeatureFingerprinting) {
gFeatureFingerprinting->ShutdownPreferences();
gFeatureFingerprinting = nullptr;
}
}
/* static */ already_AddRefed<UrlClassifierFeatureFingerprinting>
UrlClassifierFeatureFingerprinting::MaybeCreate(nsIChannel* aChannel) {
MOZ_ASSERT(aChannel);
UC_LOG(("UrlClassifierFeatureFingerprinting: MaybeCreate for channel %p",
aChannel));
if (!StaticPrefs::privacy_trackingprotection_fingerprinting_enabled()) {
return nullptr;
}
nsCOMPtr<nsIURI> chanURI;
nsresult rv = aChannel->GetURI(getter_AddRefs(chanURI));
if (NS_WARN_IF(NS_FAILED(rv))) {
return nullptr;
}
bool isThirdParty =
nsContentUtils::IsThirdPartyWindowOrChannel(nullptr, aChannel, chanURI);
if (!isThirdParty) {
if (UC_LOG_ENABLED()) {
nsCString spec = chanURI->GetSpecOrDefault();
spec.Truncate(
std::min(spec.Length(), UrlClassifierCommon::sMaxSpecLength));
UC_LOG(
("UrlClassifierFeatureFingerprinting: Skipping fingerprinting checks "
"for first party or top-level load channel[%p] "
"with uri %s",
aChannel, spec.get()));
}
return nullptr;
}
if (!UrlClassifierCommon::ShouldEnableClassifier(
aChannel, AntiTrackingCommon::eFingerprinting)) {
return nullptr;
}
MaybeInitialize();
MOZ_ASSERT(gFeatureFingerprinting);
RefPtr<UrlClassifierFeatureFingerprinting> self = gFeatureFingerprinting;
return self.forget();
}
/* static */ already_AddRefed<nsIUrlClassifierFeature>
UrlClassifierFeatureFingerprinting::GetIfNameMatches(const nsACString& aName) {
if (!aName.EqualsLiteral(FINGERPRINTING_FEATURE_NAME)) {
return nullptr;
}
MaybeInitialize();
MOZ_ASSERT(gFeatureFingerprinting);
RefPtr<UrlClassifierFeatureFingerprinting> self = gFeatureFingerprinting;
return self.forget();
}
NS_IMETHODIMP
UrlClassifierFeatureFingerprinting::ProcessChannel(nsIChannel* aChannel,
const nsACString& aList,
bool* aShouldContinue) {
NS_ENSURE_ARG_POINTER(aChannel);
NS_ENSURE_ARG_POINTER(aShouldContinue);
// This is a blocking feature.
*aShouldContinue = false;
UrlClassifierCommon::SetBlockedContent(aChannel, NS_ERROR_TRACKING_URI, aList,
EmptyCString(), EmptyCString());
UC_LOG(
("UrlClassifierFeatureFingerprinting::ProcessChannel, cancelling "
"channel[%p]",
aChannel));
nsCOMPtr<nsIHttpChannelInternal> httpChannel = do_QueryInterface(aChannel);
// FIXME: the way we cancel the channel depends on what the UI wants to show.
// This needs to change, at some point.
if (httpChannel) {
Unused << httpChannel->CancelForTrackingProtection();
} else {
Unused << aChannel->Cancel(NS_ERROR_TRACKING_URI);
}
return NS_OK;
}
NS_IMETHODIMP
UrlClassifierFeatureFingerprinting::GetURIByListType(
nsIChannel* aChannel, nsIUrlClassifierFeature::listType aListType,
nsIURI** aURI) {
NS_ENSURE_ARG_POINTER(aChannel);
NS_ENSURE_ARG_POINTER(aURI);
if (aListType == nsIUrlClassifierFeature::blacklist) {
return aChannel->GetURI(aURI);
}
MOZ_ASSERT(aListType == nsIUrlClassifierFeature::whitelist);
return UrlClassifierCommon::CreatePairwiseWhiteListURI(aChannel, aURI);
}
} // namespace net
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,46 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_net_UrlClassifierFeatureFingerprinting_h
#define mozilla_net_UrlClassifierFeatureFingerprinting_h
#include "UrlClassifierFeatureBase.h"
class nsIChannel;
namespace mozilla {
namespace net {
class UrlClassifierFeatureFingerprinting final
: public UrlClassifierFeatureBase {
public:
static const char* Name();
static void MaybeShutdown();
static already_AddRefed<UrlClassifierFeatureFingerprinting> MaybeCreate(
nsIChannel* aChannel);
static already_AddRefed<nsIUrlClassifierFeature> GetIfNameMatches(
const nsACString& aName);
NS_IMETHOD ProcessChannel(nsIChannel* aChannel, const nsACString& aList,
bool* aShouldContinue) override;
NS_IMETHOD GetURIByListType(nsIChannel* aChannel,
nsIUrlClassifierFeature::listType aListType,
nsIURI** aURI) override;
private:
UrlClassifierFeatureFingerprinting();
static void MaybeInitialize();
};
} // namespace net
} // namespace mozilla
#endif // mozilla_net_UrlClassifierFeatureFingerprinting_h

Просмотреть файл

@ -55,6 +55,15 @@ UrlClassifierFeatureFlash::UrlClassifierFeatureFlash(uint32_t aId)
"nsIHttpChannel::FlashPluginLastValue is out-of-sync!");
}
/* static */ void UrlClassifierFeatureFlash::GetFeatureNames(
nsTArray<nsCString>& aArray) {
uint32_t numFeatures =
(sizeof(sFlashFeaturesMap) / sizeof(sFlashFeaturesMap[0]));
for (uint32_t i = 0; i < numFeatures; ++i) {
aArray.AppendElement(nsDependentCString(sFlashFeaturesMap[i].mName));
}
}
/* static */ void UrlClassifierFeatureFlash::MaybeInitialize() {
MOZ_ASSERT(XRE_IsParentProcess());

Просмотреть файл

@ -14,6 +14,8 @@ namespace net {
class UrlClassifierFeatureFlash final : public UrlClassifierFeatureBase {
public:
static void GetFeatureNames(nsTArray<nsCString>& aNames);
static void MaybeShutdown();
static void MaybeCreate(

Просмотреть файл

@ -33,6 +33,12 @@ UrlClassifierFeatureLoginReputation::UrlClassifierFeatureLoginReputation()
EmptyCString()) // skip host pref
{}
/* static */ const char* UrlClassifierFeatureLoginReputation::Name() {
return StaticPrefs::browser_safebrowsing_passwords_enabled()
? LOGIN_REPUTATION_FEATURE_NAME
: "";
}
/* static */ void UrlClassifierFeatureLoginReputation::MaybeShutdown() {
UC_LOG(("UrlClassifierFeatureLoginReputation: MaybeShutdown"));
@ -76,36 +82,6 @@ UrlClassifierFeatureLoginReputation::ProcessChannel(nsIChannel* aChannel,
return NS_OK;
}
NS_IMETHODIMP
UrlClassifierFeatureLoginReputation::GetTables(
nsIUrlClassifierFeature::listType aListType, nsTArray<nsCString>& aTables) {
MOZ_ASSERT(aListType == nsIUrlClassifierFeature::whitelist,
"UrlClassifierFeatureLoginReputation is meant to be used just to "
"whitelist URLs");
return UrlClassifierFeatureBase::GetTables(aListType, aTables);
}
NS_IMETHODIMP
UrlClassifierFeatureLoginReputation::HasTable(
const nsACString& aTable, nsIUrlClassifierFeature::listType aListType,
bool* aResult) {
MOZ_ASSERT(aListType == nsIUrlClassifierFeature::whitelist,
"UrlClassifierFeatureLoginReputation is meant to be used just to "
"whitelist URLs");
return UrlClassifierFeatureBase::HasTable(aTable, aListType, aResult);
}
NS_IMETHODIMP
UrlClassifierFeatureLoginReputation::HasHostInPreferences(
const nsACString& aHost, nsIUrlClassifierFeature::listType aListType,
nsACString& aPrefTableName, bool* aResult) {
MOZ_ASSERT(aListType == nsIUrlClassifierFeature::whitelist,
"UrlClassifierFeatureLoginReputation is meant to be used just to "
"whitelist URLs");
return UrlClassifierFeatureBase::HasHostInPreferences(
aHost, aListType, aPrefTableName, aResult);
}
NS_IMETHODIMP
UrlClassifierFeatureLoginReputation::GetURIByListType(
nsIChannel* aChannel, nsIUrlClassifierFeature::listType aListType,

Просмотреть файл

@ -17,6 +17,8 @@ namespace net {
class UrlClassifierFeatureLoginReputation final
: public UrlClassifierFeatureBase {
public:
static const char* Name();
static void MaybeShutdown();
static nsIUrlClassifierFeature* MaybeGetOrCreate();
@ -24,19 +26,6 @@ class UrlClassifierFeatureLoginReputation final
static already_AddRefed<nsIUrlClassifierFeature> GetIfNameMatches(
const nsACString& aName);
NS_IMETHOD
GetTables(nsIUrlClassifierFeature::listType aListType,
nsTArray<nsCString>& aResult) override;
NS_IMETHOD
HasTable(const nsACString& aTable,
nsIUrlClassifierFeature::listType aListType, bool* aResult) override;
NS_IMETHOD
HasHostInPreferences(const nsACString& aHost,
nsIUrlClassifierFeature::listType aListType,
nsACString& aPrefTableName, bool* aResult) override;
NS_IMETHOD ProcessChannel(nsIChannel* aChannel, const nsACString& aList,
bool* aShouldContinue) override;

Просмотреть файл

@ -120,6 +120,10 @@ UrlClassifierFeatureTrackingAnnotation::UrlClassifierFeatureTrackingAnnotation()
NS_LITERAL_CSTRING(TABLE_ANNOTATION_WHITELIST_PREF),
NS_LITERAL_CSTRING(URLCLASSIFIER_TRACKING_ANNOTATION_SKIP_URLS)) {}
/* static */ const char* UrlClassifierFeatureTrackingAnnotation::Name() {
return TRACKING_ANNOTATION_FEATURE_NAME;
}
/* static */ void UrlClassifierFeatureTrackingAnnotation::MaybeInitialize() {
MOZ_ASSERT(XRE_IsParentProcess());
UC_LOG(("UrlClassifierFeatureTrackingAnnotation: MaybeInitialize"));
@ -150,7 +154,7 @@ UrlClassifierFeatureTrackingAnnotation::MaybeCreate(nsIChannel* aChannel) {
return nullptr;
}
if (!UrlClassifierCommon::ShouldEnableTrackingProtectionOrAnnotation(
if (!UrlClassifierCommon::ShouldEnableClassifier(
aChannel, AntiTrackingCommon::eTrackingAnnotations)) {
return nullptr;
}

Просмотреть файл

@ -17,6 +17,8 @@ namespace net {
class UrlClassifierFeatureTrackingAnnotation final
: public UrlClassifierFeatureBase {
public:
static const char* Name();
static void MaybeShutdown();
static already_AddRefed<UrlClassifierFeatureTrackingAnnotation> MaybeCreate(

Просмотреть файл

@ -42,6 +42,10 @@ UrlClassifierFeatureTrackingProtection::UrlClassifierFeatureTrackingProtection()
NS_LITERAL_CSTRING(TABLE_TRACKING_BLACKLIST_PREF),
NS_LITERAL_CSTRING(TABLE_TRACKING_WHITELIST_PREF), EmptyCString()) {}
/* static */ const char* UrlClassifierFeatureTrackingProtection::Name() {
return TRACKING_PROTECTION_FEATURE_NAME;
}
/* static */ void UrlClassifierFeatureTrackingProtection::MaybeInitialize() {
MOZ_ASSERT(XRE_IsParentProcess());
UC_LOG(("UrlClassifierFeatureTrackingProtection: MaybeInitialize"));
@ -97,7 +101,7 @@ UrlClassifierFeatureTrackingProtection::MaybeCreate(nsIChannel* aChannel) {
return nullptr;
}
if (!UrlClassifierCommon::ShouldEnableTrackingProtectionOrAnnotation(
if (!UrlClassifierCommon::ShouldEnableClassifier(
aChannel, AntiTrackingCommon::eTrackingProtection)) {
return nullptr;
}

Просмотреть файл

@ -17,6 +17,8 @@ namespace net {
class UrlClassifierFeatureTrackingProtection final
: public UrlClassifierFeatureBase {
public:
static const char* Name();
static void MaybeShutdown();
static already_AddRefed<UrlClassifierFeatureTrackingProtection> MaybeCreate(

Просмотреть файл

@ -22,8 +22,10 @@ UNIFIED_SOURCES += [
'nsChannelClassifier.cpp',
'UrlClassifierCommon.cpp',
'UrlClassifierFeatureBase.cpp',
'UrlClassifierFeatureCryptomining.cpp',
'UrlClassifierFeatureCustomTables.cpp',
'UrlClassifierFeatureFactory.cpp',
'UrlClassifierFeatureFingerprinting.cpp',
'UrlClassifierFeatureFlash.cpp',
'UrlClassifierFeatureLoginReputation.cpp',
'UrlClassifierFeatureResult.cpp',

Просмотреть файл

@ -95,6 +95,11 @@ interface nsIURIClassifier : nsISupports
*/
nsIUrlClassifierFeature getFeatureByName(in ACString aFeatureName);
/**
* Returns all the feature names.
*/
Array<ACString> getFeatureNames();
/**
* Create a new feature with a list of tables. This method is just for
* testing! Don't use it elsewhere.

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -17,98 +17,11 @@
@import url("chrome://global/skin/in-content/common.css");
html {
--aboutSupport-table-background: #ebebeb;
background-color: var(--in-content-page-background);
}
body {
margin: 40px 48px;
}
.hidden {
display: none;
}
.summary .title {
font-weight: bold;
}
a {
text-decoration: none;
}
a.more {
margin-left: 2ch;
}
ul.hidden_additional_items {
padding-top: 0;
margin-top: 0;
}
ul.visible_items {
padding-bottom: 0;
margin-bottom: 0;
}
li.delta {
margin-top: .5em;
}
h2 {
font-size: 1.46em;
font-weight: 300;
line-height: 1.3em;
margin: 16px 0;
-moz-user-select: none;
}
button.show_all_items {
margin-top: .5cm;
margin-left: 1cm;
}
body {
margin-left: 1cm;
overflow-x: hidden;
}
div.measuring {
background: url(chrome://global/skin/media/throbber.png) no-repeat center;
min-width: 36px;
min-height: 36px;
}
li.delta {
border-left-width: 5px;
border-left-style: solid;
padding-left: 1em;
list-style: none;
}
li.delta[impact="0"] {
border-left-color: rgb(0, 255, 0);
}
li.delta[impact="1"] {
border-left-color: rgb(24, 231, 0);
}
li.delta[impact="2"] {
border-left-color: rgb(48, 207, 0);
}
li.delta[impact="3"] {
border-left-color: rgb(72, 183, 0);
}
li.delta[impact="4"] {
border-left-color: rgb(96, 159, 0);
}
li.delta[impact="5"] {
border-left-color: rgb(120, 135, 0);
}
li.delta[impact="6"] {
border-left-color: rgb(144, 111, 0);
}
li.delta[impact="7"] {
border-left-color: rgb(168, 87, 0);
}
li.delta[impact="8"] {
border-left-color: rgb(192, 63, 0);
}
li.delta[impact="9"] {
border-left-color: rgb(216, 39, 0);
}
li.delta[impact="10"] {
border-left-color: rgb(240, 15, 0);
}
li.delta[impact="11"] {
border-left-color: rgb(255, 0, 0);
}
#dispatch-table {
-moz-user-select: none;
font-size: 1em;
@ -135,24 +48,24 @@
border-bottom: 1px solid var(--in-content-border-color);
min-width: 40em;
}
#dispatch-thead, #dispatch-tbody tr {
tr {
display: table;
table-layout: fixed;
width: 100%;
}
#dispatch-table td:nth-child(2) {
td:nth-child(2) {
width: 8em;
}
#dispatch-table td:nth-child(3) {
td:nth-child(3) {
width: 9em;
}
#dispatch-table td:nth-child(4) {
td:nth-child(4) {
width: 5em;
}
#dispatch-tbody td:nth-child(4) {
text-align: end;
}
#dispatch-table td:nth-child(5) {
td:nth-child(5) {
width: 20px;
}
@ -219,12 +132,12 @@
transform: scale(1.2);
}
#dispatch-table > thead > tr > td {
#dispatch-thead > tr > td {
border: none;
background-color: var(--in-content-box-background-hover);
padding: 5px 10px;
}
#dispatch-table > thead > tr > td:not(:first-child) {
#dispatch-thead > tr > td:not(:first-child) {
border-inline-start-width: 1px;
border-inline-start-style: solid;
border-image: linear-gradient(transparent 0%, transparent 20%, #c1c1c1 20%, #c1c1c1 80%, transparent 80%, transparent 100%) 1 1;
@ -304,47 +217,20 @@
#dispatch-tbody > tr:hover {
background-color: var(--in-content-item-hover);
}
.options {
width: 100%;
}
.options > .toggle-container-with-text {
display: inline-flex;
}
.options > .toggle-container-with-text:not(:first-child) {
margin-inline-start: 2ch;
}
</style>
</head>
<body onload="go()">
<div class="options">
<div class="toggle-container-with-text">
<input type="checkbox" checked="false" id="check-display-recent" role="checkbox"></input>
<label for="check-display-recent" id="label-display-recent">Display only the last few seconds.</label>
</div>
<div class="toggle-container-with-text">
<input type="checkbox" checked="true" id="check-autorefresh" role="checkbox"></input>
<label for="check-autorefresh">Refresh automatically</label>
</div>
</div>
<div>
<h2>Performance of Web pages</h2>
<div id="webpages" class="measuring">
</div>
</div>
<div>
<table id="dispatch-table">
<thead id="dispatch-thead">
<tr>
<td data-l10n-id="column-name"/>
<td data-l10n-id="column-type"/>
<td data-l10n-id="column-energy-impact"/>
<td data-l10n-id="column-memory"/>
<td></td><!-- actions -->
</tr>
</thead>
<tbody id="dispatch-tbody"></tbody>
</table>
</div>
<table id="dispatch-table">
<thead id="dispatch-thead">
<tr>
<td data-l10n-id="column-name"/>
<td data-l10n-id="column-type"/>
<td data-l10n-id="column-energy-impact"/>
<td data-l10n-id="column-memory"/>
<td></td><!-- actions -->
</tr>
</thead>
<tbody id="dispatch-tbody"></tbody>
</table>
</body>
</html>

Просмотреть файл

@ -1,9 +1,7 @@
[DEFAULT]
head = head.js
support-files =
browser_compartments.html
browser_compartments_frame.html
browser_compartments_script.js
[browser_aboutperformance.js]
skip-if = true

Просмотреть файл

@ -1,308 +1,64 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/* eslint-env mozilla/frame-script */
/* eslint-disable mozilla/no-arbitrary-setTimeout */
"use strict";
ChromeUtils.import("resource://testing-common/ContentTask.jsm", this);
const URL = "http://example.com/browser/toolkit/components/aboutperformance/tests/browser/browser_compartments.html?test=" + Math.random();
// This function is injected as source as a frameScript
function frameScript() {
"use strict";
addMessageListener("aboutperformance-test:done", () => {
content.postMessage("stop", "*");
sendAsyncMessage("aboutperformance-test:done", null);
});
addMessageListener("aboutperformance-test:setTitle", ({data: title}) => {
content.document.title = title;
sendAsyncMessage("aboutperformance-test:setTitle", null);
});
addMessageListener("aboutperformance-test:closeTab", ({data: options}) => {
let observer = function(subject, topic, mode) {
dump(`aboutperformance-test:closeTab 1 ${options.url}\n`);
Services.obs.removeObserver(observer, "about:performance-update-complete");
let exn;
let found = false;
try {
for (let eltContent of content.document.querySelectorAll("li.delta")) {
let eltName = eltContent.querySelector("li.name");
if (!eltName.textContent.includes(options.url)) {
continue;
}
found = true;
let [eltCloseTab, eltReloadTab] = eltContent.querySelectorAll("button");
let button;
if (options.mode == "reload") {
button = eltReloadTab;
} else if (options.mode == "close") {
button = eltCloseTab;
} else {
throw new TypeError(options.mode);
}
dump(`aboutperformance-test:closeTab clicking on ${button.textContent}\n`);
button.click();
return;
}
} catch (ex) {
dump(`aboutperformance-test:closeTab: error ${ex}\n`);
exn = ex;
} finally {
if (exn) {
sendAsyncMessage("aboutperformance-test:closeTab", { error: {message: exn.message, lineNumber: exn.lineNumber, fileName: exn.fileName}, found});
} else {
sendAsyncMessage("aboutperformance-test:closeTab", { ok: true, found });
}
}
};
Services.obs.addObserver(observer, "about:performance-update-complete");
Services.obs.notifyObservers(null, "test-about:performance-test-driver", JSON.stringify(options));
});
addMessageListener("aboutperformance-test:checkSanity", ({data: options}) => {
let exn = null;
try {
let reFullname = /Full name: (.+)/;
let reFps = /Impact on framerate: ((\d+) high-impacts, (\d+) medium-impact|(\d+)\/10)?/;
let reCPU = /CPU usage: (\d+)%/;
let reCpow = /Blocking process calls: (\d+)%( \((\d+) alerts\))?/;
let getContentOfSelector = function(eltContainer, selector, re) {
let elt = eltContainer.querySelector(selector);
if (!elt) {
throw new Error(`No item ${selector}`);
}
if (!re) {
return undefined;
}
let match = elt.textContent.match(re);
if (!match) {
throw new Error(`Item ${selector} doesn't match regexp ${re}: ${elt.textContent}`);
}
return match;
};
// Additional sanity check
let deltas = content.document.querySelectorAll(".delta");
if (!deltas.length) {
throw new Error("No deltas found to check!");
}
for (let eltContent of deltas) {
// Do we have an attribute "impact"? Is it a number between 0 and 10?
let impact = eltContent.getAttribute("impact");
let value = Number.parseInt(impact);
if (isNaN(value) || value < 0 || value > 10) {
throw new Error(`Incorrect value ${value}`);
}
// Do we have a button "more"?
getContentOfSelector(eltContent, "a.more");
// Do we have details?
getContentOfSelector(eltContent, "ul.details");
// Do we have a full name? Does it make sense?
getContentOfSelector(eltContent, "li.name", reFullname);
let eltDetails = eltContent.querySelector("ul.details");
// Do we have an impact on framerate? Does it make sense?
if (!eltDetails.querySelector("li.fps").textContent.includes("no impact")) {
let [, jankStr,, alertsStr] = getContentOfSelector(eltDetails, "li.fps", reFps);
let jank = Number.parseInt(jankStr);
if (jank < 0 || jank > 10 || isNaN(jank)) {
throw new Error(`Invalid jank ${jankStr}`);
}
if (alertsStr) {
let alerts = Number.parseInt(alertsStr);
if (alerts < 0 || isNaN(alerts)) {
throw new Error(`Invalid alerts ${alertsStr}`);
}
}
}
// Do we have a CPU usage? Does it make sense?
let [, cpuStr] = getContentOfSelector(eltDetails, "li.cpu", reCPU);
let cpu = Number.parseInt(cpuStr);
if (cpu < 0 || isNaN(cpu)) { // Note that cpu can be > 100%.
throw new Error(`Invalid CPU ${cpuStr}`);
}
// Do we have CPOW? Does it make sense?
let [, cpowStr,, alertsStr2] = getContentOfSelector(eltDetails, "li.cpow", reCpow);
let cpow = Number.parseInt(cpowStr);
if (cpow < 0 || isNaN(cpow)) {
throw new Error(`Invalid cpow ${cpowStr}`);
}
if (alertsStr2) {
let alerts = Number.parseInt(alertsStr2);
if (alerts < 0 || isNaN(alerts)) {
throw new Error(`Invalid alerts ${alertsStr2}`);
}
}
}
} catch (ex) {
dump(`aboutperformance-test:checkSanity: error ${ex}\n`);
exn = ex;
}
if (exn) {
sendAsyncMessage("aboutperformance-test:checkSanity", { error: {message: exn.message, lineNumber: exn.lineNumber, fileName: exn.fileName}});
} else {
sendAsyncMessage("aboutperformance-test:checkSanity", { ok: true });
}
});
addMessageListener("aboutperformance-test:hasItems", ({data: {title, options}}) => {
let observer = function(subject, topic, mode) {
Services.obs.removeObserver(observer, "about:performance-update-complete");
let hasTitleInWebpages = false;
try {
let eltWeb = content.document.getElementById("webpages");
if (!eltWeb) {
dump(`aboutperformance-test:hasItems: the page is not ready yet webpages:${eltWeb}\n`);
return;
}
let webTitles = Array.from(eltWeb.querySelectorAll("span.title"), elt => elt.textContent);
hasTitleInWebpages = webTitles.includes(title);
} catch (ex) {
Cu.reportError("Error in content: " + ex);
Cu.reportError(ex.stack);
} finally {
sendAsyncMessage("aboutperformance-test:hasItems", {hasTitleInWebpages, mode});
}
};
Services.obs.addObserver(observer, "about:performance-update-complete");
Services.obs.notifyObservers(null, "test-about:performance-test-driver", JSON.stringify(options));
});
}
var gTabAboutPerformance = null;
var gTabContent = null;
add_task(async function init() {
info("Setting up about:performance");
gTabAboutPerformance = gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, "about:performance");
await ContentTask.spawn(gTabAboutPerformance.linkedBrowser, null, frameScript);
let tabAboutPerformance = gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, "about:performance");
await BrowserTestUtils.browserLoaded(tabAboutPerformance.linkedBrowser);
info(`Setting up ${URL}`);
gTabContent = BrowserTestUtils.addTab(gBrowser, URL);
await ContentTask.spawn(gTabContent.linkedBrowser, null, frameScript);
});
var promiseExpectContent = async function(options) {
let title = "Testing about:performance " + Math.random();
for (let i = 0; i < 30; ++i) {
await new Promise(resolve => setTimeout(resolve, 100));
await promiseContentResponse(gTabContent.linkedBrowser, "aboutperformance-test:setTitle", title);
let {hasTitleInWebpages, mode} = (await promiseContentResponse(gTabAboutPerformance.linkedBrowser, "aboutperformance-test:hasItems", {title, options}));
info(`aboutperformance-test:hasItems ${hasTitleInWebpages}, ${mode}, ${options.displayRecent}`);
if (!hasTitleInWebpages) {
info(`Title not found in webpages`);
continue;
}
if ((mode == "recent") != options.displayRecent) {
info(`Wrong mode`);
continue;
}
let { ok, error } = await promiseContentResponse(gTabAboutPerformance.linkedBrowser, "aboutperformance-test:checkSanity", {options});
if (ok) {
info("aboutperformance-test:checkSanity: success");
}
if (error) {
Assert.ok(false, `aboutperformance-test:checkSanity error: ${JSON.stringify(error)}`);
}
return true;
}
return false;
};
// Test that we can find the title of a webpage in about:performance
add_task(async function test_find_title() {
for (let displayRecent of [true, false]) {
info(`Testing with autoRefresh, in ${displayRecent ? "recent" : "global"} mode`);
let found = await promiseExpectContent({autoRefresh: 100, displayRecent});
Assert.ok(found, `The page title appears when about:performance is set to auto-refresh`);
}
});
// Test that we can close/reload tabs using the corresponding buttons
add_task(async function test_close_tab() {
let tabs = new Map();
let closeObserver = function({type, originalTarget: tab}) {
dump(`closeObserver: ${tab}, ${tab.constructor.name}, ${tab.tagName}, ${type}\n`);
let cb = tabs.get(tab);
if (cb) {
cb(type);
}
};
let promiseTabClosed = function(tab) {
return new Promise(resolve => tabs.set(tab, resolve));
};
window.gBrowser.tabContainer.addEventListener("TabClose", closeObserver);
let promiseTabReloaded = function(tab) {
return new Promise(resolve =>
tab.linkedBrowser.contentDocument.addEventListener("readystatechange", resolve)
);
};
for (let displayRecent of [true, false]) {
for (let mode of ["close", "reload"]) {
let URL = `about:about?display-recent=${displayRecent}&mode=${mode}&salt=${Math.random()}`;
info(`Setting up ${URL}`);
let tab = BrowserTestUtils.addTab(gBrowser, URL);
await ContentTask.spawn(tab.linkedBrowser, null, frameScript);
let promiseClosed = promiseTabClosed(tab);
let promiseReloaded = promiseTabReloaded(tab);
info(`Requesting close`);
do {
await new Promise(resolve => setTimeout(resolve, 100));
await promiseContentResponse(tab.linkedBrowser, "aboutperformance-test:setTitle", URL);
let {ok, found, error} = await promiseContentResponse(gTabAboutPerformance.linkedBrowser, "aboutperformance-test:closeTab", {url: URL, autoRefresh: true, mode, displayRecent});
Assert.ok(ok, `Message aboutperformance-test:closeTab was handled correctly ${JSON.stringify(error)}`);
info(`URL ${URL} ${found ? "found" : "hasn't been found yet"}`);
if (found) {
break;
}
} while (true);
if (mode == "close") {
info(`Waiting for close`);
await promiseClosed;
} else {
info(`Waiting for reload`);
await promiseReloaded;
BrowserTestUtils.removeTab(tab);
}
}
}
});
add_task(async function cleanup() {
// Cleanup
info("Cleaning up");
await promiseContentResponse(gTabAboutPerformance.linkedBrowser, "aboutperformance-test:done", null);
info("Closing tabs");
for (let tab of gBrowser.tabs) {
BrowserTestUtils.removeTab(tab);
}
info("Done");
gBrowser.selectedTab = null;
let tabContent = BrowserTestUtils.addTab(gBrowser, URL);
await BrowserTestUtils.browserLoaded(tabContent.linkedBrowser);
let doc = tabAboutPerformance.linkedBrowser.contentDocument;
let tbody = doc.getElementById("dispatch-tbody");
// Wait until the table has first been populated.
await TestUtils.waitForCondition(() => tbody.childElementCount);
// And wait for another update using a mutation observer, to give our newly created test tab some time
// to burn some CPU.
await new Promise(resolve => {
let observer = new doc.ownerGlobal.MutationObserver(() => {
observer.disconnect();
resolve();
});
observer.observe(tbody, {childList: true});
});
// Find the row for our test tab.
let row = tbody.firstChild;
while (row && row.firstChild.textContent != "Main frame for test browser_aboutperformance.js")
row = row.nextSibling;
Assert.ok(row, "found a table row for our test tab");
Assert.equal(row.windowId, tabContent.linkedBrowser.outerWindowID, "the correct window id is set");
// Ensure it is reported as a medium or high energy impact.
let l10nId = row.children[2].getAttribute("data-l10n-id");
Assert.ok(["energy-impact-medium", "energy-impact-high"].includes(l10nId),
"our test tab is medium or high energy impact");
// Verify selecting a row works.
await BrowserTestUtils.synthesizeMouseAtCenter(row, {}, tabAboutPerformance.linkedBrowser);
Assert.equal(row.getAttribute("selected"), "true", "doing a single click selects the row");
// Verify selecting a tab with a double click.
Assert.equal(gBrowser.selectedTab, tabAboutPerformance, "the about:performance tab is selected");
await BrowserTestUtils.synthesizeMouseAtCenter(row, {clickCount: 2}, tabAboutPerformance.linkedBrowser);
Assert.equal(gBrowser.selectedTab, tabContent, "after a double click the test tab is selected");
// Verify we can close a tab using the X button.
// Switch back to about:performance...
await BrowserTestUtils.switchTab(gBrowser, tabAboutPerformance);
// ... and click the X button at the end of the row.
let tabClosing = BrowserTestUtils.waitForTabClosing(tabContent);
await BrowserTestUtils.synthesizeMouseAtCenter(row.children[4], {}, tabAboutPerformance.linkedBrowser);
await tabClosing;
BrowserTestUtils.removeTab(tabAboutPerformance);
});

Просмотреть файл

@ -1,6 +1,7 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>
Main frame for test browser_aboutperformance.js
</title>

Просмотреть файл

@ -1,6 +1,7 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>
Subframe for test browser_compartments.html (do not change this title)
</title>

Просмотреть файл

@ -1,23 +1,6 @@
var carryOn = true;
window.addEventListener("message", e => {
console.log("frame content", "message", e);
if ("title" in e.data) {
document.title = e.data.title;
}
if ("stop" in e.data) {
carryOn = false;
}
});
// Use some CPU.
var interval = window.setInterval(() => {
if (!carryOn) {
window.clearInterval(interval);
return;
}
// Compute an arbitrary value, print it out to make sure that the JS
// engine doesn't discard all our computation.
var date = Date.now();

Просмотреть файл

@ -1,50 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
ChromeUtils.import("resource://gre/modules/Services.jsm", this);
function promiseContentResponse(browser, name, message) {
let mm = browser.messageManager;
let promise = new Promise(resolve => {
function removeListener() {
mm.removeMessageListener(name, listener);
}
function listener(msg) {
removeListener();
resolve(msg.data);
}
mm.addMessageListener(name, listener);
registerCleanupFunction(removeListener);
});
mm.sendAsyncMessage(name, message);
return promise;
}
function promiseContentResponseOrNull(browser, name, message) {
if (!browser.messageManager) {
return null;
}
return promiseContentResponse(browser, name, message);
}
/**
* `true` if we are running an OS in which the OS performance
* clock has a low precision and might unpredictably
* never be updated during the execution of the test.
*/
function hasLowPrecision() {
let [sysName, sysVersion] = [Services.sysinfo.getPropertyAsAString("name"), Services.sysinfo.getPropertyAsDouble("version")];
info(`Running ${sysName} version ${sysVersion}`);
if (sysName == "Windows_NT" && sysVersion < 6) {
info("Running old Windows, need to deactivate tests due to bad precision.");
return true;
}
if (sysName == "Linux" && sysVersion <= 2.6) {
info("Running old Linux, need to deactivate tests due to bad precision.");
return true;
}
info("This platform has good precision.");
return false;
}

Просмотреть файл

@ -1372,7 +1372,11 @@ nsresult AntiTrackingCommon::IsOnContentBlockingAllowList(
if ((aPurpose == eStorageChecks &&
!StaticPrefs::browser_contentblocking_allowlist_storage_enabled()) ||
(aPurpose == eTrackingAnnotations &&
!StaticPrefs::browser_contentblocking_allowlist_annotations_enabled())) {
!StaticPrefs::browser_contentblocking_allowlist_annotations_enabled()) ||
(aPurpose == eFingerprinting &&
!StaticPrefs::privacy_trackingprotection_fingerprinting_enabled()) ||
(aPurpose == eCryptomining &&
!StaticPrefs::privacy_trackingprotection_cryptomining_enabled())) {
LOG(
("Attempting to check the content blocking allow list aborted because "
"the third-party cookies UI has been disabled."));

Просмотреть файл

@ -120,6 +120,8 @@ class AntiTrackingCommon final {
eStorageChecks,
eTrackingProtection,
eTrackingAnnotations,
eFingerprinting,
eCryptomining,
};
// Check whether a top window URI is on the content blocking allow list.

Просмотреть файл

@ -2699,6 +2699,12 @@ nsUrlClassifierDBService::GetFeatureByName(const nsACString& aFeatureName,
return NS_OK;
}
NS_IMETHODIMP
nsUrlClassifierDBService::GetFeatureNames(nsTArray<nsCString>& aArray) {
mozilla::net::UrlClassifierFeatureFactory::GetFeatureNames(aArray);
return NS_OK;
}
NS_IMETHODIMP
nsUrlClassifierDBService::CreateFeatureWithTables(
const nsACString& aName, const nsTArray<nsCString>& aBlacklistTables,

Просмотреть файл

@ -45,3 +45,5 @@ skip-if = (verify && debug && (os == 'win' || os == 'mac'))
[test_cachemiss.html]
skip-if = verify
[test_annotation_vs_TP.html]
[test_fingerprinting.html]
[test_cryptomining.html]

Просмотреть файл

@ -0,0 +1,106 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test the cryptomining classifier</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<script class="testbody" type="text/javascript">
/* eslint-env mozilla/frame-script */
var tests = [
// All disabled.
{ config: [ false, false ], loadExpected: true },
// Just whitelisted.
{ config: [ false, true ], loadExpected: true },
// Just blacklisted.
{ config: [ true, false ], loadExpected: false },
// whitelist + blacklist: whitelist wins
{ config: [ true, true ], loadExpected: true },
];
function prefValue(value, what) {
return value ? what : "";
}
async function runTest(test) {
await SpecialPowers.pushPrefEnv({set: [
[ "urlclassifier.features.cryptomining.blacklistHosts", prefValue(test.config[0], "example.com") ],
[ "urlclassifier.features.cryptomining.whitelistHosts", prefValue(test.config[1], "mochi.test") ],
[ "urlclassifier.features.cryptomining.blacklistTables", prefValue(test.config[0], "mochitest1-track-simple") ],
[ "urlclassifier.features.cryptomining.whitelistTables", "" ],
[ "privacy.trackingprotection.enabled", false ],
[ "privacy.trackingprotection.annotate_channels", false ],
[ "privacy.trackingprotection.cryptomining.enabled", true ],
[ "privacy.trackingprotection.fingerprinting.enabled", false ],
]});
info("Testing: " + test.config.toSource() + "\n");
// Let's load an image with a random query string, just to avoid network cache.
let result = await new Promise(resolve => {
let image = new Image();
image.src = "http://example.com/tests/toolkit/components/url-classifier/tests/mochitest/raptor.jpg?" + Math.random();
image.onload = _ => resolve(true);
image.onerror = _ => resolve(false);
});
is(result, test.loadExpected, "The loading happened correctly");
// Let's load an image with a random query string, just to avoid network cache.
result = await new Promise(resolve => {
let image = new Image();
image.src = "http://tracking.example.org/tests/toolkit/components/url-classifier/tests/mochitest/raptor.jpg?" + Math.random();
image.onload = _ => resolve(true);
image.onerror = _ => resolve(false);
});
is(result, test.loadExpected, "The loading happened correctly (by table)");
}
async function runTests() {
let chromeScript = SpecialPowers.loadChromeScript(_ => {
ChromeUtils.import("resource://testing-common/UrlClassifierTestUtils.jsm");
addMessageListener("loadTrackers", __ => {
UrlClassifierTestUtils.addTestTrackers().then(___ => {
sendAsyncMessage("trackersLoaded");
});
});
addMessageListener("unloadTrackers", __ => {
UrlClassifierTestUtils.cleanupTestTrackers();
sendAsyncMessage("trackersUnloaded");
});
});
await new Promise(resolve => {
chromeScript.addMessageListener("trackersLoaded", resolve);
chromeScript.sendAsyncMessage("loadTrackers");
});
for (let test in tests) {
await runTest(tests[test]);
}
await new Promise(resolve => {
chromeScript.addMessageListener("trackersUnloaded", resolve);
chromeScript.sendSyncMessage("unloadTrackers");
});
chromeScript.destroy();
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
runTests();
</script>
</body>
</html>

Просмотреть файл

@ -0,0 +1,106 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test the fingerprinting classifier</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<script class="testbody" type="text/javascript">
/* eslint-env mozilla/frame-script */
var tests = [
// All disabled.
{ config: [ false, false ], loadExpected: true },
// Just whitelisted.
{ config: [ false, true ], loadExpected: true },
// Just blacklisted.
{ config: [ true, false ], loadExpected: false },
// whitelist + blacklist: whitelist wins
{ config: [ true, true ], loadExpected: true },
];
function prefValue(value, what) {
return value ? what : "";
}
async function runTest(test) {
await SpecialPowers.pushPrefEnv({set: [
[ "urlclassifier.features.fingerprinting.blacklistHosts", prefValue(test.config[0], "example.com") ],
[ "urlclassifier.features.fingerprinting.whitelistHosts", prefValue(test.config[1], "mochi.test") ],
[ "urlclassifier.features.fingerprinting.blacklistTables", prefValue(test.config[0], "mochitest1-track-simple") ],
[ "urlclassifier.features.fingerprinting.whitelistTables", "" ],
[ "privacy.trackingprotection.enabled", false ],
[ "privacy.trackingprotection.annotate_channels", false ],
[ "privacy.trackingprotection.cryptomining.enabled", false ],
[ "privacy.trackingprotection.fingerprinting.enabled", true ],
]});
info("Testing: " + test.config.toSource() + "\n");
// Let's load an image with a random query string, just to avoid network cache.
let result = await new Promise(resolve => {
let image = new Image();
image.src = "http://example.com/tests/toolkit/components/url-classifier/tests/mochitest/raptor.jpg?" + Math.random();
image.onload = _ => resolve(true);
image.onerror = _ => resolve(false);
});
is(result, test.loadExpected, "The loading happened correctly");
// Let's load an image with a random query string, just to avoid network cache.
result = await new Promise(resolve => {
let image = new Image();
image.src = "http://tracking.example.org/tests/toolkit/components/url-classifier/tests/mochitest/raptor.jpg?" + Math.random();
image.onload = _ => resolve(true);
image.onerror = _ => resolve(false);
});
is(result, test.loadExpected, "The loading happened correctly (by table)");
}
async function runTests() {
let chromeScript = SpecialPowers.loadChromeScript(_ => {
ChromeUtils.import("resource://testing-common/UrlClassifierTestUtils.jsm");
addMessageListener("loadTrackers", __ => {
UrlClassifierTestUtils.addTestTrackers().then(___ => {
sendAsyncMessage("trackersLoaded");
});
});
addMessageListener("unloadTrackers", __ => {
UrlClassifierTestUtils.cleanupTestTrackers();
sendAsyncMessage("trackersUnloaded");
});
});
await new Promise(resolve => {
chromeScript.addMessageListener("trackersLoaded", resolve);
chromeScript.sendAsyncMessage("loadTrackers");
});
for (let test in tests) {
await runTest(tests[test]);
}
await new Promise(resolve => {
chromeScript.addMessageListener("trackersUnloaded", resolve);
chromeScript.sendSyncMessage("unloadTrackers");
});
chromeScript.destroy();
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
runTests();
</script>
</body>
</html>

Просмотреть файл

@ -11,6 +11,7 @@ const JSLOG_PREF = "browser.safebrowsing.debug";
function unLoad() {
window.removeEventListener("unload", unLoad);
Search.uninit();
Provider.uninit();
Cache.uninit();
Debug.uninit();
@ -20,11 +21,160 @@ function onLoad() {
window.removeEventListener("load", onLoad);
window.addEventListener("unload", unLoad);
Search.init();
Provider.init();
Cache.init();
Debug.init();
}
/*
* Search
*/
var Search = {
init() {
let classifier = Cc["@mozilla.org/url-classifier/dbservice;1"]
.getService(Ci.nsIURIClassifier);
let featureNames = classifier.getFeatureNames();
let fragment = document.createDocumentFragment();
featureNames.forEach(featureName => {
let div = document.createElement("div");
fragment.appendChild(div);
let checkbox = document.createElement("input");
checkbox.id = "feature_" + featureName;
checkbox.type = "checkbox";
checkbox.checked = true;
div.appendChild(checkbox);
let label = document.createElement("label");
label.for = checkbox.id;
div.appendChild(label);
let text = document.createTextNode(featureName);
label.appendChild(text);
});
let list = document.getElementById("search-features");
list.appendChild(fragment);
let btn = document.getElementById("search-button");
btn.addEventListener("click", this.search);
this.hideError();
this.hideResults();
},
uninit() {
let list = document.getElementById("search-features");
while (list.firstChild) {
list.firstChild.remove();
}
let btn = document.getElementById("search-button");
btn.removeEventListener("click", this.search);
},
search() {
Search.hideError();
Search.hideResults();
let input = document.getElementById("search-input").value;
let uri;
try {
uri = Services.io.newURI(input);
if (!uri) {
Search.reportError("url-classifier-search-error-invalid-url");
return;
}
} catch (ex) {
Search.reportError("url-classifier-search-error-invalid-url");
return;
}
let classifier = Cc["@mozilla.org/url-classifier/dbservice;1"]
.getService(Ci.nsIURIClassifier);
let featureNames = classifier.getFeatureNames();
let features = [];
featureNames.forEach(featureName => {
if (document.getElementById("feature_" + featureName).checked) {
let feature = classifier.getFeatureByName(featureName);
if (feature) {
features.push(feature);
}
}
});
if (!features.length) {
Search.reportError("url-classifier-search-error-no-features");
return;
}
let listType = document.getElementById("search-listtype").value == 0
? Ci.nsIUrlClassifierFeature.blacklist
: Ci.nsIUrlClassifierFeature.whitelist;
classifier.asyncClassifyLocalWithFeatures(uri, features, listType,
list => Search.showResults(list));
Search.hideError();
},
hideError() {
let errorMessage = document.getElementById("search-error-message");
errorMessage.style.display = "none";
},
reportError(msg) {
let errorMessage = document.getElementById("search-error-message");
document.l10n.setAttributes(errorMessage, msg);
errorMessage.style.display = "";
},
hideResults() {
let resultTitle = document.getElementById("result-title");
resultTitle.style.display = "none";
let resultTable = document.getElementById("result-table");
resultTable.style.display = "none";
},
showResults(results) {
let fragment = document.createDocumentFragment();
results.forEach(result => {
let tr = document.createElement("tr");
fragment.appendChild(tr);
let th = document.createElement("th");
tr.appendChild(th);
th.appendChild(document.createTextNode(result.feature.name));
let td = document.createElement("td");
tr.appendChild(td);
let featureName = document.createElement("div");
document.l10n.setAttributes(featureName, "url-classifier-search-result-uri", {uri: result.uri.spec});
td.appendChild(featureName);
let list = document.createElement("div");
document.l10n.setAttributes(list, "url-classifier-search-result-list", {list: result.list});
td.appendChild(list);
});
let resultTable = document.getElementById("result-table");
while (resultTable.firstChild) {
resultTable.firstChild.remove();
}
resultTable.appendChild(fragment);
resultTable.style.display = "";
let resultTitle = document.getElementById("result-title");
resultTitle.style.display = "";
},
};
/*
* Provider
*/

Просмотреть файл

@ -18,6 +18,49 @@
<body onload="onLoad()" class="wide-container">
<h1 data-l10n-id="url-classifier-title"></h1>
<div id="search">
<h2 class="major-section" data-l10n-id="url-classifier-search-title"></h2>
<div class="options">
<table id="search-table">
<tbody>
<tr>
<th class="column" data-l10n-id="url-classifier-search-input"></th>
<td>
<input id="search-input" type="text" value=""/>
</td>
</tr>
<tr>
<th class="column" data-l10n-id="url-classifier-search-listType"></th>
<td>
<select id="search-listtype">
<option value="0">Blacklist</option>
<option value="1">Whitelist</option>
</select>
</td>
</tr>
<tr>
<th class="column" data-l10n-id="url-classifier-search-features"></th>
<td id="search-features"></td>
</tr>
<tr>
<th></th>
<td>
<button id="search-button" data-l10n-id="url-classifier-search-btn"></button>
</td>
</tr>
</tbody>
</table>
<p id="search-error-message"></p>
<h2 class="major-section" id="result-title" data-l10n-id="url-classifier-search-result-title"></h2>
<table id="result-table">
<tr>
<td>
<input id="search-input" type="text" value=""/>
</td>
</tr>
</table>
</div>
</div>
<div id="provider">
<h2 class="major-section" data-l10n-id="url-classifier-provider-title"></h2>
<table id="provider-table">

Просмотреть файл

@ -3,6 +3,16 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
url-classifier-title = URL Classifier Information
url-classifier-search-title = Search
url-classifier-search-result-title = Results
url-classifier-search-result-uri = URI: { $uri }
url-classifier-search-result-list = Table list: { $list }
url-classifier-search-input = URL
url-classifier-search-error-invalid-url = Invalid URL
url-classifier-search-error-no-features = No features selected
url-classifier-search-btn = Start searching
url-classifier-search-features = Features
url-classifier-search-listType = List type
url-classifier-provider-title = Provider
url-classifier-provider = Provider
url-classifier-provider-last-update-time = Last update time