Merge autoland to central, a=merge

MozReview-Commit-ID: L5hcbQfx0kn
This commit is contained in:
Wes Kocher 2017-03-20 17:49:18 -07:00
Родитель ee7cfd05d7 56361d2b49
Коммит 0104e2c466
117 изменённых файлов: 1512 добавлений и 579 удалений

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

@ -15,7 +15,7 @@ Cu.import("resource://gre/modules/NotificationDB.jsm");
// lazy module getters
/* global AboutHome:false, AddonWatcher:false, AppConstants: false,
/* global AboutHome:false, AddonWatcher:false,
BrowserUITelemetry:false, BrowserUsageTelemetry:false, BrowserUtils:false,
CastingApps:false, CharsetMenu:false, Color:false, ContentSearch:false,
Deprecated:false, E10SUtils:false, FormValidationHandler:false,
@ -38,7 +38,6 @@ Cu.import("resource://gre/modules/NotificationDB.jsm");
[
["AboutHome", "resource:///modules/AboutHome.jsm"],
["AddonWatcher", "resource://gre/modules/AddonWatcher.jsm"],
["AppConstants", "resource://gre/modules/AppConstants.jsm"],
["BrowserUITelemetry", "resource:///modules/BrowserUITelemetry.jsm"],
["BrowserUsageTelemetry", "resource:///modules/BrowserUsageTelemetry.jsm"],
["BrowserUtils", "resource://gre/modules/BrowserUtils.jsm"],
@ -6680,6 +6679,35 @@ function BrowserOpenSyncTabs() {
gSyncUI.openSyncedTabsPanel();
}
function ReportFalseDeceptiveSite() {
let docURI = gBrowser.selectedBrowser.documentURI;
let isPhishingPage =
docURI && docURI.spec.startsWith("about:blocked?e=deceptiveBlocked");
if (isPhishingPage) {
let mm = gBrowser.selectedBrowser.messageManager;
let onMessage = (message) => {
mm.removeMessageListener("DeceptiveBlockedDetails:Result", onMessage);
let reportUrl = gSafeBrowsing.getReportURL("PhishMistake", message.data.blockedInfo);
if (reportUrl) {
openUILinkIn(reportUrl, "tab");
} else {
let promptService = Cc["@mozilla.org/embedcomp/prompt-service;1"].
getService(Ci.nsIPromptService);
let bundle =
Services.strings.createBundle("chrome://browser/locale/safebrowsing/safebrowsing.properties");
promptService.alert(window,
bundle.GetStringFromName("errorReportFalseDeceptiveTitle"),
bundle.formatStringFromName("errorReportFalseDeceptiveMessage",
[message.data.blockedInfo.provider], 1));
}
}
mm.addMessageListener("DeceptiveBlockedDetails:Result", onMessage);
mm.sendAsyncMessage("DeceptiveBlockedDetails");
}
}
/**
* Format a URL
* eg:

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

@ -262,6 +262,35 @@ function getSerializedSecurityInfo(docShell) {
return serhelper.serializeToString(securityInfo);
}
function getSiteBlockedErrorDetails(docShell) {
let blockedInfo = {};
if (docShell.failedChannel) {
let classifiedChannel = docShell.failedChannel.
QueryInterface(Ci.nsIClassifiedChannel);
if (classifiedChannel) {
let httpChannel = docShell.failedChannel.QueryInterface(Ci.nsIHttpChannel);
let reportUri = httpChannel.URI.clone();
// Remove the query to avoid leaking sensitive data
if (reportUri instanceof Ci.nsIURL) {
reportUri.query = "";
}
blockedInfo = { list: classifiedChannel.matchedList,
provider: classifiedChannel.matchedProvider,
uri: reportUri.asciiSpec };
}
}
return blockedInfo;
}
addMessageListener("DeceptiveBlockedDetails", (message) => {
sendAsyncMessage("DeceptiveBlockedDetails:Result", {
blockedInfo: getSiteBlockedErrorDetails(docShell),
});
});
var AboutNetAndCertErrorListener = {
init(chromeGlobal) {
addMessageListener("CertErrorDetails", this);
@ -583,32 +612,13 @@ var ClickEventHandler = {
let docShell = ownerDoc.defaultView.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell);
let blockedInfo = {};
if (docShell.failedChannel) {
let classifiedChannel = docShell.failedChannel.
QueryInterface(Ci.nsIClassifiedChannel);
if (classifiedChannel) {
let httpChannel = docShell.failedChannel.QueryInterface(Ci.nsIHttpChannel);
let reportUri = httpChannel.URI.clone();
// Remove the query to avoid leaking sensitive data
if (reportUri instanceof Ci.nsIURL) {
reportUri.query = "";
}
blockedInfo = { list: classifiedChannel.matchedList,
provider: classifiedChannel.matchedProvider,
uri: reportUri.asciiSpec };
}
}
sendAsyncMessage("Browser:SiteBlockedError", {
location: ownerDoc.location.href,
reason,
elementId: targetElement.getAttribute("id"),
isTopFrame: (ownerDoc.defaultView.parent === ownerDoc.defaultView),
blockedInfo
blockedInfo: getSiteBlockedErrorDetails(docShell),
});
},

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

@ -29,7 +29,7 @@
accesskey="&safeb.palm.notdeceptive.accesskey;"
insertbefore="aboutSeparator"
observes="reportPhishingErrorBroadcaster"
oncommand="openUILinkIn(gSafeBrowsing.getReportURL('PhishMistake'), 'tab');"
oncommand="ReportFalseDeceptiveSite();"
onclick="checkForMiddleClick(this, event);"/>
</menupopup>
</overlay>

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

@ -4,39 +4,31 @@
/* eslint-env mozilla/frame-script */
var testPage = "data:text/html,<body><style>:-moz-window-inactive { background-color: red; }</style><div id='area'></div></body>";
var testPage = "data:text/html;charset=utf-8,<body><style>:-moz-window-inactive { background-color: red; }</style><div id='area'></div></body>";
var colorChangeNotifications = 0;
var otherWindow;
var browser1, browser2;
function test() {
waitForExplicitFinish();
waitForFocus(reallyRunTests);
}
add_task(function* reallyRunTests() {
function reallyRunTests() {
let tab1 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, testPage);
browser1 = tab1.linkedBrowser;
let tab1 = gBrowser.addTab();
let tab2 = gBrowser.addTab();
browser1 = gBrowser.getBrowserForTab(tab1);
browser2 = gBrowser.getBrowserForTab(tab2);
// This can't use openNewForegroundTab because if we focus tab2 now, we
// won't send a focus event during test 6, further down in this file.
let tab2 = gBrowser.addTab(testPage);
browser2 = tab2.linkedBrowser;
yield BrowserTestUtils.browserLoaded(browser2);
browser1.messageManager.loadFrameScript("data:,(" + childFunction.toString() + ")();", true);
browser2.messageManager.loadFrameScript("data:,(" + childFunction.toString() + ")();", true);
gURLBar.focus();
var loadCount = 0;
function check() {
// wait for both tabs to load
if (++loadCount != 2) {
return;
}
browser1.removeEventListener("load", check, true);
browser2.removeEventListener("load", check, true);
sendGetBackgroundRequest(true);
}
let testFinished = {};
testFinished.promise = new Promise(resolve => testFinished.resolve = resolve);
// The test performs four checks, using -moz-window-inactive on two child tabs.
// First, the initial state should be transparent. The second check is done
@ -74,7 +66,7 @@ function reallyRunTests() {
break;
case 8:
is(message.data.color, "rgba(0, 0, 0, 0)", "second window after tab switch");
finishTest();
testFinished.resolve();
break;
case 9:
ok(false, "too many color change notifications");
@ -97,16 +89,17 @@ function reallyRunTests() {
ok(message.data.ok, "Test:DeactivateEvent");
});
browser1.addEventListener("load", check, true);
browser2.addEventListener("load", check, true);
browser1.contentWindow.location = testPage;
browser2.contentWindow.location = testPage;
browser1.messageManager.loadFrameScript("data:,(" + childFunction.toString() + ")();", true);
browser2.messageManager.loadFrameScript("data:,(" + childFunction.toString() + ")();", true);
gBrowser.selectedTab = tab1;
}
// Start the test.
sendGetBackgroundRequest(true);
yield testFinished.promise;
yield BrowserTestUtils.removeTab(tab1);
yield BrowserTestUtils.removeTab(tab2);
otherWindow = null;
});
function sendGetBackgroundRequest(ifChanged) {
browser1.messageManager.sendAsyncMessage("Test:GetBackgroundColor", { ifChanged });
@ -114,19 +107,12 @@ function sendGetBackgroundRequest(ifChanged) {
}
function runOtherWindowTests() {
otherWindow = window.open("data:text/html,<body>Hi</body>", "", "chrome");
otherWindow = window.open("data:text/html;charset=utf-8,<body>Hi</body>", "", "chrome");
waitForFocus(function() {
sendGetBackgroundRequest(true);
}, otherWindow);
}
function finishTest() {
gBrowser.removeCurrentTab();
gBrowser.removeCurrentTab();
otherWindow = null;
finish();
}
function childFunction() {
let oldColor = null;

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

@ -20,7 +20,7 @@
<title>&welcomeback2.tabtitle;</title>
<link rel="stylesheet" href="chrome://global/skin/in-content/info-pages.css" type="text/css" media="all"/>
<link rel="stylesheet" href="chrome://browser/skin/aboutWelcomeBack.css" type="text/css" media="all"/>
<link rel="icon" type="image/png" href="chrome://global/skin/icons/information-16.png"/>
<link rel="icon" type="image/png" href="chrome://browser/skin/info.svg"/>
<script type="application/javascript" src="chrome://browser/content/aboutSessionRestore.js"/>
</head>

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

@ -0,0 +1,6 @@
# 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/.
errorReportFalseDeceptiveTitle=This isnt a deceptive site
errorReportFalseDeceptiveMessage=Its not possible to report this error at this time.

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

@ -54,6 +54,7 @@
locale/browser/places/moveBookmarks.dtd (%chrome/browser/places/moveBookmarks.dtd)
locale/browser/safebrowsing/phishing-afterload-warning-message.dtd (%chrome/browser/safebrowsing/phishing-afterload-warning-message.dtd)
locale/browser/safebrowsing/report-phishing.dtd (%chrome/browser/safebrowsing/report-phishing.dtd)
locale/browser/safebrowsing/safebrowsing.properties (%chrome/browser/safebrowsing/safebrowsing.properties)
locale/browser/feeds/subscribe.dtd (%chrome/browser/feeds/subscribe.dtd)
locale/browser/feeds/subscribe.properties (%chrome/browser/feeds/subscribe.properties)
locale/browser/migration/migration.dtd (%chrome/browser/migration/migration.dtd)

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

@ -7,7 +7,7 @@ body {
#message-box {
margin-top: 2em;
background: url('chrome://global/skin/icons/information-24.png') no-repeat left 4px;
background: url(chrome://browser/skin/info.svg) no-repeat left 8px;
padding-inline-start: 30px;
}

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

@ -1,9 +1,9 @@
The certificate authority and server certificates here are generated by $topsrcdir/build/pgo/genpgocert.py.
You can generate a new CA cert by running:
$objdir/_virtualenv/bin/python $topsrcdir/build/pgo/genpgocert.py --gen-ca
./mach python build/pgo/genpgocert.py --gen-ca
You can generate new server certificates by running:
$objdir/_virtualenv/bin/python $topsrcdir/build/pgo/genpgocert.py --gen-server
./mach python build/pgo/genpgocert.py --gen-server
These will place the new files in this directory where you can commit them.
These commands will modify cert8.db and key3.db. The changes to these should be committed.

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

@ -442,6 +442,21 @@ BasePrincipal::GetCsp(nsIContentSecurityPolicy** aCsp)
return NS_OK;
}
NS_IMETHODIMP
BasePrincipal::SetCsp(nsIContentSecurityPolicy* aCsp)
{
// Never destroy an existing CSP on the principal.
// This method should only be called in rare cases.
MOZ_ASSERT(!mCSP, "do not destroy an existing CSP");
if (mCSP) {
return NS_ERROR_ALREADY_INITIALIZED;
}
mCSP = aCsp;
return NS_OK;
}
NS_IMETHODIMP
BasePrincipal::EnsureCSP(nsIDOMDocument* aDocument,
nsIContentSecurityPolicy** aCSP)

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

@ -222,6 +222,7 @@ public:
NS_IMETHOD SubsumesConsideringDomainIgnoringFPD(nsIPrincipal* other, bool* _retval) final;
NS_IMETHOD CheckMayLoad(nsIURI* uri, bool report, bool allowIfInheritsPrincipal) final;
NS_IMETHOD GetCsp(nsIContentSecurityPolicy** aCsp) override;
NS_IMETHOD SetCsp(nsIContentSecurityPolicy* aCsp) override;
NS_IMETHOD EnsureCSP(nsIDOMDocument* aDocument, nsIContentSecurityPolicy** aCSP) override;
NS_IMETHOD GetPreloadCsp(nsIContentSecurityPolicy** aPreloadCSP) override;
NS_IMETHOD EnsurePreloadCSP(nsIDOMDocument* aDocument, nsIContentSecurityPolicy** aCSP) override;

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

@ -151,10 +151,11 @@ interface nsIPrincipal : nsISerializable
/**
* A Content Security Policy associated with this principal.
*
* Use this function to query the associated CSP with this principal.
* Please *only* use this function to *set* a CSP when you know exactly what you are doing.
* Most likely you want to call ensureCSP instead of setCSP.
*/
[noscript] readonly attribute nsIContentSecurityPolicy csp;
[noscript] attribute nsIContentSecurityPolicy csp;
/*
* Use this function to query a CSP associated with this principal.

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

@ -108,6 +108,20 @@ nsNullPrincipal::GetHashValue(uint32_t *aResult)
return NS_OK;
}
NS_IMETHODIMP
nsNullPrincipal::SetCsp(nsIContentSecurityPolicy* aCsp) {
// Never destroy an existing CSP on the principal.
// This method should only be called in rare cases.
MOZ_ASSERT(!mCSP, "do not destroy an existing CSP");
if (mCSP) {
return NS_ERROR_ALREADY_INITIALIZED;
}
mCSP = aCsp;
return NS_OK;
}
NS_IMETHODIMP
nsNullPrincipal::GetURI(nsIURI** aURI)
{

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

@ -45,6 +45,7 @@ public:
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) override;
NS_IMETHOD GetHashValue(uint32_t* aHashValue) override;
NS_IMETHOD SetCsp(nsIContentSecurityPolicy* aCsp) override;
NS_IMETHOD GetURI(nsIURI** aURI) override;
NS_IMETHOD GetDomain(nsIURI** aDomain) override;
NS_IMETHOD SetDomain(nsIURI* aDomain) override;

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

@ -269,10 +269,68 @@ nsScriptSecurityManager::GetChannelResultPrincipal(nsIChannel* aChannel,
nsIPrincipal** aPrincipal,
bool aIgnoreSandboxing)
{
NS_PRECONDITION(aChannel, "Must have channel!");
// Check whether we have an nsILoadInfo that says what we should do.
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo();
if (loadInfo && loadInfo->GetForceInheritPrincipalOverruleOwner()) {
NS_PRECONDITION(aChannel, "Must have channel!");
// Check whether we have an nsILoadInfo that says what we should do.
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo();
if (loadInfo && loadInfo->GetForceInheritPrincipalOverruleOwner()) {
nsCOMPtr<nsIPrincipal> principalToInherit = loadInfo->PrincipalToInherit();
if (!principalToInherit) {
principalToInherit = loadInfo->TriggeringPrincipal();
}
principalToInherit.forget(aPrincipal);
return NS_OK;
}
nsCOMPtr<nsISupports> owner;
aChannel->GetOwner(getter_AddRefs(owner));
if (owner) {
CallQueryInterface(owner, aPrincipal);
if (*aPrincipal) {
return NS_OK;
}
}
if (loadInfo) {
if (!aIgnoreSandboxing && loadInfo->GetLoadingSandboxed()) {
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(loadInfo->GetSandboxedLoadingPrincipal(aPrincipal)));
MOZ_ASSERT(*aPrincipal);
// if the new NullPrincipal (above) loads an iframe[srcdoc], we
// need to inherit an existing CSP to avoid bypasses (bug 1073952).
// We continue inheriting for nested frames with e.g., data: URLs.
if (loadInfo->GetExternalContentPolicyType() == nsIContentPolicy::TYPE_SUBDOCUMENT) {
nsCOMPtr<nsIURI> uri;
aChannel->GetURI(getter_AddRefs(uri));
nsAutoCString URISpec;
uri->GetSpec(URISpec);
bool isData = (NS_SUCCEEDED(uri->SchemeIs("data", &isData)) && isData);
if (URISpec.EqualsLiteral("about:srcdoc") || isData) {
nsCOMPtr<nsIPrincipal> principalToInherit = loadInfo->PrincipalToInherit();
if (!principalToInherit) {
principalToInherit = loadInfo->TriggeringPrincipal();
}
nsCOMPtr<nsIContentSecurityPolicy> originalCsp;
principalToInherit->GetCsp(getter_AddRefs(originalCsp));
// if the principalToInherit had a CSP,
// add it to the newly created NullPrincipal.
if (originalCsp) {
nsresult rv = (*aPrincipal)->SetCsp(originalCsp);
NS_ENSURE_SUCCESS(rv, rv);
}
}
}
return NS_OK;
}
bool forceInherit = loadInfo->GetForceInheritPrincipal();
if (aIgnoreSandboxing && !forceInherit) {
// Check if SEC_FORCE_INHERIT_PRINCIPAL was dropped because of
// sandboxing:
if (loadInfo->GetLoadingSandboxed() &&
loadInfo->GetForceInheritPrincipalDropped()) {
forceInherit = true;
}
}
if (forceInherit) {
nsCOMPtr<nsIPrincipal> principalToInherit = loadInfo->PrincipalToInherit();
if (!principalToInherit) {
principalToInherit = loadInfo->TriggeringPrincipal();
@ -281,67 +339,33 @@ nsScriptSecurityManager::GetChannelResultPrincipal(nsIChannel* aChannel,
return NS_OK;
}
nsCOMPtr<nsISupports> owner;
aChannel->GetOwner(getter_AddRefs(owner));
if (owner) {
CallQueryInterface(owner, aPrincipal);
if (*aPrincipal) {
return NS_OK;
}
nsSecurityFlags securityFlags = loadInfo->GetSecurityMode();
// The data: inheritance flags should only apply to the initial load,
// not to loads that it might have redirected to.
if (loadInfo->RedirectChain().IsEmpty() &&
(securityFlags == nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS ||
securityFlags == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS ||
securityFlags == nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS)) {
nsCOMPtr<nsIURI> uri;
nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPrincipal> principalToInherit = loadInfo->PrincipalToInherit();
if (!principalToInherit) {
principalToInherit = loadInfo->TriggeringPrincipal();
}
bool inheritForAboutBlank = loadInfo->GetAboutBlankInherits();
if (nsContentUtils::ChannelShouldInheritPrincipal(principalToInherit,
uri,
inheritForAboutBlank,
false)) {
principalToInherit.forget(aPrincipal);
return NS_OK;
}
}
if (loadInfo) {
if (!aIgnoreSandboxing && loadInfo->GetLoadingSandboxed()) {
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(loadInfo->GetSandboxedLoadingPrincipal(aPrincipal)));
MOZ_ASSERT(*aPrincipal);
return NS_OK;
}
bool forceInherit = loadInfo->GetForceInheritPrincipal();
if (aIgnoreSandboxing && !forceInherit) {
// Check if SEC_FORCE_INHERIT_PRINCIPAL was dropped because of
// sandboxing:
if (loadInfo->GetLoadingSandboxed() &&
loadInfo->GetForceInheritPrincipalDropped()) {
forceInherit = true;
}
}
if (forceInherit) {
nsCOMPtr<nsIPrincipal> principalToInherit = loadInfo->PrincipalToInherit();
if (!principalToInherit) {
principalToInherit = loadInfo->TriggeringPrincipal();
}
principalToInherit.forget(aPrincipal);
return NS_OK;
}
nsSecurityFlags securityFlags = loadInfo->GetSecurityMode();
// The data: inheritance flags should only apply to the initial load,
// not to loads that it might have redirected to.
if (loadInfo->RedirectChain().IsEmpty() &&
(securityFlags == nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS ||
securityFlags == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS ||
securityFlags == nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS)) {
nsCOMPtr<nsIURI> uri;
nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPrincipal> principalToInherit = loadInfo->PrincipalToInherit();
if (!principalToInherit) {
principalToInherit = loadInfo->TriggeringPrincipal();
}
bool inheritForAboutBlank = loadInfo->GetAboutBlankInherits();
if (nsContentUtils::ChannelShouldInheritPrincipal(principalToInherit,
uri,
inheritForAboutBlank,
false)) {
principalToInherit.forget(aPrincipal);
return NS_OK;
}
}
}
return GetChannelURIPrincipal(aChannel, aPrincipal);
}
return GetChannelURIPrincipal(aChannel, aPrincipal);
}
/* The principal of the URI that this channel is loading. This is never

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

@ -57,7 +57,7 @@ nsSystemPrincipal::GetHashValue(uint32_t *result)
return NS_OK;
}
NS_IMETHODIMP
NS_IMETHODIMP
nsSystemPrincipal::GetURI(nsIURI** aURI)
{
*aURI = nullptr;
@ -78,6 +78,15 @@ nsSystemPrincipal::GetCsp(nsIContentSecurityPolicy** aCsp)
return NS_OK;
}
NS_IMETHODIMP
nsSystemPrincipal::SetCsp(nsIContentSecurityPolicy* aCsp)
{
// Never destroy an existing CSP on the principal.
// This method should only be called in rare cases.
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsSystemPrincipal::EnsureCSP(nsIDOMDocument* aDocument,
nsIContentSecurityPolicy** aCSP)

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

@ -37,6 +37,7 @@ public:
NS_IMETHOD GetDomain(nsIURI** aDomain) override;
NS_IMETHOD SetDomain(nsIURI* aDomain) override;
NS_IMETHOD GetCsp(nsIContentSecurityPolicy** aCsp) override;
NS_IMETHOD SetCsp(nsIContentSecurityPolicy* aCsp) override;
NS_IMETHOD EnsureCSP(nsIDOMDocument* aDocument, nsIContentSecurityPolicy** aCSP) override;
NS_IMETHOD GetPreloadCsp(nsIContentSecurityPolicy** aPreloadCSP) override;
NS_IMETHOD EnsurePreloadCSP(nsIDOMDocument* aDocument, nsIContentSecurityPolicy** aCSP) override;

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

@ -34,6 +34,7 @@ ostream
set
stack
string
thread
type_traits
utility
vector

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

@ -5,12 +5,6 @@
const TAB_URL = "data:text/html,<title>foo</title>";
add_task(function* setup() {
yield SpecialPowers.pushPrefEnv({
set: [["dom.ipc.processCount", 1]]
});
});
add_task(function* () {
let { tab, document } = yield openAboutDebugging("tabs");

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

@ -4,12 +4,6 @@
"use strict";
add_task(function* setup() {
yield SpecialPowers.pushPrefEnv({
set: [["dom.ipc.processCount", 1]]
});
});
// Test that the spacebar key press toggles the toggleAll button state
// when a node with no animation is selected.
// This test doesn't need to test if animations actually pause/resume

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

@ -30,12 +30,6 @@ let checkToolbox = Task.async(function* (tab, location) {
ok(!!gDevTools.getToolbox(target), `Toolbox exists ${location}`);
});
add_task(function* setup() {
yield SpecialPowers.pushPrefEnv({
set: [["dom.ipc.processCount", 1]]
});
});
add_task(function* () {
let tab = yield addTab(TEST_URL);

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

@ -51,6 +51,7 @@
.notificationbox .messageImage {
display: inline-block;
background-size: 16px;
width: 16px;
height: 16px;
margin: 6px;
@ -59,7 +60,7 @@
/* Default icons for notifications */
.notificationbox .messageImage[data-type="info"] {
background-image: url("chrome://global/skin/icons/information-16.png");
background-image: url("chrome://global/skin/icons/info.svg");
}
.notificationbox .messageImage[data-type="warning"] {

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

@ -13,12 +13,6 @@ const TEST_DOC = "https://example.com/browser/devtools/client/webconsole/" +
"test/test_bug1092055_shouldwarn.html";
const SAMPLE_MSG = "specified a header that could not be parsed successfully.";
add_task(function* setup() {
yield SpecialPowers.pushPrefEnv({
set: [["dom.ipc.processCount", 1]]
});
});
add_task(function* () {
let { browser } = yield loadTab(TEST_URI);

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

@ -9,10 +9,6 @@ const TEST_URI = "data:text/html;charset=utf-8,Web Console test for splitting";
function test() {
waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [["dom.ipc.processCount", 1]]}, runTest);
}
function runTest() {
// Test is slow on Linux EC2 instances - Bug 962931
requestLongerTimeout(2);

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

@ -4,12 +4,6 @@
"use strict";
add_task(function* setup() {
yield SpecialPowers.pushPrefEnv({
set: [["dom.ipc.processCount", 1]]
});
});
// Check that the duration, iterationCount and delay are retrieved correctly for
// multiple animations.

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

@ -4406,7 +4406,8 @@ nsDocument::LoadAdditionalStyleSheet(additionalSheetType aType,
return NS_ERROR_INVALID_ARG;
// Loading the sheet sync.
RefPtr<css::Loader> loader = new css::Loader(GetStyleBackendType());
RefPtr<css::Loader> loader =
new css::Loader(GetStyleBackendType(), GetDocGroup());
css::SheetParsingMode parsingMode;
switch (aType) {

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

@ -12,7 +12,7 @@
namespace mozilla {
#define NS_EVENT_STATE_HIGHEST_SERVO_BIT 12
#define NS_EVENT_STATE_HIGHEST_SERVO_BIT 19
/**
* EventStates is the class used to represent the event states of nsIContent
@ -223,6 +223,21 @@ private:
#define NS_EVENT_STATE_INVALID NS_DEFINE_EVENT_STATE_MACRO(11)
// UI friendly version of :valid pseudo-class.
#define NS_EVENT_STATE_MOZ_UI_VALID NS_DEFINE_EVENT_STATE_MACRO(12)
// Content could not be rendered (image/object/etc).
#define NS_EVENT_STATE_BROKEN NS_DEFINE_EVENT_STATE_MACRO(13)
// Content disabled by the user (images turned off, say).
#define NS_EVENT_STATE_USERDISABLED NS_DEFINE_EVENT_STATE_MACRO(14)
// Content suppressed by the user (ad blocking, etc).
#define NS_EVENT_STATE_SUPPRESSED NS_DEFINE_EVENT_STATE_MACRO(15)
// Content is still loading such that there is nothing to show the
// user (eg an image which hasn't started coming in yet).
#define NS_EVENT_STATE_LOADING NS_DEFINE_EVENT_STATE_MACRO(16)
// Handler for the content has been blocked.
#define NS_EVENT_STATE_HANDLER_BLOCKED NS_DEFINE_EVENT_STATE_MACRO(17)
// Handler for the content has been disabled.
#define NS_EVENT_STATE_HANDLER_DISABLED NS_DEFINE_EVENT_STATE_MACRO(18)
// Handler for the content has crashed
#define NS_EVENT_STATE_HANDLER_CRASHED NS_DEFINE_EVENT_STATE_MACRO(19)
/*
* Bits below here do not have Servo-related ordering constraints.
@ -232,42 +247,27 @@ private:
*/
// Drag is hovering over content.
#define NS_EVENT_STATE_DRAGOVER NS_DEFINE_EVENT_STATE_MACRO(13)
#define NS_EVENT_STATE_DRAGOVER NS_DEFINE_EVENT_STATE_MACRO(20)
// Content is required.
#define NS_EVENT_STATE_REQUIRED NS_DEFINE_EVENT_STATE_MACRO(14)
#define NS_EVENT_STATE_REQUIRED NS_DEFINE_EVENT_STATE_MACRO(21)
// Content is optional (and can be required).
#define NS_EVENT_STATE_OPTIONAL NS_DEFINE_EVENT_STATE_MACRO(15)
#define NS_EVENT_STATE_OPTIONAL NS_DEFINE_EVENT_STATE_MACRO(22)
// Link has been visited.
#define NS_EVENT_STATE_VISITED NS_DEFINE_EVENT_STATE_MACRO(16)
#define NS_EVENT_STATE_VISITED NS_DEFINE_EVENT_STATE_MACRO(23)
// Link hasn't been visited.
#define NS_EVENT_STATE_UNVISITED NS_DEFINE_EVENT_STATE_MACRO(17)
#define NS_EVENT_STATE_UNVISITED NS_DEFINE_EVENT_STATE_MACRO(24)
// Content value is in-range (and can be out-of-range).
#define NS_EVENT_STATE_INRANGE NS_DEFINE_EVENT_STATE_MACRO(18)
#define NS_EVENT_STATE_INRANGE NS_DEFINE_EVENT_STATE_MACRO(25)
// Content value is out-of-range.
#define NS_EVENT_STATE_OUTOFRANGE NS_DEFINE_EVENT_STATE_MACRO(19)
#define NS_EVENT_STATE_OUTOFRANGE NS_DEFINE_EVENT_STATE_MACRO(26)
// These two are temporary (see bug 302188)
// Content is read-only.
#define NS_EVENT_STATE_MOZ_READONLY NS_DEFINE_EVENT_STATE_MACRO(20)
#define NS_EVENT_STATE_MOZ_READONLY NS_DEFINE_EVENT_STATE_MACRO(27)
// Content is editable.
#define NS_EVENT_STATE_MOZ_READWRITE NS_DEFINE_EVENT_STATE_MACRO(21)
#define NS_EVENT_STATE_MOZ_READWRITE NS_DEFINE_EVENT_STATE_MACRO(28)
// Content is the default one (meaning depends of the context).
#define NS_EVENT_STATE_DEFAULT NS_DEFINE_EVENT_STATE_MACRO(22)
// Content could not be rendered (image/object/etc).
#define NS_EVENT_STATE_BROKEN NS_DEFINE_EVENT_STATE_MACRO(23)
// Content disabled by the user (images turned off, say).
#define NS_EVENT_STATE_USERDISABLED NS_DEFINE_EVENT_STATE_MACRO(24)
// Content suppressed by the user (ad blocking, etc).
#define NS_EVENT_STATE_SUPPRESSED NS_DEFINE_EVENT_STATE_MACRO(25)
// Content is still loading such that there is nothing to show the
// user (eg an image which hasn't started coming in yet).
#define NS_EVENT_STATE_LOADING NS_DEFINE_EVENT_STATE_MACRO(26)
#define NS_EVENT_STATE_INCREMENT_SCRIPT_LEVEL NS_DEFINE_EVENT_STATE_MACRO(27)
// Handler for the content has been blocked.
#define NS_EVENT_STATE_HANDLER_BLOCKED NS_DEFINE_EVENT_STATE_MACRO(28)
// Handler for the content has been disabled.
#define NS_EVENT_STATE_HANDLER_DISABLED NS_DEFINE_EVENT_STATE_MACRO(29)
// Handler for the content has crashed
#define NS_EVENT_STATE_HANDLER_CRASHED NS_DEFINE_EVENT_STATE_MACRO(30)
#define NS_EVENT_STATE_DEFAULT NS_DEFINE_EVENT_STATE_MACRO(29)
#define NS_EVENT_STATE_INCREMENT_SCRIPT_LEVEL NS_DEFINE_EVENT_STATE_MACRO(30)
// Content has focus and should show a ring.
#define NS_EVENT_STATE_FOCUSRING NS_DEFINE_EVENT_STATE_MACRO(31)
// Content is a submit control and the form isn't valid.

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

@ -0,0 +1,11 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Bug 1073952 - CSP should restrict scripts in srcdoc iframe even if sandboxed</title>
</head>
<body>
<iframe srcdoc="<img src=x onerror='parent.postMessage({result: `unexpected-csp-violation`}, `*`);'>"
sandbox="allow-scripts"></iframe>
</body>
</html>

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

@ -0,0 +1 @@
content-security-policy: default-src *;

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

@ -0,0 +1,79 @@
// Custom *.sjs file specifically for the needs of
// https://bugzilla.mozilla.org/show_bug.cgi?id=1073952
"use strict";
Components.utils.importGlobalProperties(["URLSearchParams"]);
const SCRIPT = `
<script>
parent.parent.postMessage({result: &quot;allowed&quot;}, &quot;*&quot;);
</script>`;
const SIMPLE_IFRAME_SRCDOC = `
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"></head>
<body>
<iframe sandbox="allow-scripts" srcdoc="` + SCRIPT + `"></iframe>
</body>
</html>`;
const INNER_SRCDOC_IFRAME = `
<iframe sandbox='allow-scripts' srcdoc='<script>
parent.parent.parent.postMessage({result: &quot;allowed&quot;}, &quot;*&quot;);
</script>'>
</iframe>`;
const NESTED_IFRAME_SRCDOC = `
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"></head>
<body>
<iframe sandbox="allow-scripts" srcdoc="` + INNER_SRCDOC_IFRAME + `"></iframe>
</body>
</html>`;
const INNER_DATAURI_IFRAME = `
<iframe sandbox='allow-scripts' src='data:text/html,<script>
parent.parent.parent.postMessage({result: &quot;allowed&quot;}, &quot;*&quot;);
</script>'>
</iframe>`;
const NESTED_IFRAME_SRCDOC_DATAURI = `
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"></head>
<body>
<iframe sandbox="allow-scripts" srcdoc="` + INNER_DATAURI_IFRAME + `"></iframe>
</body>
</html>`;
function handleRequest(request, response) {
const query = new URLSearchParams(request.queryString);
response.setHeader("Cache-Control", "no-cache", false);
if (typeof query.get("csp") === "string") {
response.setHeader("Content-Security-Policy", query.get("csp"), false);
}
response.setHeader("Content-Type", "text/html", false);
if (query.get("action") === "simple_iframe_srcdoc") {
response.write(SIMPLE_IFRAME_SRCDOC);
return;
}
if (query.get("action") === "nested_iframe_srcdoc") {
response.write(NESTED_IFRAME_SRCDOC);
return;
}
if (query.get("action") === "nested_iframe_srcdoc_datauri") {
response.write(NESTED_IFRAME_SRCDOC_DATAURI);
return;
}
// we should never get here, but just in case
// return something unexpected
response.write("do'h");
}

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

@ -205,6 +205,9 @@ support-files =
file_upgrade_insecure_navigation.sjs
file_punycode_host_src.sjs
file_punycode_host_src.js
file_iframe_srcdoc.sjs
file_iframe_sandbox_srcdoc.html
file_iframe_sandbox_srcdoc.html^headers^
[test_base-uri.html]
[test_blob_data_schemes.html]
@ -293,3 +296,5 @@ tags = mcb
[test_strict_dynamic_default_src.html]
[test_upgrade_insecure_navigation.html]
[test_punycode_host_src.html]
[test_iframe_sandbox_srcdoc.html]
[test_iframe_srcdoc.html]

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

@ -0,0 +1,62 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Bug 1073952 - CSP should restrict scripts in srcdoc iframe even if sandboxed</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<p id="display">Bug 1073952</p>
<iframe style="width:200px;height:200px;" id='cspframe'></iframe>
<script class="testbody" type="text/javascript">
// This is used to watch the blocked data bounce off CSP and allowed data
// get sent out to the wire.
function examiner() {
SpecialPowers.addObserver(this, "csp-on-violate-policy", false);
}
examiner.prototype = {
observe: function(subject, topic, data) {
if(topic === "csp-on-violate-policy") {
var violationString = SpecialPowers.getPrivilegedProps(SpecialPowers.
do_QueryInterface(subject, "nsISupportsCString"), "data");
// the violation subject for inline script violations is unfortunately vague,
// all we can do is match the string.
if (!violationString.includes("Inline Script")) {
return
}
ok(true, "CSP inherited into sandboxed srcdoc iframe, script blocked.");
window.testFinished();
}
},
// must eventually call this to remove the listener,
// or mochitests might get borked.
remove: function() {
SpecialPowers.removeObserver(this, "csp-on-violate-policy");
}
}
window.examiner = new examiner();
function testFinished() {
window.examiner.remove();
SimpleTest.finish();
}
addEventListener("message", function(e) {
ok(false, "We should not execute JS in srcdoc iframe.");
window.testFinished();
})
SimpleTest.waitForExplicitFinish();
// save this for last so that our listeners are registered.
// ... this loads the testbed of good and bad requests.
document.getElementById('cspframe').src = 'file_iframe_sandbox_srcdoc.html';
</script>
</body>
</html>

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

@ -0,0 +1,140 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Bug 1073952 - Test CSP enforcement within iframe srcdoc</title>
<!-- Including SimpleTest.js so we can use waitForExplicitFinish !-->
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<iframe style="width:100%;" id="testframe"></iframe>
<script class="testbody" type="text/javascript">
/*
* Description of the test:
* (1) We serve a site which makes use of script-allowed sandboxed iframe srcdoc
* and make sure that CSP applies to the nested browsing context
* within the iframe.
* [PAGE WITH CSP [IFRAME SANDBOX SRCDOC [SCRIPT]]]
*
* (2) We serve a site which nests script within an script-allowed sandboxed
* iframe srcdoc within another script-allowed sandboxed iframe srcdoc and
* make sure that CSP applies to the nested browsing context
* within the iframe*s*.
* [PAGE WITH CSP [IFRAME SANDBOX SRCDOC [IFRAME SANDBOX SRCDOC [SCRIPT]]]]
*
* Please note that the test relies on the "csp-on-violate-policy" observer.
* Whenever the script within the iframe is blocked observers are notified.
* In turn, this renders the 'result' within tests[] unused. In case the script
* would execute however, the postMessageHandler would bubble up 'allowed' and
* the test would fail.
*/
SimpleTest.waitForExplicitFinish();
var tests = [
// [PAGE *WITHOUT* CSP [IFRAME SRCDOC [SCRIPT]]]
{ csp: "",
result: "allowed",
query: "simple_iframe_srcdoc",
desc: "No CSP should run script within script-allowed sandboxed iframe srcdoc"
},
{ csp: "script-src https://test1.com",
result: "blocked",
query: "simple_iframe_srcdoc",
desc: "CSP should block script within script-allowed sandboxediframe srcdoc"
},
// [PAGE *WITHOUT* CSP [IFRAME SRCDOC [IFRAME SRCDOC [SCRIPT]]]]
{ csp: "",
result: "allowed",
query: "nested_iframe_srcdoc",
desc: "No CSP should run script within script-allowed sandboxed iframe srcdoc nested within another script-allowed sandboxed iframe srcdoc"
},
// [PAGE WITH CSP [IFRAME SRCDOC ]]
{ csp: "script-src https://test2.com",
result: "blocked",
query: "nested_iframe_srcdoc",
desc: "CSP should block script within script-allowed sandboxed iframe srcdoc nested within another script-allowed sandboxed iframe srcdoc"
},
{ csp: "",
result: "allowed",
query: "nested_iframe_srcdoc_datauri",
desc: "No CSP, should run script within script-allowed sandboxed iframe src with data URL nested within another script-allowed sandboxed iframe srcdoc"
},
{ csp: "script-src https://test3.com",
result: "blocked",
query: "nested_iframe_srcdoc_datauri",
desc: "CSP should block script within script-allowed sandboxed iframe src with data URL nested within another script-allowed sandboxed iframe srcdoc"
},
];
// initializing to -1 so we start at index 0 when we start the test
var counter = -1;
function finishTest() {
window.removeEventListener("message", receiveMessage, false);
window.examiner.remove();
SimpleTest.finish();
}
window.addEventListener("message", receiveMessage, false);
function receiveMessage(event) {
var result = event.data.result;
testComplete(result, tests[counter].result, tests[counter].desc);
}
function examiner() {
SpecialPowers.addObserver(this, "csp-on-violate-policy", false);
}
examiner.prototype = {
observe: function(subject, topic, data) {
if (topic === "csp-on-violate-policy") {
var violationString = SpecialPowers.getPrivilegedProps(SpecialPowers.
do_QueryInterface(subject, "nsISupportsCString"), "data");
// the violation subject for inline script violations is unfortunately vague,
// all we can do is match the string.
if (!violationString.includes("Inline Script")) {
return
}
testComplete("blocked", tests[counter].result, tests[counter].desc);
}
},
remove: function() {
SpecialPowers.removeObserver(this, "csp-on-violate-policy");
}
}
function testComplete(result, expected, desc) {
is(result, expected, desc);
// ignore cases when we get csp violations and postMessage from the same frame.
var frameURL = new URL(document.getElementById("testframe").src);
var params = new URLSearchParams(frameURL.search);
var counterInFrame = params.get("counter");
if (counterInFrame == counter) {
loadNextTest();
}
}
function loadNextTest() {
counter++;
if (counter == tests.length) {
finishTest();
return;
}
var src = "file_iframe_srcdoc.sjs";
src += "?csp=" + escape(tests[counter].csp);
src += "&action=" + escape(tests[counter].query);
src += "&counter=" + counter;
document.getElementById("testframe").src = src;
}
// start running the tests
window.examiner = new examiner();
loadNextTest();
</script>
</body>
</html>

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

@ -0,0 +1,77 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width; initial-scale=1.0">
<title>Dragging the scrollbar on a page with a fixed-positioned element just past the right edge of the content</title>
<script type="application/javascript" src="apz_test_native_event_utils.js"></script>
<script type="application/javascript" src="apz_test_utils.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
<style>
body {
height: 2000px;
}
#fixed {
width: 240px;
height: 100%;
position: fixed;
top: 0px;
right: -240px;
z-index: 1000;
overflow-y: scroll;
}
#fixed-content {
height: 2000px;
}
</style>
<script type="text/javascript">
var root;
var scrollPos;
var haveScrolled = false;
var generatedAll = false;
// Be careful not to call subtestDone() until we've scrolled AND generated
// all of the events.
function maybeDone() {
if (haveScrolled && generatedAll) {
subtestDone();
}
}
function scrolled(e) {
// Test that we have scrolled
ok(root.scrollTop > scrollPos, "document scrolled after dragging scrollbar");
haveScrolled = true;
maybeDone();
}
function* test(testDriver) {
root = document.scrollingElement;
scrollPos = root.scrollTop;
document.addEventListener('scroll', scrolled);
var scrollbarX = (window.innerWidth + root.clientWidth) / 2;
// Move the mouse to the scrollbar
yield synthesizeNativeMouseEvent(root, scrollbarX, 100, nativeMouseMoveEventMsg(), testDriver);
// mouse down
yield synthesizeNativeMouseEvent(root, scrollbarX, 100, nativeMouseDownEventMsg(), testDriver);
// drag vertically
yield synthesizeNativeMouseEvent(root, scrollbarX, 150, nativeMouseMoveEventMsg(), testDriver);
// and release
yield synthesizeNativeMouseEvent(root, scrollbarX, 150, nativeMouseUpEventMsg(), testDriver);
generatedAll = true;
maybeDone();
}
waitUntilApzStable()
.then(runContinuation(test));
</script>
</head>
<body>
<div id="fixed">
<p id="fixed-content"></p>
</div>
</body>
</html>

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

@ -10,6 +10,7 @@
helper_bug1280013.html
helper_bug1285070.html
helper_bug1299195.html
helper_bug1346632.html
helper_click.html
helper_div_pan.html
helper_drag_click.html

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

@ -17,7 +17,9 @@ var subtests = [
// Sanity test for click but with some mouse movement between the down and up
{'file': 'helper_drag_click.html'},
// Test for dragging on a fake-scrollbar element that scrolls the page
{'file': 'helper_drag_scroll.html'}
{'file': 'helper_drag_scroll.html'},
// Test for dragging the scrollbar with a fixed-pos element overlaying it
{'file': 'helper_bug1346632.html'}
];
if (isApzEnabled()) {

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

@ -628,8 +628,15 @@ PrepareForSetTargetAPZCNotification(nsIWidget* aWidget,
ScrollableLayerGuid guid(aGuid.mLayersId, 0, FrameMetrics::NULL_SCROLL_ID);
nsPoint point =
nsLayoutUtils::GetEventCoordinatesRelativeTo(aWidget, aRefPoint, aRootFrame);
uint32_t flags = 0;
#ifdef MOZ_WIDGET_ANDROID
// On Android, we need IGNORE_ROOT_SCROLL_FRAME for correct hit testing
// when zoomed out. On desktop, don't use it because it interferes with
// hit testing for some purposes such as scrollbar dragging.
flags = nsLayoutUtils::IGNORE_ROOT_SCROLL_FRAME;
#endif
nsIFrame* target =
nsLayoutUtils::GetFrameForPoint(aRootFrame, point, nsLayoutUtils::IGNORE_ROOT_SCROLL_FRAME);
nsLayoutUtils::GetFrameForPoint(aRootFrame, point, flags);
nsIScrollableFrame* scrollAncestor = target
? nsLayoutUtils::GetAsyncScrollableAncestorFrame(target)
: aRootFrame->PresContext()->PresShell()->GetRootScrollFrameAsScrollable();

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

@ -74,6 +74,7 @@ APZThreadUtils::IsControllerThread()
}
NS_IMPL_ISUPPORTS(GenericTimerCallbackBase, nsITimerCallback)
NS_IMPL_ISUPPORTS(GenericNamedTimerCallbackBase, nsITimerCallback, nsINamed)
} // namespace layers
} // namespace mozilla

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

@ -7,6 +7,7 @@
#define mozilla_layers_APZThreadUtils_h
#include "base/message_loop.h"
#include "nsINamed.h"
#include "nsITimer.h"
namespace mozilla {
@ -98,6 +99,68 @@ GenericTimerCallback<Function>* NewTimerCallback(const Function& aFunction)
return new GenericTimerCallback<Function>(aFunction);
}
// A base class for GenericNamedTimerCallback<Function>.
// This is necessary because NS_IMPL_ISUPPORTS doesn't work for a class
// template.
class GenericNamedTimerCallbackBase : public nsITimerCallback,
public nsINamed
{
public:
NS_DECL_THREADSAFE_ISUPPORTS
protected:
virtual ~GenericNamedTimerCallbackBase() {}
};
// An nsITimerCallback implementation with nsINamed that can be used with any
// function object that's callable with no arguments.
template <typename Function>
class GenericNamedTimerCallback final : public GenericNamedTimerCallbackBase
{
public:
explicit GenericNamedTimerCallback(const Function& aFunction,
const char* aName)
: mFunction(aFunction)
, mName(aName)
{
}
NS_IMETHOD Notify(nsITimer*) override
{
mFunction();
return NS_OK;
}
NS_IMETHOD GetName(nsACString& aName) override
{
aName = mName;
return NS_OK;
}
NS_IMETHOD SetName(const char * aName) override
{
mName.Assign(aName);
return NS_OK;
}
private:
Function mFunction;
nsCString mName;
};
// Convenience function for constructing a GenericNamedTimerCallback.
// Returns a raw pointer, suitable for passing directly as an argument to
// nsITimer::InitWithCallback(). The intention is to enable the following
// terse inline usage:
// timer->InitWithCallback(NewNamedTimerCallback([](){ ... }, name), delay);
template <typename Function>
GenericNamedTimerCallback<Function>*
NewNamedTimerCallback(const Function& aFunction,
const char* aName)
{
return new GenericNamedTimerCallback<Function>(aFunction, aName);
}
} // namespace layers
} // namespace mozilla

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

@ -98,6 +98,7 @@ static pfn_ovr_GetFloatArray ovr_GetFloatArray = nullptr;
static pfn_ovr_SetFloatArray ovr_SetFloatArray = nullptr;
static pfn_ovr_GetString ovr_GetString = nullptr;
static pfn_ovr_SetString ovr_SetString = nullptr;
static pfn_ovr_GetBoundaryDimensions ovr_GetBoundaryDimensions = nullptr;
#ifdef XP_WIN
static pfn_ovr_CreateTextureSwapChainDX ovr_CreateTextureSwapChainDX = nullptr;
@ -286,6 +287,7 @@ InitializeOculusCAPI()
REQUIRE_FUNCTION(ovr_SetFloatArray);
REQUIRE_FUNCTION(ovr_GetString);
REQUIRE_FUNCTION(ovr_SetString);
REQUIRE_FUNCTION(ovr_GetBoundaryDimensions);
#ifdef XP_WIN
@ -356,6 +358,7 @@ VRDisplayOculus::VRDisplayOculus(ovrSession aSession)
, mVertexBuffer(nullptr)
, mInputLayout(nullptr)
, mIsPresenting(false)
, mEyeHeight(OVR_DEFAULT_EYE_HEIGHT)
{
MOZ_COUNT_CTOR_INHERITED(VRDisplayOculus, VRDisplayHost);
@ -373,6 +376,7 @@ VRDisplayOculus::VRDisplayOculus(ovrSession aSession)
if (mDesc.AvailableTrackingCaps & ovrTrackingCap_Position) {
mDisplayInfo.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_Position;
mDisplayInfo.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_LinearAcceleration;
mDisplayInfo.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_StageParameters;
}
mDisplayInfo.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_External;
mDisplayInfo.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_MountDetection;
@ -401,6 +405,8 @@ VRDisplayOculus::VRDisplayOculus(ovrSession aSession)
// take the max of both for eye resolution
mDisplayInfo.mEyeResolution.width = std::max(texSize[VRDisplayInfo::Eye_Left].w, texSize[VRDisplayInfo::Eye_Right].w);
mDisplayInfo.mEyeResolution.height = std::max(texSize[VRDisplayInfo::Eye_Left].h, texSize[VRDisplayInfo::Eye_Right].h);
UpdateStageParameters();
}
VRDisplayOculus::~VRDisplayOculus() {
@ -418,10 +424,49 @@ VRDisplayOculus::Destroy()
}
}
void
VRDisplayOculus::UpdateStageParameters()
{
ovrVector3f playArea;
ovrResult res = ovr_GetBoundaryDimensions(mSession, ovrBoundary_PlayArea, &playArea);
if (res == ovrSuccess) {
mDisplayInfo.mStageSize.width = playArea.x;
mDisplayInfo.mStageSize.height = playArea.z;
} else {
// If we fail, fall back to reasonable defaults.
// 1m x 1m space
mDisplayInfo.mStageSize.width = 1.0f;
mDisplayInfo.mStageSize.height = 1.0f;
}
mEyeHeight = ovr_GetFloat(mSession, OVR_KEY_EYE_HEIGHT, OVR_DEFAULT_EYE_HEIGHT);
mDisplayInfo.mSittingToStandingTransform._11 = 1.0f;
mDisplayInfo.mSittingToStandingTransform._12 = 0.0f;
mDisplayInfo.mSittingToStandingTransform._13 = 0.0f;
mDisplayInfo.mSittingToStandingTransform._14 = 0.0f;
mDisplayInfo.mSittingToStandingTransform._21 = 0.0f;
mDisplayInfo.mSittingToStandingTransform._22 = 1.0f;
mDisplayInfo.mSittingToStandingTransform._23 = 0.0f;
mDisplayInfo.mSittingToStandingTransform._24 = 0.0f;
mDisplayInfo.mSittingToStandingTransform._31 = 0.0f;
mDisplayInfo.mSittingToStandingTransform._32 = 0.0f;
mDisplayInfo.mSittingToStandingTransform._33 = 1.0f;
mDisplayInfo.mSittingToStandingTransform._34 = 0.0f;
mDisplayInfo.mSittingToStandingTransform._41 = 0.0f;
mDisplayInfo.mSittingToStandingTransform._42 = mEyeHeight;
mDisplayInfo.mSittingToStandingTransform._43 = 0.0f;
mDisplayInfo.mSittingToStandingTransform._44 = 1.0f;
}
void
VRDisplayOculus::ZeroSensor()
{
ovr_RecenterTrackingOrigin(mSession);
UpdateStageParameters();
}
VRHMDSensorState
@ -440,6 +485,7 @@ VRDisplayOculus::GetSensorState()
result = GetSensorState(frameDelta);
result.inputFrameID = mInputFrameID;
mLastSensorState[result.inputFrameID % kMaxLatencyFrames] = result;
result.position[1] -= mEyeHeight;
return result;
}
@ -988,6 +1034,11 @@ VRSystemManagerOculus::GetHMDs(nsTArray<RefPtr<VRDisplayHost>>& aHMDResult)
ovrResult orv = ovr_Create(&session, &luid);
if (orv == ovrSuccess) {
mSession = session;
orv = ovr_SetTrackingOriginType(session, ovrTrackingOrigin_FloorLevel);
if (orv != ovrSuccess) {
NS_WARNING("ovr_SetTrackingOriginType failed.\n");
}
mHMDInfo = new VRDisplayOculus(session);
}
}
@ -1099,6 +1150,9 @@ VRSystemManagerOculus::HandleInput()
poseState.linearAcceleration[0] = pose.LinearAcceleration.x;
poseState.linearAcceleration[1] = pose.LinearAcceleration.y;
poseState.linearAcceleration[2] = pose.LinearAcceleration.z;
float eyeHeight = ovr_GetFloat(mSession, OVR_KEY_EYE_HEIGHT, OVR_DEFAULT_EYE_HEIGHT);
poseState.position[1] -= eyeHeight;
}
HandlePoseTracking(i, poseState, controller);
}

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

@ -48,6 +48,7 @@ protected:
const VRHMDSensorState& aSensorState,
const gfx::Rect& aLeftEyeRect,
const gfx::Rect& aRightEyeRect) override;
void UpdateStageParameters();
public:
explicit VRDisplayOculus(ovrSession aSession);
@ -82,7 +83,8 @@ protected:
RefPtr<ID3D11InputLayout> mInputLayout;
bool mIsPresenting;
float mEyeHeight;
bool UpdateConstantBuffers();
struct Vertex

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

@ -45,10 +45,6 @@ parent:
// asynchronously to children via UpdateDisplayInfo.
async RefreshDisplays();
// GetDisplays synchronously returns the VR displays that have already been
// enumerated by RefreshDisplays() but does not enumerate new ones.
sync GetDisplays() returns(VRDisplayInfo[] aDisplayInfo);
// Reset the sensor of the display identified by aDisplayID so that the current
// sensor state is the "Zero" position.
async ResetSensor(uint32_t aDisplayID);

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

@ -293,16 +293,6 @@ VRManagerChild::RecvUpdateDisplayInfo(nsTArray<VRDisplayInfo>&& aDisplayUpdates)
bool
VRManagerChild::GetVRDisplays(nsTArray<RefPtr<VRDisplayClient>>& aDisplays)
{
if (!mDisplaysInitialized) {
/**
* If we haven't received any asynchronous callback after requesting
* display enumeration with RefreshDisplays, get the existing displays
* that have already been enumerated by other VRManagerChild instances.
*/
nsTArray<VRDisplayInfo> displays;
Unused << SendGetDisplays(&displays);
UpdateDisplayInfo(displays);
}
aDisplays = mDisplays;
return true;
}

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

@ -241,14 +241,6 @@ VRManagerParent::RecvRefreshDisplays()
return IPC_OK();
}
mozilla::ipc::IPCResult
VRManagerParent::RecvGetDisplays(nsTArray<VRDisplayInfo> *aDisplays)
{
VRManager* vm = VRManager::Get();
vm->GetVRDisplayInfo(*aDisplays);
return IPC_OK();
}
mozilla::ipc::IPCResult
VRManagerParent::RecvResetSensor(const uint32_t& aDisplayID)
{

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

@ -86,7 +86,6 @@ protected:
void OnChannelConnected(int32_t pid) override;
virtual mozilla::ipc::IPCResult RecvRefreshDisplays() override;
virtual mozilla::ipc::IPCResult RecvGetDisplays(nsTArray<VRDisplayInfo> *aDisplays) override;
virtual mozilla::ipc::IPCResult RecvResetSensor(const uint32_t& aDisplayID) override;
virtual mozilla::ipc::IPCResult RecvGetSensorState(const uint32_t& aDisplayID, VRHMDSensorState* aState) override;
virtual mozilla::ipc::IPCResult RecvSetHaveEventListener(const bool& aHaveEventListener) override;

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

@ -567,8 +567,15 @@ typedef enum {
ovrDebugHudStereo_EnumSize = 0x7fffffff
} ovrDebugHudStereoMode;
typedef enum {
// Outer boundary - closely represents user setup walls
ovrBoundary_Outer = 0x0001,
// Play area - safe rectangular area inside outer boundary which can optionally be used to restrict user interactions and motion.
ovrBoundary_PlayArea = 0x0100,
} ovrBoundaryType;
typedef ovrBool(OVR_PFN* pfn_ovr_GetBool)(ovrSession session, const char* propertyName, ovrBool defaultVal);
typedef ovrBool(OVR_PFN* pfn_ovr_SetBool)(ovrSession session, const char* propertyName, ovrBool value);
typedef ovrBool(OVR_PFN* pfn_ovr_SetBool)(ovrSession session, const char* propertyName, ovrBool value);
typedef int (OVR_PFN* pfn_ovr_GetInt)(ovrSession session, const char* propertyName, int defaultVal);
typedef ovrBool (OVR_PFN* pfn_ovr_SetInt)(ovrSession session, const char* propertyName, int value);
typedef float (OVR_PFN* pfn_ovr_GetFloat)(ovrSession session, const char* propertyName, float defaultVal);
@ -581,8 +588,9 @@ typedef const char* (OVR_PFN* pfn_ovr_GetString)(ovrSession session, const char*
const char* defaultVal);
typedef ovrBool (OVR_PFN* pfn_ovr_SetString)(ovrSession session, const char* propertyName,
const char* value);
typedef ovrResult (OVR_PFN* pfn_ovr_GetBoundaryDimensions)(ovrSession session,
ovrBoundaryType boundaryType,
ovrVector3f* outDimensions);
typedef enum {
ovrError_MemoryAllocationFailure = -1000,
@ -714,7 +722,10 @@ typedef ovrResult (OVR_PFN* pfn_ovr_GetMirrorTextureBufferGL)(ovrSession session
ovrMirrorTexture mirrorTexture,
unsigned int* out_TexId);
#ifdef __cplusplus
#define OVR_KEY_EYE_HEIGHT "EyeHeight" // float meters
#define OVR_DEFAULT_EYE_HEIGHT 1.675f
#ifdef __cplusplus
}
#endif

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

@ -949,8 +949,6 @@ description =
description =
[PWebRenderBridge::DPGetSnapshot]
description =
[PVRManager::GetDisplays]
description =
[PVRManager::GetSensorState]
description =
[PVRManager::SetHaveEventListener]

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

@ -552,7 +552,7 @@ PrintSingleError(JSContext* cx, FILE* file, JS::ConstUTF8CharsZ toStringResult,
const char* kindPrefix = nullptr;
switch (kind) {
case PrintErrorKind::Error:
break;
MOZ_CRASH("unreachable");
case PrintErrorKind::Warning:
kindPrefix = "warning";
break;

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

@ -2294,8 +2294,8 @@ nsDocumentViewer::CreateStyleSet(nsIDocument* aDocument)
nsAutoString sheets;
elt->GetAttribute(NS_LITERAL_STRING("usechromesheets"), sheets);
if (!sheets.IsEmpty() && baseURI) {
RefPtr<mozilla::css::Loader> cssLoader =
new mozilla::css::Loader(backendType);
RefPtr<css::Loader> cssLoader =
new css::Loader(backendType, aDocument->GetDocGroup());
char *str = ToNewCString(sheets);
char *newStr = str;

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

@ -218,7 +218,7 @@ LoadSheet(nsIURI* aURI,
StyleBackendType aType,
RefPtr<StyleSheet>* aResult)
{
RefPtr<css::Loader> loader = new css::Loader(aType);
RefPtr<css::Loader> loader = new css::Loader(aType, nullptr);
return loader->LoadSheetSync(aURI, aParsingMode, true, aResult);
}

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

@ -386,10 +386,10 @@ fails == 315920-14.html 315920-14.html
== 315920-15.html 315920-15.html
fails == 315920-16.html 315920-16.html
fails == 315920-17.html 315920-17.html
== 315920-18a.html 315920-18a.html
fails == 315920-18b.html 315920-18b.html
== 315920-18c.html 315920-18c.html
== 315920-18d.html 315920-18d.html
skip-if(stylo) == 315920-18a.html 315920-18a.html # bug 1338982, which makes this timing-dependent
skip-if(stylo) == 315920-18b.html 315920-18b.html # bug 1338982, which makes this timing-dependent
skip-if(stylo) == 315920-18c.html 315920-18c.html # bug 1338982, which makes this timing-dependent
skip-if(stylo) == 315920-18d.html 315920-18d.html # bug 1338982, which makes this timing-dependent
fails == 315920-18e.html 315920-18e.html
fails == 315920-18f.html 315920-18f.html
fails == 315920-18g.html 315920-18g.html

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

@ -0,0 +1,7 @@
<!DOCTYPE html>
<style>
img {
border: 10px solid green;
}
</style>
<img src="nosuch:url">

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

@ -0,0 +1,7 @@
<!DOCTYPE html>
<style>
:-moz-broken {
border: 10px solid green;
}
</style>
<img src="nosuch:url">

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

@ -126,3 +126,5 @@ fuzzy(1,1) == image-orientation-background.html?90&flip image-orientation-r
== image-resize-percent-height.html image-resize-ref.html
== image-resize-percent-width.html image-resize-ref.html
== moz-broken-matching-1.html moz-broken-matching-1-ref.html

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

@ -988,7 +988,7 @@ CSSStyleSheet::ReparseSheet(const nsAString& aInput)
loader = mDocument->CSSLoader();
NS_ASSERTION(loader, "Document with no CSS loader!");
} else {
loader = new css::Loader(StyleBackendType::Gecko);
loader = new css::Loader(StyleBackendType::Gecko, nullptr);
}
mozAutoDocUpdate updateBatch(mDocument, UPDATE_STYLE, true);

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

@ -11,6 +11,7 @@
#include "mozilla/css/Loader.h"
#include "mozilla/Preferences.h"
#include "mozilla/Services.h"
#include "mozilla/SystemGroup.h"
#include "nsCSSScanner.h"
#include "nsIConsoleService.h"
#include "nsIDocument.h"
@ -153,7 +154,11 @@ ErrorReporter::~ErrorReporter()
// balance between performance and memory usage, so we only allow
// short-term caching.
if (sSpecCache && sSpecCache->IsInUse() && !sSpecCache->IsPending()) {
if (NS_FAILED(NS_DispatchToCurrentThread(sSpecCache))) {
nsCOMPtr<nsIRunnable> runnable(sSpecCache);
nsresult rv =
SystemGroup::Dispatch("ShortTermURISpecCache", TaskCategory::Other,
runnable.forget());
if (NS_FAILED(rv)) {
// Peform the "deferred" cleanup immediately if the dispatch fails.
sSpecCache->Run();
} else {

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

@ -104,6 +104,8 @@ FontFaceSet::FontFaceSet(nsPIDOMWindowInner* aWindow, nsIDocument* aDocument)
, mHasLoadingFontFacesIsDirty(false)
, mDelayedLoadCheck(false)
{
MOZ_ASSERT(mDocument, "We should get a valid document from the caller!");
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aWindow);
// If the pref is not set, don't create the Promise (which the page wouldn't
@ -1473,9 +1475,9 @@ FontFaceSet::OnFontFaceStatusChanged(FontFace* aFontFace)
if (!mDelayedLoadCheck) {
mDelayedLoadCheck = true;
nsCOMPtr<nsIRunnable> checkTask =
NewRunnableMethod("FontFaceSet::CheckLoadingFinishedAfterDelay",
this, &FontFaceSet::CheckLoadingFinishedAfterDelay);
NS_DispatchToMainThread(checkTask);
NewRunnableMethod(this, &FontFaceSet::CheckLoadingFinishedAfterDelay);
mDocument->Dispatch("FontFaceSet::CheckLoadingFinishedAfterDelay",
TaskCategory::Other, checkTask.forget());
}
}
}

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

@ -162,6 +162,8 @@ public:
return set ? set->GetPresContext() : nullptr;
}
nsIDocument* Document() const { return mDocument; }
// -- Web IDL --------------------------------------------------------------
IMPL_EVENT_HANDLER(loading)

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

@ -19,11 +19,12 @@
#include "mozilla/css/Loader.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/dom/DocGroup.h"
#include "mozilla/IntegerPrintfMacros.h"
#include "mozilla/LoadInfo.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/StyleSheetInlines.h"
#include "mozilla/SystemGroup.h"
#include "nsIRunnable.h"
#include "nsIUnicharStreamLoader.h"
#include "nsSyncLoadService.h"
@ -519,8 +520,9 @@ LoaderReusableStyleSheets::FindReusableStyleSheet(nsIURI* aURL,
* Loader Implementation *
*************************/
Loader::Loader(StyleBackendType aType)
Loader::Loader(StyleBackendType aType, DocGroup* aDocGroup)
: mDocument(nullptr)
, mDocGroup(aDocGroup)
, mDatasToNotifyOn(0)
, mCompatMode(eCompatibility_FullStandards)
, mStyleBackendType(Some(aType))
@ -542,6 +544,8 @@ Loader::Loader(nsIDocument* aDocument)
, mSyncCallback(false)
#endif
{
MOZ_ASSERT(mDocument, "We should get a valid document from the caller!");
// We can just use the preferred set, since there are no sheets in the
// document yet (if there are, how did they get there? _we_ load the sheets!)
// and hence the selected set makes no sense at this time.
@ -2471,13 +2475,24 @@ Loader::PostLoadEvent(nsIURI* aURI,
aObserver,
nullptr,
mDocument);
NS_ENSURE_TRUE(evt, NS_ERROR_OUT_OF_MEMORY);
if (!mPostedEvents.AppendElement(evt)) {
return NS_ERROR_OUT_OF_MEMORY;
}
nsresult rv = NS_DispatchToCurrentThread(evt);
nsresult rv;
RefPtr<SheetLoadData> runnable(evt);
if (mDocument) {
rv = mDocument->Dispatch("SheetLoadData", TaskCategory::Other,
runnable.forget());
} else if (mDocGroup) {
rv = mDocGroup->Dispatch("SheetLoadData", TaskCategory::Other,
runnable.forget());
} else {
rv = SystemGroup::Dispatch("SheetLoadData", TaskCategory::Other,
runnable.forget());
}
if (NS_FAILED(rv)) {
NS_WARNING("failed to dispatch stylesheet load event");
mPostedEvents.RemoveElement(evt);

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

@ -36,6 +36,7 @@ class nsIStyleSheetLinkingElement;
namespace mozilla {
namespace dom {
class DocGroup;
class Element;
} // namespace dom
} // namespace mozilla
@ -191,7 +192,11 @@ class Loader final {
typedef mozilla::net::ReferrerPolicy ReferrerPolicy;
public:
explicit Loader(StyleBackendType aType);
// aDocGroup is used for dispatching SheetLoadData in PostLoadEvent(). It
// can be null if you want to use this constructor, and there's no
// document when the Loader is constructed.
Loader(StyleBackendType aType, mozilla::dom::DocGroup* aDocGroup);
explicit Loader(nsIDocument*);
private:
@ -574,6 +579,8 @@ private:
// DropDocumentReference().
nsIDocument* MOZ_NON_OWNING_REF mDocument; // the document we live for
// For dispatching events via DocGroup::Dispatch() when mDocument is nullptr.
RefPtr<mozilla::dom::DocGroup> mDocGroup;
// Number of datas still waiting to be notified on if we're notifying on a
// whole bunch at once (e.g. in one of the stop methods). This is used to

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

@ -71,7 +71,7 @@ PreloadedStyleSheet::GetSheet(StyleBackendType aType, StyleSheet** aResult)
aType == StyleBackendType::Gecko ? mGecko : mServo;
if (!sheet) {
RefPtr<css::Loader> loader = new css::Loader(aType);
RefPtr<css::Loader> loader = new css::Loader(aType, nullptr);
nsresult rv = loader->LoadSheetSync(mURI, mParsingMode, true, &sheet);
NS_ENSURE_SUCCESS(rv, rv);
MOZ_ASSERT(sheet);

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

@ -41,6 +41,7 @@
#include "mozilla/ServoElementSnapshot.h"
#include "mozilla/ServoRestyleManager.h"
#include "mozilla/StyleAnimationValue.h"
#include "mozilla/SystemGroup.h"
#include "mozilla/DeclarationBlockInlines.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/ElementInlines.h"
@ -344,7 +345,8 @@ Gecko_DropElementSnapshot(ServoElementSnapshotOwned aSnapshot)
// descendants of a new display:none root).
if (MOZ_UNLIKELY(!NS_IsMainThread())) {
nsCOMPtr<nsIRunnable> task = NS_NewRunnableFunction([=]() { delete aSnapshot; });
NS_DispatchToMainThread(task.forget());
SystemGroup::Dispatch("Gecko_DropElementSnapshot", TaskCategory::Other,
task.forget());
} else {
delete aSnapshot;
}

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

@ -3057,7 +3057,9 @@ css::ImageValue::Initialize(nsIDocument* aDocument)
css::ImageValue::~ImageValue()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(NS_IsMainThread() || mRequests.Count() == 0,
"Destructor should run on main thread, or on non-main thread "
"when mRequest is empty!");
for (auto iter = mRequests.Iter(); !iter.Done(); iter.Next()) {
nsIDocument* doc = iter.Key();

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

@ -11,8 +11,6 @@
#include "nsFontFaceLoader.h"
#include "mozilla/Logging.h"
#include "nsError.h"
#include "nsContentUtils.h"
#include "mozilla/Preferences.h"
@ -55,6 +53,8 @@ nsFontFaceLoader::nsFontFaceLoader(gfxUserFontEntry* aUserFontEntry,
mFontFaceSet(aFontFaceSet),
mChannel(aChannel)
{
MOZ_ASSERT(mFontFaceSet,
"We should get a valid FontFaceSet from the caller!");
mStartTime = TimeStamp::Now();
}
@ -87,10 +87,13 @@ nsFontFaceLoader::StartedLoading(nsIStreamLoader* aStreamLoader)
if (loadTimeout > 0) {
mLoadTimer = do_CreateInstance("@mozilla.org/timer;1");
if (mLoadTimer) {
mLoadTimer->InitWithFuncCallback(LoadTimerCallback,
static_cast<void*>(this),
loadTimeout,
nsITimer::TYPE_ONE_SHOT);
mLoadTimer->SetTarget(
mFontFaceSet->Document()->EventTargetFor(TaskCategory::Other));
mLoadTimer->InitWithNamedFuncCallback(LoadTimerCallback,
static_cast<void*>(this),
loadTimeout,
nsITimer::TYPE_ONE_SHOT,
"LoadTimerCallback");
}
} else {
mUserFontEntry->mFontDataLoadingState = gfxUserFontEntry::LOADING_SLOWLY;

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

@ -773,7 +773,7 @@ nsLayoutStylesheetCache::LoadSheet(nsIURI* aURI,
gCSSLoader_Servo;
if (!loader) {
loader = new mozilla::css::Loader(mBackendType);
loader = new Loader(mBackendType, nullptr);
if (!loader) {
ErrorLoadingSheet(aURI, "no Loader", eCrash);
return;

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

@ -33,6 +33,7 @@
#include "CounterStyleManager.h"
#include "mozilla/dom/AnimationEffectReadOnlyBinding.h" // for PlaybackDirection
#include "mozilla/dom/DocGroup.h"
#include "mozilla/dom/ImageTracker.h"
#include "mozilla/Likely.h"
#include "nsIURI.h"
@ -1890,7 +1891,7 @@ nsStyleGradient::HasCalc()
/**
* Runnable to release the nsStyleImageRequest's mRequestProxy,
* mImageValue and mImageValue on the main thread, and to perform
* mImageValue and mImageTracker on the main thread, and to perform
* any necessary unlocking and untracking of the image.
*/
class StyleImageRequestCleanupTask : public mozilla::Runnable
@ -1911,7 +1912,8 @@ public:
NS_IMETHOD Run() final
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!mRequestProxy || NS_IsMainThread(),
"If mRequestProxy is non-null, we need to run on main thread!");
if (!mRequestProxy) {
return NS_OK;
@ -1932,7 +1934,15 @@ public:
}
protected:
virtual ~StyleImageRequestCleanupTask() { MOZ_ASSERT(NS_IsMainThread()); }
virtual ~StyleImageRequestCleanupTask()
{
MOZ_ASSERT(mImageValue->mRequests.Count() == 0 || NS_IsMainThread(),
"If mImageValue has any mRequests, we need to run on main "
"thread to release ImageValues!");
MOZ_ASSERT((!mRequestProxy && !mImageTracker) || NS_IsMainThread(),
"mRequestProxy and mImageTracker's destructor need to run "
"on the main thread!");
}
private:
Mode mModeFlags;
@ -1986,10 +1996,13 @@ nsStyleImageRequest::~nsStyleImageRequest()
mRequestProxy.forget(),
mImageValue.forget(),
mImageTracker.forget());
if (NS_IsMainThread()) {
if (NS_IsMainThread() || !IsResolved()) {
task->Run();
} else {
NS_DispatchToMainThread(task.forget());
MOZ_ASSERT(IsResolved() == bool(mDocGroup),
"We forgot to cache mDocGroup in Resolve()?");
mDocGroup->Dispatch("StyleImageRequestCleanupTask",
TaskCategory::Other, task.forget());
}
}
@ -2003,8 +2016,10 @@ nsStyleImageRequest::Resolve(nsPresContext* aPresContext)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!IsResolved(), "already resolved");
MOZ_ASSERT(aPresContext);
mResolved = true;
mDocGroup = aPresContext->Document()->GetDocGroup();
// For now, just have unique nsCSSValue/ImageValue objects. We should
// really store the ImageValue on the Servo specified value, so that we can

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

@ -385,6 +385,9 @@ private:
RefPtr<mozilla::css::ImageValue> mImageValue;
RefPtr<mozilla::dom::ImageTracker> mImageTracker;
// Cache DocGroup for dispatching events in the destructor.
RefPtr<mozilla::dom::DocGroup> mDocGroup;
Mode mModeFlags;
bool mResolved;
};

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

@ -378,7 +378,6 @@ to mochitest command.
* background-position invalid 3-value form **issue to be filed**
* test_shorthand_property_getters.html `should serialize to 4-value` [2]
* test_variables.html `--weird`: name of custom property is not escaped properly servo/servo#15399 [1]
* ... `got "--`: CSS-wide keywords in custom properties servo/servo#15401 [3]
* image-layer values should omit some of its parts when they are initial servo/servo#15951
* test_shorthand_property_getters.html `background` [2]
* counter-{reset,increment} doesn't serialize none servo/servo#15977
@ -407,7 +406,7 @@ to mochitest command.
* :-moz-window-inactive bug 1348489
* test_selectors.html `:-moz-window-inactive` [2]
* :-moz-{first,last}-node
* test_selectors.html `:-moz-` [13]
* test_selectors.html `:-moz-` [6]
* ... `unexpected rule index` [5]
* :dir
* test_selectors.html `:dir` [10]

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

@ -66,18 +66,26 @@ import java.util.concurrent.ConcurrentLinkedQueue;
private synchronized void onSample(Sample sample) {
if (sample == null) {
Log.w(LOGTAG, "WARN: null input sample");
// Ignore empty input.
mSamplePool.recycleInput(mDequeuedSamples.remove());
Log.w(LOGTAG, "WARN: empty input sample");
return;
}
if (!sample.isEOS()) {
Sample temp = sample;
sample = mDequeuedSamples.remove();
sample.info = temp.info;
sample.cryptoInfo = temp.cryptoInfo;
temp.dispose();
if (sample.isEOS()) {
queueSample(sample);
return;
}
Sample dequeued = mDequeuedSamples.remove();
dequeued.info = sample.info;
dequeued.cryptoInfo = sample.cryptoInfo;
queueSample(dequeued);
sample.dispose();
}
private void queueSample(Sample sample) {
if (!mInputSamples.offer(sample)) {
reportError(Error.FATAL, new Exception("FAIL: input sample queue is full"));
return;
@ -196,8 +204,8 @@ import java.util.concurrent.ConcurrentLinkedQueue;
return;
}
Sample output = obtainOutputSample(index, info);
try {
Sample output = obtainOutputSample(index, info);
mSentIndices.add(index);
mSentOutputs.add(output);
mCallbacks.onOutput(output);
@ -471,8 +479,13 @@ import java.util.concurrent.ConcurrentLinkedQueue;
}
@Override
public synchronized Sample dequeueInput(int size) {
return mInputProcessor.onAllocate(size);
public synchronized Sample dequeueInput(int size) throws RemoteException {
try {
return mInputProcessor.onAllocate(size);
} catch (Exception e) {
// Translate allocation error to remote exception.
throw new RemoteException(e.getMessage());
}
}
@Override

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

@ -170,34 +170,40 @@ public final class CodecProxy {
Log.e(LOGTAG, "cannot send input to an ended codec");
return false;
}
boolean eos = info.flags == MediaCodec.BUFFER_FLAG_END_OF_STREAM;
mCallbacks.setEndOfInput(eos);
if (eos) {
return sendInput(Sample.EOS);
}
try {
return sendInput(mRemote.dequeueInput(info.size).set(bytes, info, cryptoInfo));
} catch (RemoteException e) {
Log.e(LOGTAG, "fail to dequeue input buffer", e);
return false;
} catch (IOException e) {
Log.e(LOGTAG, "fail to copy input data.", e);
// Balance dequeue/queue.
return sendInput(null);
}
}
private boolean sendInput(Sample sample) {
try {
Sample sample = processInput(bytes, info, cryptoInfo);
if (sample == null) {
return false;
}
mRemote.queueInput(sample);
sample.dispose();
if (sample != null) {
sample.dispose();
}
} catch (Exception e) {
Log.e(LOGTAG, "fail to input sample: size=" + info.size +
", pts=" + info.presentationTimeUs +
", flags=" + Integer.toHexString(info.flags), e);
Log.e(LOGTAG, "fail to queue input:" + sample, e);
return false;
}
return true;
}
private Sample processInput(ByteBuffer bytes, BufferInfo info, CryptoInfo cryptoInfo)
throws RemoteException, IOException {
if (info.flags == MediaCodec.BUFFER_FLAG_END_OF_STREAM) {
mCallbacks.setEndOfInput(true);
return Sample.EOS;
} else {
mCallbacks.setEndOfInput(false);
return mRemote.dequeueInput(info.size).set(bytes, info, cryptoInfo);
}
}
@WrapForJNI
public synchronized boolean flush() {
if (mRemote == null) {

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

@ -32,7 +32,7 @@ final class SamplePool {
mDefaultBufferSize = size;
}
private synchronized Sample obtain(int size) {
private synchronized Sample obtain(int size) {
if (!mRecycledSamples.isEmpty()) {
return mRecycledSamples.remove(0);
}
@ -48,13 +48,11 @@ final class SamplePool {
SharedMemory shm = null;
try {
shm = new SharedMemory(mNextId++, Math.max(size, mDefaultBufferSize));
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (NoSuchMethodException | IOException e) {
throw new UnsupportedOperationException(e);
}
return shm != null ? Sample.create(shm) : Sample.create();
return Sample.create(shm);
}
private synchronized void recycle(Sample recycled) {

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

@ -54,7 +54,11 @@ public final class SharedMemBuffer implements Sample.Buffer {
if (!src.isDirect()) {
throw new IOException("SharedMemBuffer only support reading from direct byte buffer.");
}
nativeReadFromDirectBuffer(src, mSharedMem.getPointer(), offset, size);
try {
nativeReadFromDirectBuffer(src, mSharedMem.getPointer(), offset, size);
} catch (NullPointerException e) {
throw new IOException(e);
}
}
private native static void nativeReadFromDirectBuffer(ByteBuffer src, long dest, int offset, int size);
@ -64,7 +68,11 @@ public final class SharedMemBuffer implements Sample.Buffer {
if (!dest.isDirect()) {
throw new IOException("SharedMemBuffer only support writing to direct byte buffer.");
}
nativeWriteToDirectBuffer(mSharedMem.getPointer(), dest, offset, size);
try {
nativeWriteToDirectBuffer(mSharedMem.getPointer(), dest, offset, size);
} catch (NullPointerException e) {
throw new IOException(e);
}
}
private native static void nativeWriteToDirectBuffer(long src, ByteBuffer dest, int offset, int size);

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

@ -133,7 +133,12 @@ public class SharedMemory implements Parcelable {
}
if (!mIsMapped) {
mHandle = map(getFD(), mSize);
try {
mHandle = map(getFD(), mSize);
} catch (NullPointerException e) {
Log.e(LOGTAG, "SharedMemory#" + mId + " error.", e);
throw e;
}
if (mHandle != 0) {
mIsMapped = true;
}

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

@ -3,7 +3,9 @@
* 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 <errno.h>
#include <jni.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
@ -52,6 +54,12 @@ jlong JNICALL
Java_org_mozilla_gecko_mozglue_SharedMemory_map(JNIEnv *env, jobject jobj, jint fd, jint length)
{
void* address = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (address == MAP_FAILED) {
char msg[128];
snprintf(msg, sizeof(msg), "mmap failed. errno=%d", errno);
env->ThrowNew(env->FindClass("java/lang/NullPointerException"), msg);
return 0;
}
return jlong(address);
}
@ -62,4 +70,4 @@ Java_org_mozilla_gecko_mozglue_SharedMemory_unmap(JNIEnv *env, jobject jobj, jlo
munmap((void*)address, (size_t)size);
}
}
}

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

@ -70,13 +70,11 @@ add_task(async function test_decline_undecline() {
await SyncTestingInfrastructure(server);
try {
let bzGuid = "999999999999";
await PlacesSyncUtils.bookmarks.insert({
kind: PlacesSyncUtils.bookmarks.KINDS.BOOKMARK,
syncId: bzGuid,
parentSyncId: "menu",
let { guid: bzGuid } = await PlacesUtils.bookmarks.insert({
parentGuid: PlacesUtils.bookmarks.menuGuid,
url: "https://bugzilla.mozilla.org",
index: PlacesUtils.bookmarks.DEFAULT_INDEX,
title: "bugzilla",
});
ok(!getBookmarkWBO(server, bzGuid), "Shouldn't have been uploaded yet");

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

@ -478,7 +478,10 @@ impl LayoutElementHelpers for LayoutJS<Element> {
if let Some(font_size) = font_size {
hints.push(from_declaration(
shared_lock,
PropertyDeclaration::FontSize(font_size::SpecifiedValue(font_size.into()))))
PropertyDeclaration::FontSize(
font_size::SpecifiedValue::from_html_size(font_size as u8)
)
))
}
let cellspacing = if let Some(this) = self.downcast::<HTMLTableElement>() {

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

@ -18,7 +18,6 @@ use html5ever_atoms::LocalName;
use servo_atoms::Atom;
use style::attr::AttrValue;
use style::str::{HTML_SPACE_CHARACTERS, read_numbers};
use style::values::specified;
#[dom_struct]
pub struct HTMLFontElement {
@ -62,8 +61,7 @@ impl HTMLFontElementMethods for HTMLFontElement {
// https://html.spec.whatwg.org/multipage/#dom-font-size
fn SetSize(&self, value: DOMString) {
let element = self.upcast::<Element>();
let length = parse_length(&value);
element.set_attribute(&local_name!("size"), AttrValue::Length(value.into(), length));
element.set_attribute(&local_name!("size"), parse_size(&value));
}
}
@ -76,10 +74,7 @@ impl VirtualMethods for HTMLFontElement {
match name {
&local_name!("face") => AttrValue::from_atomic(value.into()),
&local_name!("color") => AttrValue::from_legacy_color(value.into()),
&local_name!("size") => {
let length = parse_length(&value);
AttrValue::Length(value.into(), length)
},
&local_name!("size") => parse_size(&value),
_ => self.super_type().unwrap().parse_plain_attribute(name, value),
}
}
@ -88,7 +83,7 @@ impl VirtualMethods for HTMLFontElement {
pub trait HTMLFontElementLayoutHelpers {
fn get_color(&self) -> Option<RGBA>;
fn get_face(&self) -> Option<Atom>;
fn get_size(&self) -> Option<specified::Length>;
fn get_size(&self) -> Option<u32>;
}
impl HTMLFontElementLayoutHelpers for LayoutJS<HTMLFontElement> {
@ -113,18 +108,21 @@ impl HTMLFontElementLayoutHelpers for LayoutJS<HTMLFontElement> {
}
#[allow(unsafe_code)]
fn get_size(&self) -> Option<specified::Length> {
unsafe {
fn get_size(&self) -> Option<u32> {
let size = unsafe {
(*self.upcast::<Element>().unsafe_get())
.get_attr_for_layout(&ns!(), &local_name!("size"))
.and_then(AttrValue::as_length)
.cloned()
};
match size {
Some(&AttrValue::UInt(_, s)) => Some(s),
_ => None,
}
}
}
/// https://html.spec.whatwg.org/multipage/#rules-for-parsing-a-legacy-font-size
fn parse_length(mut input: &str) -> Option<specified::Length> {
fn parse_size(mut input: &str) -> AttrValue {
let original_input = input;
// Steps 1 & 2 are not relevant
// Step 3
@ -138,7 +136,7 @@ fn parse_length(mut input: &str) -> Option<specified::Length> {
let mut input_chars = input.chars().peekable();
let parse_mode = match input_chars.peek() {
// Step 4
None => return None,
None => return AttrValue::String(original_input.into()),
// Step 5
Some(&'+') => {
@ -155,7 +153,7 @@ fn parse_length(mut input: &str) -> Option<specified::Length> {
// Steps 6, 7, 8
let mut value = match read_numbers(input_chars) {
(Some(v), _) if v >= 0 => v,
_ => return None,
_ => return AttrValue::String(original_input.into()),
};
// Step 9
@ -166,5 +164,5 @@ fn parse_length(mut input: &str) -> Option<specified::Length> {
}
// Steps 10, 11, 12
Some(specified::Length::from_font_size_int(value as u8))
AttrValue::UInt(original_input.into(), value as u32)
}

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

@ -112,12 +112,56 @@ pub fn matches<E>(selector_list: &[Selector<E::Impl>],
})
}
fn may_match<E>(mut selector: &ComplexSelector<E::Impl>,
bf: &BloomFilter)
-> bool
where E: Element,
{
// See if the bloom filter can exclude any of the descendant selectors, and
// reject if we can.
loop {
match selector.next {
None => break,
Some((ref cs, Combinator::Descendant)) => selector = &**cs,
Some((ref cs, _)) => {
selector = &**cs;
continue;
}
};
for ss in selector.compound_selector.iter() {
match *ss {
SimpleSelector::LocalName(LocalName { ref name, ref lower_name }) => {
if !bf.might_contain(name) &&
!bf.might_contain(lower_name) {
return false
}
},
SimpleSelector::Namespace(ref namespace) => {
if !bf.might_contain(&namespace.url) {
return false
}
},
SimpleSelector::ID(ref id) => {
if !bf.might_contain(id) {
return false
}
},
SimpleSelector::Class(ref class) => {
if !bf.might_contain(class) {
return false
}
},
_ => {},
}
}
}
// If we haven't proven otherwise, it may match.
true
}
/// Determines whether the given element matches the given complex selector.
///
/// NB: If you add support for any new kinds of selectors to this routine, be sure to set
/// `shareable` to false unless you are willing to update the style sharing logic. Otherwise things
/// will almost certainly break as elements will start mistakenly sharing styles. (See
/// `can_share_style_with` in `servo/components/style/matching.rs`.)
pub fn matches_complex_selector<E>(selector: &ComplexSelector<E::Impl>,
element: &E,
parent_bf: Option<&BloomFilter>,
@ -126,7 +170,13 @@ pub fn matches_complex_selector<E>(selector: &ComplexSelector<E::Impl>,
-> bool
where E: Element
{
match matches_complex_selector_internal(selector, element, parent_bf, relations, flags) {
if let Some(filter) = parent_bf {
if !may_match::<E>(selector, filter) {
return false;
}
}
match matches_complex_selector_internal(selector, element, relations, flags) {
SelectorMatchingResult::Matched => {
match selector.next {
Some((_, Combinator::NextSibling)) |
@ -190,81 +240,19 @@ enum SelectorMatchingResult {
NotMatchedGlobally,
}
/// Quickly figures out whether or not the complex selector is worth doing more
/// work on. If the simple selectors don't match, or there's a child selector
/// that does not appear in the bloom parent bloom filter, we can exit early.
fn can_fast_reject<E>(mut selector: &ComplexSelector<E::Impl>,
element: &E,
parent_bf: Option<&BloomFilter>,
relations: &mut StyleRelations,
flags: &mut ElementSelectorFlags)
-> Option<SelectorMatchingResult>
where E: Element
{
if !selector.compound_selector.iter().all(|simple_selector| {
matches_simple_selector(simple_selector, element, parent_bf, relations, flags) }) {
return Some(SelectorMatchingResult::NotMatchedAndRestartFromClosestLaterSibling);
}
let bf: &BloomFilter = match parent_bf {
None => return None,
Some(ref bf) => bf,
};
// See if the bloom filter can exclude any of the descendant selectors, and
// reject if we can.
loop {
match selector.next {
None => break,
Some((ref cs, Combinator::Descendant)) => selector = &**cs,
Some((ref cs, _)) => {
selector = &**cs;
continue;
}
};
for ss in selector.compound_selector.iter() {
match *ss {
SimpleSelector::LocalName(LocalName { ref name, ref lower_name }) => {
if !bf.might_contain(name) &&
!bf.might_contain(lower_name) {
return Some(SelectorMatchingResult::NotMatchedGlobally);
}
},
SimpleSelector::Namespace(ref namespace) => {
if !bf.might_contain(&namespace.url) {
return Some(SelectorMatchingResult::NotMatchedGlobally);
}
},
SimpleSelector::ID(ref id) => {
if !bf.might_contain(id) {
return Some(SelectorMatchingResult::NotMatchedGlobally);
}
},
SimpleSelector::Class(ref class) => {
if !bf.might_contain(class) {
return Some(SelectorMatchingResult::NotMatchedGlobally);
}
},
_ => {},
}
}
}
// Can't fast reject.
None
}
fn matches_complex_selector_internal<E>(selector: &ComplexSelector<E::Impl>,
element: &E,
parent_bf: Option<&BloomFilter>,
relations: &mut StyleRelations,
flags: &mut ElementSelectorFlags)
-> SelectorMatchingResult
element: &E,
relations: &mut StyleRelations,
flags: &mut ElementSelectorFlags)
-> SelectorMatchingResult
where E: Element
{
if let Some(result) = can_fast_reject(selector, element, parent_bf, relations, flags) {
return result;
let matches_all_simple_selectors = selector.compound_selector.iter().all(|simple| {
matches_simple_selector(simple, element, relations, flags)
});
if !matches_all_simple_selectors {
return SelectorMatchingResult::NotMatchedAndRestartFromClosestLaterSibling;
}
match selector.next {
@ -287,10 +275,9 @@ fn matches_complex_selector_internal<E>(selector: &ComplexSelector<E::Impl>,
Some(next_element) => next_element,
};
let result = matches_complex_selector_internal(&**next_selector,
&element,
parent_bf,
relations,
flags);
&element,
relations,
flags);
match (result, combinator) {
// Return the status immediately.
(SelectorMatchingResult::Matched, _) => return result,
@ -332,7 +319,6 @@ fn matches_complex_selector_internal<E>(selector: &ComplexSelector<E::Impl>,
fn matches_simple_selector<E>(
selector: &SimpleSelector<E::Impl>,
element: &E,
parent_bf: Option<&BloomFilter>,
relations: &mut StyleRelations,
flags: &mut ElementSelectorFlags)
-> bool
@ -466,7 +452,10 @@ fn matches_simple_selector<E>(
}
SimpleSelector::Negation(ref negated) => {
!negated.iter().all(|s| {
matches_complex_selector(s, element, parent_bf, relations, flags)
match matches_complex_selector_internal(s, element, relations, flags) {
SelectorMatchingResult::Matched => true,
_ => false,
}
})
}
}

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

@ -772,17 +772,22 @@ mod bindings {
pub fn generate() {
use self::common::*;
use std::fs;
use std::thread;
use std::{env, fs, thread};
println!("cargo:rerun-if-changed=build_gecko.rs");
fs::create_dir_all(&*OUTDIR_PATH).unwrap();
bindings::setup_logging();
let threads = vec![
thread::spawn(|| bindings::generate_structs(BuildType::Debug)),
thread::spawn(|| bindings::generate_structs(BuildType::Release)),
thread::spawn(|| bindings::generate_bindings()),
];
for t in threads.into_iter() {
t.join().unwrap();
if env::var("STYLO_BUILD_LOG").is_ok() {
bindings::generate_structs(BuildType::Debug);
bindings::generate_structs(BuildType::Release);
bindings::generate_bindings();
} else {
let threads = vec![
thread::spawn(|| bindings::generate_structs(BuildType::Debug)),
thread::spawn(|| bindings::generate_structs(BuildType::Release)),
thread::spawn(|| bindings::generate_bindings()),
];
for t in threads.into_iter() {
t.join().unwrap();
}
}
}

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

@ -341,6 +341,10 @@ impl<'a> ::selectors::Parser for SelectorParser<'a> {
let selectors = parser.parse_comma_separated(|input| {
ComplexSelector::parse(self, input)
})?;
// Selectors inside `:-moz-any` may not include combinators.
if selectors.iter().any(|s| s.next.is_some()) {
return Err(())
}
NonTSPseudoClass::MozAny(selectors)
}
_ => return Err(())

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

@ -400,24 +400,129 @@ ${helpers.single_keyword("font-variant-caps",
impl ToCss for SpecifiedValue {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
self.0.to_css(dest)
match *self {
SpecifiedValue::Length(ref lop) => lop.to_css(dest),
SpecifiedValue::Keyword(kw) => kw.to_css(dest),
SpecifiedValue::Smaller => dest.write_str("smaller"),
SpecifiedValue::Larger => dest.write_str("larger"),
}
}
}
impl HasViewportPercentage for SpecifiedValue {
fn has_viewport_percentage(&self) -> bool {
return self.0.has_viewport_percentage()
match *self {
SpecifiedValue::Length(ref lop) => lop.has_viewport_percentage(),
_ => false
}
}
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct SpecifiedValue(pub specified::LengthOrPercentage);
pub enum SpecifiedValue {
Length(specified::LengthOrPercentage),
Keyword(KeywordSize),
Smaller,
Larger,
}
pub mod computed_value {
use app_units::Au;
pub type T = Au;
}
/// CSS font keywords
#[derive(Debug, Copy, Clone, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum KeywordSize {
XXSmall = 0,
XSmall = 1,
Small = 2,
Medium = 3,
Large = 4,
XLarge = 5,
XXLarge = 6,
// This is not a real font keyword and will not parse
// HTML font-size 7 corresponds to this value
XXXLarge = 7,
}
pub use self::KeywordSize::*;
impl KeywordSize {
pub fn parse(input: &mut Parser) -> Result<Self, ()> {
Ok(match_ignore_ascii_case! {&*input.expect_ident()?,
"xx-small" => XXSmall,
"x-small" => XSmall,
"small" => Small,
"medium" => Medium,
"large" => Large,
"x-large" => XLarge,
"xx-large" => XXLarge,
_ => return Err(())
})
}
}
impl ToCss for KeywordSize {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
dest.write_str(match *self {
XXSmall => "xx-small",
XSmall => "x-small",
Small => "small",
Medium => "medium",
Large => "large",
XLarge => "x-large",
XXLarge => "xx-large",
XXXLarge => unreachable!("We should never serialize \
specified values set via
HTML presentation attributes"),
})
}
}
impl ToComputedValue for KeywordSize {
type ComputedValue = Au;
#[inline]
fn to_computed_value(&self, _: &Context) -> computed_value::T {
// https://drafts.csswg.org/css-fonts-3/#font-size-prop
use values::FONT_MEDIUM_PX;
match *self {
XXSmall => Au::from_px(FONT_MEDIUM_PX) * 3 / 5,
XSmall => Au::from_px(FONT_MEDIUM_PX) * 3 / 4,
Small => Au::from_px(FONT_MEDIUM_PX) * 8 / 9,
Medium => Au::from_px(FONT_MEDIUM_PX),
Large => Au::from_px(FONT_MEDIUM_PX) * 6 / 5,
XLarge => Au::from_px(FONT_MEDIUM_PX) * 3 / 2,
XXLarge => Au::from_px(FONT_MEDIUM_PX) * 2,
XXXLarge => Au::from_px(FONT_MEDIUM_PX) * 3,
}
}
#[inline]
fn from_computed_value(_: &computed_value::T) -> Self {
unreachable!()
}
}
impl SpecifiedValue {
/// https://html.spec.whatwg.org/multipage/#rules-for-parsing-a-legacy-font-size
pub fn from_html_size(size: u8) -> Self {
SpecifiedValue::Keyword(match size {
// If value is less than 1, let it be 1.
0 | 1 => XSmall,
2 => Small,
3 => Medium,
4 => Large,
5 => XLarge,
6 => XXLarge,
// If value is greater than 7, let it be 7.
_ => XXXLarge,
})
}
}
#[inline]
#[allow(missing_docs)]
pub fn get_initial_value() -> computed_value::T {
@ -426,7 +531,7 @@ ${helpers.single_keyword("font-variant-caps",
#[inline]
pub fn get_initial_specified_value() -> SpecifiedValue {
SpecifiedValue(specified::LengthOrPercentage::Length(NoCalcLength::medium()))
SpecifiedValue::Keyword(Medium)
}
impl ToComputedValue for SpecifiedValue {
@ -434,45 +539,61 @@ ${helpers.single_keyword("font-variant-caps",
#[inline]
fn to_computed_value(&self, context: &Context) -> computed_value::T {
match self.0 {
LengthOrPercentage::Length(NoCalcLength::FontRelative(value)) => {
use values::specified::length::FontRelativeLength;
match *self {
SpecifiedValue::Length(LengthOrPercentage::Length(
NoCalcLength::FontRelative(value))) => {
value.to_computed_value(context, /* use inherited */ true)
}
LengthOrPercentage::Length(NoCalcLength::ServoCharacterWidth(value)) => {
SpecifiedValue::Length(LengthOrPercentage::Length(
NoCalcLength::ServoCharacterWidth(value))) => {
value.to_computed_value(context.inherited_style().get_font().clone_font_size())
}
LengthOrPercentage::Length(ref l) => {
SpecifiedValue::Length(LengthOrPercentage::Length(ref l)) => {
l.to_computed_value(context)
}
LengthOrPercentage::Percentage(Percentage(value)) => {
SpecifiedValue::Length(LengthOrPercentage::Percentage(Percentage(value))) => {
context.inherited_style().get_font().clone_font_size().scale_by(value)
}
LengthOrPercentage::Calc(ref calc) => {
SpecifiedValue::Length(LengthOrPercentage::Calc(ref calc)) => {
let calc = calc.to_computed_value(context);
calc.length() + context.inherited_style().get_font().clone_font_size()
.scale_by(calc.percentage())
}
SpecifiedValue::Keyword(ref key) => {
key.to_computed_value(context)
}
SpecifiedValue::Smaller => {
FontRelativeLength::Em(0.85).to_computed_value(context,
/* use_inherited */ true)
}
SpecifiedValue::Larger => {
FontRelativeLength::Em(1.2).to_computed_value(context,
/* use_inherited */ true)
}
}
}
#[inline]
fn from_computed_value(computed: &computed_value::T) -> Self {
SpecifiedValue(LengthOrPercentage::Length(
SpecifiedValue::Length(LengthOrPercentage::Length(
ToComputedValue::from_computed_value(computed)
))
}
}
/// <length> | <percentage> | <absolute-size> | <relative-size>
pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
use values::specified::{Length, LengthOrPercentage};
input.try(specified::LengthOrPercentage::parse_non_negative)
.or_else(|()| {
let ident = try!(input.expect_ident());
NoCalcLength::from_str(&ident as &str)
.ok_or(())
.map(specified::LengthOrPercentage::Length)
}).map(SpecifiedValue)
pub fn parse(_: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
if let Ok(lop) = input.try(specified::LengthOrPercentage::parse_non_negative) {
Ok(SpecifiedValue::Length(lop))
} else if let Ok(kw) = input.try(KeywordSize::parse) {
Ok(SpecifiedValue::Keyword(kw))
} else {
match_ignore_ascii_case! {&*input.expect_ident()?,
"smaller" => Ok(SpecifiedValue::Smaller),
"larger" => Ok(SpecifiedValue::Larger),
_ => Err(())
}
}
}
</%helpers:longhand>

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

@ -1175,7 +1175,9 @@ impl PropertyDeclaration {
pub fn value_is_unparsed(&self) -> bool {
match *self {
PropertyDeclaration::WithVariables(..) => true,
PropertyDeclaration::Custom(..) => true,
PropertyDeclaration::Custom(_, ref value) => {
!matches!(value.borrow(), DeclaredValue::CSSWideKeyword(..))
}
_ => false,
}
}

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

@ -276,38 +276,6 @@ impl Mul<CSSFloat> for NoCalcLength {
}
impl NoCalcLength {
/// https://drafts.csswg.org/css-fonts-3/#font-size-prop
pub fn from_str(s: &str) -> Option<NoCalcLength> {
Some(match_ignore_ascii_case! { s,
"xx-small" => NoCalcLength::Absolute(Au::from_px(FONT_MEDIUM_PX) * 3 / 5),
"x-small" => NoCalcLength::Absolute(Au::from_px(FONT_MEDIUM_PX) * 3 / 4),
"small" => NoCalcLength::Absolute(Au::from_px(FONT_MEDIUM_PX) * 8 / 9),
"medium" => NoCalcLength::Absolute(Au::from_px(FONT_MEDIUM_PX)),
"large" => NoCalcLength::Absolute(Au::from_px(FONT_MEDIUM_PX) * 6 / 5),
"x-large" => NoCalcLength::Absolute(Au::from_px(FONT_MEDIUM_PX) * 3 / 2),
"xx-large" => NoCalcLength::Absolute(Au::from_px(FONT_MEDIUM_PX) * 2),
// https://github.com/servo/servo/issues/3423#issuecomment-56321664
"smaller" => NoCalcLength::FontRelative(FontRelativeLength::Em(0.85)),
"larger" => NoCalcLength::FontRelative(FontRelativeLength::Em(1.2)),
_ => return None
})
}
/// https://drafts.csswg.org/css-fonts-3/#font-size-prop
pub fn from_font_size_int(i: u8) -> Self {
let au = match i {
0 | 1 => Au::from_px(FONT_MEDIUM_PX) * 3 / 4,
2 => Au::from_px(FONT_MEDIUM_PX) * 8 / 9,
3 => Au::from_px(FONT_MEDIUM_PX),
4 => Au::from_px(FONT_MEDIUM_PX) * 6 / 5,
5 => Au::from_px(FONT_MEDIUM_PX) * 3 / 2,
6 => Au::from_px(FONT_MEDIUM_PX) * 2,
_ => Au::from_px(FONT_MEDIUM_PX) * 3,
};
NoCalcLength::Absolute(au)
}
/// Parse a given absolute or relative dimension.
pub fn parse_dimension(value: CSSFloat, unit: &str) -> Result<NoCalcLength, ()> {
match_ignore_ascii_case! { unit,
@ -444,21 +412,11 @@ impl Length {
Length::NoCalc(NoCalcLength::zero())
}
/// https://drafts.csswg.org/css-fonts-3/#font-size-prop
pub fn from_str(s: &str) -> Option<Length> {
NoCalcLength::from_str(s).map(Length::NoCalc)
}
/// Parse a given absolute or relative dimension.
pub fn parse_dimension(value: CSSFloat, unit: &str) -> Result<Length, ()> {
NoCalcLength::parse_dimension(value, unit).map(Length::NoCalc)
}
/// https://drafts.csswg.org/css-fonts-3/#font-size-prop
pub fn from_font_size_int(i: u8) -> Self {
Length::NoCalc(NoCalcLength::from_font_size_int(i))
}
#[inline]
fn parse_internal(input: &mut Parser, context: AllowedNumericType) -> Result<Length, ()> {
match try!(input.next()) {

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

@ -1111,7 +1111,7 @@ pub extern "C" fn Servo_DeclarationBlock_SetKeywordValue(declarations:
value: i32) {
use style::properties::{PropertyDeclaration, LonghandId};
use style::properties::longhands;
use style::values::specified::{BorderStyle, NoCalcLength};
use style::values::specified::BorderStyle;
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
let long = get_longhand_from_id!(property);
@ -1127,7 +1127,7 @@ pub extern "C" fn Servo_DeclarationBlock_SetKeywordValue(declarations:
Clear => longhands::clear::SpecifiedValue::from_gecko_keyword(value),
FontSize => {
// We rely on Gecko passing in font-size values (0...7) here.
longhands::font_size::SpecifiedValue(NoCalcLength::from_font_size_int(value as u8).into())
longhands::font_size::SpecifiedValue::from_html_size(value as u8)
},
ListStyleType => longhands::list_style_type::SpecifiedValue::from_gecko_keyword(value),
WhiteSpace => longhands::white_space::SpecifiedValue::from_gecko_keyword(value),

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

@ -8,7 +8,7 @@
# except according to those terms.
import os
import site
import sys
from servo_tidy.tidy import LintRunner, filter_file
@ -28,11 +28,13 @@ class Lint(LintRunner):
def run(self):
if self.stylo:
return
wpt_working_dir = os.path.abspath(os.path.join(WPT_PATH, "web-platform-tests"))
for suite in SUITES:
files = self._get_wpt_files(suite)
site.addsitedir(wpt_working_dir)
sys.path.insert(0, wpt_working_dir)
from tools.lint import lint
sys.path.remove(wpt_working_dir)
file_dir = os.path.abspath(os.path.join(WPT_PATH, suite))
returncode = lint.lint(file_dir, files, output_json=False, css_mode=False)
if returncode:

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

@ -111,11 +111,11 @@ def progress_wrapper(iterator):
class FileList(object):
def __init__(self, directory, only_changed_files=False, exclude_dirs=[], progress=True, stylo=False):
def __init__(self, directory, only_changed_files=False, exclude_dirs=[], progress=True):
self.directory = directory
self.excluded = exclude_dirs
iterator = self._filter_excluded() if exclude_dirs else self._default_walk()
if only_changed_files and not stylo:
if only_changed_files:
try:
# Fall back if git doesn't work
newiter = self._git_changed_files()
@ -168,10 +168,9 @@ def filter_file(file_name):
return True
def filter_files(start_dir, only_changed_files, progress, stylo):
def filter_files(start_dir, only_changed_files, progress):
file_iter = FileList(start_dir, only_changed_files=only_changed_files,
exclude_dirs=config["ignore"]["directories"], progress=progress,
stylo=stylo)
exclude_dirs=config["ignore"]["directories"], progress=progress)
for file_name in file_iter:
base_name = os.path.basename(file_name)
if not any(fnmatch.fnmatch(base_name, pattern) for pattern in FILE_PATTERNS_TO_CHECK):
@ -1018,20 +1017,22 @@ class LintRunner(object):
dir_name, filename = os.path.split(self.path)
sys.path.append(dir_name)
module = imp.load_source(filename[:-3], self.path)
if hasattr(module, 'Lint'):
if issubclass(module.Lint, LintRunner):
lint = module.Lint(self.path, self.only_changed_files,
self.exclude_dirs, self.progress, stylo=self.stylo)
for error in lint.run():
if not hasattr(error, '__iter__'):
yield (self.path, 1, "errors should be a tuple of (path, line, reason)")
return
yield error
else:
yield (self.path, 1, "class 'Lint' should inherit from 'LintRunner'")
else:
yield (self.path, 1, "script should contain a class named 'Lint'")
sys.path.remove(dir_name)
if not hasattr(module, 'Lint'):
yield (self.path, 1, "script should contain a class named 'Lint'")
return
if not issubclass(module.Lint, LintRunner):
yield (self.path, 1, "class 'Lint' should inherit from 'LintRunner'")
return
lint = module.Lint(self.path, self.only_changed_files,
self.exclude_dirs, self.progress, stylo=self.stylo)
for error in lint.run():
if type(error) is not tuple or (type(error) is tuple and len(error) != 3):
yield (self.path, 1, "errors should be a tuple of (path, line, reason)")
return
yield error
def get_files(self, path, **kwargs):
args = ['only_changed_files', 'exclude_dirs', 'progress']
@ -1071,7 +1072,7 @@ def scan(only_changed_files=False, progress=True, stylo=False):
# check directories contain expected files
directory_errors = check_directory_files(config['check_ext'])
# standard checks
files_to_check = filter_files('.', only_changed_files, progress, stylo)
files_to_check = filter_files('.', only_changed_files and not stylo, progress)
checking_functions = (check_flake8, check_lock, check_webidl_spec, check_json, check_yaml)
line_checking_functions = (check_license, check_by_line, check_toml, check_shell,
check_rust, check_spec, check_modeline)

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

@ -1130,4 +1130,25 @@ mod shorthand_serialization {
assert_eq!(serialization, block_text);
}
}
mod keywords {
pub use super::*;
#[test]
fn css_wide_keywords_should_be_parsed() {
let block_text = "--a:inherit;";
let block = parse_declaration_block(block_text);
let serialization = block.to_css_string();
assert_eq!(serialization, "--a: inherit;");
}
#[test]
fn non_keyword_custom_property_should_be_unparsed() {
let block_text = "--main-color: #06c;";
let block = parse_declaration_block(block_text);
let serialization = block.to_css_string();
assert_eq!(serialization, block_text);
}
}
}

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

@ -264,6 +264,23 @@ class MarionetteProtocol(Protocol):
with self.marionette.using_context(self.marionette.CONTEXT_CHROME):
self.marionette.execute_script(script)
def clear_origin(self, url):
self.logger.info("Clearing origin %s" % (url))
script = """
let url = '%s';
let uri = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Ci.nsIIOService)
.newURI(url);
let ssm = Components.classes["@mozilla.org/scriptsecuritymanager;1"]
.getService(Ci.nsIScriptSecurityManager);
let principal = ssm.createCodebasePrincipal(uri, {});
let qms = Components.classes["@mozilla.org/dom/quota-manager-service;1"]
.getService(Components.interfaces.nsIQuotaManagerService);
qms.clearStoragesForPrincipal(principal, "default", true);
""" % url
with self.marionette.using_context(self.marionette.CONTEXT_CHROME):
self.marionette.execute_script(script)
class RemoteMarionetteProtocol(Protocol):
def __init__(self, executor, browser):
@ -325,6 +342,11 @@ class ExecuteAsyncScriptRun(object):
self.result_flag = threading.Event()
def run(self):
index = self.url.rfind("/storage/");
if index != -1:
# Clear storage
self.protocol.clear_origin(self.url)
timeout = self.timeout
try:

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

@ -24,7 +24,7 @@ add_task(function* test_default_behavior_host() {
yield addBookmark( { uri: uri4, title: "tpbk" } );
yield addBookmark( { uri: uri5, title: "title", tags: ["foo"] } );
yield setFaviconForHref(uri1.spec, "chrome://global/skin/icons/information-16.png");
yield setFaviconForHref(uri1.spec, "chrome://global/skin/icons/info.svg");
yield setFaviconForHref(uri3.spec, "chrome://global/skin/icons/error-16.png");
yield setFaviconForHref(uri6.spec, "chrome://global/skin/icons/question-16.png");
@ -45,7 +45,7 @@ add_task(function* test_default_behavior_host() {
yield check_autocomplete({
search: "ty",
matches: [ { uri: uri1, title: "typed", style: [ "autofill", "heuristic" ],
icon: "chrome://global/skin/icons/information-16.png" } ],
icon: "chrome://global/skin/icons/info.svg" } ],
autofilled: "typed/",
completed: "typed/"
});
@ -116,7 +116,7 @@ add_task(function* test_default_behavior_host() {
yield check_autocomplete({
search: "ty",
matches: [ { uri: uri1, title: "typed", style: [ "autofill", "heuristic" ],
icon: "chrome://global/skin/icons/information-16.png"} ],
icon: "chrome://global/skin/icons/info.svg"} ],
autofilled: "typed/",
completed: "typed/"
});
@ -223,7 +223,7 @@ add_task(function* test_default_behavior_url() {
yield addBookmark( { uri: uri3, title: "bookmarked" } );
yield addBookmark( { uri: uri4, title: "tpbk" } );
yield setFaviconForHref(uri1.spec, "chrome://global/skin/icons/information-16.png");
yield setFaviconForHref(uri1.spec, "chrome://global/skin/icons/info.svg");
yield setFaviconForHref(uri3.spec, "chrome://global/skin/icons/error-16.png");
// RESTRICT TO HISTORY.
@ -245,7 +245,7 @@ add_task(function* test_default_behavior_url() {
yield check_autocomplete({
search: "typed/t",
matches: [ { uri: uri1, title: "typed/ty/", style: [ "autofill", "heuristic" ],
icon: "chrome://global/skin/icons/information-16.png"} ],
icon: "chrome://global/skin/icons/info.svg"} ],
autofilled: "typed/ty/",
completed: "http://typed/ty/"
});

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

@ -176,7 +176,7 @@ add_task(function* test_import_chromefavicon() {
// 9. empty bookmarks db and continue
const PAGE_URI = NetUtil.newURI("http://example.com/chromefavicon_page");
const CHROME_FAVICON_URI = NetUtil.newURI("chrome://global/skin/icons/information-16.png");
const CHROME_FAVICON_URI = NetUtil.newURI("chrome://global/skin/icons/info.svg");
const CHROME_FAVICON_URI_2 = NetUtil.newURI("chrome://global/skin/icons/error-16.png");
do_print("Importing from html");

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

@ -1,5 +1,5 @@
[flake8]
# See http://pep8.readthedocs.io/en/latest/intro.html#configuration
ignore = E121, E123, E126, E129, E133, E226, E241, E242, E704, W503, E402, E128, E501, E202, W602, E127, W601
ignore = E121, E123, E126, E129, E133, E226, E241, E242, E704, W503, E402, E501, E202, W602, E127, W601
max-line-length = 99
filename = *.py, +.lint

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

@ -10462,11 +10462,11 @@
},
"DOM_SCRIPT_SRC_ENCODING": {
"alert_emails": ["dteller@mozilla.com"],
"expires_in_version": "never",
"expires_in_version": "61",
"kind": "count",
"keyed": true,
"bug_numbers": [1344152],
"description": "Encoding used in a <script src>."
"description": "Note the encoding (e.g. 'UTF-8', 'windows-1252', 'ASCII') of each external <script> element that is successfully loaded and decoded."
},
"VIDEO_FASTSEEK_USED": {
"alert_emails": ["lchristie@mozilla.com", "cpearce@mozilla.com"],

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

@ -21,16 +21,16 @@ def print_array_entry(output, histogram, name_index, exp_index, label_index, lab
if cpp_guard:
print("#if defined(%s)" % cpp_guard, file=output)
print(" { %s, %s, %s, %s, %d, %d, %s, %d, %d, %s },"
% (histogram.low(),
histogram.high(),
histogram.n_buckets(),
histogram.nsITelemetry_kind(),
name_index,
exp_index,
histogram.dataset(),
label_index,
label_count,
"true" if histogram.keyed() else "false"), file=output)
% (histogram.low(),
histogram.high(),
histogram.n_buckets(),
histogram.nsITelemetry_kind(),
name_index,
exp_index,
histogram.dataset(),
label_index,
label_count,
"true" if histogram.keyed() else "false"), file=output)
if cpp_guard:
print("#endif", file=output)

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

@ -371,14 +371,14 @@ associated with the histogram. Returns None if no guarding is necessary."""
continue
if not isinstance(definition[key], key_type):
raise ValueError, ('value for key "{0}" in Histogram "{1}" '
'should be {2}').format(key, name, nice_type_name(key_type))
'should be {2}').format(key, name, nice_type_name(key_type))
for key, key_type in type_checked_list_fields.iteritems():
if key not in definition:
continue
if not all(isinstance(x, key_type) for x in definition[key]):
raise ValueError, ('all values for list "{0}" in Histogram "{1}" '
'should be {2}').format(key, name, nice_type_name(key_type))
'should be {2}').format(key, name, nice_type_name(key_type))
@staticmethod
def check_keys(name, definition, allowed_keys):
@ -393,8 +393,8 @@ associated with the histogram. Returns None if no guarding is necessary."""
if whitelists is not None and self._n_buckets > 100 and type(self._n_buckets) is int:
if self._name not in whitelists['n_buckets']:
raise KeyError, ('New histogram "%s" is not permitted to have more than 100 buckets. '
'Histograms with large numbers of buckets use disproportionately high amounts of resources. '
'Contact the Telemetry team (e.g. in #telemetry) if you think an exception ought to be made.' % self._name)
'Histograms with large numbers of buckets use disproportionately high amounts of resources. '
'Contact the Telemetry team (e.g. in #telemetry) if you think an exception ought to be made.' % self._name)
@staticmethod
def boolean_flag_bucket_parameters(definition):

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

@ -49,7 +49,7 @@ class ScalarType:
for n in [group_name, probe_name]:
if len(n) > MAX_NAME_LENGTH:
raise ValueError("Name '{}' exceeds maximum name length of {} characters."
.format(n, MAX_NAME_LENGTH))
.format(n, MAX_NAME_LENGTH))
def check_name(name, error_msg_prefix, allowed_char_regexp):
# Check if we only have the allowed characters.
@ -60,8 +60,8 @@ class ScalarType:
# Don't allow leading/trailing digits, '.' or '_'.
if re.search(r'(^[\d\._])|([\d\._])$', name):
raise ValueError(error_msg_prefix +
" name must not have a leading/trailing digit, a dot or underscore. Got: '{}'"
.format(name))
" name must not have a leading/trailing digit, a dot or underscore. Got: '{}'"
.format(name))
check_name(group_name, 'Group', r'\.')
check_name(probe_name, 'Probe', r'_')
@ -115,7 +115,7 @@ class ScalarType:
# Checks the type for all the fields.
wrong_type_names = ['{} must be {}'.format(f, ALL_FIELDS[f].__name__)
for f in definition.keys() if not isinstance(definition[f], ALL_FIELDS[f])]
for f in definition.keys() if not isinstance(definition[f], ALL_FIELDS[f])]
if len(wrong_type_names) > 0:
raise TypeError(self._name + ' - ' + ', '.join(wrong_type_names))
@ -237,7 +237,7 @@ class ScalarType:
release_channel_collection = \
self._definition.get('release_channel_collection', 'opt-in')
return 'nsITelemetry::' + ('DATASET_RELEASE_CHANNEL_OPTOUT'
if release_channel_collection == 'opt-out' else 'DATASET_RELEASE_CHANNEL_OPTIN')
if release_channel_collection == 'opt-out' else 'DATASET_RELEASE_CHANNEL_OPTIN')
@property
def cpp_guard(self):

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

@ -155,7 +155,9 @@ this.SafeBrowsing = {
throw err;
}
if (!info.list || !info.uri) {
// The "Phish" reports are about submitting new phishing URLs to Google so
// they don't have an associated list URL
if (kind != "Phish" && (!info.list || !info.uri)) {
return null;
}

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

@ -21,6 +21,7 @@
const host_track = "http://trackertest.org/";
const path_ping = "tests/toolkit/components/url-classifier/tests/mochitest/ping.sjs";
const TP_ENABLE_PREF = "privacy.trackingprotection.enabled";
const RETRY_TIMEOUT_MS = 200;
var testData = [
{ url: "trackertest.org/",
@ -37,9 +38,8 @@
ping(id, host_nottrack);
return new Promise(function(resolve, reject) {
setTimeout(function() {
isPinged(id, expectPing, msg, resolve);
}, timeout);
// Retry at most 30 seconds.
isPingedWithRetry(id, expectPing, msg, resolve, 30 * 1000 / RETRY_TIMEOUT_MS);
});
}
@ -85,19 +85,30 @@
document.body.removeChild(elm);
}
function isPinged(id, expected, msg, callback) {
function isPingedWithRetry(id, expected, msg, callback, retryCnt) {
var url = "http://mochi.test:8888/" + path_ping;
var xhr = new XMLHttpRequest();
xhr.open('GET', url + "?id=" + id);
xhr.onload = function() {
var isPinged = xhr.response === "ping";
is(expected, isPinged, msg);
callback();
let success = isPinged === expected;
if (success || 0 === retryCnt) {
is(expected, isPinged, msg);
callback();
return;
}
// Retry on failure.
setTimeout(() => {
isPingedWithRetry(id, expected, msg, callback, retryCnt - 1);
}, RETRY_TIMEOUT_MS);
};
xhr.send();
}
function isPinged(id, expected, msg, callback) {
isPingedWithRetry(id, expected, msg, callback, 0);
}
function cleanup() {
SpecialPowers.clearUserPref(TP_ENABLE_PREF);
}

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

@ -44,9 +44,9 @@
#include "linux/crash_generation/crash_generation_server.h"
#include "linux/crash_generation/client_info.h"
#include "linux/handler/exception_handler.h"
#include "linux/handler/guid_generator.h"
#include "linux/minidump_writer/minidump_writer.h"
#include "common/linux/eintr_wrapper.h"
#include "common/linux/guid_creator.h"
#include "common/linux/safe_readlink.h"
static const char kCommandQuit = 'x';

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

@ -0,0 +1,108 @@
// Copyright (c) 2006, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "linux/handler/guid_generator.h"
#include <assert.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
//
// GUIDGenerator
//
// This class is used to generate random GUID.
// Currently use random number to generate a GUID since Linux has
// no native GUID generator. This should be OK since we don't expect
// crash to happen very offen.
//
class GUIDGenerator {
public:
static uint16_t BytesToUInt16(const uint8_t bytes[]) {
return ((uint16_t) bytes[1] << 8) | ((uint16_t) bytes[0]);
}
// The last field in a GUID is 48 bits long so we're converting only 6 bytes
static uint64_t BytesToUInt48(const uint8_t bytes[]) {
return ((uint64_t) bytes[0] << 40) | ((uint64_t) bytes[1] << 32) |
((uint64_t) bytes[2] << 24) | ((uint64_t) bytes[3] << 16) |
((uint64_t) bytes[4] << 8) | (uint64_t) bytes[5];
}
static void UInt32ToBytes(uint8_t bytes[], uint32_t n) {
bytes[0] = n & 0xff;
bytes[1] = (n >> 8) & 0xff;
bytes[2] = (n >> 16) & 0xff;
bytes[3] = (n >> 24) & 0xff;
}
static bool CreateGUID(GUID *guid) {
InitOnce();
guid->data1 = random();
guid->data2 = (uint16_t)(random());
guid->data3 = (uint16_t)(random());
UInt32ToBytes(&guid->data4[0], random());
UInt32ToBytes(&guid->data4[4], random());
return true;
}
private:
static void InitOnce() {
pthread_once(&once_control, &InitOnceImpl);
}
static void InitOnceImpl() {
srandom(time(NULL));
}
static pthread_once_t once_control;
};
pthread_once_t GUIDGenerator::once_control = PTHREAD_ONCE_INIT;
bool CreateGUID(GUID *guid) {
return GUIDGenerator::CreateGUID(guid);
}
// Parse guid to string.
bool GUIDToString(const GUID *guid, char *buf, size_t buf_len) {
// Should allow more space the the max length of GUID.
assert(buf_len > kGUIDStringLength);
int num = snprintf(buf, buf_len, kGUIDFormatString,
guid->data1, guid->data2, guid->data3,
GUIDGenerator::BytesToUInt16(&(guid->data4[0])),
GUIDGenerator::BytesToUInt48(&(guid->data4[2])));
if (num != kGUIDStringLength)
return false;
buf[num] = '\0';
return true;
}

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

@ -0,0 +1,48 @@
// Copyright (c) 2006, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef LINUX_HANDLER_GUID_GENERATOR_H__
#define LINUX_HANDLER_GUID_GENERATOR_H__
#include "google_breakpad/common/minidump_format.h"
typedef MDGUID GUID;
// Format string for parsing GUID.
const char kGUIDFormatString[] = "%08x-%04x-%04x-%04x-%012" PRIx64;
// Length of GUID string. Don't count the ending '\0'.
const size_t kGUIDStringLength = 36;
// Create a guid.
bool CreateGUID(GUID *guid);
// Get the string from guid.
bool GUIDToString(const GUID *guid, char *buf, size_t buf_len);
#endif

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше