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

This commit is contained in:
Noemi Erli 2019-05-22 06:45:38 +03:00
Родитель 29ee64cea5 d6c1e69556
Коммит 98ff24cc58
222 изменённых файлов: 2060 добавлений и 3256 удалений

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

@ -61,8 +61,7 @@ class ClickHandlerChild extends ActorChild {
}
}
// Bug 965637, query the CSP from the doc instead of the Principal
let csp = ownerDoc.nodePrincipal.csp;
let csp = ownerDoc.csp;
if (csp) {
csp = E10SUtils.serializeCSP(csp);
}

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

@ -781,8 +781,7 @@ class ContextMenuChild extends ActorChild {
context.target = node;
context.principal = context.target.ownerDocument.nodePrincipal;
// Bug 965637, query the CSP from the doc instead of the Principal
context.csp = E10SUtils.serializeCSP(context.target.ownerDocument.nodePrincipal.csp);
context.csp = E10SUtils.serializeCSP(context.target.ownerDocument.csp);
context.frameOuterWindowID = WebNavigationFrames.getFrameId(context.target.ownerGlobal);

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

@ -2599,19 +2599,6 @@ function loadURI(uri, referrerInfo, postData, allowThirdPartyFixup,
throw new Error("Must load with a triggering Principal");
}
// After Bug 965637 we can remove that Error because the CSP will not
// hang off the Principal anymore. Please note that the SystemPrincipal
// can not hold a CSP!
if (AppConstants.EARLY_BETA_OR_EARLIER) {
// Please note that the backend will still query the CSP from the Principal in
// release versions of Firefox. We use this error just to annotate all the
// callsites to explicitly pass a CSP before we can remove the CSP from
// the Principal within Bug 965637.
if (!triggeringPrincipal.isSystemPrincipal && triggeringPrincipal.csp && !csp) {
throw new Error("If Principal has CSP then we need an explicit CSP");
}
}
try {
openLinkIn(uri, "current",
{ referrerInfo,
@ -5802,19 +5789,6 @@ nsBrowserAccess.prototype = {
throw Cr.NS_ERROR_FAILURE;
}
// After Bug 965637 we can remove that Error because the CSP will not
// hang off the Principal anymore. Please note that the SystemPrincipal
// can not hold a CSP!
if (AppConstants.EARLY_BETA_OR_EARLIER) {
// Please note that the backend will still query the CSP from the Principal in
// release versions of Firefox. We use this error just to annotate all the
// callsites to explicitly pass a CSP before we can remove the CSP from
// the Principal within Bug 965637.
if (!aTriggeringPrincipal.isSystemPrincipal && aTriggeringPrincipal.csp && !aCsp) {
throw new Error("If Principal has CSP then we need an explicit CSP");
}
}
var newWindow = null;
var isExternal = !!(aFlags & Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL);
@ -6507,9 +6481,6 @@ function handleLinkClick(event, href, linkNode) {
!BrowserUtils.linkHasNoReferrer(linkNode),
referrerURI);
// Bug 965637, query the CSP from the doc instead of the Principal
let csp = doc.nodePrincipal.csp;
urlSecurityCheck(href, doc.nodePrincipal);
let params = {
charset: doc.characterSet,
@ -6517,7 +6488,7 @@ function handleLinkClick(event, href, linkNode) {
referrerInfo,
originPrincipal: doc.nodePrincipal,
triggeringPrincipal: doc.nodePrincipal,
csp,
csp: doc.csp,
frameOuterWindowID,
};

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

@ -2,3 +2,4 @@
[browser_principalSerialization_version1.js]
[browser_principalSerialization_csp.js]
skip-if = debug # deliberately bypass assertions when deserializing. Bug 965637 removed the CSP from Principals, but the remaining bits in such Principals should deserialize correctly.

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

@ -45,7 +45,8 @@ add_task(async function test_deserialize_principal_with_csp() {
{
"input": "ZT4OTT7kRfqycpfCC8AeuAAAAAAAAAAAwAAAAAAAAEYB3pRy0IA0EdOTmQAQS6D9QJIHOlRteE8wkTq4cYEyCMYAAAAC/////wAAAbsBAAAAHmh0dHBzOi8vd3d3Lm1vemlsbGEub3JnL2VuLVVTLwAAAAAAAAAFAAAACAAAAA8AAAAA/////wAAAAD/////AAAACAAAAA8AAAAXAAAABwAAABcAAAAHAAAAFwAAAAcAAAAeAAAAAAAAAAD/////AAAAAP////8AAAAA/////wAAAAD/////AQAAAAAAAAAAAAAAAQnZ7Rrl1EAEv+Anzrkj2ayzxMCuvV5MrYfgjSENuz+fAd6UctCANBHTk5kAEEug/UCSBzpUbXhPMJE6uHGBMgjGAAAAAv////8AAAG7AQAAAB5odHRwczovL3d3dy5tb3ppbGxhLm9yZy9lbi1VUy8AAAAAAAAABQAAAAgAAAAPAAAAAP////8AAAAA/////wAAAAgAAAAPAAAAFwAAAAcAAAAXAAAABwAAABcAAAAHAAAAHgAAAAAAAAAA/////wAAAAD/////AAAAAP////8AAAAA/////wEAAAAAAAAAAAABAAAFtgBzAGMAcgBpAHAAdAAtAHMAcgBjACAAJwBzAGUAbABmACcAIABoAHQAdABwAHMAOgAvAC8AKgAuAG0AbwB6AGkAbABsAGEALgBuAGUAdAAgAGgAdAB0AHAAcwA6AC8ALwAqAC4AbQBvAHoAaQBsAGwAYQAuAG8AcgBnACAAaAB0AHQAcABzADoALwAvACoALgBtAG8AegBpAGwAbABhAC4AYwBvAG0AIAAnAHUAbgBzAGEAZgBlAC0AaQBuAGwAaQBuAGUAJwAgACcAdQBuAHMAYQBmAGUALQBlAHYAYQBsACcAIABoAHQAdABwAHMAOgAvAC8AdwB3AHcALgBnAG8AbwBnAGwAZQB0AGEAZwBtAGEAbgBhAGcAZQByAC4AYwBvAG0AIABoAHQAdABwAHMAOgAvAC8AdwB3AHcALgBnAG8AbwBnAGwAZQAtAGEAbgBhAGwAeQB0AGkAYwBzAC4AYwBvAG0AIABoAHQAdABwAHMAOgAvAC8AdABhAGcAbQBhAG4AYQBnAGUAcgAuAGcAbwBvAGcAbABlAC4AYwBvAG0AIABoAHQAdABwAHMAOgAvAC8AdwB3AHcALgB5AG8AdQB0AHUAYgBlAC4AYwBvAG0AIABoAHQAdABwAHMAOgAvAC8AcwAuAHkAdABpAG0AZwAuAGMAbwBtADsAIABpAG0AZwAtAHMAcgBjACAAJwBzAGUAbABmACcAIABoAHQAdABwAHMAOgAvAC8AKgAuAG0AbwB6AGkAbABsAGEALgBuAGUAdAAgAGgAdAB0AHAAcwA6AC8ALwAqAC4AbQBvAHoAaQBsAGwAYQAuAG8AcgBnACAAaAB0AHQAcABzADoALwAvACoALgBtAG8AegBpAGwAbABhAC4AYwBvAG0AIABkAGEAdABhADoAIABoAHQAdABwAHMAOgAvAC8AbQBvAHoAaQBsAGwAYQAuAG8AcgBnACAAaAB0AHQAcABzADoALwAvAHcAdwB3AC4AZwBvAG8AZwBsAGUAdABhAGcAbQBhAG4AYQBnAGUAcgAuAGMAbwBtACAAaAB0AHQAcABzADoALwAvAHcAdwB3AC4AZwBvAG8AZwBsAGUALQBhAG4AYQBsAHkAdABpAGMAcwAuAGMAbwBtACAAaAB0AHQAcABzADoALwAvAGEAZABzAGUAcgB2AGkAYwBlAC4AZwBvAG8AZwBsAGUALgBjAG8AbQAgAGgAdAB0AHAAcwA6AC8ALwBhAGQAcwBlAHIAdgBpAGMAZQAuAGcAbwBvAGcAbABlAC4AZABlACAAaAB0AHQAcABzADoALwAvAGEAZABzAGUAcgB2AGkAYwBlAC4AZwBvAG8AZwBsAGUALgBkAGsAIABoAHQAdABwAHMAOgAvAC8AYwByAGUAYQB0AGkAdgBlAGMAbwBtAG0AbwBuAHMALgBvAHIAZwAgAGgAdAB0AHAAcwA6AC8ALwBhAGQALgBkAG8AdQBiAGwAZQBjAGwAaQBjAGsALgBuAGUAdAA7ACAAZABlAGYAYQB1AGwAdAAtAHMAcgBjACAAJwBzAGUAbABmACcAIABoAHQAdABwAHMAOgAvAC8AKgAuAG0AbwB6AGkAbABsAGEALgBuAGUAdAAgAGgAdAB0AHAAcwA6AC8ALwAqAC4AbQBvAHoAaQBsAGwAYQAuAG8AcgBnACAAaAB0AHQAcABzADoALwAvACoALgBtAG8AegBpAGwAbABhAC4AYwBvAG0AOwAgAGYAcgBhAG0AZQAtAHMAcgBjACAAaAB0AHQAcABzADoALwAvAHcAdwB3AC4AZwBvAG8AZwBsAGUAdABhAGcAbQBhAG4AYQBnAGUAcgAuAGMAbwBtACAAaAB0AHQAcABzADoALwAvAHcAdwB3AC4AZwBvAG8AZwBsAGUALQBhAG4AYQBsAHkAdABpAGMAcwAuAGMAbwBtACAAaAB0AHQAcABzADoALwAvAHcAdwB3AC4AeQBvAHUAdAB1AGIAZQAtAG4AbwBjAG8AbwBrAGkAZQAuAGMAbwBtACAAaAB0AHQAcABzADoALwAvAHQAcgBhAGMAawBlAHIAdABlAHMAdAAuAG8AcgBnACAAaAB0AHQAcABzADoALwAvAHcAdwB3AC4AcwB1AHIAdgBlAHkAZwBpAHoAbQBvAC4AYwBvAG0AIABoAHQAdABwAHMAOgAvAC8AYQBjAGMAbwB1AG4AdABzAC4AZgBpAHIAZQBmAG8AeAAuAGMAbwBtACAAaAB0AHQAcABzADoALwAvAGEAYwBjAG8AdQBuAHQAcwAuAGYAaQByAGUAZgBvAHgALgBjAG8AbQAuAGMAbgAgAGgAdAB0AHAAcwA6AC8ALwB3AHcAdwAuAHkAbwB1AHQAdQBiAGUALgBjAG8AbQA7ACAAcwB0AHkAbABlAC0AcwByAGMAIAAnAHMAZQBsAGYAJwAgAGgAdAB0AHAAcwA6AC8ALwAqAC4AbQBvAHoAaQBsAGwAYQAuAG4AZQB0ACAAaAB0AHQAcABzADoALwAvACoALgBtAG8AegBpAGwAbABhAC4AbwByAGcAIABoAHQAdABwAHMAOgAvAC8AKgAuAG0AbwB6AGkAbABsAGEALgBjAG8AbQAgACcAdQBuAHMAYQBmAGUALQBpAG4AbABpAG4AZQAnADsAIABjAG8AbgBuAGUAYwB0AC0AcwByAGMAIAAnAHMAZQBsAGYAJwAgAGgAdAB0AHAAcwA6AC8ALwAqAC4AbQBvAHoAaQBsAGwAYQAuAG4AZQB0ACAAaAB0AHQAcABzADoALwAvACoALgBtAG8AegBpAGwAbABhAC4AbwByAGcAIABoAHQAdABwAHMAOgAvAC8AKgAuAG0AbwB6AGkAbABsAGEALgBjAG8AbQAgAGgAdAB0AHAAcwA6AC8ALwB3AHcAdwAuAGcAbwBvAGcAbABlAHQAYQBnAG0AYQBuAGEAZwBlAHIALgBjAG8AbQAgAGgAdAB0AHAAcwA6AC8ALwB3AHcAdwAuAGcAbwBvAGcAbABlAC0AYQBuAGEAbAB5AHQAaQBjAHMALgBjAG8AbQAgAGgAdAB0AHAAcwA6AC8ALwBhAGMAYwBvAHUAbgB0AHMALgBmAGkAcgBlAGYAbwB4AC4AYwBvAG0ALwAgAGgAdAB0AHAAcwA6AC8ALwBhAGMAYwBvAHUAbgB0AHMALgBmAGkAcgBlAGYAbwB4AC4AYwBvAG0ALgBjAG4ALwA7ACAAYwBoAGkAbABkAC0AcwByAGMAIABoAHQAdABwAHMAOgAvAC8AdwB3AHcALgBnAG8AbwBnAGwAZQB0AGEAZwBtAGEAbgBhAGcAZQByAC4AYwBvAG0AIABoAHQAdABwAHMAOgAvAC8AdwB3AHcALgBnAG8AbwBnAGwAZQAtAGEAbgBhAGwAeQB0AGkAYwBzAC4AYwBvAG0AIABoAHQAdABwAHMAOgAvAC8AdwB3AHcALgB5AG8AdQB0AHUAYgBlAC0AbgBvAGMAbwBvAGsAaQBlAC4AYwBvAG0AIABoAHQAdABwAHMAOgAvAC8AdAByAGEAYwBrAGUAcgB0AGUAcwB0AC4AbwByAGcAIABoAHQAdABwAHMAOgAvAC8AdwB3AHcALgBzAHUAcgB2AGUAeQBnAGkAegBtAG8ALgBjAG8AbQAgAGgAdAB0AHAAcwA6AC8ALwBhAGMAYwBvAHUAbgB0AHMALgBmAGkAcgBlAGYAbwB4AC4AYwBvAG0AIABoAHQAdABwAHMAOgAvAC8AYQBjAGMAbwB1AG4AdABzAC4AZgBpAHIAZQBmAG8AeAAuAGMAbwBtAC4AYwBuACAAaAB0AHQAcABzADoALwAvAHcAdwB3AC4AeQBvAHUAdAB1AGIAZQAuAGMAbwBtAAA=",
"output": {
"cspJSON": "{\"csp-policies\":[{\"child-src\":[\"https://www.googletagmanager.com\",\"https://www.google-analytics.com\",\"https://www.youtube-nocookie.com\",\"https://trackertest.org\",\"https://www.surveygizmo.com\",\"https://accounts.firefox.com\",\"https://accounts.firefox.com.cn\",\"https://www.youtube.com\"],\"connect-src\":[\"'self'\",\"https://*.mozilla.net\",\"https://*.mozilla.org\",\"https://*.mozilla.com\",\"https://www.googletagmanager.com\",\"https://www.google-analytics.com\",\"https://accounts.firefox.com/\",\"https://accounts.firefox.com.cn/\"],\"default-src\":[\"'self'\",\"https://*.mozilla.net\",\"https://*.mozilla.org\",\"https://*.mozilla.com\"],\"frame-src\":[\"https://www.googletagmanager.com\",\"https://www.google-analytics.com\",\"https://www.youtube-nocookie.com\",\"https://trackertest.org\",\"https://www.surveygizmo.com\",\"https://accounts.firefox.com\",\"https://accounts.firefox.com.cn\",\"https://www.youtube.com\"],\"img-src\":[\"'self'\",\"https://*.mozilla.net\",\"https://*.mozilla.org\",\"https://*.mozilla.com\",\"data:\",\"https://mozilla.org\",\"https://www.googletagmanager.com\",\"https://www.google-analytics.com\",\"https://adservice.google.com\",\"https://adservice.google.de\",\"https://adservice.google.dk\",\"https://creativecommons.org\",\"https://ad.doubleclick.net\"],\"report-only\":false,\"script-src\":[\"'self'\",\"https://*.mozilla.net\",\"https://*.mozilla.org\",\"https://*.mozilla.com\",\"'unsafe-inline'\",\"'unsafe-eval'\",\"https://www.googletagmanager.com\",\"https://www.google-analytics.com\",\"https://tagmanager.google.com\",\"https://www.youtube.com\",\"https://s.ytimg.com\"],\"style-src\":[\"'self'\",\"https://*.mozilla.net\",\"https://*.mozilla.org\",\"https://*.mozilla.com\",\"'unsafe-inline'\"]}]}",
// Within Bug 965637 we removed CSP from Principals. Already serialized Principals however should still deserialize correctly (just without the CSP).
// "cspJSON": "{\"csp-policies\":[{\"child-src\":[\"https://www.googletagmanager.com\",\"https://www.google-analytics.com\",\"https://www.youtube-nocookie.com\",\"https://trackertest.org\",\"https://www.surveygizmo.com\",\"https://accounts.firefox.com\",\"https://accounts.firefox.com.cn\",\"https://www.youtube.com\"],\"connect-src\":[\"'self'\",\"https://*.mozilla.net\",\"https://*.mozilla.org\",\"https://*.mozilla.com\",\"https://www.googletagmanager.com\",\"https://www.google-analytics.com\",\"https://accounts.firefox.com/\",\"https://accounts.firefox.com.cn/\"],\"default-src\":[\"'self'\",\"https://*.mozilla.net\",\"https://*.mozilla.org\",\"https://*.mozilla.com\"],\"frame-src\":[\"https://www.googletagmanager.com\",\"https://www.google-analytics.com\",\"https://www.youtube-nocookie.com\",\"https://trackertest.org\",\"https://www.surveygizmo.com\",\"https://accounts.firefox.com\",\"https://accounts.firefox.com.cn\",\"https://www.youtube.com\"],\"img-src\":[\"'self'\",\"https://*.mozilla.net\",\"https://*.mozilla.org\",\"https://*.mozilla.com\",\"data:\",\"https://mozilla.org\",\"https://www.googletagmanager.com\",\"https://www.google-analytics.com\",\"https://adservice.google.com\",\"https://adservice.google.de\",\"https://adservice.google.dk\",\"https://creativecommons.org\",\"https://ad.doubleclick.net\"],\"report-only\":false,\"script-src\":[\"'self'\",\"https://*.mozilla.net\",\"https://*.mozilla.org\",\"https://*.mozilla.com\",\"'unsafe-inline'\",\"'unsafe-eval'\",\"https://www.googletagmanager.com\",\"https://www.google-analytics.com\",\"https://tagmanager.google.com\",\"https://www.youtube.com\",\"https://s.ytimg.com\"],\"style-src\":[\"'self'\",\"https://*.mozilla.net\",\"https://*.mozilla.org\",\"https://*.mozilla.com\",\"'unsafe-inline'\"]}]}",
"URISpec": "https://www.mozilla.org/en-US/",
"originAttributes": {
"firstPartyDomain": "",
@ -65,14 +66,14 @@ add_task(async function test_deserialize_principal_with_csp() {
"privateBrowsingId": 0,
"userContextId": 0,
},
"cspJSON": "{\"csp-policies\":[{\"child-src\":[\"https://www.googletagmanager.com\",\"https://www.google-analytics.com\",\"https://www.youtube-nocookie.com\",\"https://trackertest.org\",\"https://www.surveygizmo.com\",\"https://accounts.firefox.com\",\"https://accounts.firefox.com.cn\",\"https://www.youtube.com\"],\"connect-src\":[\"'self'\",\"https://*.mozilla.net\",\"https://*.mozilla.org\",\"https://*.mozilla.com\",\"https://www.googletagmanager.com\",\"https://www.google-analytics.com\",\"https://accounts.firefox.com/\",\"https://accounts.firefox.com.cn/\"],\"default-src\":[\"'self'\",\"https://*.mozilla.net\",\"https://*.mozilla.org\",\"https://*.mozilla.com\"],\"frame-src\":[\"https://www.googletagmanager.com\",\"https://www.google-analytics.com\",\"https://www.youtube-nocookie.com\",\"https://trackertest.org\",\"https://www.surveygizmo.com\",\"https://accounts.firefox.com\",\"https://accounts.firefox.com.cn\",\"https://www.youtube.com\"],\"img-src\":[\"'self'\",\"https://*.mozilla.net\",\"https://*.mozilla.org\",\"https://*.mozilla.com\",\"data:\",\"https://mozilla.org\",\"https://www.googletagmanager.com\",\"https://www.google-analytics.com\",\"https://adservice.google.com\",\"https://adservice.google.de\",\"https://adservice.google.dk\",\"https://creativecommons.org\",\"https://ad.doubleclick.net\"],\"report-only\":false,\"script-src\":[\"'self'\",\"https://*.mozilla.net\",\"https://*.mozilla.org\",\"https://*.mozilla.com\",\"'unsafe-inline'\",\"'unsafe-eval'\",\"https://www.googletagmanager.com\",\"https://www.google-analytics.com\",\"https://tagmanager.google.com\",\"https://www.youtube.com\",\"https://s.ytimg.com\"],\"style-src\":[\"'self'\",\"https://*.mozilla.net\",\"https://*.mozilla.org\",\"https://*.mozilla.com\",\"'unsafe-inline'\"]}]}",
// Within Bug 965637 we removed CSP from Principals. Already serialized Principals however should still deserialize correctly (just without the CSP).
// "cspJSON": "{\"csp-policies\":[{\"child-src\":[\"https://www.googletagmanager.com\",\"https://www.google-analytics.com\",\"https://www.youtube-nocookie.com\",\"https://trackertest.org\",\"https://www.surveygizmo.com\",\"https://accounts.firefox.com\",\"https://accounts.firefox.com.cn\",\"https://www.youtube.com\"],\"connect-src\":[\"'self'\",\"https://*.mozilla.net\",\"https://*.mozilla.org\",\"https://*.mozilla.com\",\"https://www.googletagmanager.com\",\"https://www.google-analytics.com\",\"https://accounts.firefox.com/\",\"https://accounts.firefox.com.cn/\"],\"default-src\":[\"'self'\",\"https://*.mozilla.net\",\"https://*.mozilla.org\",\"https://*.mozilla.com\"],\"frame-src\":[\"https://www.googletagmanager.com\",\"https://www.google-analytics.com\",\"https://www.youtube-nocookie.com\",\"https://trackertest.org\",\"https://www.surveygizmo.com\",\"https://accounts.firefox.com\",\"https://accounts.firefox.com.cn\",\"https://www.youtube.com\"],\"img-src\":[\"'self'\",\"https://*.mozilla.net\",\"https://*.mozilla.org\",\"https://*.mozilla.com\",\"data:\",\"https://mozilla.org\",\"https://www.googletagmanager.com\",\"https://www.google-analytics.com\",\"https://adservice.google.com\",\"https://adservice.google.de\",\"https://adservice.google.dk\",\"https://creativecommons.org\",\"https://ad.doubleclick.net\"],\"report-only\":false,\"script-src\":[\"'self'\",\"https://*.mozilla.net\",\"https://*.mozilla.org\",\"https://*.mozilla.com\",\"'unsafe-inline'\",\"'unsafe-eval'\",\"https://www.googletagmanager.com\",\"https://www.google-analytics.com\",\"https://tagmanager.google.com\",\"https://www.youtube.com\",\"https://s.ytimg.com\"],\"style-src\":[\"'self'\",\"https://*.mozilla.net\",\"https://*.mozilla.org\",\"https://*.mozilla.com\",\"'unsafe-inline'\"]}]}",
},
},
];
for (let test of serializedPrincipalsFromFirefox) {
let principal = E10SUtils.deserializePrincipal(test.input);
is(principal.cspJSON, test.output.cspJSON, "should have CSP");
for (let key in principal.originAttributes) {
is(principal.originAttributes[key], test.output.originAttributes[key], `Ensure value of ${key} is ${test.output.originAttributes[key]}`);

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

@ -98,7 +98,6 @@ add_task(async function test_realHistoryCheck() {
testData.output.URISpec = principal.URI.spec;
}
testData.output.originAttributes = principal.originAttributes;
testData.output.cspJSON = principal.cspJSON;
tests.push(testData);
}
@ -118,7 +117,6 @@ add_task(async function test_realHistoryCheck() {
"privateBrowsingId": 0,
"userContextId": 0,
},
"cspJSON": "{}",
},
},
{
@ -131,7 +129,6 @@ add_task(async function test_realHistoryCheck() {
"privateBrowsingId": 0,
"userContextId": 0,
},
"cspJSON": "{}",
},
},
{
@ -144,7 +141,6 @@ add_task(async function test_realHistoryCheck() {
"privateBrowsingId": 0,
"userContextId": 0,
},
"cspJSON": "{}",
},
},
{
@ -157,14 +153,12 @@ add_task(async function test_realHistoryCheck() {
"privateBrowsingId": 0,
"userContextId": 0,
},
"cspJSON": "{}",
},
},
];
for (let test of serializedPrincipalsFromFirefox) {
let principal = E10SUtils.deserializePrincipal(test.input);
is(principal.cspJSON, test.output.cspJSON, "should have CSP");
for (let key in principal.originAttributes) {
is(principal.originAttributes[key], test.output.originAttributes[key], `Ensure value of ${key} is ${test.output.originAttributes[key]}`);

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

@ -35,6 +35,7 @@ let LEGACY_ACTORS = {
matches: ["about:logins"],
module: "resource:///actors/AboutLoginsChild.jsm",
events: {
"AboutLoginsCreateLogin": {wantUntrusted: true},
"AboutLoginsDeleteLogin": {wantUntrusted: true},
"AboutLoginsOpenSite": {wantUntrusted: true},
"AboutLoginsUpdateLogin": {wantUntrusted: true},
@ -546,6 +547,7 @@ const listeners = {
},
mm: {
"AboutLogins:CreateLogin": ["AboutLoginsParent"],
"AboutLogins:DeleteLogin": ["AboutLoginsParent"],
"AboutLogins:OpenSite": ["AboutLoginsParent"],
"AboutLogins:Subscribe": ["AboutLoginsParent"],

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

@ -115,6 +115,10 @@ static const RedirEntry kRedirMap[] = {
nsIAboutModule::URI_MUST_LOAD_IN_CHILD |
nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
nsIAboutModule::ALLOW_SCRIPT | nsIAboutModule::HIDE_FROM_ABOUTABOUT},
{"protections", "chrome://browser/content/protections.html",
nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
nsIAboutModule::URI_MUST_LOAD_IN_CHILD | nsIAboutModule::ALLOW_SCRIPT |
nsIAboutModule::URI_CAN_LOAD_IN_PRIVILEGED_CHILD},
};
static nsAutoCString GetAboutModuleName(nsIURI* aURI) {

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

@ -19,6 +19,7 @@ pages = [
'policies',
'preferences',
'privatebrowsing',
'protections',
'reader',
'restartrequired',
'rights',

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

@ -31,6 +31,10 @@ class AboutLoginsChild extends ActorChild {
});
break;
}
case "AboutLoginsCreateLogin": {
this.mm.sendAsyncMessage("AboutLogins:CreateLogin", {login: event.detail});
break;
}
case "AboutLoginsDeleteLogin": {
this.mm.sendAsyncMessage("AboutLogins:DeleteLogin", {login: event.detail});
break;

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

@ -39,12 +39,26 @@ const isValidLogin = login => {
};
const convertSubjectToLogin = subject => {
subject.QueryInterface(Ci.nsILoginMetaInfo).QueryInterface(Ci.nsILoginInfo);
const login = LoginHelper.loginToVanillaObject(subject);
if (!isValidLogin(login)) {
return null;
}
return login;
subject.QueryInterface(Ci.nsILoginMetaInfo).QueryInterface(Ci.nsILoginInfo);
const login = LoginHelper.loginToVanillaObject(subject);
if (!isValidLogin(login)) {
return null;
}
return augmentVanillaLoginObject(login);
};
const augmentVanillaLoginObject = login => {
let title;
try {
title = (new URL(login.hostname)).host;
} catch (ex) {
title = login.hostname;
}
title = title.replace(/^http(s)?:\/\//, "").
replace(/^www\d*\./, "");
return Object.assign({}, login, {
title,
});
};
var AboutLoginsParent = {
@ -60,6 +74,16 @@ var AboutLoginsParent = {
}
switch (message.name) {
case "AboutLogins:CreateLogin": {
let newLogin = message.data.login;
Object.assign(newLogin, {
formSubmitURL: "",
usernameField: "",
passwordField: "",
});
Services.logins.addLogin(LoginHelper.vanillaObjectToLogin(newLogin));
break;
}
case "AboutLogins:DeleteLogin": {
let login = LoginHelper.vanillaObjectToLogin(message.data.login);
Services.logins.removeLogin(login);
@ -68,8 +92,8 @@ var AboutLoginsParent = {
case "AboutLogins:OpenSite": {
let guid = message.data.login.guid;
let logins = LoginHelper.searchLoginsWithObject({guid});
if (!logins || logins.length != 1) {
log.warn(`AboutLogins:OpenSite: expected to find a login for guid: ${guid} but found ${(logins || []).length}`);
if (logins.length != 1) {
log.warn(`AboutLogins:OpenSite: expected to find a login for guid: ${guid} but found ${logins.length}`);
return;
}
@ -91,8 +115,8 @@ var AboutLoginsParent = {
case "AboutLogins:UpdateLogin": {
let loginUpdates = message.data.login;
let logins = LoginHelper.searchLoginsWithObject({guid: loginUpdates.guid});
if (!logins || logins.length != 1) {
log.warn(`AboutLogins:UpdateLogin: expected to find a login for guid: ${loginUpdates.guid} but found ${(logins || []).length}`);
if (logins.length != 1) {
log.warn(`AboutLogins:UpdateLogin: expected to find a login for guid: ${loginUpdates.guid} but found ${logins.length}`);
return;
}
@ -232,6 +256,7 @@ var AboutLoginsParent = {
return Services.logins
.getAllLogins()
.filter(isValidLogin)
.map(LoginHelper.loginToVanillaObject);
.map(LoginHelper.loginToVanillaObject)
.map(augmentVanillaLoginObject);
},
};

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

@ -17,6 +17,7 @@ header {
align-items: center;
background-color: var(--in-content-box-background);
border-bottom: 1px solid var(--in-content-box-border-color);
padding: 0 18px;
}
login-filter {
@ -26,6 +27,7 @@ login-filter {
login-list {
grid-area: logins;
overflow: hidden auto;
}
login-item {
@ -35,7 +37,12 @@ login-item {
#branding-logo {
height: 32px;
margin-inline-end: 18px;
}
#create-login-button {
margin-inline-start: 18px;
margin-inline-end: 0;
}
:root:not(.official-branding) #branding-logo {

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

@ -10,7 +10,9 @@
### need to be applied to the composed node where they can be moved to the proper
### descendant after translation.
about-logins-page-title = Login Manager
about-logins-page-title = Logins & Passwords
create-login-button = New Login
login-filter =
.placeholder = Search Logins
@ -24,20 +26,21 @@ login-list =
login-item =
.cancel-button = Cancel
.copied-password-button = ✓ Copied!
.copied-username-button = ✓ Copied!
.copy-password-button = Copy
.copy-username-button = Copy
.delete-button = Delete
.edit-button = Edit
.hostname-label = Website Address
.modal-input-reveal-checkbox-hide = Hide password
.modal-input-reveal-checkbox-show = Show password
.copied-password-button = ✓ Copied!
.copied-username-button = ✓ Copied!
.copy-password-button = Copy
.copy-username-button = Copy
.new-login-title = New Entry
.open-site-button = Launch
.password-label = Password
.save-changes-button = Save Changes
.time-created = Created: { DATETIME($timeCreated, day: "numeric", month: "long", year: "numeric") }
.time-changed = Last changed: { DATETIME($timeChanged, day: "numeric", month: "long", year: "numeric") }
.time-changed = Last modified: { DATETIME($timeChanged, day: "numeric", month: "long", year: "numeric") }
.time-used = Last used: { DATETIME($timeUsed, day: "numeric", month: "long", year: "numeric") }
.username-label = Username

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

@ -25,6 +25,7 @@
<img id="branding-logo" src="chrome://branding/content/aboutlogins.svg" alt=""/>
<login-filter data-l10n-id="login-filter"
data-l10n-attrs="placeholder"></login-filter>
<button id="create-login-button" data-l10n-id="create-login-button"></button>
</header>
<login-list data-l10n-id="login-list"
data-l10n-attrs="count"
@ -41,6 +42,7 @@
hostname-label,
modal-input-reveal-checkbox-hide,
modal-input-reveal-checkbox-show,
new-login-title,
open-site-button,
password-label,
save-changes-button,
@ -77,7 +79,8 @@
<div class="detail-row">
<label>
<span class="hostname-label field-label"></span>
<span class="hostname"/>
<span class="hostname-saved-value"></span>
<input type="text" name="hostname"/>
</label>
<button class="open-site-button"></button>
</div>

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

@ -7,6 +7,12 @@ let gElements = {};
document.addEventListener("DOMContentLoaded", () => {
gElements.loginList = document.querySelector("login-list");
gElements.loginItem = document.querySelector("login-item");
gElements.newLoginButton = document.querySelector("#create-login-button");
gElements.newLoginButton.addEventListener("click", () => {
gElements.loginItem.setLogin({});
gElements.loginList.clearSelection();
});
document.dispatchEvent(new CustomEvent("AboutLoginsInit", {bubbles: true}));
}, {once: true});
@ -19,6 +25,7 @@ window.addEventListener("AboutLoginsChromeToContent", event => {
}
case "LoginAdded": {
gElements.loginList.loginAdded(event.detail.value);
gElements.loginItem.loginAdded(event.detail.value);
break;
}
case "LoginModified": {

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

@ -7,6 +7,5 @@
}
input {
margin: 18px;
flex: auto;
}

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

@ -8,6 +8,11 @@
padding-right: 40px;
}
:host([isNewLogin]) .hostname-saved-value,
:host([isNewLogin]) copy-to-clipboard-button,
:host([isNewLogin]) .open-site-button,
:host([isNewLogin]) .meta-info,
:host(:not([isNewLogin])) input[name="hostname"],
:host(:not([editing])) .save-changes-button,
:host(:not([editing])) .cancel-button {
display: none;

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

@ -57,6 +57,7 @@ class LoginItem extends ReflectedFluentElement {
"hostname-label",
"modal-input-reveal-checkbox-hide",
"modal-input-reveal-checkbox-show",
"new-login-title",
"open-site-button",
"password-label",
"save-changes-button",
@ -97,6 +98,14 @@ class LoginItem extends ReflectedFluentElement {
.setAttribute("reveal-checkbox-show", this.getAttribute(attrName));
break;
}
case "new-login-title": {
let title = this.shadowRoot.querySelector(".title");
title.setAttribute(attrName, this.getAttribute(attrName));
if (!this._login.title) {
title.textContent = this.getAttribute(attrName);
}
break;
}
default:
return false;
}
@ -110,9 +119,10 @@ class LoginItem extends ReflectedFluentElement {
timeUsed: this._login.timeLastUsed || "",
};
document.l10n.setAttributes(this, "login-item", l10nArgs);
let hostnameNoScheme = this._login.hostname && new URL(this._login.hostname).hostname;
this.shadowRoot.querySelector(".title").textContent = hostnameNoScheme || "";
this.shadowRoot.querySelector(".hostname").textContent = this._login.hostname || "";
let title = this.shadowRoot.querySelector(".title");
title.textContent = this._login.title || title.getAttribute("new-login-title");
this.shadowRoot.querySelector(".hostname-saved-value").textContent = this._login.hostname || "";
this.shadowRoot.querySelector("modal-input[name='username']").setAttribute("value", this._login.username || "");
this.shadowRoot.querySelector("modal-input[name='password']").setAttribute("value", this._login.password || "");
}
@ -154,21 +164,19 @@ class LoginItem extends ReflectedFluentElement {
return;
}
if (event.target.classList.contains("save-changes-button")) {
let loginUpdates = {
guid: this._login.guid,
};
let formUsername = this.shadowRoot.querySelector("modal-input[name='username']").value.trim();
if (formUsername != this._login.username) {
loginUpdates.username = formUsername;
let loginUpdates = this._loginFromForm();
if (this._login.guid) {
loginUpdates.guid = this._login.guid;
document.dispatchEvent(new CustomEvent("AboutLoginsUpdateLogin", {
bubbles: true,
detail: loginUpdates,
}));
} else {
document.dispatchEvent(new CustomEvent("AboutLoginsCreateLogin", {
bubbles: true,
detail: loginUpdates,
}));
}
let formPassword = this.shadowRoot.querySelector("modal-input[name='password']").value.trim();
if (formPassword != this._login.password) {
loginUpdates.password = formPassword;
}
document.dispatchEvent(new CustomEvent("AboutLoginsUpdateLogin", {
bubbles: true,
detail: loginUpdates,
}));
}
break;
}
@ -176,17 +184,29 @@ class LoginItem extends ReflectedFluentElement {
}
setLogin(login) {
this._login = login;
this.toggleAttribute("isNewLogin", !login.guid);
this.toggleEditing(!login.guid);
this.render();
}
loginAdded(login) {
if (this._login.guid ||
!window.AboutLoginsUtils.doLoginsMatch(login, this._loginFromForm())) {
return;
}
this.toggleEditing(false);
this._login = login;
this.render();
}
loginModified(login) {
if (login.guid != this._login.guid) {
if (this._login.guid != login.guid) {
return;
}
this._login = login;
this.toggleEditing(false);
this.render();
}
@ -200,10 +220,24 @@ class LoginItem extends ReflectedFluentElement {
toggleEditing(force) {
let shouldEdit = force !== undefined ? force : !this.hasAttribute("editing");
if (!shouldEdit) {
this.removeAttribute("isNewLogin");
}
this.shadowRoot.querySelector(".edit-button").disabled = shouldEdit;
this.shadowRoot.querySelectorAll("modal-input")
.forEach(el => el.toggleAttribute("editing", shouldEdit));
this.toggleAttribute("editing", shouldEdit);
}
_loginFromForm() {
return {
username: this.shadowRoot.querySelector("modal-input[name='username']").value.trim(),
password: this.shadowRoot.querySelector("modal-input[name='password']").value.trim(),
hostname: this.hasAttribute("isNewLogin") ? this.shadowRoot.querySelector("input[name='hostname']").value.trim()
: this.shadowRoot.querySelector(".hostname-saved-value").textContent,
};
}
}
customElements.define("login-item", LoginItem);

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

@ -29,6 +29,7 @@ class LoginList extends ReflectedFluentElement {
render() {
let list = this.shadowRoot.querySelector("ol");
list.textContent = "";
for (let login of this._logins) {
list.append(new LoginListItem(login));
}
@ -65,10 +66,10 @@ class LoginList extends ReflectedFluentElement {
if (this._selectedItem.getAttribute("guid") == event.detail.guid) {
return;
}
this._selectedItem.classList.toggle("selected", false);
this._selectedItem.classList.remove("selected");
}
this._selectedItem = this.shadowRoot.querySelector(`login-list-item[guid="${event.detail.guid}"]`);
this._selectedItem.classList.toggle("selected", true);
this._selectedItem.classList.add("selected");
break;
}
}
@ -82,9 +83,15 @@ class LoginList extends ReflectedFluentElement {
return this.reflectedFluentIDs;
}
clearSelection() {
if (!this._selectedItem) {
return;
}
this._selectedItem.classList.remove("selected");
this._selectedItem = null;
}
setLogins(logins) {
let list = this.shadowRoot.querySelector("ol");
list.textContent = "";
this._logins = logins;
this.render();
}
@ -93,6 +100,7 @@ class LoginList extends ReflectedFluentElement {
this._logins.push(login);
let list = this.shadowRoot.querySelector("ol");
list.append(new LoginListItem(login));
document.l10n.setAttributes(this, "login-list", {count: this._logins.length});
}
loginModified(login) {
@ -120,6 +128,7 @@ class LoginList extends ReflectedFluentElement {
break;
}
}
document.l10n.setAttributes(this, "login-list", {count: this._logins.length});
}
}
customElements.define("login-list", LoginList);

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

@ -8,6 +8,7 @@
--reveal-button-opacity-active: 1;
display: flex;
align-items: center;
}
:host([editing]) .locked-value,

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

@ -54,19 +54,25 @@ add_task(async function setup() {
add_task(async function test_empty_item() {
ok(gLoginItem, "loginItem exists");
is(gLoginItem.shadowRoot.querySelector(".hostname").textContent, "", "hostname should be blank");
is(gLoginItem.shadowRoot.querySelector(".hostname-saved-value").textContent, "", "hostname should be blank");
is(gLoginItem.shadowRoot.querySelector("modal-input[name='username']").value, "", "username should be blank");
is(gLoginItem.shadowRoot.querySelector("modal-input[name='password']").value, "", "password should be blank");
is(gLoginItem.shadowRoot.querySelector(".time-created").textContent, "", "time-created should be blank");
is(gLoginItem.shadowRoot.querySelector(".time-changed").textContent, "", "time-changed should be blank");
is(gLoginItem.shadowRoot.querySelector(".time-used").textContent, "", "time-used should be blank");
is(gLoginItem.shadowRoot.querySelector(".time-created").textContent, "", "time-created should be blank when undefined");
is(gLoginItem.shadowRoot.querySelector(".time-changed").textContent, "", "time-changed should be blank when undefined");
is(gLoginItem.shadowRoot.querySelector(".time-used").textContent, "", "time-used should be blank when undefined");
});
add_task(async function test_set_login() {
gLoginItem.setLogin(TEST_LOGIN_1);
await asyncElementRendered();
is(gLoginItem.shadowRoot.querySelector(".hostname").textContent, TEST_LOGIN_1.hostname, "hostname should be populated");
ok(!gLoginItem.hasAttribute("editing"), "loginItem should not be in 'edit' mode");
ok(!gLoginItem.hasAttribute("isNewLogin"), "loginItem should not be in 'isNewLogin' mode");
let savedHostname = gLoginItem.shadowRoot.querySelector(".hostname-saved-value");
is(getComputedStyle(savedHostname).display, "inline", ".hostname-saved-value should be visible for non-editing existing logins");
let hostnameInput = gLoginItem.shadowRoot.querySelector("input[name='hostname']");
is(getComputedStyle(hostnameInput).display, "none", "input[name='hostname'] should be hidden for non-editing existing logins");
is(savedHostname.textContent, TEST_LOGIN_1.hostname, "hostname should be populated");
is(gLoginItem.shadowRoot.querySelector("modal-input[name='username']").value, TEST_LOGIN_1.username, "username should be populated");
is(gLoginItem.shadowRoot.querySelector("modal-input[name='password']").value, TEST_LOGIN_1.password, "password should be populated");
is(gLoginItem.shadowRoot.querySelector(".time-created").textContent, TEST_LOGIN_1.timeCreated, "time-created should be populated");
@ -74,12 +80,95 @@ add_task(async function test_set_login() {
is(gLoginItem.shadowRoot.querySelector(".time-used").textContent, TEST_LOGIN_1.timeLastUsed, "time-used should be populated");
});
add_task(async function test_edit_login() {
gLoginItem.setLogin(TEST_LOGIN_1);
gLoginItem.shadowRoot.querySelector(".edit-button").click();
await asyncElementRendered();
ok(gLoginItem.hasAttribute("editing"), "loginItem should be in 'edit' mode");
ok(!gLoginItem.hasAttribute("isNewLogin"), "loginItem should not be in 'isNewLogin' mode");
let savedHostname = gLoginItem.shadowRoot.querySelector(".hostname-saved-value");
is(getComputedStyle(savedHostname).display, "inline", ".hostname-saved-value should be visible for editing existing logins");
let hostnameInput = gLoginItem.shadowRoot.querySelector("input[name='hostname']");
is(getComputedStyle(hostnameInput).display, "none", "input[name='hostname'] should be hidden for editing existing logins");
is(savedHostname.textContent, TEST_LOGIN_1.hostname, "hostname should be populated");
is(gLoginItem.shadowRoot.querySelector("modal-input[name='username']").value, TEST_LOGIN_1.username, "username should be populated");
is(gLoginItem.shadowRoot.querySelector("modal-input[name='password']").value, TEST_LOGIN_1.password, "password should be populated");
is(gLoginItem.shadowRoot.querySelector(".time-created").textContent, TEST_LOGIN_1.timeCreated, "time-created should be populated");
is(gLoginItem.shadowRoot.querySelector(".time-changed").textContent, TEST_LOGIN_1.timePasswordChanged, "time-changed should be populated");
is(gLoginItem.shadowRoot.querySelector(".time-used").textContent, TEST_LOGIN_1.timeLastUsed, "time-used should be populated");
gLoginItem.shadowRoot.querySelector("modal-input[name='username']").value = "newUsername";
gLoginItem.shadowRoot.querySelector("modal-input[name='password']").value = "newPassword";
let updateEventDispatched = false;
document.addEventListener("AboutLoginsUpdateLogin", event => {
is(event.detail.guid, TEST_LOGIN_1.guid, "event should include guid");
is(event.detail.hostname, TEST_LOGIN_1.hostname, "event should include hostname");
is(event.detail.username, "newUsername", "event should include new username");
is(event.detail.password, "newPassword", "event should include new password");
updateEventDispatched = true;
}, {once: true});
gLoginItem.shadowRoot.querySelector(".save-changes-button").click();
ok(updateEventDispatched, "Clicking the .save-changes-button should dispatch the AboutLoginsUpdateLogin event");
});
add_task(async function test_edit_login_cancel() {
for (let login of [{}, TEST_LOGIN_1]) {
let isNewLogin = !login.username;
info("Testing with" + (isNewLogin ? "out" : "") + " a login");
gLoginItem.setLogin(login);
gLoginItem.shadowRoot.querySelector(".edit-button").click();
ok(gLoginItem.hasAttribute("editing"), "loginItem should be in 'edit' mode");
is(gLoginItem.hasAttribute("isNewLogin"), isNewLogin,
"loginItem should " + (isNewLogin ? "" : "not ") + "be in 'isNewLogin' mode");
gLoginItem.shadowRoot.querySelector(".cancel-button").click();
ok(!gLoginItem.hasAttribute("editing"), "loginItem should not be in 'edit' mode");
ok(!gLoginItem.hasAttribute("isNewLogin"), "loginItem should not be in 'isNewLogin' mode");
}
});
add_task(async function test_set_login_empty() {
gLoginItem.setLogin({});
await asyncElementRendered();
ok(gLoginItem.hasAttribute("editing"), "loginItem should be in 'edit' mode");
ok(gLoginItem.hasAttribute("isNewLogin"), "loginItem should be in 'isNewLogin' mode");
let savedHostname = gLoginItem.shadowRoot.querySelector(".hostname-saved-value");
is(getComputedStyle(savedHostname).display, "none", ".hostname-saved-value should be hidden for new logins");
let hostnameInput = gLoginItem.shadowRoot.querySelector("input[name='hostname']");
is(getComputedStyle(hostnameInput).display, "inline", "input[name='hostname'] should be visible for new logins");
is(gLoginItem.shadowRoot.querySelector("modal-input[name='username']").value, "", "username should be empty");
is(gLoginItem.shadowRoot.querySelector("modal-input[name='password']").value, "", "password should be empty");
is(gLoginItem.shadowRoot.querySelector(".time-created").textContent, "", "time-created should be blank when undefined");
is(gLoginItem.shadowRoot.querySelector(".time-changed").textContent, "", "time-changed should be blank when undefined");
is(gLoginItem.shadowRoot.querySelector(".time-used").textContent, "", "time-used should be blank when undefined");
hostnameInput.value = "https://example.com/foo";
gLoginItem.shadowRoot.querySelector("modal-input[name='username']").value = "user1";
gLoginItem.shadowRoot.querySelector("modal-input[name='password']").value = "pass1";
let createEventDispatched = false;
document.addEventListener("AboutLoginsCreateLogin", event => {
is(event.detail.guid, undefined, "event should not include guid");
is(event.detail.hostname, "https://example.com/foo", "event should include hostname");
is(event.detail.username, "user1", "event should include new username");
is(event.detail.password, "pass1", "event should include new password");
createEventDispatched = true;
}, {once: true});
gLoginItem.shadowRoot.querySelector(".save-changes-button").click();
ok(createEventDispatched, "Clicking the .save-changes-button should dispatch the AboutLoginsCreateLogin event");
});
add_task(async function test_different_login_modified() {
gLoginItem.setLogin(TEST_LOGIN_1);
let otherLogin = Object.assign({}, TEST_LOGIN_1, {username: "fakeuser", guid: "fakeguid"});
gLoginItem.loginModified(otherLogin);
await asyncElementRendered();
is(gLoginItem.shadowRoot.querySelector(".hostname").textContent, TEST_LOGIN_1.hostname, "hostname should be unchanged");
is(gLoginItem.shadowRoot.querySelector(".hostname-saved-value").textContent, TEST_LOGIN_1.hostname, "hostname should be unchanged");
is(gLoginItem.shadowRoot.querySelector("modal-input[name='username']").value, TEST_LOGIN_1.username, "username should be unchanged");
is(gLoginItem.shadowRoot.querySelector("modal-input[name='password']").value, TEST_LOGIN_1.password, "password should be unchanged");
is(gLoginItem.shadowRoot.querySelector(".time-created").textContent, TEST_LOGIN_1.timeCreated, "time-created should be unchanged");
@ -88,11 +177,12 @@ add_task(async function test_different_login_modified() {
});
add_task(async function test_different_login_removed() {
gLoginItem.setLogin(TEST_LOGIN_1);
let otherLogin = Object.assign({}, TEST_LOGIN_1, {username: "fakeuser", guid: "fakeguid"});
gLoginItem.loginRemoved(otherLogin);
await asyncElementRendered();
is(gLoginItem.shadowRoot.querySelector(".hostname").textContent, TEST_LOGIN_1.hostname, "hostname should be unchanged");
is(gLoginItem.shadowRoot.querySelector(".hostname-saved-value").textContent, TEST_LOGIN_1.hostname, "hostname should be unchanged");
is(gLoginItem.shadowRoot.querySelector("modal-input[name='username']").value, TEST_LOGIN_1.username, "username should be unchanged");
is(gLoginItem.shadowRoot.querySelector("modal-input[name='password']").value, TEST_LOGIN_1.password, "password should be unchanged");
is(gLoginItem.shadowRoot.querySelector(".time-created").textContent, TEST_LOGIN_1.timeCreated, "time-created should be unchanged");
@ -101,11 +191,12 @@ add_task(async function test_different_login_removed() {
});
add_task(async function test_login_modified() {
gLoginItem.setLogin(TEST_LOGIN_1);
let modifiedLogin = Object.assign({}, TEST_LOGIN_1, {username: "updateduser"});
gLoginItem.loginModified(modifiedLogin);
await asyncElementRendered();
is(gLoginItem.shadowRoot.querySelector(".hostname").textContent, modifiedLogin.hostname, "hostname should be updated");
is(gLoginItem.shadowRoot.querySelector(".hostname-saved-value").textContent, modifiedLogin.hostname, "hostname should be updated");
is(gLoginItem.shadowRoot.querySelector("modal-input[name='username']").value, modifiedLogin.username, "username should be updated");
is(gLoginItem.shadowRoot.querySelector("modal-input[name='password']").value, modifiedLogin.password, "password should be updated");
is(gLoginItem.shadowRoot.querySelector(".time-created").textContent, modifiedLogin.timeCreated, "time-created should be updated");
@ -114,15 +205,16 @@ add_task(async function test_login_modified() {
});
add_task(async function test_login_removed() {
gLoginItem.setLogin(TEST_LOGIN_1);
gLoginItem.loginRemoved(TEST_LOGIN_1);
await asyncElementRendered();
is(gLoginItem.shadowRoot.querySelector(".hostname").textContent, "", "hostname should be cleared");
is(gLoginItem.shadowRoot.querySelector(".hostname-saved-value").textContent, "", "hostname should be cleared");
is(gLoginItem.shadowRoot.querySelector("modal-input[name='username']").value, "", "username should be cleared");
is(gLoginItem.shadowRoot.querySelector("modal-input[name='password']").value, "", "password should be cleared");
is(gLoginItem.shadowRoot.querySelector(".time-created").textContent, "", "time-created should be cleared");
is(gLoginItem.shadowRoot.querySelector(".time-changed").textContent, "", "time-changed should be cleared");
is(gLoginItem.shadowRoot.querySelector(".time-used").textContent, "", "time-used should be cleared");
is(gLoginItem.shadowRoot.querySelector(".time-created").textContent, "", "time-created should be blank when undefined");
is(gLoginItem.shadowRoot.querySelector(".time-changed").textContent, "", "time-changed should be blank when undefined");
is(gLoginItem.shadowRoot.querySelector(".time-used").textContent, "", "time-used should be blank when undefined");
});
</script>

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

@ -87,15 +87,15 @@ async function test_cookie_settings({
"Cookie lifetime pref lock status should be what is expected");
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:preferences");
await tab.linkedBrowser.contentWindow.gotoPref("panePrivacy");
// eslint-disable-next-line no-shadow
await ContentTask.spawn(tab.linkedBrowser, {cookiesEnabled, cookieSettingsLocked}, async function({cookiesEnabled, cookieSettingsLocked}) {
content.setTimeout(() => {
let deleteOnCloseCheckbox = content.document.getElementById("deleteOnClose");
let deleteOnCloseCheckbox = content.document.getElementById("deleteOnClose");
isnot(deleteOnCloseCheckbox, null, "deleteOnCloseCheckbox should not be null.");
let expectControlsDisabled = !cookiesEnabled || cookieSettingsLocked;
is(deleteOnCloseCheckbox.disabled, expectControlsDisabled,
"\"Delete cookies when Firefox is closed\" checkbox disabled status should match expected");
}, 0);
let expectControlsDisabled = !cookiesEnabled || cookieSettingsLocked;
is(deleteOnCloseCheckbox.disabled, expectControlsDisabled,
"\"Delete cookies when Firefox is closed\" checkbox disabled status should match expected");
});
BrowserTestUtils.removeTab(tab);

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

@ -220,8 +220,8 @@ this.windows = class extends ExtensionAPI {
args.appendElement(context.principal); // originPrincipal - not important.
args.appendElement(principal); // triggeringPrincipal
args.appendElement(Cc["@mozilla.org/supports-PRBool;1"].createInstance(Ci.nsISupportsPRBool)); // allowInheritPrincipal
// Bug 965637, query the CSP from the doc instead of the Principal
args.appendElement(principal.csp); // csp
// There is no CSP associated with this extension, hence we explicitly pass null as the CSP argument.
args.appendElement(null); // csp
let features = ["chrome"];

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

@ -47,6 +47,7 @@ DIRS += [
'pocket',
'preferences',
'privatebrowsing',
'protections',
'protocolhandler',
'resistfingerprinting',
'search',

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

@ -57,20 +57,25 @@ export class _Trailhead extends React.PureComponent {
link.rel = "localization";
});
if (this.props.fxaEndpoint && !this.fxaMetricsInitialized) {
await this.componentWillUpdate(this.props);
}
// Get the fxa data if we don't have it yet from mount or update
async componentWillUpdate(props) {
if (props.fxaEndpoint && !this.fxaMetricsInitialized) {
try {
this.fxaMetricsInitialized = true;
const url = new URL(`${this.props.fxaEndpoint}/metrics-flow?entrypoint=activity-stream-firstrun&form_type=email`);
const url = new URL(`${props.fxaEndpoint}/metrics-flow?entrypoint=activity-stream-firstrun&form_type=email`);
this.addUtmParams(url);
const response = await fetch(url, {credentials: "omit"});
if (response.status === 200) {
const {deviceId, flowId, flowBeginTime} = await response.json();
this.setState({deviceId, flowId, flowBeginTime});
} else {
this.props.dispatch(ac.OnlyToMain({type: at.TELEMETRY_UNDESIRED_EVENT, data: {event: "FXA_METRICS_FETCH_ERROR", value: response.status}}));
props.dispatch(ac.OnlyToMain({type: at.TELEMETRY_UNDESIRED_EVENT, data: {event: "FXA_METRICS_FETCH_ERROR", value: response.status}}));
}
} catch (error) {
this.props.dispatch(ac.OnlyToMain({type: at.TELEMETRY_UNDESIRED_EVENT, data: {event: "FXA_METRICS_ERROR"}}));
props.dispatch(ac.OnlyToMain({type: at.TELEMETRY_UNDESIRED_EVENT, data: {event: "FXA_METRICS_ERROR"}}));
}
}
}

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

@ -3368,11 +3368,15 @@ class _Trailhead extends react__WEBPACK_IMPORTED_MODULE_4___default.a.PureCompon
link.href = file;
link.rel = "localization";
});
await this.componentWillUpdate(this.props);
} // Get the fxa data if we don't have it yet from mount or update
if (this.props.fxaEndpoint && !this.fxaMetricsInitialized) {
async componentWillUpdate(props) {
if (props.fxaEndpoint && !this.fxaMetricsInitialized) {
try {
this.fxaMetricsInitialized = true;
const url = new URL(`${this.props.fxaEndpoint}/metrics-flow?entrypoint=activity-stream-firstrun&form_type=email`);
const url = new URL(`${props.fxaEndpoint}/metrics-flow?entrypoint=activity-stream-firstrun&form_type=email`);
this.addUtmParams(url);
const response = await fetch(url, {
credentials: "omit"
@ -3390,7 +3394,7 @@ class _Trailhead extends react__WEBPACK_IMPORTED_MODULE_4___default.a.PureCompon
flowBeginTime
});
} else {
this.props.dispatch(common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__["actionCreators"].OnlyToMain({
props.dispatch(common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__["actionCreators"].OnlyToMain({
type: common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__["actionTypes"].TELEMETRY_UNDESIRED_EVENT,
data: {
event: "FXA_METRICS_FETCH_ERROR",
@ -3399,7 +3403,7 @@ class _Trailhead extends react__WEBPACK_IMPORTED_MODULE_4___default.a.PureCompon
}));
}
} catch (error) {
this.props.dispatch(common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__["actionCreators"].OnlyToMain({
props.dispatch(common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__["actionCreators"].OnlyToMain({
type: common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__["actionTypes"].TELEMETRY_UNDESIRED_EVENT,
data: {
event: "FXA_METRICS_ERROR"

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

@ -62,9 +62,9 @@ const TRAILHEAD_CONFIG = {
},
LOCALES: ["en-US", "en-GB", "en-CA", "de", "de-DE", "fr", "fr-FR"],
EXPERIMENT_RATIOS: [
["", 1],
["", 0],
["interrupts", 1],
["triplets", 1],
["triplets", 3],
],
};

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

@ -402,6 +402,7 @@ class PageAction {
}
footerText.parentNode.appendChild(stepsContainer);
for (let step of content.descriptionDetails.steps) {
// This li is a generic xul element with custom styling
const li = this.window.document.createXULElement("li");
this._l10n.setAttributes(li, step.string_id);
stepsContainer.appendChild(li);

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

@ -6,6 +6,7 @@ const {Localization} = ChromeUtils.import("resource://gre/modules/Localization.j
const {FxAccountsConfig} = ChromeUtils.import("resource://gre/modules/FxAccountsConfig.jsm");
const {AttributionCode} = ChromeUtils.import("resource:///modules/AttributionCode.jsm");
const {AddonRepository} = ChromeUtils.import("resource://gre/modules/addons/AddonRepository.jsm");
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
async function getAddonInfo() {
try {
@ -223,7 +224,10 @@ const ONBOARDING_MESSAGES = async () => ([
icon: "tracking",
primary_button: {
label: {string_id: "onboarding-tracking-protection-button2"},
action: {
action: Services.locale.appLocaleAsLangTag.substr(0, 2) === "en" ? {
type: "OPEN_URL",
data: {args: "https://mzl.la/ETPdefault", where: "tabshifted"},
} : {
type: "OPEN_PREFERENCES_PAGE",
data: {category: "privacy-trackingprotection"},
},
@ -343,7 +347,7 @@ const ONBOARDING_MESSAGES = async () => ([
label: {string_id: "onboarding-send-tabs-button"},
action: {
type: "OPEN_URL",
data: {args: "https://support.mozilla.org/kb/send-tab-firefox-desktop-mobile", where: "tabshifted"},
data: {args: "https://support.mozilla.org/kb/send-tab-firefox-desktop-other-devices", where: "tabshifted"},
},
},
},

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

@ -93,6 +93,7 @@ prefs_home_header=Conținutul paginii de start Firefox
prefs_home_description=Alege ce conținut vrei pe ecranul de start Firefox.
prefs_content_discovery_header=Pagina de start Firefox
prefs_content_discovery_description=Descoperirea de conținut din pagina de start Firefox îți permite să descoperi articole relevante de calitate înaltă de pe web.
prefs_content_discovery_button=Dezactivează descoperirea de conținut
@ -204,7 +205,7 @@ firstrun_invalid_input=Necesită o adresă de e-mail validă
# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
firstrun_extra_legal_links=Prin continuare, agreezi {terms} și {privacy}.
firstrun_extra_legal_links=Prin continuare, ești de acord cu {terms} și {privacy}.
firstrun_terms_of_service=Termenii de utilizare a serviciului
firstrun_privacy_notice=Politica de confidențialitate

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

@ -87,6 +87,10 @@ section_disclaimer_topstories_buttontext=ٹھیک ہے مجھے سمجھ آگئ
# sidebar mozilla-central string for the panel that has preferences related to
# what is shown for the homepage, new windows, and new tabs.
prefs_home_header=Firefox ابتائی مواد
prefs_content_discovery_header=Firefox ابتدائی صفحہ
# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
# plural forms used in a drop down of multiple row options (1 row, 2 rows).
# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals

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

@ -100,7 +100,7 @@ window.gActivityStreamStrings = {
"firstrun_form_sub_header": "pentru a continua la Firefox Sync.",
"firstrun_email_input_placeholder": "E-mail",
"firstrun_invalid_input": "Necesită o adresă de e-mail validă",
"firstrun_extra_legal_links": "Prin continuare, agreezi {terms} și {privacy}.",
"firstrun_extra_legal_links": "Prin continuare, ești de acord cu {terms} și {privacy}.",
"firstrun_terms_of_service": "Termenii de utilizare a serviciului",
"firstrun_privacy_notice": "Politica de confidențialitate",
"firstrun_continue_to_login": "Continuă",

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

@ -64,6 +64,7 @@ describe("CFRPageActions", () => {
PrivateBrowsingUtils: {isWindowPrivate: sandbox.stub().returns(false)},
gBrowser: {selectedBrowser: fakeBrowser},
});
document.createXULElement = document.createElement;
elements = {};
const [body] = document.getElementsByTagName("body");

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

@ -18,7 +18,7 @@ describe("BookmarkPanelHub", () => {
sandbox = sinon.createSandbox();
globals = new GlobalOverrider();
fakeL10n = {setAttributes: sandbox.stub(), translateElements: sandbox.stub()};
fakeL10n = {setAttributes: sandbox.stub()};
globals.set("DOMLocalization", function() { return fakeL10n; }); // eslint-disable-line prefer-arrow-callback
globals.set("FxAccounts", {config: {promiseEmailFirstURI: sandbox.stub()}});
isBrowserPrivateStub = sandbox.stub().returns(false);
@ -61,7 +61,10 @@ describe("BookmarkPanelHub", () => {
close: sandbox.stub(),
};
fakeDispatch = sandbox.stub();
fakeWindow = {ownerGlobal: {openLinkIn: sandbox.stub(), gBrowser: {selectedBrowser: "browser"}}};
fakeWindow = {
ownerGlobal: {openLinkIn: sandbox.stub(), gBrowser: {selectedBrowser: "browser"}},
MozXULElement: {insertFTLIfNeeded: sandbox.stub()},
};
});
afterEach(() => {
instance.uninit();
@ -140,6 +143,13 @@ describe("BookmarkPanelHub", () => {
assert.calledWithExactly(instance.showMessage, "content", fakeTarget, fakeWindow);
assert.calledOnce(instance.sendImpression);
});
it("should insert the appropriate ftl files with translations", () => {
instance.onResponse({content: "content"}, fakeTarget, fakeWindow);
assert.calledTwice(fakeWindow.MozXULElement.insertFTLIfNeeded);
assert.calledWith(fakeWindow.MozXULElement.insertFTLIfNeeded, "browser/newtab/asrouter.ftl");
assert.calledWith(fakeWindow.MozXULElement.insertFTLIfNeeded, "browser/branding/sync-brand.ftl");
});
it("should dispatch a user impression", () => {
sandbox.spy(instance, "sendUserEventTelemetry");

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

@ -597,9 +597,7 @@ var pktUIMessaging = (function() {
var payload = JSON.parse(e.target.getAttribute("payload"))[0];
var panelId = payload.panelId;
var data = payload.data;
// After Bug 965637 we can query the csp from the document instead
// of the nodePrincipal, we can just use: e.target.ownerDocument.csp;
var csp = e.target.nodePrincipal.csp;
var csp = e.target.ownerDocument.csp;
callback(panelId, data, nodePrincipal, csp);
// Cleanup the element

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

@ -0,0 +1,12 @@
/* 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/. */
.under-construction {
background-image: url("chrome://browser/content/illustrations/under-construction.svg");
background-repeat: no-repeat;
background-position: center;
min-height: 300px;
min-width: 300px;
/* Move the image down a bit - should be slightly higher than halfway down the page */
margin-top: -10%;
}

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

@ -0,0 +1,21 @@
<!-- 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/. -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Security-Policy" content="default-src chrome: blob:">
<link rel="stylesheet" media="screen, projection" type="text/css"
href="chrome://global/skin/in-content/info-pages.css" title="infop">
<link rel="stylesheet" type="text/css"
href="chrome://browser/content/protections.css">
<link rel="icon" href="chrome://global/skin/icons/warning.svg">
<title>Protection Report</title>
</head>
<body>
<div class="under-construction"><div/>
</body>
</html>

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

@ -0,0 +1,7 @@
# 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/.
browser.jar:
content/browser/protections.css (content/protections.css)
content/browser/protections.html (content/protections.html)

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

@ -0,0 +1,10 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
JAR_MANIFESTS += ['jar.mn']
with Files('**'):
BUG_COMPONENT = ('Firefox', 'Tracking Protection')

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

@ -1,21 +1,15 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// This test is two fold:
// a) if security.data_uri.unique_opaque_origin == false, then
// this tests that session restore component does restore the right
// content security policy with the document. (The policy being
// tested disallows inline scripts).
// b) if security.data_uri.unique_opaque_origin == true, then
// this tests that data: URIs do not inherit the CSP from
// it's enclosing context.
// This test tests that session restore component does restore the right
// content security policy with the document. (The policy being tested
// disallows inline scripts).
add_task(async function test() {
// allow top level data: URI navigations, otherwise clicking a data: link fails
await SpecialPowers.pushPrefEnv({
"set": [["security.data_uri.block_toplevel_data_uri_navigations", false]],
});
let dataURIPref = Services.prefs.getBoolPref("security.data_uri.unique_opaque_origin");
// create a tab that has a CSP
let testURL = "http://mochi.test:8888/browser/browser/components/sessionstore/test/browser_911547_sample.html";
let tab = gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, testURL);
@ -32,27 +26,15 @@ add_task(async function test() {
await ContentTask.spawn(browser, null, function() {
is(content.document.getElementById("test_id1").value, "id1_initial",
"CSP should block the inline script that modifies test_id");
// (a) if security.data_uri.unique_opaque_origin == false:
// attempt to click a link to a data: URI (will inherit the CSP of
// the origin document) and navigate to the data URI in the link.
// (b) if security.data_uri.unique_opaque_origin == true:
// attempt to click a link to a data: URI (will *not* inherit the CSP of
// the origin document) and navigate to the data URI in the link.
content.document.getElementById("test_data_link").click();
});
await loadedPromise;
await ContentTask.spawn(browser, {dataURIPref}, function( {dataURIPref}) { // eslint-disable-line
if (dataURIPref) {
is(content.document.getElementById("test_id2").value, "id2_modified",
"data: URI should *not* inherit the CSP of the enclosing context");
} else {
is(content.document.getElementById("test_id2").value, "id2_initial",
"CSP should block the script loaded by the clicked data URI");
}
await ContentTask.spawn(browser, {}, function( {}) { // eslint-disable-line
// the data: URI inherits the CSP and the inline script needs to be blocked
is(content.document.getElementById("test_id2").value, "id2_initial",
"CSP should block the script loaded by the clicked data URI");
});
// close the tab
@ -63,14 +45,11 @@ add_task(async function test() {
await promiseTabRestored(tab);
browser = tab.linkedBrowser;
await ContentTask.spawn(browser, {dataURIPref}, function({dataURIPref}) { // eslint-disable-line
if (dataURIPref) {
is(content.document.getElementById("test_id2").value, "id2_modified",
"data: URI should *not* inherit the CSP of the enclosing context");
} else {
is(content.document.getElementById("test_id2").value, "id2_initial",
"CSP should block the script loaded by the clicked data URI after restore");
}
await ContentTask.spawn(browser, {}, function({}) { // eslint-disable-line
// the data: URI should be restored including the inherited CSP and the
// inline script should be blocked.
is(content.document.getElementById("test_id2").value, "id2_initial",
"CSP should block the script loaded by the clicked data URI after restore");
});
// clean up

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

@ -8,8 +8,7 @@
<!--
this element gets modified by an injected script;
that script should be blocked by CSP if security.data_uri.unique_opaque_origin == false;
Inline scripts can modify it, but not data uris.
that script should be blocked by CSP
-->
<input type="text" id="test_id1" value="id1_initial">

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

@ -11,7 +11,10 @@ import platform
import subprocess
import sys
import uuid
import __builtin__
try:
import builtins
except ImportError:
import __builtin__ as builtins
from types import ModuleType
@ -434,4 +437,4 @@ class ImportHook(object):
# Install our hook
__builtin__.__import__ = ImportHook(__builtin__.__import__)
builtins.__import__ = ImportHook(builtins.__import__)

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

@ -7,7 +7,6 @@
#include "mozilla/BasePrincipal.h"
#include "nsDocShell.h"
#include "nsIContentSecurityPolicy.h"
#include "nsIObjectInputStream.h"
#include "nsIObjectOutputStream.h"
#include "nsIStandardURL.h"
@ -22,8 +21,6 @@
#include "mozilla/NullPrincipal.h"
#include "mozilla/dom/BlobURLProtocolHandler.h"
#include "mozilla/dom/ChromeUtils.h"
#include "mozilla/dom/CSPDictionariesBinding.h"
#include "mozilla/dom/nsCSPContext.h"
#include "mozilla/dom/ToJSValue.h"
namespace mozilla {
@ -165,88 +162,6 @@ BasePrincipal::CheckMayLoad(nsIURI* aURI, bool aReport,
return NS_ERROR_DOM_BAD_URI;
}
NS_IMETHODIMP
BasePrincipal::GetCsp(nsIContentSecurityPolicy** aCsp) {
NS_IF_ADDREF(*aCsp = mCSP);
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(dom::Document* aDocument,
nsIContentSecurityPolicy** aCSP) {
if (mCSP) {
// if there is a CSP already associated with this principal
// then just return that - do not overwrite it!!!
NS_IF_ADDREF(*aCSP = mCSP);
return NS_OK;
}
nsresult rv = NS_OK;
mCSP = do_CreateInstance("@mozilla.org/cspcontext;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
// Store the request context for violation reports
rv = aDocument ? mCSP->SetRequestContext(aDocument, nullptr)
: mCSP->SetRequestContext(nullptr, this);
NS_ENSURE_SUCCESS(rv, rv);
NS_IF_ADDREF(*aCSP = mCSP);
return NS_OK;
}
NS_IMETHODIMP
BasePrincipal::GetPreloadCsp(nsIContentSecurityPolicy** aPreloadCSP) {
NS_IF_ADDREF(*aPreloadCSP = mPreloadCSP);
return NS_OK;
}
NS_IMETHODIMP
BasePrincipal::EnsurePreloadCSP(dom::Document* aDocument,
nsIContentSecurityPolicy** aPreloadCSP) {
if (mPreloadCSP) {
// if there is a speculative CSP already associated with this principal
// then just return that - do not overwrite it!!!
NS_IF_ADDREF(*aPreloadCSP = mPreloadCSP);
return NS_OK;
}
nsresult rv = NS_OK;
mPreloadCSP = do_CreateInstance("@mozilla.org/cspcontext;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
// Store the request context for violation reports
rv = aDocument ? mPreloadCSP->SetRequestContext(aDocument, nullptr)
: mPreloadCSP->SetRequestContext(nullptr, this);
NS_ENSURE_SUCCESS(rv, rv);
NS_IF_ADDREF(*aPreloadCSP = mPreloadCSP);
return NS_OK;
}
NS_IMETHODIMP
BasePrincipal::GetCspJSON(nsAString& outCSPinJSON) {
outCSPinJSON.Truncate();
dom::CSPPolicies jsonPolicies;
if (!mCSP) {
jsonPolicies.ToJSON(outCSPinJSON);
return NS_OK;
}
return mCSP->ToJSON(outCSPinJSON);
}
NS_IMETHODIMP
BasePrincipal::GetIsNullPrincipal(bool* aResult) {
*aResult = Kind() == eNullPrincipal;
@ -509,20 +424,6 @@ void BasePrincipal::FinishInit(BasePrincipal* aOther,
mOriginNoSuffix = aOther->mOriginNoSuffix;
mHasExplicitDomain = aOther->mHasExplicitDomain;
if (aOther->mPreloadCSP) {
mPreloadCSP = do_CreateInstance("@mozilla.org/cspcontext;1");
nsCSPContext* preloadCSP = static_cast<nsCSPContext*>(mPreloadCSP.get());
preloadCSP->InitFromOther(
static_cast<nsCSPContext*>(aOther->mPreloadCSP.get()), nullptr, this);
}
if (aOther->mCSP) {
mCSP = do_CreateInstance("@mozilla.org/cspcontext;1");
nsCSPContext* csp = static_cast<nsCSPContext*>(mCSP.get());
csp->InitFromOther(static_cast<nsCSPContext*>(aOther->mCSP.get()), nullptr,
this);
}
}
bool SiteIdentifier::Equals(const SiteIdentifier& aOther) const {

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

@ -106,14 +106,6 @@ class BasePrincipal : public nsJSPrincipals {
NS_IMETHOD CheckMayLoad(nsIURI* uri, bool report,
bool allowIfInheritsPrincipal) final;
NS_IMETHOD GetAddonPolicy(nsISupports** aResult) final;
NS_IMETHOD GetCsp(nsIContentSecurityPolicy** aCsp) override;
NS_IMETHOD SetCsp(nsIContentSecurityPolicy* aCsp) override;
NS_IMETHOD EnsureCSP(dom::Document* aDocument,
nsIContentSecurityPolicy** aCSP) override;
NS_IMETHOD GetPreloadCsp(nsIContentSecurityPolicy** aPreloadCSP) override;
NS_IMETHOD EnsurePreloadCSP(dom::Document* aDocument,
nsIContentSecurityPolicy** aCSP) override;
NS_IMETHOD GetCspJSON(nsAString& outCSPinJSON) override;
NS_IMETHOD GetIsNullPrincipal(bool* aResult) override;
NS_IMETHOD GetIsCodebasePrincipal(bool* aResult) override;
NS_IMETHOD GetIsExpandedPrincipal(bool* aResult) override;
@ -249,9 +241,6 @@ class BasePrincipal : public nsJSPrincipals {
void FinishInit(BasePrincipal* aOther,
const OriginAttributes& aOriginAttributes);
nsCOMPtr<nsIContentSecurityPolicy> mCSP;
nsCOMPtr<nsIContentSecurityPolicy> mPreloadCSP;
private:
static already_AddRefed<BasePrincipal> CreateCodebasePrincipal(
nsIURI* aURI, const OriginAttributes& aAttrs,

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

@ -30,7 +30,6 @@
#include "js/Wrapper.h"
#include "mozilla/dom/BlobURLProtocolHandler.h"
#include "mozilla/dom/nsCSPContext.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/ExtensionPolicyService.h"
@ -51,10 +50,6 @@ NS_IMPL_CI_INTERFACE_GETTER(ContentPrincipal, nsIPrincipal, nsISerializable)
ContentPrincipal::ContentPrincipal() : BasePrincipal(eCodebasePrincipal) {}
ContentPrincipal::~ContentPrincipal() {
// let's clear the principal within the csp to avoid a tangling pointer
if (mCSP) {
static_cast<nsCSPContext*>(mCSP.get())->clearLoadingPrincipal();
}
}
nsresult ContentPrincipal::Init(nsIURI* aCodebase,
@ -581,8 +576,18 @@ ContentPrincipal::Read(nsIObjectInputStream* aStream) {
bool ok = attrs.PopulateFromSuffix(suffix);
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
rv = NS_ReadOptionalObject(aStream, true, getter_AddRefs(supports));
NS_ENSURE_SUCCESS(rv, rv);
// Since Bug 965637 we do not serialize the CSP within the
// Principal anymore. Nevertheless there might still be
// serialized Principals that do have a serialized CSP.
// For now, we just read the CSP here but do not actually
// consume it. Please note that we deliberately ignore
// the return value to avoid CSP deserialization problems.
// After Bug 1508939 we will have a new serialization for
// Principals which allows us to update the code here.
// Additionally, the format for serialized CSPs changed
// within Bug 965637 which also can cause failures within
// the CSP deserialization code.
Unused << NS_ReadOptionalObject(aStream, true, getter_AddRefs(supports));
nsAutoCString originNoSuffix;
rv = GenerateOriginNoSuffixFromURI(codebase, originNoSuffix);
@ -591,13 +596,6 @@ ContentPrincipal::Read(nsIObjectInputStream* aStream) {
rv = Init(codebase, attrs, originNoSuffix);
NS_ENSURE_SUCCESS(rv, rv);
mCSP = do_QueryInterface(supports, &rv);
// make sure setRequestContext is called after Init(),
// to make sure the principals URI been initalized.
if (mCSP) {
mCSP->SetRequestContext(nullptr, this);
}
// Note: we don't call SetDomain here because we don't need the wrapper
// recomputation code there (we just created this principal).
mDomain = domain;
@ -629,8 +627,14 @@ ContentPrincipal::Write(nsIObjectOutputStream* aStream) {
rv = aStream->WriteStringZ(suffix.get());
NS_ENSURE_SUCCESS(rv, rv);
// Since Bug 965637 we do not serialize the CSP within the
// Principal anymore. Nevertheless there might still be
// serialized Principals that do have a serialized CSP.
// For now, we just write a null CSP here to avoid breakage.
// After Bug 1508939 we will have a new serialization for
// Principals which allows us to update the code here.
rv = NS_WriteOptionalCompoundObject(
aStream, mCSP, NS_GET_IID(nsIContentSecurityPolicy), true);
aStream, nullptr, NS_GET_IID(nsIContentSecurityPolicy), true);
if (NS_FAILED(rv)) {
return rv;
}

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

@ -169,6 +169,14 @@ bool ExpandedPrincipal::AddonAllowsLoad(nsIURI* aURI,
return false;
}
void ExpandedPrincipal::SetCsp(nsIContentSecurityPolicy* aCSP) { mCSP = aCSP; }
NS_IMETHODIMP
ExpandedPrincipal::GetCsp(nsIContentSecurityPolicy** aCsp) {
NS_IF_ADDREF(*aCsp = mCSP);
return NS_OK;
}
nsIPrincipal* ExpandedPrincipal::PrincipalToInherit(nsIURI* aRequestedURI) {
if (aRequestedURI) {
// If a given sub-principal subsumes the given URI, use that principal for

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

@ -12,6 +12,8 @@
#include "nsNetUtil.h"
#include "mozilla/BasePrincipal.h"
class nsIContentSecurityPolicy;
class ExpandedPrincipal : public nsIExpandedPrincipal,
public mozilla::BasePrincipal {
public:
@ -46,6 +48,8 @@ class ExpandedPrincipal : public nsIExpandedPrincipal,
bool AddonAllowsLoad(nsIURI* aURI, bool aExplicit = false);
void SetCsp(nsIContentSecurityPolicy* aCSP);
// Returns the principal to inherit when this principal requests the given
// URL. See BasePrincipal::PrincipalToInherit.
nsIPrincipal* PrincipalToInherit(nsIURI* aRequestedURI = nullptr);
@ -64,6 +68,7 @@ class ExpandedPrincipal : public nsIExpandedPrincipal,
private:
nsTArray<nsCOMPtr<nsIPrincipal>> mPrincipals;
nsCOMPtr<nsIContentSecurityPolicy> mCSP;
};
#define NS_EXPANDEDPRINCIPAL_CONTRACTID "@mozilla.org/expandedprincipal;1"

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

@ -133,20 +133,6 @@ nsresult NullPrincipal::GetScriptLocation(nsACString& aStr) {
uint32_t NullPrincipal::GetHashValue() { return (NS_PTR_TO_INT32(this) >> 2); }
NS_IMETHODIMP
NullPrincipal::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
NullPrincipal::GetURI(nsIURI** aURI) {
nsCOMPtr<nsIURI> uri = mURI;

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

@ -16,7 +16,6 @@
#include "nsJSPrincipals.h"
#include "nsIScriptSecurityManager.h"
#include "nsCOMPtr.h"
#include "nsIContentSecurityPolicy.h"
#include "mozilla/BasePrincipal.h"
@ -48,7 +47,6 @@ class NullPrincipal final : public BasePrincipal {
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) override;
uint32_t GetHashValue() 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;

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

@ -51,40 +51,6 @@ SystemPrincipal::GetURI(nsIURI** aURI) {
return NS_OK;
}
NS_IMETHODIMP
SystemPrincipal::GetCsp(nsIContentSecurityPolicy** aCsp) {
*aCsp = nullptr;
return NS_OK;
}
NS_IMETHODIMP
SystemPrincipal::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
SystemPrincipal::EnsureCSP(dom::Document* aDocument,
nsIContentSecurityPolicy** aCSP) {
// CSP on a system principal makes no sense
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
SystemPrincipal::GetPreloadCsp(nsIContentSecurityPolicy** aPreloadCSP) {
*aPreloadCSP = nullptr;
return NS_OK;
}
NS_IMETHODIMP
SystemPrincipal::EnsurePreloadCSP(dom::Document* aDocument,
nsIContentSecurityPolicy** aPreloadCSP) {
// CSP on a system principal makes no sense
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
SystemPrincipal::GetDomain(nsIURI** aDomain) {
*aDomain = nullptr;

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

@ -38,13 +38,6 @@ class SystemPrincipal final : public BasePrincipal {
NS_IMETHOD GetURI(nsIURI** aURI) override;
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(dom::Document* aDocument,
nsIContentSecurityPolicy** aCSP) override;
NS_IMETHOD GetPreloadCsp(nsIContentSecurityPolicy** aPreloadCSP) override;
NS_IMETHOD EnsurePreloadCSP(dom::Document* aDocument,
nsIContentSecurityPolicy** aCSP) override;
NS_IMETHOD GetBaseDomain(nsACString& aBaseDomain) override;
NS_IMETHOD GetAddonId(nsAString& aAddonId) override;

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

@ -5,6 +5,7 @@
/* Defines the abstract interface for a principal. */
#include "nsIContentSecurityPolicy.idl"
#include "nsISerializable.idl"
%{C++
@ -37,9 +38,6 @@ class OriginAttributes;
%}
interface nsIURI;
interface nsIContentSecurityPolicy;
webidl Document;
[ptr] native JSContext(JSContext);
[ptr] native JSPrincipals(JSPrincipals);
@ -150,53 +148,6 @@ interface nsIPrincipal : nsISerializable
void checkMayLoad(in nsIURI uri, in boolean report,
in boolean allowIfInheritsPrincipal);
/**
* A Content Security Policy associated with this principal. Use this function to
* query the associated CSP with this principal, but 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.
*/
readonly attribute nsIContentSecurityPolicy csp;
[noscript] void setCsp(in nsIContentSecurityPolicy aCsp);
/*
* Use this function to query a CSP associated with this principal.
* If no CSP is associated with this principal then one is created
* internally and setRequestContext is called on the CSP using aDocument.
*
* Please note if aDocument is null, then setRequestContext on the
* CSP object is called using the current principal.
*/
[noscript] nsIContentSecurityPolicy ensureCSP(in Document aDocument);
/**
* A speculative Content Security Policy associated with this
* principal. Set during speculative loading (preloading) and
* used *only* for preloads.
*
* If you want to query the CSP associated with that principal,
* then this is *not* what you want. Instead query 'csp'.
*/
[noscript] readonly attribute nsIContentSecurityPolicy preloadCsp;
/*
* Use this function to query a speculative CSP associated with this
* principal. If no speculative CSP is associated with this principal
* then one is created internally and setRequestContext is called on
* the CSP using aDocument.
*
* Please note if aDocument is null, then setRequestContext on the
* speculative CSP object is called using the current principal.
*/
[noscript] nsIContentSecurityPolicy ensurePreloadCSP(in Document aDocument);
/**
* The CSP of the principal in JSON notation.
* Note, that the CSP itself is not exposed to JS, but script
* should be able to obtain a JSON representation of the CSP.
*/
readonly attribute AString cspJSON;
/**
* A dictionary of the non-default origin attributes associated with this
* nsIPrincipal.
@ -361,4 +312,24 @@ interface nsIExpandedPrincipal : nsISupports
*/
[noscript, notxpcom, nostdcall]
PrincipalArray AllowList();
/**
* Bug 1548468: Move CSP off ExpandedPrincipal.
*
* A Content Security Policy associated with this principal. Use this function
* to query the associated CSP with this principal.
*/
readonly attribute nsIContentSecurityPolicy csp;
%{ C++
inline already_AddRefed<nsIContentSecurityPolicy> GetCsp()
{
nsCOMPtr<nsIContentSecurityPolicy> result;
mozilla::DebugOnly<nsresult> rv = GetCsp(getter_AddRefs(result));
MOZ_ASSERT(NS_SUCCEEDED(rv));
return result.forget();
}
%}
};

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

@ -123,10 +123,10 @@ bool nsJSPrincipals::ReadPrincipals(JSContext* aCx,
return ReadKnownPrincipalType(aCx, aReader, tag, aOutPrincipals);
}
static bool ReadPrincipalInfo(
JSStructuredCloneReader* aReader, OriginAttributes& aAttrs,
nsACString& aSpec, nsACString& aOriginNoSuffix, nsACString& aBaseDomain,
nsTArray<ContentSecurityPolicy>* aPolicies = nullptr) {
static bool ReadPrincipalInfo(JSStructuredCloneReader* aReader,
OriginAttributes& aAttrs, nsACString& aSpec,
nsACString& aOriginNoSuffix,
nsACString& aBaseDomain) {
uint32_t suffixLength, specLength;
if (!JS_ReadUint32Pair(aReader, &suffixLength, &specLength)) {
return false;
@ -153,13 +153,14 @@ static bool ReadPrincipalInfo(
return false;
}
uint32_t originNoSuffixLength, policyCount;
if (!JS_ReadUint32Pair(aReader, &originNoSuffixLength, &policyCount)) {
uint32_t originNoSuffixLength, dummy;
if (!JS_ReadUint32Pair(aReader, &originNoSuffixLength, &dummy)) {
return false;
}
if (!aPolicies) {
MOZ_ASSERT(policyCount == 0);
MOZ_ASSERT(dummy == 0);
if (dummy != 0) {
return false;
}
if (!aOriginNoSuffix.SetLength(originNoSuffixLength, fallible)) {
@ -171,29 +172,6 @@ static bool ReadPrincipalInfo(
return false;
}
for (uint32_t i = 0; i < policyCount; i++) {
uint32_t policyLength, reportAndMeta;
if (!JS_ReadUint32Pair(aReader, &policyLength, &reportAndMeta)) {
return false;
}
bool reportOnly = reportAndMeta & 1;
bool deliveredViaMetaTag = reportAndMeta & 2;
nsAutoCString policyStr;
if (!policyStr.SetLength(policyLength, fallible)) {
return false;
}
if (!JS_ReadBytes(aReader, policyStr.BeginWriting(), policyLength)) {
return false;
}
if (aPolicies) {
aPolicies->AppendElement(ContentSecurityPolicy(
NS_ConvertUTF8toUTF16(policyStr), reportOnly, deliveredViaMetaTag));
}
}
uint32_t baseDomainIsVoid, baseDomainLength;
if (!JS_ReadUint32Pair(aReader, &baseDomainIsVoid, &baseDomainLength)) {
return false;
@ -259,9 +237,7 @@ static bool ReadPrincipalInfo(JSStructuredCloneReader* aReader, uint32_t aTag,
nsAutoCString spec;
nsAutoCString originNoSuffix;
nsAutoCString baseDomain;
nsTArray<ContentSecurityPolicy> policies;
if (!ReadPrincipalInfo(aReader, attrs, spec, originNoSuffix, baseDomain,
&policies)) {
if (!ReadPrincipalInfo(aReader, attrs, spec, originNoSuffix, baseDomain)) {
return false;
}
@ -275,7 +251,7 @@ static bool ReadPrincipalInfo(JSStructuredCloneReader* aReader, uint32_t aTag,
// XXX: Do we care about mDomain for structured clone?
aInfo = ContentPrincipalInfo(attrs, originNoSuffix, spec, Nothing(),
std::move(policies), baseDomain);
baseDomain);
} else {
#ifdef FUZZING
return false;
@ -344,37 +320,23 @@ bool nsJSPrincipals::ReadKnownPrincipalType(JSContext* aCx,
return true;
}
static bool WritePrincipalInfo(
JSStructuredCloneWriter* aWriter, const OriginAttributes& aAttrs,
const nsCString& aSpec, const nsCString& aOriginNoSuffix,
const nsCString& aBaseDomain,
const nsTArray<ContentSecurityPolicy>* aPolicies = nullptr) {
static bool WritePrincipalInfo(JSStructuredCloneWriter* aWriter,
const OriginAttributes& aAttrs,
const nsCString& aSpec,
const nsCString& aOriginNoSuffix,
const nsCString& aBaseDomain) {
nsAutoCString suffix;
aAttrs.CreateSuffix(suffix);
size_t policyCount = aPolicies ? aPolicies->Length() : 0;
if (!(JS_WriteUint32Pair(aWriter, suffix.Length(), aSpec.Length()) &&
JS_WriteBytes(aWriter, suffix.get(), suffix.Length()) &&
JS_WriteBytes(aWriter, aSpec.get(), aSpec.Length()) &&
JS_WriteUint32Pair(aWriter, aOriginNoSuffix.Length(), policyCount) &&
JS_WriteUint32Pair(aWriter, aOriginNoSuffix.Length(), 0) &&
JS_WriteBytes(aWriter, aOriginNoSuffix.get(),
aOriginNoSuffix.Length()))) {
return false;
}
for (uint32_t i = 0; i < policyCount; i++) {
nsCString policy;
CopyUTF16toUTF8((*aPolicies)[i].policy(), policy);
uint32_t reportAndMeta =
((*aPolicies)[i].reportOnlyFlag() ? 1 : 0) |
((*aPolicies)[i].deliveredViaMetaTagFlag() ? 2 : 0);
if (!(JS_WriteUint32Pair(aWriter, policy.Length(), reportAndMeta) &&
JS_WriteBytes(aWriter, PromiseFlatCString(policy).get(),
policy.Length()))) {
return false;
}
}
if (aBaseDomain.IsVoid()) {
return JS_WriteUint32Pair(aWriter, 1, 0);
}
@ -413,8 +375,7 @@ static bool WritePrincipalInfo(JSStructuredCloneWriter* aWriter,
const ContentPrincipalInfo& cInfo = aInfo;
return JS_WriteUint32Pair(aWriter, SCTAG_DOM_CONTENT_PRINCIPAL, 0) &&
WritePrincipalInfo(aWriter, cInfo.attrs(), cInfo.spec(),
cInfo.originNoSuffix(), cInfo.baseDomain(),
&(cInfo.securityPolicies()));
cInfo.originNoSuffix(), cInfo.baseDomain());
}
bool nsJSPrincipals::write(JSContext* aCx, JSStructuredCloneWriter* aWriter) {

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

@ -274,97 +274,6 @@ nsScriptSecurityManager::GetChannelResultPrincipals(
aStoragePrincipal);
}
static void InheritAndSetCSPOnPrincipalIfNeeded(nsIChannel* aChannel,
nsIPrincipal* aPrincipal) {
// loading a data: URI into an iframe, or loading frame[srcdoc] need
// to inherit the CSP (see Bug 1073952, 1381761).
MOZ_ASSERT(aChannel && aPrincipal, "need a valid channel and principal");
if (!aChannel) {
return;
}
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
if (loadInfo->GetExternalContentPolicyType() !=
nsIContentPolicy::TYPE_SUBDOCUMENT) {
return;
}
nsCOMPtr<nsIURI> uri;
nsresult rv = aChannel->GetURI(getter_AddRefs(uri));
NS_ENSURE_SUCCESS_VOID(rv);
nsAutoCString URISpec;
rv = uri->GetSpec(URISpec);
NS_ENSURE_SUCCESS_VOID(rv);
bool isSrcDoc = URISpec.EqualsLiteral("about:srcdoc");
bool isData = (NS_SUCCEEDED(uri->SchemeIs("data", &isData)) && isData);
if (!isSrcDoc && !isData) {
return;
}
nsCOMPtr<nsIPrincipal> principalToInherit =
loadInfo->FindPrincipalToInherit(aChannel);
nsCOMPtr<nsIContentSecurityPolicy> originalCSP;
principalToInherit->GetCsp(getter_AddRefs(originalCSP));
if (!originalCSP) {
return;
}
// if the principalToInherit had a CSP, add it to the before
// created NullPrincipal (unless it already has one)
MOZ_ASSERT(aPrincipal->GetIsNullPrincipal(),
"inheriting the CSP only valid for NullPrincipal");
nsCOMPtr<nsIContentSecurityPolicy> nullPrincipalCSP;
aPrincipal->GetCsp(getter_AddRefs(nullPrincipalCSP));
if (nullPrincipalCSP) {
MOZ_ASSERT(nsCSPContext::Equals(originalCSP, nullPrincipalCSP));
// CSPs are equal, no need to set it again.
return;
}
// After 965637 all that magical CSP inheritance goes away. For now,
// we have to create a clone of the current CSP and have to manually
// set it on the Principal.
uint32_t count = 0;
rv = originalCSP->GetPolicyCount(&count);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
if (count == 0) {
// fast path: if there is nothing to inherit, we can return here.
return;
}
RefPtr<nsCSPContext> newCSP = new nsCSPContext();
nsWeakPtr loadingContext =
static_cast<nsCSPContext*>(originalCSP.get())->GetLoadingContext();
nsCOMPtr<Document> doc = do_QueryReferent(loadingContext);
rv = doc ? newCSP->SetRequestContext(doc, nullptr)
: newCSP->SetRequestContext(nullptr, aPrincipal);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
for (uint32_t i = 0; i < count; ++i) {
const nsCSPPolicy* policy = originalCSP->GetPolicy(i);
MOZ_ASSERT(policy);
nsAutoString policyString;
policy->toString(policyString);
rv = newCSP->AppendPolicy(policyString, policy->getReportOnlyFlag(),
policy->getDeliveredViaMetaTagFlag());
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
}
aPrincipal->SetCsp(newCSP);
}
nsresult nsScriptSecurityManager::GetChannelResultPrincipal(
nsIChannel* aChannel, nsIPrincipal** aPrincipal, bool aIgnoreSandboxing) {
MOZ_ASSERT(aChannel, "Must have channel!");
@ -391,7 +300,6 @@ nsresult nsScriptSecurityManager::GetChannelResultPrincipal(
nsCOMPtr<nsIPrincipal> sandboxedLoadingPrincipal =
loadInfo->GetSandboxedLoadingPrincipal();
MOZ_ASSERT(sandboxedLoadingPrincipal);
InheritAndSetCSPOnPrincipalIfNeeded(aChannel, sandboxedLoadingPrincipal);
sandboxedLoadingPrincipal.forget(aPrincipal);
return NS_OK;
}
@ -433,10 +341,7 @@ nsresult nsScriptSecurityManager::GetChannelResultPrincipal(
return NS_OK;
}
}
nsresult rv = GetChannelURIPrincipal(aChannel, aPrincipal);
NS_ENSURE_SUCCESS(rv, rv);
InheritAndSetCSPOnPrincipalIfNeeded(aChannel, *aPrincipal);
return NS_OK;
return GetChannelURIPrincipal(aChannel, aPrincipal);
}
/* The principal of the URI that this channel is loading. This is never
@ -494,16 +399,18 @@ NS_IMPL_ISUPPORTS(nsScriptSecurityManager, nsIScriptSecurityManager)
bool nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction(
JSContext* cx, JS::HandleValue aValue) {
MOZ_ASSERT(cx == nsContentUtils::GetCurrentJSContext());
nsCOMPtr<nsIPrincipal> subjectPrincipal = nsContentUtils::SubjectPrincipal();
#if defined(DEBUG) && !defined(ANDROID)
nsCOMPtr<nsIPrincipal> subjectPrincipal = nsContentUtils::SubjectPrincipal();
nsContentSecurityManager::AssertEvalNotUsingSystemPrincipal(subjectPrincipal,
cx);
#endif
// Get the window, if any, corresponding to the current global
nsCOMPtr<nsIContentSecurityPolicy> csp;
nsresult rv = subjectPrincipal->GetCsp(getter_AddRefs(csp));
NS_ASSERTION(NS_SUCCEEDED(rv), "CSP: Failed to get CSP from principal.");
if (nsGlobalWindowInner* win = xpc::CurrentWindowOrNull(cx)) {
csp = win->GetCsp();
}
// don't do anything unless there's a CSP
if (!csp) return true;
@ -519,7 +426,7 @@ bool nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction(
bool evalOK = true;
bool reportViolation = false;
rv = csp->GetAllowsEval(&reportViolation, &evalOK);
nsresult rv = csp->GetAllowsEval(&reportViolation, &evalOK);
if (NS_FAILED(rv)) {
NS_WARNING("CSP: failed to get allowsEval");

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

@ -54,7 +54,7 @@
"babel-plugin-transform-imports": "^1.5.0",
"codemirror": "^5.28.0",
"devtools-environment": "^0.0.6",
"devtools-launchpad": "^0.0.153",
"devtools-launchpad": "^0.0.154",
"devtools-linters": "^0.0.4",
"devtools-reps": "0.23.0",
"devtools-source-map": "0.16.0",

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

@ -38,7 +38,7 @@
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.0",
"babel-preset-react": "^6.24.1",
"devtools-config": "^0.0.16",
"devtools-launchpad": "^0.0.153",
"devtools-launchpad": "^0.0.154",
"devtools-license-check": "^0.7.0",
"devtools-modules": "~1.1.0",
"devtools-services": "^0.0.1",

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

@ -15,7 +15,6 @@ import {
getXHRBreakpoints,
getSelectedSource,
getBreakpointAtLocation,
getConditionalPanelLocation,
getBreakpointsForSource,
getBreakpointsAtLine,
} from "../../selectors";
@ -27,7 +26,6 @@ import {
disableBreakpoint,
} from "./modify";
import remapLocations from "./remapLocations";
import { closeConditionalPanel } from "../ui";
// this will need to be changed so that addCLientBreakpoint is removed
@ -218,10 +216,6 @@ export function toggleBreakpointAtLine(cx: Context, line: number) {
return;
}
if (getConditionalPanelLocation(getState())) {
dispatch(closeConditionalPanel());
}
const bp = getBreakpointAtLocation(state, { line, column: undefined });
if (bp) {
return dispatch(removeBreakpoint(cx, bp));

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

@ -106,10 +106,15 @@ class Breakpoint extends PureComponent<Props> {
};
onContextMenu = (event: MouseEvent) => {
const { cx, breakpoint, breakpointActions } = this.props;
const { cx, breakpoint, selectedSource, breakpointActions } = this.props;
event.stopPropagation();
event.preventDefault();
showMenu(event, breakpointItems(cx, breakpoint, breakpointActions));
const selectedLocation = getSelectedLocation(breakpoint, selectedSource);
showMenu(
event,
breakpointItems(cx, breakpoint, selectedLocation, breakpointActions)
);
};
addBreakpoint(props: Props) {

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

@ -9,6 +9,7 @@ import { showMenu } from "devtools-contextmenu";
import { getDocument } from "../../utils/editor";
import { breakpointItems, createBreakpointItems } from "./menus/breakpoints";
import { getSelectedLocation } from "../../utils/selected-location";
// eslint-disable-next-line max-len
import type { ColumnBreakpoint as ColumnBreakpointType } from "../../selectors/visibleColumnBreakpoints";
@ -101,12 +102,22 @@ export default class ColumnBreakpoint extends PureComponent<Props> {
const {
cx,
columnBreakpoint: { breakpoint, location },
source,
breakpointActions,
} = this.props;
const items = breakpoint
? breakpointItems(cx, breakpoint, breakpointActions)
: createBreakpointItems(cx, location, breakpointActions);
let items = createBreakpointItems(cx, location, breakpointActions);
if (breakpoint) {
const selectedLocation = getSelectedLocation(breakpoint, source);
items = breakpointItems(
cx,
breakpoint,
selectedLocation,
breakpointActions
);
}
showMenu(event, items);
};

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

@ -137,6 +137,7 @@ export class ConditionalPanel extends PureComponent<Props> {
noHScroll: true,
}
);
if (this.input) {
let parent: ?Node = this.input.parentNode;
while (parent) {
@ -158,7 +159,7 @@ export class ConditionalPanel extends PureComponent<Props> {
}
createEditor = (input: ?HTMLTextAreaElement) => {
const { log, editor } = this.props;
const { log, editor, closeConditionalPanel } = this.props;
const codeMirror = editor.CodeMirror.fromTextArea(input, {
mode: "javascript",
@ -176,6 +177,8 @@ export class ConditionalPanel extends PureComponent<Props> {
}
});
codeMirror.on("blur", (cm, e) => closeConditionalPanel());
const codeMirrorWrapper = codeMirror.getWrapperElement();
codeMirrorWrapper.addEventListener("keydown", e => {
@ -206,7 +209,6 @@ export class ConditionalPanel extends PureComponent<Props> {
"log-point": log,
})}
onClick={() => this.keepFocusOnInput()}
onBlur={this.props.closeConditionalPanel}
ref={node => (this.panelNode = node)}
>
<div className="prompt">»</div>

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

@ -61,11 +61,11 @@ export const editConditionalBreakpointItem = (
export const conditionalBreakpointItem = (
breakpoint: Breakpoint,
location: SourceLocation,
breakpointActions: BreakpointItemActions
) => {
const {
options: { condition },
location,
} = breakpoint;
return condition
? editConditionalBreakpointItem(location, breakpointActions)
@ -98,11 +98,11 @@ export const editLogPointItem = (
export const logPointItem = (
breakpoint: Breakpoint,
location: SourceLocation,
breakpointActions: BreakpointItemActions
) => {
const {
options: { logValue },
location,
} = breakpoint;
return logValue
? editLogPointItem(location, breakpointActions)
@ -133,6 +133,7 @@ export const toggleDisabledBreakpointItem = (
export function breakpointItems(
cx: Context,
breakpoint: Breakpoint,
selectedLocation: SourceLocation,
breakpointActions: BreakpointItemActions
) {
const items = [
@ -140,30 +141,19 @@ export function breakpointItems(
toggleDisabledBreakpointItem(cx, breakpoint, breakpointActions),
];
if (features.columnBreakpoints) {
items.push(
{ type: "separator" },
removeBreakpointsOnLineItem(cx, breakpoint.location, breakpointActions),
breakpoint.disabled
? enableBreakpointsOnLineItem(
cx,
breakpoint.location,
breakpointActions
)
: disableBreakpointsOnLineItem(
cx,
breakpoint.location,
breakpointActions
),
{ type: "separator" }
);
}
items.push(
{ type: "separator" },
removeBreakpointsOnLineItem(cx, selectedLocation, breakpointActions),
breakpoint.disabled
? enableBreakpointsOnLineItem(cx, selectedLocation, breakpointActions)
: disableBreakpointsOnLineItem(cx, selectedLocation, breakpointActions),
{ type: "separator" }
);
items.push(conditionalBreakpointItem(breakpoint, breakpointActions));
if (features.logPoints) {
items.push(logPointItem(breakpoint, breakpointActions));
}
items.push(
conditionalBreakpointItem(breakpoint, selectedLocation, breakpointActions)
);
items.push(logPointItem(breakpoint, selectedLocation, breakpointActions));
return items;
}

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

@ -42,6 +42,7 @@
// Globals introduced in debugger-specific head.js
"getContext": false,
"getEditorLineGutter": false,
"getCM": false,
"getDebuggerSplitConsole": false,
"hasConsoleMessage": false,
@ -112,6 +113,7 @@
"clickElement": false,
"clickElementWithSelector": false,
"clickDOMElement": false,
"dblClickElement": false,
"altClickElement": false,
"rightClickElement": false,
"rightClickEl": false,

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

@ -689,6 +689,7 @@ skip-if = os == "win" # Bug 1448523, Bug 1448450
[browser_dbg-breakpoints-actions.js]
[browser_dbg-breakpoints-columns.js]
[browser_dbg-breakpoints-cond.js]
[browser_dbg-breakpoints-cond-source-maps.js]
[browser_dbg-breakpoints-duplicate-functions.js]
[browser_dbg-browser-content-toolbox.js]
skip-if = !e10s || verify # This test is only valid in e10s

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

@ -0,0 +1,41 @@
/* 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/>. */
async function setLogPoint(dbg, index) {
const gutterEl = await getEditorLineGutter(dbg, index);
rightClickEl(dbg, gutterEl);
selectContextMenuItem(
dbg,
`${selectors.addLogItem},${selectors.editLogItem}`
);
}
async function waitForConditionalPanelFocus(dbg) {
await waitFor(() => dbg.win.document.activeElement.tagName === "TEXTAREA");
}
function getConditionalPanel(dbg, line) {
return getCM(dbg).doc.getLineHandle(line - 1).widgets[0];
}
// Confirms that a conditional panel is opened at the
// correct location in generated files.
add_task(async function() {
const dbg = await initDebugger("doc-sourcemaps.html", "entry.js");
await selectSource(dbg, "bundle.js");
getCM(dbg).scrollIntoView({ line: 55, ch: 0 });
setLogPoint(dbg, 55);
await waitForConditionalPanelFocus(dbg);
ok(
!!getConditionalPanel(dbg, 55),
"conditional panel panel is open on line 55"
);
is(
dbg.selectors.getConditionalPanelLocation().line,
55,
"conditional panel location is line 55"
);
});

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

@ -63,7 +63,6 @@ async function waitForConditionalPanelFocus(dbg) {
add_task(async function() {
const dbg = await initDebugger("doc-scripts.html", "simple2");
await pushPref("devtools.debugger.features.column-breakpoints", true);
await pushPref("devtools.debugger.features.log-points", true);
await selectSource(dbg, "simple2");
await waitForSelectedSource(dbg, "simple2");
@ -130,10 +129,10 @@ add_task(async function() {
"TEXTAREA",
"The textarea of conditional breakpoint panel is focused"
);
info("Click the conditional breakpoint in secondary pane");
await clickElement(dbg, "conditionalBreakpointInSecPane");
let conditonalPanel = findElement(dbg, "conditionalPanel");
const conditonalPanel = findElement(dbg, "conditionalPanel");
is(conditonalPanel, null, "The conditional breakpoint panel is closed");
rightClickElement(dbg, "breakpointItem", 2);
@ -162,9 +161,9 @@ add_task(async function() {
"TEXTAREA",
"The textarea of logpoint panel is focused"
);
info("Click the logpoint in secondary pane");
await clickElement(dbg, "logPointInSecPane");
let logPointPanel = findElement(dbg, "logPointPanel");
const logPointPanel = findElement(dbg, "logPointPanel");
is(logPointPanel, null, "The logpoint panel is closed");
});

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

@ -1154,6 +1154,11 @@ function isVisible(outerEl, innerEl) {
return visible;
}
async function getEditorLineGutter(dbg, line) {
const lineEl = await getEditorLineEl(dbg, line);
return lineEl.firstChild;
}
async function getEditorLineEl(dbg, line) {
let el = await codeMirrorGutterElement(dbg, line);
while (el && !el.matches(".CodeMirror-code > div")) {

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

@ -3273,12 +3273,10 @@ devtools-config@^0.0.16:
devtools-connection@^1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/devtools-connection/-/devtools-connection-1.0.7.tgz#16f23256f842dce339038cdc273c49c473ef83e0"
integrity sha512-SrBHnM4nVhTrSfI4WnqcmppDOwB5iQvoEjqVNpwv63puGdKGtcdfWqv4+4gqfRYKHrdGB8tJfWJV2n+EyXb1Xw==
devtools-contextmenu@~1.0.6:
version "1.0.6"
resolved "https://registry.yarnpkg.com/devtools-contextmenu/-/devtools-contextmenu-1.0.6.tgz#db31a6e5c90a7efeeb84fd156bd312633e642006"
integrity sha512-5hYcY0RHkFeStvpA+Kyg1K5n0KuCuAntzHGID0xmwJsSjNrU5fs4gEEVk6BAOtW92IMSpdJ8qA8LIi+s6LkQXQ==
devtools-contextmenu@~1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/devtools-contextmenu/-/devtools-contextmenu-1.0.7.tgz#dd56353a706c3be4cd06d49d6da6dc5219254c90"
dependencies:
devtools-modules "~1.1.3"
@ -3290,10 +3288,9 @@ devtools-environment@^0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/devtools-environment/-/devtools-environment-0.0.6.tgz#11584f5b1ead784c2356d8da647a630fed591a4e"
devtools-launchpad@^0.0.153:
version "0.0.153"
resolved "https://registry.yarnpkg.com/devtools-launchpad/-/devtools-launchpad-0.0.153.tgz#e310d4dfd67206b1ad2f59aabd2cffe885ae97ef"
integrity sha512-i4v+Wf0ia9eGAryEKKMGvPfGvdj4WMLsNYxMmWUnfMNqGitlgyFxD3f5oZO7yNQgY6iX7P5vczxceJILsag57g==
devtools-launchpad@^0.0.154:
version "0.0.154"
resolved "https://registry.yarnpkg.com/devtools-launchpad/-/devtools-launchpad-0.0.154.tgz#ee408dcae5b5e36eca9eb55338eeaf6920a46bf7"
dependencies:
amd-loader "0.0.8"
autoprefixer "^7.1.2"
@ -3319,7 +3316,7 @@ devtools-launchpad@^0.0.153:
debug "^3.1.0"
devtools-config "^0.0.16"
devtools-connection "^1.0.7"
devtools-contextmenu "~1.0.6"
devtools-contextmenu "~1.0.7"
devtools-environment "^0.0.5"
devtools-license-check "^0.7.0"
devtools-mc-assets "^0.0.7"
@ -3414,7 +3411,6 @@ devtools-modules@~1.1.0:
devtools-modules@~1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/devtools-modules/-/devtools-modules-1.1.3.tgz#4fbeee232263794bd3dd5b314c1a0ae28d76ea6f"
integrity sha512-2bwfU72vwDcPCzLgXcK/rdtsmi9oWV764vxKttQdY43a7euwo94oCWOKfTOEXJG6HVgxMlYk87+/8QN9ELz9jQ==
dependencies:
devtools-services "0.0.1"
punycode "^2.1.0"
@ -3510,7 +3506,6 @@ domelementtype@1, domelementtype@^1.3.0:
domelementtype@^1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f"
integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==
domelementtype@~1.1.1:
version "1.1.3"
@ -3871,7 +3866,6 @@ eslint-config-prettier@^4.0.0:
eslint-import-resolver-node@^0.3.2:
version "0.3.2"
resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz#58f15fb839b8d0576ca980413476aab2472db66a"
integrity sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==
dependencies:
debug "^2.6.9"
resolve "^1.5.0"
@ -3879,7 +3873,6 @@ eslint-import-resolver-node@^0.3.2:
eslint-module-utils@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.3.0.tgz#546178dab5e046c8b562bbb50705e2456d7bda49"
integrity sha512-lmDJgeOOjk8hObTysjqH7wyMi+nsHwwvfBykwfhjR1LNdd7C2uFJBvx4OpWYpXOw4df1yE1cDEVd1yLHitk34w==
dependencies:
debug "^2.6.8"
pkg-dir "^2.0.0"
@ -3903,7 +3896,6 @@ eslint-plugin-flowtype@^3.0.0:
eslint-plugin-import@^2.16.0:
version "2.16.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.16.0.tgz#97ac3e75d0791c4fac0e15ef388510217be7f66f"
integrity sha512-z6oqWlf1x5GkHIFgrSvtmudnqM6Q60KM4KvpWi5ubonMjycLjndvd5+8VAZIsTlHC03djdgJuyKG6XO577px6A==
dependencies:
contains-path "^0.1.0"
debug "^2.6.9"
@ -3944,7 +3936,6 @@ eslint-plugin-mozilla@1.1.3:
eslint-plugin-mozilla@1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/eslint-plugin-mozilla/-/eslint-plugin-mozilla-1.2.1.tgz#8aa80dca43bd45f300188d4ee53bc5a983aac0ba"
integrity sha512-i6SAWTPgKI6T50L6Gy41efR3StjPGR3IWkFOW/4aGsJtpl+OmJVaOmUfhp5PGis3ZbDisNvQ/vzLiNicAWC7nw==
dependencies:
htmlparser2 "3.10.1"
ini-parser "0.0.2"
@ -4623,7 +4614,6 @@ flatten@^1.0.2:
flow-bin@0.97.0:
version "0.97.0"
resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.97.0.tgz#036ffcfc27503367a9d906ec9d843a0aa6f6bb83"
integrity sha512-jXjD05gkatLuC4+e28frH1hZoRwr1iASP6oJr61Q64+kR4kmzaS+AdFBhYgoYS5kpoe4UzwDebWK8ETQFNh00w==
flush-write-stream@^1.0.0:
version "1.0.3"
@ -5371,7 +5361,6 @@ htmlparser2@3.10.0:
htmlparser2@3.10.1:
version "3.10.1"
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f"
integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==
dependencies:
domelementtype "^1.3.1"
domhandler "^2.3.0"
@ -8270,7 +8259,6 @@ path-parse@^1.0.5:
path-parse@^1.0.6:
version "1.0.6"
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c"
integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==
path-to-regexp@0.1.7:
version "0.1.7"
@ -9394,7 +9382,6 @@ readable-stream@^3.0.6:
readable-stream@^3.1.1:
version "3.3.0"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.3.0.tgz#cb8011aad002eb717bf040291feba8569c986fb9"
integrity sha512-EsI+s3k3XsW+fU8fQACLN59ky34AZ14LoeVZpYwmZvldCFo0r0gnelwF2TcMjLor/BTL5aDJVBMkss0dthToPw==
dependencies:
inherits "^2.0.3"
string_decoder "^1.1.1"
@ -10137,7 +10124,6 @@ resolve@^1.1.6, resolve@^1.2.0, resolve@^1.3.2, resolve@^1.5.0:
resolve@^1.9.0:
version "1.10.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.10.0.tgz#3bdaaeaf45cc07f375656dfd2e54ed0810b101ba"
integrity sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==
dependencies:
path-parse "^1.0.6"

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

@ -17,6 +17,7 @@ support-files =
doc_filter.html
doc_frame_script.js
doc_grid_names.html
doc_grid_area_gridline_names.html
doc_inline_sourcemap.html
doc_invalid_sourcemap.css
doc_invalid_sourcemap.html
@ -190,6 +191,8 @@ skip-if = (os == "win" && debug) # bug 963492: win.
[browser_rules_grid-toggle_04.js]
[browser_rules_grid-toggle_05.js]
[browser_rules_gridline-names-autocomplete.js]
[browser_rules_gridline-names-are-shown-correctly.js]
skip-if = os == 'linux' # focusEditableField times out consistently on linux.
[browser_rules_guessIndentation.js]
[browser_rules_highlight-element-rule.js]
[browser_rules_highlight-property.js]

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

@ -0,0 +1,106 @@
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Tests that the text editor correctly calculates the grid line names shown in the
// autocomplete popup. We generally want to show all the grid line names for a grid
// container, except for implicit line names created by an implicitly named area.
const TEST_URL = URL_ROOT + "doc_grid_area_gridline_names.html";
add_task(async function() {
await addTab(TEST_URL);
const { inspector, view } = await openRuleView();
info("Test that implicit grid line names from explicit grid areas are shown.");
await testExplicitNamedAreas(inspector, view);
info("Test that explicit grid line names creating implicit grid areas are shown.");
await testImplicitNamedAreasWithExplicitGridLineNames(inspector, view);
info("Test that implicit grid line names creating implicit grid areas are not shown.");
await testImplicitAreasWithImplicitGridLineNames(inspector, view);
await testImplicitNamedAreasWithReversedGridLineNames(inspector, view);
});
async function testExplicitNamedAreas(inspector, view) {
await selectNode(".header", inspector);
const gridColLines = ["header-start", "header-end", "main-start", "main-end"];
const propertyName = view.styleDocument.querySelectorAll(".ruleview-propertyvalue")[0];
const gridLineNamesUpdated = inspector.once("grid-line-names-updated");
const editor = await focusEditableField(view, propertyName);
const onPopupShown = once(editor.popup, "popup-opened");
await gridLineNamesUpdated;
EventUtils.synthesizeKey("VK_DOWN", { shiftKey: true }, view.styleWindow);
await onPopupShown;
info("Check that the expected grid line column names are shown in the editor popup.");
for (const lineName of gridColLines) {
ok(editor.gridLineNames.cols.indexOf(lineName) > -1,
`${lineName} is a suggested implicit grid line`);
}
}
async function testImplicitNamedAreasWithExplicitGridLineNames(inspector, view) {
await selectNode(".contentArea", inspector);
const gridRowLines = ["main-start", "main-end", "content-start", "content-end"];
const propertyName = view.styleDocument.querySelectorAll(".ruleview-propertyvalue")[1];
const gridLineNamesUpdated = inspector.once("grid-line-names-updated");
const editor = await focusEditableField(view, propertyName);
const onPopupShown = once(editor.popup, "popup-opened");
await gridLineNamesUpdated;
EventUtils.synthesizeKey("VK_DOWN", { shiftKey: true }, view.styleWindow);
await onPopupShown;
info("Check that the expected grid line row names are shown in the editor popup.");
for (const lineName of gridRowLines) {
ok(editor.gridLineNames.rows.indexOf(lineName) > -1,
`${lineName} is a suggested explicit grid line`);
}
}
async function testImplicitAreasWithImplicitGridLineNames(inspector, view) {
await selectNode(".a", inspector);
const propertyName = view.styleDocument.querySelectorAll(".ruleview-propertyvalue")[0];
const gridLineNamesUpdated = inspector.once("grid-line-names-updated");
const editor = await focusEditableField(view, propertyName);
const onPopupShown = once(editor.popup, "popup-opened");
await gridLineNamesUpdated;
EventUtils.synthesizeKey("VK_DOWN", { shiftKey: true }, view.styleWindow);
await onPopupShown;
info("Check that the implicit grid lines created by implicit areas are not shown.");
ok(!(editor.gridLineNames.cols.indexOf("a-end") > -1),
"a-end is not shown because it is created by an implicit named area.");
}
async function testImplicitNamedAreasWithReversedGridLineNames(inspector, view) {
await selectNode(".b", inspector);
const propertyName = view.styleDocument.querySelectorAll(".ruleview-propertyvalue")[0];
const gridLineNamesUpdated = inspector.once("grid-line-names-updated");
const editor = await focusEditableField(view, propertyName);
const onPopupShown = once(editor.popup, "popup-opened");
await gridLineNamesUpdated;
EventUtils.synthesizeKey("VK_DOWN", { shiftKey: true }, view.styleWindow);
await onPopupShown;
info("Test that reversed implicit grid line names from implicit areas are not shown");
ok(!(editor.gridLineNames.cols.indexOf("b-start") > -1),
"b-start is not shown because it is created by an implicit named area.");
}

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

@ -0,0 +1,59 @@
<!doctype html>
<style type='text/css'>
/* Implicit gridlines created from explicit grid areas. */
.wrapperA {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: minmax(100px, auto);
grid-template-areas:
"header header header"
"main main main";
}
.header {
grid-column: header-start / header-end;
grid-row: header-start / header-end;
}
.main {
grid-area: main;
}
/* Implicit grid areas created from explicit gridlines */
.wrapperB {
display: grid;
grid-template-columns: [main-start] 1fr [content-start] 1fr [content-end main-end];
grid-template-rows: [main-start] 100px [content-start] 100px [content-end main-end];
}
.contentArea {
grid-column: content-start / content-end;
grid-row: content-start / content-end;
}
.wrapperC {
display: grid;
grid-template-columns: [a-start b-end] 1fr [c];
}
.a {
grid-column: a-start / a-end;
}
.b {
grid-column: b-start / b-end;
}
</style>
<div>
<div class="wrapperA">
<div class="header">Header</div>
<div class="main">Content</div>
</div>
<div class="wrapperB">
<div class="contentArea">Implicit area named "content".</div>
</div>
<div class="wrapperC">
<div class="a">A.</div>
<div class="b">B.</div>
</div>
</div>

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

@ -330,10 +330,39 @@ TextPropertyEditor.prototype = {
for (const gridFragment of gridFragments) {
for (const rowLine of gridFragment.rows.lines) {
gridLineNames.rows = gridLineNames.rows.concat(rowLine.names);
// We specifically ignore implicit line names created from implicitly named
// areas. This is because showing implicit line names can be confusing for
// designers who may have used a line name with "-start" or "-end" and created
// an implicitly named grid area without meaning to.
let gridArea;
for (const name of rowLine.names) {
const rowLineName = name.substring(0, name.lastIndexOf("-start")) ||
name.substring(0, name.lastIndexOf("-end"));
gridArea = gridFragment.areas.find(area => area.name === rowLineName);
if (rowLine.type === "implicit" && gridArea &&
gridArea.type === "implicit") {
continue;
}
gridLineNames.rows.push(name);
}
}
for (const colLine of gridFragment.cols.lines) {
gridLineNames.cols = gridLineNames.cols.concat(colLine.names);
let gridArea;
for (const name of colLine.names) {
const colLineName = name.substring(0, name.lastIndexOf("-start")) ||
name.substring(0, name.lastIndexOf("-end"));
gridArea = gridFragment.areas.find(area => area.name === colLineName);
if (colLine.type === "implicit" && gridArea &&
gridArea.type === "implicit") {
continue;
}
gridLineNames.cols.push(name);
}
}
}
}

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

@ -130,10 +130,6 @@ exports.ANIMATION_TYPE_FOR_LONGHANDS = [
"ruby-position",
"scroll-behavior",
"scroll-snap-align",
"scroll-snap-coordinate",
"scroll-snap-destination",
"scroll-snap-points-x",
"scroll-snap-points-y",
"scroll-snap-type",
"shape-rendering",
"-moz-stack-sizing",

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

@ -58,8 +58,8 @@ function getStringifiableArea({ columnEnd, columnStart, name, rowEnd, rowStart,
return { columnEnd, columnStart, name, rowEnd, rowStart, type };
}
function getStringifiableLine({ breadth, names, number, start }) {
return { breadth, names, number, start };
function getStringifiableLine({ breadth, names, number, start, type }) {
return { breadth, names, number, start, type };
}
function getStringifiableTrack({ breadth, start, state, type }) {

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

@ -40,18 +40,21 @@ const GRID_FRAGMENT_DATA = {
names: ["col-1", "col-start-1", "sidebar-start"],
number: 1,
start: 0,
type: "explicit",
},
{
breadth: 0,
names: ["col-2", "header-start", "sidebar-end", "content-start"],
number: 2,
start: 100,
type: "explicit",
},
{
breadth: 0,
names: ["header-end", "content-end"],
number: 3,
start: 200,
type: "explicit",
},
],
tracks: [
@ -76,18 +79,21 @@ const GRID_FRAGMENT_DATA = {
names: ["header-start"],
number: 1,
start: 0,
type: "explicit",
},
{
breadth: 0,
names: ["header-end", "sidebar-start", "content-start"],
number: 2,
start: 100,
type: "explicit",
},
{
breadth: 0,
names: ["sidebar-end", "content-end"],
number: 3,
start: 200,
type: "explicit",
},
],
tracks: [

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

@ -3084,10 +3084,6 @@ exports.CSS_PROPERTIES = {
"animation-play-state",
"animation-fill-mode",
"animation-delay",
"scroll-snap-points-x",
"scroll-snap-points-y",
"scroll-snap-destination",
"scroll-snap-coordinate",
"transform",
"rotate",
"scale",
@ -10719,10 +10715,6 @@ exports.PREFERENCES = [
"scale",
"layout.css.individual-transform.enabled"
],
[
"scroll-snap-coordinate",
"layout.css.scroll-snap.enabled"
],
[
"scrollbar-color",
"layout.css.scrollbar-color.enabled"
@ -10731,18 +10723,6 @@ exports.PREFERENCES = [
"translate",
"layout.css.individual-transform.enabled"
],
[
"scroll-snap-points-x",
"layout.css.scroll-snap.enabled"
],
[
"scroll-snap-points-y",
"layout.css.scroll-snap.enabled"
],
[
"scroll-snap-destination",
"layout.css.scroll-snap.enabled"
],
[
"-moz-binding",
"layout.css.moz-binding.content.enabled"

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

@ -4628,12 +4628,7 @@ nsDocShell::Reload(uint32_t aReloadFlags) {
bool loadReplace = false;
nsIPrincipal* triggeringPrincipal = doc->NodePrincipal();
// Currently the NodePrincipal holds the CSP for that document,
// after Bug 965637 we can query the CSP directly from the doc
// instead of doc->NodePrincipal().
nsCOMPtr<nsIContentSecurityPolicy> csp;
rv = doc->NodePrincipal()->GetCsp(getter_AddRefs(csp));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIContentSecurityPolicy> csp = doc->GetCsp();
nsAutoString contentTypeHint;
doc->GetContentType(contentTypeHint);
@ -5885,21 +5880,17 @@ nsDocShell::ForceRefreshURI(nsIURI* aURI, nsIPrincipal* aPrincipal,
// Set the triggering pricipal to aPrincipal if available, or current
// document's principal otherwise.
nsCOMPtr<nsIPrincipal> principal = aPrincipal;
RefPtr<Document> doc = GetDocument();
if (!principal) {
RefPtr<Document> doc = GetDocument();
if (!doc) {
return NS_ERROR_FAILURE;
}
principal = doc->NodePrincipal();
}
loadState->SetTriggeringPrincipal(principal);
// Currently the principal (NodePrincipal) holds the CSP for that
// document, after Bug 965637 we can query the CSP directly from
// the doc instead of the principal.
nsCOMPtr<nsIContentSecurityPolicy> csp;
nsresult rv = principal->GetCsp(getter_AddRefs(csp));
NS_ENSURE_SUCCESS(rv, rv);
loadState->SetCsp(csp);
if (doc) {
loadState->SetCsp(doc->GetCsp());
}
loadState->SetPrincipalIsExplicit(true);
@ -5907,7 +5898,7 @@ nsDocShell::ForceRefreshURI(nsIURI* aURI, nsIPrincipal* aPrincipal,
* to another site.
*/
bool equalUri = false;
rv = aURI->Equals(mCurrentURI, &equalUri);
nsresult rv = aURI->Equals(mCurrentURI, &equalUri);
if (NS_SUCCEEDED(rv) && (!equalUri) && aMetaRefresh &&
aDelay <= REFRESH_REDIRECT_TIMER) {
/* It is a META refresh based redirection within the threshold time
@ -6905,13 +6896,7 @@ nsresult nsDocShell::EndPageLoad(nsIWebProgress* aProgress,
LoadURIOptions loadURIOptions;
loadURIOptions.mTriggeringPrincipal = triggeringPrincipal;
// Currently we query the CSP from the triggeringPrincipal within
// the loadInfo. After Bug 965637, we can query the CSP from the
// loadInfo, which internally queries the CSP from the Client.
nsCOMPtr<nsIContentSecurityPolicy> csp;
nsresult rv = triggeringPrincipal->GetCsp(getter_AddRefs(csp));
NS_ENSURE_SUCCESS(rv, rv);
loadURIOptions.mCsp = csp;
loadURIOptions.mCsp = loadInfo->GetCsp();
loadURIOptions.mPostData = newPostData;
return LoadURI(newSpecW, loadURIOptions);
}
@ -6976,6 +6961,7 @@ nsresult nsDocShell::EnsureContentViewer() {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIContentSecurityPolicy> cspToInheritForAboutBlank;
nsCOMPtr<nsIURI> baseURI;
nsIPrincipal* principal = GetInheritedPrincipal(false);
nsCOMPtr<nsIDocShellTreeItem> parentItem;
@ -6985,11 +6971,13 @@ nsresult nsDocShell::EnsureContentViewer() {
nsCOMPtr<Element> parentElement = domWin->GetFrameElementInternal();
if (parentElement) {
baseURI = parentElement->GetBaseURI();
cspToInheritForAboutBlank = parentElement->GetCsp();
}
}
}
nsresult rv = CreateAboutBlankContentViewer(principal, baseURI);
nsresult rv = CreateAboutBlankContentViewer(
principal, cspToInheritForAboutBlank, baseURI);
NS_ENSURE_STATE(mContentViewer);
@ -7015,8 +7003,8 @@ nsresult nsDocShell::EnsureContentViewer() {
}
nsresult nsDocShell::CreateAboutBlankContentViewer(
nsIPrincipal* aPrincipal, nsIURI* aBaseURI, bool aTryToSaveOldPresentation,
bool aCheckPermitUnload) {
nsIPrincipal* aPrincipal, nsIContentSecurityPolicy* aCSP, nsIURI* aBaseURI,
bool aTryToSaveOldPresentation, bool aCheckPermitUnload) {
RefPtr<Document> blankDoc;
nsCOMPtr<nsIContentViewer> viewer;
nsresult rv = NS_ERROR_FAILURE;
@ -7120,6 +7108,16 @@ nsresult nsDocShell::CreateAboutBlankContentViewer(
// generate (about:blank) document to load
blankDoc = nsContentDLF::CreateBlankDocument(mLoadGroup, principal, this);
if (blankDoc) {
// Hack: manually set the CSP for the new document
// Please create an actual copy of the CSP (do not share the same
// reference) otherwise appending a new policy within the new
// document will be incorrectly propagated to the opening doc.
if (aCSP) {
RefPtr<nsCSPContext> cspToInherit = new nsCSPContext();
cspToInherit->InitFromOther(static_cast<nsCSPContext*>(aCSP));
blankDoc->SetCsp(cspToInherit);
}
// Hack: set the base URI manually, since this document never
// got Reset() with a channel.
blankDoc->SetBaseURI(aBaseURI);
@ -7159,8 +7157,9 @@ nsresult nsDocShell::CreateAboutBlankContentViewer(
}
NS_IMETHODIMP
nsDocShell::CreateAboutBlankContentViewer(nsIPrincipal* aPrincipal) {
return CreateAboutBlankContentViewer(aPrincipal, nullptr);
nsDocShell::CreateAboutBlankContentViewer(nsIPrincipal* aPrincipal,
nsIContentSecurityPolicy* aCSP) {
return CreateAboutBlankContentViewer(aPrincipal, aCSP, nullptr);
}
bool nsDocShell::CanSavePresentation(uint32_t aLoadType,
@ -9050,13 +9049,7 @@ nsresult nsDocShell::MaybeHandleSameDocumentNavigation(
} else {
newURITriggeringPrincipal = aLoadState->TriggeringPrincipal();
newURIPrincipalToInherit = doc->NodePrincipal();
// This is a same-document navigation hence we query the CSP
// from the current document. Please note that currently the
// NodePrincipal holds the CSP for that document, after
// Bug 965637 we can query the CSP directly from
// the doc instead of the NodePrincipal.
nsresult rv = doc->NodePrincipal()->GetCsp(getter_AddRefs(newCsp));
NS_ENSURE_SUCCESS(rv, rv);
newCsp = doc->GetCsp();
}
// Pass true for aCloneSHChildren, since we're not
// changing documents here, so all of our subframes are
@ -9354,7 +9347,7 @@ nsresult nsDocShell::InternalLoad(nsDocShellLoadState* aLoadState,
}
// clear the decks to prevent context bleed-through (bug 298255)
rv = CreateAboutBlankContentViewer(nullptr, nullptr);
rv = CreateAboutBlankContentViewer(nullptr, nullptr, nullptr);
if (NS_FAILED(rv)) {
return NS_ERROR_FAILURE;
}
@ -10010,23 +10003,10 @@ nsresult nsDocShell::DoURILoad(nsDocShellLoadState* aLoadState,
isc->SetBaseURI(baseURI);
}
// Navigational requests that are same origin need to be upgraded in case
// upgrade-insecure-requests is present. Please note that in that case
// the triggeringPrincipal is holding the CSP that potentially
// holds upgrade-insecure-requests.
nsCOMPtr<nsIContentSecurityPolicy> csp;
aLoadState->TriggeringPrincipal()->GetCsp(getter_AddRefs(csp));
#ifdef DEBUG
// We only serialize the CSP within CodebasePrincipals hence
// lets only assert if the load is triggered by a CodebesPrincipal.
// After Bug 965637 we can remove that assertion anyway.
if (aLoadState->TriggeringPrincipal()->GetIsCodebasePrincipal()) {
nsCOMPtr<nsIContentSecurityPolicy> argsCSP = aLoadState->Csp();
MOZ_ASSERT(nsCSPContext::Equals(csp, argsCSP));
}
#endif
nsCOMPtr<nsIContentSecurityPolicy> csp = aLoadState->Csp();
if (csp) {
// Navigational requests that are same origin need to be upgraded in case
// upgrade-insecure-requests is present.
bool upgradeInsecureRequests = false;
csp->GetUpgradeInsecureRequests(&upgradeInsecureRequests);
if (upgradeInsecureRequests) {
@ -10040,6 +10020,17 @@ nsresult nsDocShell::DoURILoad(nsDocShellLoadState* aLoadState,
loadInfo->SetUpgradeInsecureRequests();
}
}
if (CSP_ShouldResponseInheritCSP(channel)) {
// If the new load needs to inherit the CSP, temporarily store the CSP
// on the loadinfo, and transfer it to the new Document within
// Document::InitCSP(). Please create an actual copy of the CSP (do not
// share the same reference) otherwise a Meta CSP of an opaque origin
// will incorrectly be propagated to the embedding document.
RefPtr<nsCSPContext> cspToInherit = new nsCSPContext();
cspToInherit->InitFromOther(static_cast<nsCSPContext*>(csp.get()));
loadInfo->SetCSPToInherit(cspToInherit);
}
}
nsCOMPtr<nsIApplicationCacheChannel> appCacheChannel =
@ -11140,12 +11131,7 @@ nsresult nsDocShell::UpdateURLAndHistory(Document* aDocument, nsIURI* aNewURI,
mOSHE->SetScrollPosition(scrollPos.x, scrollPos.y);
bool scrollRestorationIsManual = mOSHE->GetScrollRestorationIsManual();
// Currently the NodePrincipal holds the CSP for that document,
// after Bug 965637 we can query the CSP directly from
// the doc instead of the NodePrincipal.
nsCOMPtr<nsIContentSecurityPolicy> csp;
aDocument->NodePrincipal()->GetCsp(getter_AddRefs(csp));
nsCOMPtr<nsIContentSecurityPolicy> csp = aDocument->GetCsp();
// Since we're not changing which page we have loaded, pass
// true for aCloneChildren.
@ -11185,18 +11171,12 @@ nsresult nsDocShell::UpdateURLAndHistory(Document* aDocument, nsIURI* aNewURI,
// Step 3.
newSHEntry = mOSHE;
// Currently the NodePrincipal holds the CSP for that document,
// after Bug 965637 we can query the CSP directly from
// the doc instead of the NodePrincipal.
nsCOMPtr<nsIContentSecurityPolicy> csp;
aDocument->NodePrincipal()->GetCsp(getter_AddRefs(csp));
// Since we're not changing which page we have loaded, pass
if (!newSHEntry) {
nsresult rv = AddToSessionHistory(
aNewURI, nullptr,
aDocument->NodePrincipal(), // triggeringPrincipal
nullptr, csp, true, getter_AddRefs(newSHEntry));
nullptr, aDocument->GetCsp(), true, getter_AddRefs(newSHEntry));
NS_ENSURE_SUCCESS(rv, rv);
mOSHE = newSHEntry;
}
@ -11448,13 +11428,8 @@ nsresult nsDocShell::AddToSessionHistory(nsIURI* aURI, nsIChannel* aChannel,
if (!triggeringPrincipal) {
triggeringPrincipal = loadInfo->TriggeringPrincipal();
}
if (!csp && triggeringPrincipal) {
// Currently if no CSP is passed explicitly we query the CSP from
// the triggeringPrincipal from within the loadinfo. After Bug 965637,
// we can query the CSP from the loadInfo directly in case the CSP is
// not passed explicitly. Internally the loadinfo queries the CSP
// from the Client.
triggeringPrincipal->GetCsp(getter_AddRefs(csp));
if (!csp) {
csp = static_cast<net::LoadInfo*>(loadInfo.get())->GetCSPToInherit();
}
loadInfo->GetResultPrincipalURI(getter_AddRefs(resultPrincipalURI));
@ -11619,7 +11594,7 @@ nsresult nsDocShell::LoadHistoryEntry(nsISHEntry* aEntry, uint32_t aLoadType) {
// Don't cache the presentation if we're going to just reload the
// current entry. Caching would lead to trying to save the different
// content viewers in the same nsISHEntry object.
rv = CreateAboutBlankContentViewer(principalToInherit, nullptr,
rv = CreateAboutBlankContentViewer(principalToInherit, nullptr, nullptr,
aEntry != mOSHE);
if (NS_FAILED(rv)) {
@ -12659,9 +12634,8 @@ nsDocShell::OnLinkClickSync(
nsCOMPtr<nsIContentSecurityPolicy> csp = aCsp;
if (!csp) {
// Currently, if no csp is passed explicitly we fall back to querying the
// CSP from the NodePrincipal(). After Bug 965637 we can fall back to
// querying the CSP from the document (aContent->OwnerDoc()).
aContent->NodePrincipal()->GetCsp(getter_AddRefs(csp));
// CSP from the document.
csp = aContent->GetCsp();
}
uint32_t flags = INTERNAL_LOAD_FLAGS_NONE;
@ -12930,7 +12904,8 @@ nsDocShell::InitOrReusePrintPreviewViewer(nsIWebBrowserPrint** aPrintPreview) {
NullPrincipal::CreateWithInheritedAttributes(this);
nsCOMPtr<nsIURI> uri;
NS_NewURI(getter_AddRefs(uri), NS_LITERAL_CSTRING("about:printpreview"));
nsresult rv = CreateAboutBlankContentViewer(principal, uri);
nsresult rv =
CreateAboutBlankContentViewer(principal, /* aCsp = */ nullptr, uri);
NS_ENSURE_SUCCESS(rv, rv);
// Here we manually set current URI since we have just created a
// brand new content viewer (about:blank) to host preview.

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

@ -486,7 +486,9 @@ class nsDocShell final : public nsDocLoader,
// aPrincipal can be passed in if the caller wants. If null is
// passed in, the about:blank principal will end up being used.
// aCSP, if any, will be used for the new about:blank load.
nsresult CreateAboutBlankContentViewer(nsIPrincipal* aPrincipal,
nsIContentSecurityPolicy* aCSP,
nsIURI* aBaseURI,
bool aTryToSaveOldPresentation = true,
bool aCheckPermitUnload = true);

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

@ -43,6 +43,7 @@ class ClientSource;
interface nsIURI;
interface nsIChannel;
interface nsIContentViewer;
interface nsIContentSecurityPolicy;
interface nsIDocShellLoadInfo;
interface nsIEditor;
interface nsIEditingSession;
@ -606,8 +607,10 @@ interface nsIDocShell : nsIDocShellTreeItem
/**
* Create a new about:blank document and content viewer.
* @param aPrincipal the principal to use for the new document.
* @param aCsp the CSP to use for the new document.
*/
void createAboutBlankContentViewer(in nsIPrincipal aPrincipal);
void createAboutBlankContentViewer(in nsIPrincipal aPrincipal,
[optional] in nsIContentSecurityPolicy aCSP);
/**
* Upon getting, returns the canonical encoding label of the document

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

@ -35,8 +35,7 @@ function verifyResult(aTestName, aBrowser, aDataURI, aPID, aSamePID) {
}
// finally, evaluate that the CSP was set.
let principal = channel.loadInfo.triggeringPrincipal;
let cspOBJ = JSON.parse(principal.cspJSON);
let cspOBJ = JSON.parse(content.document.cspJSON);
let policies = cspOBJ["csp-policies"];
is(policies.length, 1, "should be one policy");
let policy = policies[0];

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

@ -15,8 +15,7 @@ function verifyCSP(aTestName, aBrowser, aDataURI) {
return ContentTask.spawn(aBrowser, {aTestName, aDataURI}, async function({aTestName, aDataURI}) {
let channel = content.docShell.currentDocumentChannel;
is(channel.URI.spec, aDataURI, "testing CSP for " + aTestName);
let principal = channel.loadInfo.triggeringPrincipal;
let cspJSON = principal.cspJSON;
let cspJSON = content.document.cspJSON;
let cspOBJ = JSON.parse(cspJSON);
let policies = cspOBJ["csp-policies"];
is(policies.length, 1, "should be one policy");

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

@ -206,17 +206,12 @@ ContentAreaDropListener.prototype =
if (sourceNode &&
(sourceNode.localName !== "browser" ||
sourceNode.namespaceURI !== "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul")) {
// Use sourceNode's principal only if the sourceNode is not browser.
// Use sourceNode's csp only if the sourceNode is not browser.
//
// If sourceNode is browser, the actual triggering principal may be
// differ than sourceNode's principal, since sourceNode's principal is
// top level document's one and the drag may be triggered from a frame
// with different principal.
if (sourceNode.nodePrincipal) {
// Currently we query the CSP from the nodePrincipal. After Bug 965637 we can
// query the CSP directly from the sourceNode.
return sourceNode.nodePrincipal.csp;
}
// If sourceNode is browser, the actual triggering csp may be differ than sourceNode's csp,
// since sourceNode's csp is top level document's one and the drag may be triggered from a
// frame with different csp.
return sourceNode.csp;
}
return null;
},

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

@ -24,6 +24,7 @@
#include "mozilla/IntegerRange.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/Likely.h"
#include "mozilla/LoadInfo.h"
#include "mozilla/PresShell.h"
#include "mozilla/PresShellInlines.h"
#include "mozilla/RestyleManager.h"
@ -69,6 +70,7 @@
#include "mozilla/dom/Attr.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/CSPDictionariesBinding.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/Event.h"
#include "mozilla/dom/FeaturePolicy.h"
@ -2697,7 +2699,8 @@ nsresult Document::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
// XFO needs to be checked after CSP because it is ignored if
// the CSP defines frame-ancestors.
if (!FramingChecker::CheckFrameOptions(aChannel, docShell, NodePrincipal())) {
nsCOMPtr<nsIContentSecurityPolicy> cspForFA = mCSP;
if (!FramingChecker::CheckFrameOptions(aChannel, docShell, cspForFA)) {
MOZ_LOG(gCspPRLog, LogLevel::Debug,
("XFO doesn't like frame's ancestry, not loading."));
// stop! ERROR page!
@ -2719,6 +2722,29 @@ nsresult Document::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
return NS_OK;
}
nsIContentSecurityPolicy* Document::GetCsp() const { return mCSP; }
void Document::SetCsp(nsIContentSecurityPolicy* aCSP) { mCSP = aCSP; }
nsIContentSecurityPolicy* Document::GetPreloadCsp() const {
return mPreloadCSP;
}
void Document::SetPreloadCsp(nsIContentSecurityPolicy* aPreloadCSP) {
mPreloadCSP = aPreloadCSP;
}
void Document::GetCspJSON(nsString& aJSON) {
aJSON.Truncate();
if (!mCSP) {
dom::CSPPolicies jsonPolicies;
jsonPolicies.ToJSON(aJSON);
return;
}
mCSP->ToJSON(aJSON);
}
void Document::SendToConsole(nsCOMArray<nsISecurityConsoleMessage>& aMessages) {
for (uint32_t i = 0; i < aMessages.Length(); ++i) {
nsAutoString messageTag;
@ -2738,14 +2764,11 @@ void Document::ApplySettingsFromCSP(bool aSpeculative) {
nsresult rv = NS_OK;
if (!aSpeculative) {
// 1) apply settings from regular CSP
nsCOMPtr<nsIContentSecurityPolicy> csp;
rv = NodePrincipal()->GetCsp(getter_AddRefs(csp));
NS_ENSURE_SUCCESS_VOID(rv);
if (csp) {
if (mCSP) {
// Set up 'block-all-mixed-content' if not already inherited
// from the parent context or set by any other CSP.
if (!mBlockAllMixedContent) {
rv = csp->GetBlockAllMixedContent(&mBlockAllMixedContent);
rv = mCSP->GetBlockAllMixedContent(&mBlockAllMixedContent);
NS_ENSURE_SUCCESS_VOID(rv);
}
if (!mBlockAllMixedContentPreloads) {
@ -2755,7 +2778,7 @@ void Document::ApplySettingsFromCSP(bool aSpeculative) {
// Set up 'upgrade-insecure-requests' if not already inherited
// from the parent context or set by any other CSP.
if (!mUpgradeInsecureRequests) {
rv = csp->GetUpgradeInsecureRequests(&mUpgradeInsecureRequests);
rv = mCSP->GetUpgradeInsecureRequests(&mUpgradeInsecureRequests);
NS_ENSURE_SUCCESS_VOID(rv);
}
if (!mUpgradeInsecurePreloads) {
@ -2766,16 +2789,13 @@ void Document::ApplySettingsFromCSP(bool aSpeculative) {
}
// 2) apply settings from speculative csp
nsCOMPtr<nsIContentSecurityPolicy> preloadCsp;
rv = NodePrincipal()->GetPreloadCsp(getter_AddRefs(preloadCsp));
NS_ENSURE_SUCCESS_VOID(rv);
if (preloadCsp) {
if (mPreloadCSP) {
if (!mBlockAllMixedContentPreloads) {
rv = preloadCsp->GetBlockAllMixedContent(&mBlockAllMixedContentPreloads);
rv = mPreloadCSP->GetBlockAllMixedContent(&mBlockAllMixedContentPreloads);
NS_ENSURE_SUCCESS_VOID(rv);
}
if (!mUpgradeInsecurePreloads) {
rv = preloadCsp->GetUpgradeInsecureRequests(&mUpgradeInsecurePreloads);
rv = mPreloadCSP->GetUpgradeInsecureRequests(&mUpgradeInsecurePreloads);
NS_ENSURE_SUCCESS_VOID(rv);
}
}
@ -2795,10 +2815,41 @@ nsresult Document::InitCSP(nsIChannel* aChannel) {
return NS_OK;
}
// If this is a system privileged document - do not apply a CSP.
// After Bug 1496418 we can remove the early return and apply
// a CSP even when loading using a SystemPrincipal.
if (nsContentUtils::IsSystemPrincipal(NodePrincipal())) {
return NS_OK;
}
MOZ_ASSERT(!mCSP, "where did mCSP get set if not here?");
// If there is a CSP that needs to be inherited either from the
// embedding doc or from the opening doc, then we query it here
// from the loadinfo because the docshell temporarily stored it
// on the loadinfo so we can set it here.
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
mCSP = static_cast<net::LoadInfo*>(loadInfo.get())->GetCSPToInherit();
// If there is no CSP to inherit, then we create a new CSP here so
// that history entries always have the right reference in case a
// Meta CSP gets dynamically added after the history entry has
// already been created.
if (!mCSP) {
mCSP = new nsCSPContext();
}
// Always overwrite the requesting context of the CSP so that any new
// 'self' keyword added to an inherited CSP translates correctly.
nsresult rv = mCSP->SetRequestContextWithDocument(this);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
nsAutoCString tCspHeaderValue, tCspROHeaderValue;
nsCOMPtr<nsIHttpChannel> httpChannel;
nsresult rv = GetHttpChannelHelper(aChannel, getter_AddRefs(httpChannel));
rv = GetHttpChannelHelper(aChannel, getter_AddRefs(httpChannel));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -2818,20 +2869,6 @@ nsresult Document::InitCSP(nsIChannel* aChannel) {
nsCOMPtr<nsIPrincipal> principal = NodePrincipal();
auto addonPolicy = BasePrincipal::Cast(principal)->AddonPolicy();
// Unless the NodePrincipal is a SystemPrincipal, which currently can not
// hold a CSP, we always call EnsureCSP() on the Principal. We do this
// so that a Meta CSP does not have to create a new CSP object. This is
// important because history entries hold a reference to the CSP object,
// which then gets dynamically updated in case a meta CSP is present.
// Note that after Bug 965637 we can remove that carve out, because the
// CSP will hang off the Client/Document and not the Principal anymore.
if (principal->IsSystemPrincipal()) {
return NS_OK;
}
nsCOMPtr<nsIContentSecurityPolicy> csp;
rv = principal->EnsureCSP(this, getter_AddRefs(csp));
NS_ENSURE_SUCCESS(rv, rv);
// If there's no CSP to apply, go ahead and return early
if (!addonPolicy && cspHeaderValue.IsEmpty() && cspROHeaderValue.IsEmpty()) {
if (MOZ_LOG_TEST(gCspPRLog, LogLevel::Debug)) {
@ -2853,20 +2890,28 @@ nsresult Document::InitCSP(nsIChannel* aChannel) {
if (addonPolicy) {
nsAutoString addonCSP;
Unused << ExtensionPolicyService::GetSingleton().GetBaseCSP(addonCSP);
csp->AppendPolicy(addonCSP, false, false);
mCSP->AppendPolicy(addonCSP, false, false);
csp->AppendPolicy(addonPolicy->ContentSecurityPolicy(), false, false);
mCSP->AppendPolicy(addonPolicy->ContentSecurityPolicy(), false, false);
// Bug 1548468: Move CSP off ExpandedPrincipal
// Currently the LoadInfo holds the source of truth for every resource load
// because LoadInfo::GetCSP() queries the CSP from an ExpandedPrincipal
// (and not from the Client) if the load was triggered by an extension.
auto* basePrin = BasePrincipal::Cast(principal);
if (basePrin->Is<ExpandedPrincipal>()) {
basePrin->As<ExpandedPrincipal>()->SetCsp(mCSP);
}
}
// ----- if there's a full-strength CSP header, apply it.
if (!cspHeaderValue.IsEmpty()) {
rv = CSP_AppendCSPFromHeader(csp, cspHeaderValue, false);
rv = CSP_AppendCSPFromHeader(mCSP, cspHeaderValue, false);
NS_ENSURE_SUCCESS(rv, rv);
}
// ----- if there's a report-only CSP header, apply it.
if (!cspROHeaderValue.IsEmpty()) {
rv = CSP_AppendCSPFromHeader(csp, cspROHeaderValue, true);
rv = CSP_AppendCSPFromHeader(mCSP, cspROHeaderValue, true);
NS_ENSURE_SUCCESS(rv, rv);
}
@ -2876,7 +2921,7 @@ nsresult Document::InitCSP(nsIChannel* aChannel) {
// directive, intersect the CSP sandbox flags with the existing flags. This
// corresponds to the _least_ permissive policy.
uint32_t cspSandboxFlags = SANDBOXED_NONE;
rv = csp->GetCSPSandboxFlags(&cspSandboxFlags);
rv = mCSP->GetCSPSandboxFlags(&cspSandboxFlags);
NS_ENSURE_SUCCESS(rv, rv);
// Probably the iframe sandbox attribute already caused the creation of a
@ -2889,7 +2934,6 @@ nsresult Document::InitCSP(nsIChannel* aChannel) {
if (needNewNullPrincipal) {
principal = NullPrincipal::CreateWithInheritedAttributes(principal);
principal->SetCsp(csp);
SetPrincipals(principal, principal);
}
@ -2899,7 +2943,7 @@ nsresult Document::InitCSP(nsIChannel* aChannel) {
bool safeAncestry = false;
// PermitsAncestry sends violation reports when necessary
rv = csp->PermitsAncestry(docShell, &safeAncestry);
rv = mCSP->PermitsAncestry(docShell, &safeAncestry);
if (NS_FAILED(rv) || !safeAncestry) {
MOZ_LOG(gCspPRLog, LogLevel::Debug,
@ -4733,10 +4777,8 @@ void Document::SetScriptGlobalObject(
// Now that we know what our window is, we can flush the CSP errors to the
// Web Console. We are flushing all messages that occured and were stored
// in the queue prior to this point.
nsCOMPtr<nsIContentSecurityPolicy> csp;
NodePrincipal()->GetCsp(getter_AddRefs(csp));
if (csp) {
static_cast<nsCSPContext*>(csp.get())->flushConsoleMessages();
if (mCSP) {
static_cast<nsCSPContext*>(mCSP.get())->flushConsoleMessages();
}
nsCOMPtr<nsIHttpChannelInternal> internalChannel =
@ -5112,12 +5154,11 @@ void Document::DispatchContentLoadedEvents() {
// the CSP allows precisely the resources that need to be loaded; but it
// should at least be as strong as:
// <meta http-equiv="Content-Security-Policy" content="default-src chrome:"/>
static void AssertAboutPageHasCSP(nsIURI* aDocumentURI,
nsIPrincipal* aPrincipal) {
static void AssertAboutPageHasCSP(Document* aDocument) {
// Check if we are loading an about: URI at all
nsCOMPtr<nsIURI> documentURI = aDocument->GetDocumentURI();
bool isAboutURI =
(NS_SUCCEEDED(aDocumentURI->SchemeIs("about", &isAboutURI)) &&
isAboutURI);
(NS_SUCCEEDED(documentURI->SchemeIs("about", &isAboutURI)) && isAboutURI);
if (!isAboutURI ||
Preferences::GetBool("csp.skip_about_page_has_csp_assert")) {
@ -5145,7 +5186,7 @@ static void AssertAboutPageHasCSP(nsIURI* aDocumentURI,
// Check if the about URI is whitelisted
nsAutoCString aboutSpec;
aDocumentURI->GetSpec(aboutSpec);
documentURI->GetSpec(aboutSpec);
ToLowerCase(aboutSpec);
for (auto& legacyPageEntry : *sLegacyAboutPagesWithNoCSP) {
// please note that we perform a substring match here on purpose,
@ -5156,8 +5197,7 @@ static void AssertAboutPageHasCSP(nsIURI* aDocumentURI,
}
}
nsCOMPtr<nsIContentSecurityPolicy> csp;
aPrincipal->GetCsp(getter_AddRefs(csp));
nsCOMPtr<nsIContentSecurityPolicy> csp = aDocument->GetCsp();
bool foundDefaultSrc = false;
if (csp) {
uint32_t policyCount = 0;
@ -5185,7 +5225,7 @@ void Document::EndLoad() {
// only assert if nothing stopped the load on purpose
// TODO: we probably also want to check XUL documents here too
if (!mParserAborted && !IsXULDocument()) {
AssertAboutPageHasCSP(mDocumentURI, NodePrincipal());
AssertAboutPageHasCSP(this);
}
#endif
@ -11687,12 +11727,9 @@ bool Document::HasScriptsBlockedBySandbox() {
bool Document::InlineScriptAllowedByCSP() {
// this function assumes the inline script is parser created
// (e.g., before setting attribute(!) event handlers)
nsCOMPtr<nsIContentSecurityPolicy> csp;
nsresult rv = NodePrincipal()->GetCsp(getter_AddRefs(csp));
NS_ENSURE_SUCCESS(rv, true);
bool allowsInlineScript = true;
if (csp) {
nsresult rv = csp->GetAllowsInline(
if (mCSP) {
nsresult rv = mCSP->GetAllowsInline(
nsIContentPolicy::TYPE_SCRIPT,
EmptyString(), // aNonce
true, // aParserCreated

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

@ -98,6 +98,7 @@ class nsAtom;
class nsIBFCacheEntry;
class nsIChannel;
class nsIContent;
class nsIContentSecurityPolicy;
class nsIContentSink;
class nsIDocShell;
class nsIDocShellTreeItem;
@ -696,6 +697,24 @@ class Document : public nsINode,
*/
void SetChromeXHRDocBaseURI(nsIURI* aURI) { mChromeXHRDocBaseURI = aURI; }
/**
* The CSP in general is stored in the ClientInfo, but we also cache
* the CSP on the document so subresources loaded within a document
* can query that cached CSP instead of having to deserialize the CSP
* from the Client.
*
* Please note that at the time of CSP parsing the Client is not
* available yet, hence we sync CSP of document and Client when the
* Client becomes available within nsGlobalWindowInner::EnsureClientSource().
*/
nsIContentSecurityPolicy* GetCsp() const;
void SetCsp(nsIContentSecurityPolicy* aCSP);
nsIContentSecurityPolicy* GetPreloadCsp() const;
void SetPreloadCsp(nsIContentSecurityPolicy* aPreloadCSP);
void GetCspJSON(nsString& aJSON);
/**
* Set referrer policy and upgrade-insecure-requests flags
*/
@ -4415,6 +4434,12 @@ class Document : public nsINode,
// The channel that got passed to Document::StartDocumentLoad(), if any.
nsCOMPtr<nsIChannel> mChannel;
// The CSP for every load lives in the Client within the LoadInfo. For all
// document-initiated subresource loads we can use that cached version of the
// CSP so we do not have to deserialize the CSP from the Client all the time.
nsCOMPtr<nsIContentSecurityPolicy> mCSP;
nsCOMPtr<nsIContentSecurityPolicy> mPreloadCSP;
private:
nsCString mContentType;

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

@ -150,15 +150,9 @@ already_AddRefed<nsDocShellLoadState> Location::CheckURL(
RefPtr<nsDocShellLoadState> loadState = new nsDocShellLoadState(aURI);
loadState->SetTriggeringPrincipal(triggeringPrincipal);
// Currently we query the CSP from the triggeringPrincipal, which is the
// doc->NodePrincipal() in case there is a doc. In that case we can query
// the CSP directly from the doc after Bug 965637. In case there is no doc,
// then we also do not need to query the CSP, because only documents can have
// a CSP attached.
nsCOMPtr<nsIContentSecurityPolicy> csp;
triggeringPrincipal->GetCsp(getter_AddRefs(csp));
loadState->SetCsp(csp);
if (doc) {
loadState->SetCsp(doc->GetCsp());
}
if (sourceURI) {
nsCOMPtr<nsIReferrerInfo> referrerInfo =

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

@ -6,6 +6,7 @@
#include "mozilla/dom/ResizeObserver.h"
#include "mozilla/dom/DOMRect.h"
#include "mozilla/dom/Document.h"
#include "nsIContent.h"
#include "nsSVGUtils.h"
@ -219,15 +220,13 @@ uint32_t ResizeObserver::BroadcastActiveObservations() {
for (auto& observation : mActiveTargets) {
Element* target = observation->Target();
RefPtr<ResizeObserverEntry> entry = new ResizeObserverEntry(this, *target);
nsSize borderBoxSize =
GetTargetSize(target, ResizeObserverBoxOptions::Border_box);
entry->SetBorderBoxSize(borderBoxSize);
nsSize contentBoxSize =
GetTargetSize(target, ResizeObserverBoxOptions::Content_box);
entry->SetContentRectAndSize(contentBoxSize);
RefPtr<ResizeObserverEntry> entry =
new ResizeObserverEntry(this, *target, borderBoxSize, contentBoxSize);
if (!entries.AppendElement(entry.forget(), fallible)) {
// Out of memory.
@ -271,13 +270,6 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ResizeObserverEntry)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
already_AddRefed<ResizeObserverEntry> ResizeObserverEntry::Constructor(
const GlobalObject& aGlobal, Element& aTarget, ErrorResult& aRv) {
RefPtr<ResizeObserverEntry> observerEntry =
new ResizeObserverEntry(aGlobal.GetAsSupports(), aTarget);
return observerEntry.forget();
}
void ResizeObserverEntry::SetBorderBoxSize(const nsSize& aSize) {
nsIFrame* frame = mTarget->GetPrimaryFrame();
const WritingMode wm = frame ? frame->GetWritingMode() : WritingMode();
@ -292,7 +284,7 @@ void ResizeObserverEntry::SetContentRectAndSize(const nsSize& aSize) {
// Per the spec, we need to use the top-left padding offset as the origin of
// our contentRect.
nsRect rect(nsPoint(padding.left, padding.top), aSize);
RefPtr<DOMRect> contentRect = new DOMRect(mTarget);
RefPtr<DOMRect> contentRect = new DOMRect(this);
contentRect->SetLayoutRect(rect);
mContentRect = contentRect.forget();

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

@ -175,10 +175,15 @@ class ResizeObserverEntry final : public nsISupports, public nsWrapperCache {
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ResizeObserverEntry)
ResizeObserverEntry(nsISupports* aOwner, Element& aTarget)
ResizeObserverEntry(nsISupports* aOwner, Element& aTarget,
const nsSize& aBorderBoxSize,
const nsSize& aContentBoxSize)
: mOwner(aOwner), mTarget(&aTarget) {
MOZ_ASSERT(mOwner, "Need a non-null owner");
MOZ_ASSERT(mTarget, "Need a non-null target element");
SetBorderBoxSize(aBorderBoxSize);
SetContentRectAndSize(aContentBoxSize);
}
nsISupports* GetParentObject() const { return mOwner; }
@ -188,9 +193,6 @@ class ResizeObserverEntry final : public nsISupports, public nsWrapperCache {
return ResizeObserverEntry_Binding::Wrap(aCx, this, aGivenProto);
}
static already_AddRefed<ResizeObserverEntry> Constructor(
const GlobalObject& global, Element& target, ErrorResult& aRv);
Element* Target() const { return mTarget; }
/**
@ -206,14 +208,14 @@ class ResizeObserverEntry final : public nsISupports, public nsWrapperCache {
ResizeObserverSize* BorderBoxSize() const { return mBorderBoxSize; }
ResizeObserverSize* ContentBoxSize() const { return mContentBoxSize; }
private:
~ResizeObserverEntry() = default;
// Set borderBoxSize.
void SetBorderBoxSize(const nsSize& aSize);
// Set contentRect and contentBoxSize.
void SetContentRectAndSize(const nsSize& aSize);
protected:
~ResizeObserverEntry() = default;
nsCOMPtr<nsISupports> mOwner;
nsCOMPtr<Element> mTarget;

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

@ -70,7 +70,6 @@ inline nsresult nsContentPolicy::CheckPolicy(CPMethod policyMethod,
int16_t* decision) {
nsContentPolicyType contentType = loadInfo->InternalContentPolicyType();
nsCOMPtr<nsISupports> requestingContext = loadInfo->GetLoadingContext();
nsCOMPtr<nsIPrincipal> requestPrincipal = loadInfo->TriggeringPrincipal();
nsCOMPtr<nsIURI> requestingLocation;
nsCOMPtr<nsIPrincipal> loadingPrincipal = loadInfo->LoadingPrincipal();
if (loadingPrincipal) {
@ -98,18 +97,17 @@ inline nsresult nsContentPolicy::CheckPolicy(CPMethod policyMethod,
* iframes with an image as src. Get the uri from the dom node.
* See bug 254510
*/
if (!requestingLocation) {
nsCOMPtr<mozilla::dom::Document> doc;
nsCOMPtr<nsIContent> node = do_QueryInterface(requestingContext);
if (node) {
doc = node->OwnerDoc();
}
if (!doc) {
doc = do_QueryInterface(requestingContext);
}
if (doc) {
requestingLocation = doc->GetDocumentURI();
}
nsCOMPtr<mozilla::dom::Document> doc;
nsCOMPtr<nsIContent> node = do_QueryInterface(requestingContext);
if (node) {
doc = node->OwnerDoc();
}
if (!doc) {
doc = do_QueryInterface(requestingContext);
}
if (!requestingLocation && doc) {
requestingLocation = doc->GetDocumentURI();
}
nsContentPolicyType externalType =
@ -129,9 +127,8 @@ inline nsresult nsContentPolicy::CheckPolicy(CPMethod policyMethod,
window = do_QueryInterface(requestingContext);
}
if (requestPrincipal) {
nsCOMPtr<nsIContentSecurityPolicy> csp;
requestPrincipal->GetCsp(getter_AddRefs(csp));
if (doc) {
nsCOMPtr<nsIContentSecurityPolicy> csp = doc->GetCsp();
if (csp && window) {
csp->EnsureEventTarget(
window->EventTargetFor(mozilla::TaskCategory::Other));

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

@ -5058,12 +5058,8 @@ void nsContentUtils::TriggerLink(nsIContent* aContent,
fileName.SetIsVoid(true); // No actionable download attribute was found.
}
// Currently we query the CSP from the triggeringPrincipal, which is
// aContent->NodePrincipal(). After Bug 965637 we can query the CSP
// directly from the doc instead (aContent->OwnerDoc()).
nsCOMPtr<nsIPrincipal> triggeringPrincipal = aContent->NodePrincipal();
nsCOMPtr<nsIContentSecurityPolicy> csp;
triggeringPrincipal->GetCsp(getter_AddRefs(csp));
nsCOMPtr<nsIContentSecurityPolicy> csp = aContent->GetCsp();
handler->OnLinkClick(
aContent, aLinkURI, fileName.IsVoid() ? aTargetSpec : EmptyString(),
@ -9795,15 +9791,7 @@ bool nsContentUtils::AttemptLargeAllocationLoad(nsIHttpChannel* aChannel) {
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
nsCOMPtr<nsIPrincipal> triggeringPrincipal = loadInfo->TriggeringPrincipal();
// Currently we query the CSP from the triggeringPrincipal within the
// loadInfo. After Bug 965637, we can query the CSP from the loadInfo, which
// internally queries the CSP from the Client.
nsCOMPtr<nsIContentSecurityPolicy> csp;
if (triggeringPrincipal) {
rv = triggeringPrincipal->GetCsp(getter_AddRefs(csp));
NS_ENSURE_SUCCESS(rv, false);
}
nsCOMPtr<nsIContentSecurityPolicy> csp = loadInfo->GetCsp();
// Get the channel's load flags, and use them to generate nsIWebNavigation
// load flags. We want to make sure to propagate the refresh and cache busting

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

@ -73,6 +73,7 @@
#include "BrowserParent.h"
#include "mozilla/AsyncEventDispatcher.h"
#include "mozilla/BasePrincipal.h"
#include "mozilla/ExpandedPrincipal.h"
#include "mozilla/GuardObjects.h"
#include "mozilla/HTMLEditor.h"
#include "mozilla/NullPrincipal.h"
@ -405,10 +406,7 @@ void nsFrameLoader::LoadFrame(bool aOriginalSrc) {
if (isSrcdoc) {
src.AssignLiteral("about:srcdoc");
principal = mOwnerContent->NodePrincipal();
// Currently the NodePrincipal holds the CSP for a document. After
// Bug 965637 we can query the CSP from mOwnerContent->OwnerDoc()
// instead of mOwnerContent->NodePrincipal().
mOwnerContent->NodePrincipal()->GetCsp(getter_AddRefs(csp));
csp = mOwnerContent->GetCsp();
} else {
GetURL(src, getter_AddRefs(principal), getter_AddRefs(csp));
@ -425,10 +423,7 @@ void nsFrameLoader::LoadFrame(bool aOriginalSrc) {
}
src.AssignLiteral("about:blank");
principal = mOwnerContent->NodePrincipal();
// Currently the NodePrincipal holds the CSP for a document. After
// Bug 965637 we can query the CSP from mOwnerContent->OwnerDoc()
// instead of mOwnerContent->NodePrincipal().
mOwnerContent->NodePrincipal()->GetCsp(getter_AddRefs(csp));
csp = mOwnerContent->GetCsp();
}
}
@ -520,8 +515,7 @@ void nsFrameLoader::ResumeLoad(uint64_t aPendingSwitchID) {
mURIToLoad = nullptr;
mPendingSwitchID = aPendingSwitchID;
mTriggeringPrincipal = mOwnerContent->NodePrincipal();
// NOTE: This can be gotten off of the document after bug 965637.
mOwnerContent->NodePrincipal()->GetCsp(getter_AddRefs(mCsp));
mCsp = mOwnerContent->GetCsp();
nsresult rv = doc->InitializeFrameLoader(this);
if (NS_FAILED(rv)) {
@ -627,18 +621,14 @@ nsresult nsFrameLoader::ReallyStartLoadingInternal() {
}
// If we have an explicit CSP, we set it. If not, we only query it from
// the NodePrincipal in case there was no explicit triggeringPrincipal.
// the document in case there was no explicit triggeringPrincipal.
// Otherwise it's possible that the original triggeringPrincipal did not
// have a CSP which causes the CSP on the Principal and explicit CSP
// to be out of sync.
if (mCsp) {
loadState->SetCsp(mCsp);
} else if (!mTriggeringPrincipal) {
// Currently the NodePrincipal holds the CSP for a document. After
// Bug 965637 we can query the CSP from mOwnerContent->OwnerDoc()
// instead of mOwnerContent->NodePrincipal().
nsCOMPtr<nsIContentSecurityPolicy> csp;
mOwnerContent->NodePrincipal()->GetCsp(getter_AddRefs(csp));
nsCOMPtr<nsIContentSecurityPolicy> csp = mOwnerContent->GetCsp();
loadState->SetCsp(csp);
}
@ -2343,16 +2333,12 @@ void nsFrameLoader::GetURL(nsString& aURI, nsIPrincipal** aTriggeringPrincipal,
nsIContentSecurityPolicy** aCsp) {
aURI.Truncate();
// Within this function we default to using the NodePrincipal as the
// triggeringPrincipal and the CSP of the document, currently stored
// on the NodePrincipal. After Bug 965637 we can query the CSP from
// mOwnerContent->OwnerDoc() instead of mOwnerContent->NodePrincipal().
// triggeringPrincipal and the CSP of the document.
// Expanded Principals however override the CSP of the document, hence
// if frame->GetSrcTriggeringPrincipal() returns a valid principal, we
// have to query the CSP from that Principal. Note that even after
// Bug 965637, Expanded Principals will hold their own CSP.
// have to query the CSP from that Principal.
nsCOMPtr<nsIPrincipal> triggeringPrincipal = mOwnerContent->NodePrincipal();
nsCOMPtr<nsIContentSecurityPolicy> csp;
mOwnerContent->NodePrincipal()->GetCsp(getter_AddRefs(csp));
nsCOMPtr<nsIContentSecurityPolicy> csp = mOwnerContent->GetCsp();
if (mOwnerContent->IsHTMLElement(nsGkAtoms::object)) {
mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::data, aURI);
@ -2363,7 +2349,11 @@ void nsFrameLoader::GetURL(nsString& aURI, nsIPrincipal** aTriggeringPrincipal,
nsCOMPtr<nsIPrincipal> srcPrincipal = frame->GetSrcTriggeringPrincipal();
if (srcPrincipal) {
triggeringPrincipal = srcPrincipal;
triggeringPrincipal->GetCsp(getter_AddRefs(csp));
nsCOMPtr<nsIExpandedPrincipal> ep =
do_QueryInterface(triggeringPrincipal);
if (ep) {
csp = ep->GetCsp();
}
}
}
}

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

@ -50,6 +50,7 @@
#include "nsDOMWindowList.h"
#include "mozilla/dom/WakeLock.h"
#include "mozilla/dom/power/PowerManagerService.h"
#include "nsIContentSecurityPolicy.h"
#include "nsIDocShellTreeOwner.h"
#include "nsIDocumentLoader.h"
#include "nsIInterfaceRequestorUtils.h"
@ -1122,11 +1123,12 @@ void nsGlobalWindowInner::FreeInnerObjects() {
#endif
if (mDoc) {
// Remember the document's principal and URI.
// Remember the document's principal, URI, and CSP.
mDocumentPrincipal = mDoc->NodePrincipal();
mDocumentStoragePrincipal = mDoc->EffectiveStoragePrincipal();
mDocumentURI = mDoc->GetDocumentURI();
mDocBaseURI = mDoc->GetDocBaseURI();
mDocumentCsp = mDoc->GetCsp();
while (mDoc->EventHandlingSuppressed()) {
mDoc->UnsuppressEventHandlingAndFireEvents(false);
@ -1350,6 +1352,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGlobalWindowInner)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIndexedDB)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentPrincipal)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentStoragePrincipal)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentCsp)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBrowserChild)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDoc)
@ -1454,6 +1457,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGlobalWindowInner)
}
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentPrincipal)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentStoragePrincipal)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentCsp)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mBrowserChild)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDoc)
@ -1789,6 +1793,14 @@ nsresult nsGlobalWindowInner::EnsureClientSource() {
}
}
// Generally the CSP is stored within the Client and cached on the document.
// At the time of CSP parsing however, the Client has not been created yet,
// hence we store the CSP on the document and propagate/sync the CSP with
// Client here when we create the Client.
if (mClientSource) {
mClientSource->SetCsp(mDoc->GetCsp());
}
// Its possible that we got a client just after being frozen in
// the bfcache. In that case freeze the client immediately.
if (newClientSource && IsFrozen()) {
@ -2197,6 +2209,18 @@ Maybe<ServiceWorkerDescriptor> nsPIDOMWindowInner::GetController() const {
return nsGlobalWindowInner::Cast(this)->GetController();
}
void nsPIDOMWindowInner::SetCsp(nsIContentSecurityPolicy* aCsp) {
return nsGlobalWindowInner::Cast(this)->SetCsp(aCsp);
}
void nsPIDOMWindowInner::SetPreloadCsp(nsIContentSecurityPolicy* aPreloadCsp) {
return nsGlobalWindowInner::Cast(this)->SetPreloadCsp(aPreloadCsp);
}
nsIContentSecurityPolicy* nsPIDOMWindowInner::GetCsp() {
return nsGlobalWindowInner::Cast(this)->GetCsp();
}
void nsPIDOMWindowInner::NoteCalledRegisterForServiceWorkerScope(
const nsACString& aScope) {
nsGlobalWindowInner::Cast(this)->NoteCalledRegisterForServiceWorkerScope(
@ -5363,6 +5387,37 @@ Maybe<ServiceWorkerDescriptor> nsGlobalWindowInner::GetController() const {
return controller;
}
void nsGlobalWindowInner::SetCsp(nsIContentSecurityPolicy* aCsp) {
if (!mClientSource) {
return;
}
mClientSource->SetCsp(aCsp);
// Also cache the CSP within the document
mDoc->SetCsp(aCsp);
}
void nsGlobalWindowInner::SetPreloadCsp(nsIContentSecurityPolicy* aPreloadCsp) {
if (!mClientSource) {
return;
}
mClientSource->SetPreloadCsp(aPreloadCsp);
// Also cache the preload CSP within the document
mDoc->SetPreloadCsp(aPreloadCsp);
}
nsIContentSecurityPolicy* nsGlobalWindowInner::GetCsp() {
if (mDoc) {
return mDoc->GetCsp();
}
// If the window is partially torn down and has its document nulled out,
// we query the CSP we snapshot in FreeInnerObjects.
if (mDocumentCsp) {
return mDocumentCsp;
}
return nullptr;
}
RefPtr<ServiceWorker> nsGlobalWindowInner::GetOrCreateServiceWorker(
const ServiceWorkerDescriptor& aDescriptor) {
MOZ_ASSERT(NS_IsMainThread());

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

@ -322,6 +322,10 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
mozilla::Maybe<mozilla::dom::ServiceWorkerDescriptor> GetController()
const override;
void SetCsp(nsIContentSecurityPolicy* aCsp);
void SetPreloadCsp(nsIContentSecurityPolicy* aPreloadCsp);
nsIContentSecurityPolicy* GetCsp();
virtual RefPtr<mozilla::dom::ServiceWorker> GetOrCreateServiceWorker(
const mozilla::dom::ServiceWorkerDescriptor& aDescriptor) override;
@ -1301,8 +1305,11 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
RefPtr<mozilla::dom::VisualViewport> mVisualViewport;
// The document's principals and CSP are only stored if
// FreeInnerObjects has been called.
nsCOMPtr<nsIPrincipal> mDocumentPrincipal;
nsCOMPtr<nsIPrincipal> mDocumentStoragePrincipal;
nsCOMPtr<nsIContentSecurityPolicy> mDocumentCsp;
// mBrowserChild is only ever populated in the content process.
nsCOMPtr<nsIBrowserChild> mBrowserChild;

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

@ -1548,7 +1548,8 @@ bool nsGlobalWindowOuter::WouldReuseInnerWindow(Document* aNewDocument) {
return false;
}
void nsGlobalWindowOuter::SetInitialPrincipalToSubject() {
void nsGlobalWindowOuter::SetInitialPrincipalToSubject(
nsIContentSecurityPolicy* aCSP) {
// First, grab the subject principal.
nsCOMPtr<nsIPrincipal> newWindowPrincipal =
nsContentUtils::SubjectPrincipalOrSystemIfNativeCaller();
@ -1581,7 +1582,7 @@ void nsGlobalWindowOuter::SetInitialPrincipalToSubject() {
#endif
}
GetDocShell()->CreateAboutBlankContentViewer(newWindowPrincipal);
GetDocShell()->CreateAboutBlankContentViewer(newWindowPrincipal, aCSP);
if (mDoc) {
mDoc->SetIsInitialDocument(true);

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

@ -298,7 +298,8 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
mozilla::dom::EventTarget* aChromeEventHandler) override;
// Outer windows only.
virtual void SetInitialPrincipalToSubject() override;
virtual void SetInitialPrincipalToSubject(
nsIContentSecurityPolicy* aCSP) override;
virtual already_AddRefed<nsISupports> SaveWindowState() override;
virtual nsresult RestoreWindowState(nsISupports* aState) override;

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

@ -195,6 +195,10 @@ void* nsINode::UnsetProperty(const nsAtom* aPropertyName, nsresult* aStatus) {
aStatus);
}
nsIContentSecurityPolicy* nsINode::GetCsp() const {
return OwnerDoc()->GetCsp();
}
nsINode::nsSlots* nsINode::CreateSlots() { return new nsSlots(); }
nsIContent* nsINode::GetTextEditorRootContent(TextEditor** aTextEditor) {

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

@ -40,6 +40,7 @@ class nsAttrChildContentList;
class nsDOMAttributeMap;
class nsIAnimationObserver;
class nsIContent;
class nsIContentSecurityPolicy;
class nsIFrame;
class nsIHTMLCollection;
class nsIMutationObserver;
@ -854,6 +855,11 @@ class nsINode : public mozilla::dom::EventTarget {
return mNodeInfo->NodeInfoManager()->DocumentPrincipal();
}
/**
* Return the CSP of this node's document, if any.
*/
nsIContentSecurityPolicy* GetCsp() const;
/**
* Get the parent nsIContent for this node.
* @return the parent, or null if no parent or the parent is not an nsIContent

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

@ -18,7 +18,6 @@
#include "nsContentUtils.h"
#include "nsError.h"
#include "nsGlobalWindow.h"
#include "nsIContentSecurityPolicy.h"
#include "mozilla/dom/Document.h"
#include "nsIScriptTimeoutHandler.h"
#include "nsIXPConnect.h"

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

@ -228,10 +228,6 @@ class nsObjectLoadingContent : public nsImageLoadingContent,
mozilla::ErrorResult& aRv) {
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
}
void LegacyCall(JSContext* aCx, JS::Handle<JS::Value> aThisVal,
const mozilla::dom::Sequence<JS::Value>& aArguments,
JS::MutableHandle<JS::Value> aRetval,
mozilla::ErrorResult& aRv);
uint32_t GetRunID(mozilla::dom::SystemCallerGuarantee,
mozilla::ErrorResult& aRv);

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

@ -31,6 +31,7 @@ class nsGlobalWindowOuter;
class nsIArray;
class nsIChannel;
class nsIContent;
class nsIContentSecurityPolicy;
class nsICSSDeclaration;
class nsIDocShell;
class nsDocShellLoadState;
@ -326,6 +327,10 @@ class nsPIDOMWindowInner : public mozIDOMWindow {
mozilla::Maybe<mozilla::dom::ClientState> GetClientState() const;
mozilla::Maybe<mozilla::dom::ServiceWorkerDescriptor> GetController() const;
void SetCsp(nsIContentSecurityPolicy* aCsp);
void SetPreloadCsp(nsIContentSecurityPolicy* aPreloadCsp);
nsIContentSecurityPolicy* GetCsp();
void NoteCalledRegisterForServiceWorkerScope(const nsACString& aScope);
void NoteDOMContentLoaded();
@ -821,8 +826,8 @@ class nsPIDOMWindowOuter : public mozIDOMWindowProxy {
}
// Set the window up with an about:blank document with the current subject
// principal.
virtual void SetInitialPrincipalToSubject() = 0;
// principal and potentially a CSP.
virtual void SetInitialPrincipalToSubject(nsIContentSecurityPolicy* aCSP) = 0;
// Returns an object containing the window's state. This also suspends
// all running timeouts in the window.

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

@ -330,9 +330,8 @@ nsStyleLinkElement::DoUpdateStyleSheet(Document* aOldDocument,
MOZ_ASSERT(thisContent->IsElement());
nsresult rv = NS_OK;
if (!nsStyleUtil::CSPAllowsInlineStyle(
thisContent->AsElement(), thisContent->NodePrincipal(),
info->mTriggeringPrincipal, doc->GetDocumentURI(), mLineNumber,
mColumnNumber, text, &rv)) {
thisContent->AsElement(), doc, info->mTriggeringPrincipal,
mLineNumber, mColumnNumber, text, &rv)) {
if (NS_FAILED(rv)) {
return Err(rv);
}

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

@ -185,9 +185,9 @@ void nsStyledElement::ParseStyleAttribute(const nsAString& aValue,
Document* doc = OwnerDoc();
bool isNativeAnon = IsInNativeAnonymousSubtree();
if (!isNativeAnon && !nsStyleUtil::CSPAllowsInlineStyle(
this, NodePrincipal(), aMaybeScriptedPrincipal,
doc->GetDocumentURI(), 0, 0, aValue, nullptr))
if (!isNativeAnon &&
!nsStyleUtil::CSPAllowsInlineStyle(this, doc, aMaybeScriptedPrincipal, 0,
0, aValue, nullptr))
return;
if (aForceInDataDoc || !doc->IsLoadedAsData() || GetExistingStyle() ||

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