merge mozilla-inbound to mozilla-central a=merge

This commit is contained in:
Carsten "Tomcat" Book 2016-09-28 15:56:33 +02:00
Родитель c084656336 398815ad9b
Коммит 572e74ee99
374 изменённых файлов: 5330 добавлений и 4417 удалений

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

@ -1456,7 +1456,7 @@ pref("dom.ipc.cpows.forbid-unsafe-from-browser", true);
pref("dom.ipc.cpows.forbid-cpows-in-compat-addons", true);
// ...except for these add-ons:
pref("dom.ipc.cpows.allow-cpows-in-compat-addons", "{b9db16a4-6edc-47ec-a1f4-b86292ed211d},privateTab@infocatcher,mousegesturessuite@lemon_juice.addons.mozilla.org,firegestures@xuldev.org,treestyletab@piro.sakura.ne.jp,{DDC359D1-844A-42a7-9AA1-88A850A938A8},ich@maltegoetz.de,{AE93811A-5C9A-4d34-8462-F7B864FC4696}");
pref("dom.ipc.cpows.allow-cpows-in-compat-addons", "{b9db16a4-6edc-47ec-a1f4-b86292ed211d},firegestures@xuldev.org,{DDC359D1-844A-42a7-9AA1-88A850A938A8},privateTab@infocatcher,mousegesturessuite@lemon_juice.addons.mozilla.org,treestyletab@piro.sakura.ne.jp,cliqz@cliqz.com,{AE93811A-5C9A-4d34-8462-F7B864FC4696},contextsearch2@lwz.addons.mozilla.org,{EF522540-89F5-46b9-B6FE-1829E2B572C6},{677a8f98-fd64-40b0-a883-b8c95d0cbf17},images@wink.su,fx-devtools,toolkit/require,url_advisor@kaspersky.com,{d10d0bf8-f5b5-c8b4-a8b2-2b9879e08c5d},{dc572301-7619-498c-a57d-39143191b318},dta@downthemall.net,{86095750-AD15-46d8-BF32-C0789F7E6A32},screenwise-prod@google.com,{91aa5abe-9de4-4347-b7b5-322c38dd9271},secureLogin@blueimp.net,ich@maltegoetz.de,come.back.block.image.from@cat-in-136.blogspot.com,{7b1bf0b6-a1b9-42b0-b75d-252036438bdc},s3crypto@data,{1e0fd655-5aea-4b4c-a583-f76ef1e3af9c},akahuku.fx.sp@toshiakisp.github.io,{aff87fa2-a58e-4edd-b852-0a20203c1e17},{1018e4d6-728f-4b20-ad56-37578a4de76b},rehostimage@engy.us,lazarus@interclue.com,{b2e69492-2358-071a-7056-24ad0c3defb1},flashstopper@byo.co.il,{e4a8a97b-f2ed-450b-b12d-ee082ba24781},jid1-f3mYMbCpz2AZYl@jetpack,{8c550e28-88c9-4764-bb52-aa489cf2efcd},{37fa1426-b82d-11db-8314-0800200c9a66},{ac2cfa60-bc96-11e0-962b-0800200c9a66},igetter@presenta.net,killspinners@byo.co.il,abhere2@moztw.org,{fc6339b8-9581-4fc7-b824-dffcb091fcb7},wampi@wink.su,backtrack@byalexv.co.uk,Gladiator_X@mail.ru,{73a6fe31-595d-460b-a920-fcc0f8843232},{46551EC9-40F0-4e47-8E18-8E5CF550CFB8},acewebextension_unlisted@acestream.org,@screen_maker,yasearch@yandex.ru,sp@avast.com,s3google@translator,igetterextension@presenta.net,{C1A2A613-35F1-4FCF-B27F-2840527B6556},screenwise-testing@google.com,helper-sig@savefrom.net,browser-loader,ImageSaver@Merci.chao,proxtube@abz.agency,wrc@avast.com,{9AA46F4F-4DC7-4c06-97AF-5035170634FE},jid1-CikLKKPVkw6ipw@jetpack,artur.dubovoy@gmail.com,nlgfeb@nlgfeb.ext,{A065A84F-95B6-433A-A0C8-4C040B77CE8A},fdm_ffext@freedownloadmanager.org");
// Enable e10s hang monitoring (slow script checking and plugin hang
// detection).

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

@ -1128,6 +1128,7 @@ var gBrowserInit = {
// [4]: allowThirdPartyFixup (bool)
// [5]: referrerPolicy (int)
// [6]: userContextId (int)
// [7]: originPrincipal (nsIPrincipal)
else if (window.arguments.length >= 3) {
let referrerURI = window.arguments[2];
if (typeof(referrerURI) == "string") {
@ -1142,7 +1143,10 @@ var gBrowserInit = {
let userContextId = (window.arguments[6] != undefined ?
window.arguments[6] : Ci.nsIScriptSecurityManager.DEFAULT_USER_CONTEXT_ID);
loadURI(uriToLoad, referrerURI, window.arguments[3] || null,
window.arguments[4] || false, referrerPolicy, userContextId);
window.arguments[4] || false, referrerPolicy, userContextId,
// pass the origin principal (if any) and force its use to create
// an initial about:blank viewer if present:
window.arguments[7], !!window.arguments[7]);
window.focus();
}
// Note: loadOneOrMoreURIs *must not* be called if window.arguments.length >= 3.
@ -2033,14 +2037,17 @@ function BrowserTryToCloseWindow()
}
function loadURI(uri, referrer, postData, allowThirdPartyFixup, referrerPolicy,
userContextId) {
userContextId, originPrincipal, forceAboutBlankViewerInCurrent) {
try {
openLinkIn(uri, "current",
{ referrerURI: referrer,
referrerPolicy: referrerPolicy,
postData: postData,
allowThirdPartyFixup: allowThirdPartyFixup,
userContextId: userContextId });
userContextId: userContextId,
originPrincipal,
forceAboutBlankViewerInCurrent,
});
} catch (e) {}
}
@ -5584,11 +5591,14 @@ function handleLinkClick(event, href, linkNode) {
}
urlSecurityCheck(href, doc.nodePrincipal);
let params = { charset: doc.characterSet,
allowMixedContent: persistAllowMixedContentInChildTab,
referrerURI: referrerURI,
referrerPolicy: referrerPolicy,
noReferrer: BrowserUtils.linkHasNoReferrer(linkNode) };
let params = {
charset: doc.characterSet,
allowMixedContent: persistAllowMixedContentInChildTab,
referrerURI: referrerURI,
referrerPolicy: referrerPolicy,
noReferrer: BrowserUtils.linkHasNoReferrer(linkNode),
originPrincipal: doc.nodePrincipal,
};
// The new tab/window must use the same userContextId
if (doc.nodePrincipal.originAttributes.userContextId) {

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

@ -507,6 +507,7 @@ var ClickEventHandler = {
json.allowMixedContent = true;
} catch (e) {}
}
json.originPrincipal = ownerDoc.nodePrincipal;
sendAsyncMessage("Content:Click", json);
return;

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

@ -965,6 +965,7 @@ nsContextMenu.prototype = {
_openLinkInParameters : function (extra) {
let params = { charset: gContextMenuContentData.charSet,
originPrincipal: this.principal,
referrerURI: gContextMenuContentData.documentURIObject,
referrerPolicy: gContextMenuContentData.referrerPolicy,
noReferrer: this.linkHasNoReferrer };

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

@ -1500,6 +1500,7 @@
var aNoReferrer;
var aUserContextId;
var aRelatedBrowser;
var aOriginPrincipal;
if (arguments.length == 2 &&
typeof arguments[1] == "object" &&
!(arguments[1] instanceof Ci.nsIURI)) {
@ -1518,6 +1519,7 @@
aNoReferrer = params.noReferrer;
aUserContextId = params.userContextId;
aRelatedBrowser = params.relatedBrowser;
aOriginPrincipal = params.originPrincipal;
}
var bgLoad = (aLoadInBackground != null) ? aLoadInBackground :
@ -1537,6 +1539,7 @@
forceNotRemote: aForceNotRemote,
noReferrer: aNoReferrer,
userContextId: aUserContextId,
originPrincipal: aOriginPrincipal,
relatedBrowser: aRelatedBrowser });
if (!bgLoad)
this.selectedTab = tab;
@ -2043,6 +2046,7 @@
var aUserContextId;
var aEventDetail;
var aRelatedBrowser;
var aOriginPrincipal;
if (arguments.length == 2 &&
typeof arguments[1] == "object" &&
!(arguments[1] instanceof Ci.nsIURI)) {
@ -2062,6 +2066,7 @@
aUserContextId = params.userContextId;
aEventDetail = params.eventDetail;
aRelatedBrowser = params.relatedBrowser;
aOriginPrincipal = params.originPrincipal;
}
// if we're adding tabs, we're past interrupt mode, ditch the owner
@ -2141,6 +2146,10 @@
var evt = new CustomEvent("TabOpen", { bubbles: true, detail });
t.dispatchEvent(evt);
if (!usingPreloadedContent && aOriginPrincipal) {
b.createAboutBlankContentViewer(aOriginPrincipal);
}
// If we didn't swap docShells with a preloaded browser
// then let's just continue loading the page normally.
if (!usingPreloadedContent && !uriIsAboutBlank) {
@ -3669,7 +3678,11 @@
assert: function(cond) {
if (!cond) {
dump("Assertion failure\n" + Error().stack);
throw new Error("Assertion failure");
// Don't break a user's browser if an assertion fails.
if (this.tabbrowser.AppConstants.DEBUG) {
throw new Error("Assertion failure");
}
}
},

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

@ -118,6 +118,7 @@ support-files =
file_bug1045809_2.html
file_csp_block_all_mixedcontent.html
file_csp_block_all_mixedcontent.js
!/image/test/mochitest/blue.png
!/toolkit/components/passwordmgr/test/browser/form_basic.html
!/toolkit/components/passwordmgr/test/browser/insecure_test.html
!/toolkit/components/passwordmgr/test/browser/insecure_test_subframe.html
@ -342,6 +343,7 @@ subsuite = clipboard
[browser_mixed_content_cert_override.js]
[browser_mixedcontent_securityflags.js]
tags = mcb
[browser_modifiedclick_inherit_principal.js]
[browser_offlineQuotaNotification.js]
skip-if = buildapp == 'mulet'
[browser_feed_discovery.js]

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

@ -0,0 +1,30 @@
"use strict";
const kURL =
"http://example.com/browser/browser/base/content/test/general/dummy_page.html";
"data:text/html,<a href=''>Middle-click me</a>";
/*
* Check that when manually opening content JS links in new tabs/windows,
* we use the correct principal, and we don't clear the URL bar.
*/
add_task(function* () {
yield BrowserTestUtils.withNewTab(kURL, function* (browser) {
let newTabPromise = BrowserTestUtils.waitForNewTab(gBrowser);
yield ContentTask.spawn(browser, null, function* () {
let a = content.document.createElement("a");
a.href = "javascript:document.write('spoof'); void(0);";
a.textContent = "Some link";
content.document.body.appendChild(a);
});
info("Added element");
yield BrowserTestUtils.synthesizeMouseAtCenter("a", {button: 1}, browser);
let newTab = yield newTabPromise;
is(newTab.linkedBrowser.contentPrincipal.origin, "http://example.com",
"Principal should be for example.com");
yield BrowserTestUtils.switchTab(gBrowser, newTab);
info(gURLBar.value);
isnot(gURLBar.value, "", "URL bar should not be empty.");
yield BrowserTestUtils.removeTab(newTab);
});
});

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

@ -222,6 +222,9 @@ function openLinkIn(url, where, params) {
var aAllowPopups = !!params.allowPopups;
var aUserContextId = params.userContextId;
var aIndicateErrorPageLoad = params.indicateErrorPageLoad;
var aPrincipal = params.originPrincipal;
var aForceAboutBlankViewerInCurrent =
params.forceAboutBlankViewerInCurrent;
if (where == "save") {
// TODO(1073187): propagate referrerPolicy.
@ -290,6 +293,7 @@ function openLinkIn(url, where, params) {
sa.AppendElement(allowThirdPartyFixupSupports);
sa.AppendElement(referrerPolicySupports);
sa.AppendElement(userContextIdSupports);
sa.AppendElement(aPrincipal);
let features = "chrome,dialog=no,all";
if (aIsPrivate) {
@ -357,6 +361,10 @@ function openLinkIn(url, where, params) {
flags |= Ci.nsIWebNavigation.LOAD_FLAGS_ERROR_LOAD_CHANGES_RV;
}
if (aForceAboutBlankViewerInCurrent) {
w.gBrowser.selectedBrowser.createAboutBlankContentViewer(aPrincipal);
}
w.gBrowser.loadURIWithFlags(url, {
flags: flags,
referrerURI: aNoReferrer ? null : aReferrerURI,
@ -380,7 +388,8 @@ function openLinkIn(url, where, params) {
skipAnimation: aSkipTabAnimation,
allowMixedContent: aAllowMixedContent,
noReferrer: aNoReferrer,
userContextId: aUserContextId
userContextId: aUserContextId,
originPrincipal: aPrincipal,
});
break;
}

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

@ -77,12 +77,15 @@ var ContentClick = {
// Todo(903022): code for where == save
let params = { charset: browser.characterSet,
referrerURI: browser.documentURI,
referrerPolicy: json.referrerPolicy,
noReferrer: json.noReferrer,
allowMixedContent: json.allowMixedContent,
isContentWindowPrivate: json.isContentWindowPrivate};
let params = {
charset: browser.characterSet,
referrerURI: browser.documentURI,
referrerPolicy: json.referrerPolicy,
noReferrer: json.noReferrer,
allowMixedContent: json.allowMixedContent,
isContentWindowPrivate: json.isContentWindowPrivate,
originPrincipal: json.originPrincipal,
};
// The new tab/window must use the same userContextId.
if (json.originAttributes.userContextId) {

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

@ -191,22 +191,11 @@ toolbar[brighttext] #downloads-indicator-counter {
box-shadow: none !important;
}
:root[devtoolstheme="dark"] #identity-icon:-moz-lwtheme {
--identity-icon-normal: url(chrome://browser/skin/identity-icon.svg#normal-white);
--identity-icon-hover: url(chrome://browser/skin/identity-icon.svg#hover-white);
--identity-icon-notice: url(chrome://browser/skin/identity-icon.svg#notice-white);
--identity-icon-notice-hover: url(chrome://browser/skin/identity-icon.svg#notice-hover-white);
}
:root[devtoolstheme="dark"] #tracking-protection-icon:-moz-lwtheme {
--tracking-protection-icon-enabled: url(chrome://browser/skin/tracking-protection-16.svg#enabled-white);
--tracking-protection-icon-disabled: url(chrome://browser/skin/tracking-protection-16.svg#disabled-white);
}
:root[devtoolstheme="dark"] #connection-icon:-moz-lwtheme {
--connection-icon-mixed-passive-loaded: url(chrome://browser/skin/connection-mixed-passive-loaded.svg#icon-white);
--connection-icon-mixed-active-loaded: url(chrome://browser/skin/connection-mixed-active-loaded.svg#icon-white);
}
%filter substitution
%define selectorPrefix :root[devtoolstheme="dark"]
%define selectorSuffix :-moz-lwtheme
%define iconVariant -white
%include identity-block/icons.inc.css
#urlbar {
border-inline-start: none !important;

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

@ -0,0 +1,62 @@
%if 0
/* 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/. */
%endif
@selectorPrefix@#identity-icon@selectorSuffix@ {
list-style-image: url(chrome://browser/skin/identity-icon.svg#normal@iconVariant@);
}
@selectorPrefix@#identity-box:hover > #identity-icon:not(.no-hover)@selectorSuffix@,
@selectorPrefix@#identity-box[open=true] > #identity-icon@selectorSuffix@ {
list-style-image: url(chrome://browser/skin/identity-icon.svg#hover@iconVariant@);
}
@selectorPrefix@#identity-box.grantedPermissions > #identity-icon@selectorSuffix@ {
list-style-image: url(chrome://browser/skin/identity-icon.svg#notice@iconVariant@);
}
@selectorPrefix@#identity-box.grantedPermissions:hover > #identity-icon:not(.no-hover)@selectorSuffix@,
@selectorPrefix@#identity-box.grantedPermissions[open=true] > #identity-icon@selectorSuffix@ {
list-style-image: url(chrome://browser/skin/identity-icon.svg#notice-hover@iconVariant@);
}
@selectorPrefix@#urlbar[pageproxystate="valid"] > #identity-box.chromeUI > #identity-icon@selectorSuffix@ {
list-style-image: url(chrome://branding/content/identity-icons-brand.svg);
}
@selectorPrefix@#tracking-protection-icon@selectorSuffix@ {
list-style-image: url(chrome://browser/skin/tracking-protection-16.svg#enabled@iconVariant@);
}
@selectorPrefix@#tracking-protection-icon[state="loaded-tracking-content"]@selectorSuffix@ {
list-style-image: url(chrome://browser/skin/tracking-protection-16.svg#disabled@iconVariant@);
}
@selectorPrefix@#urlbar[pageproxystate="valid"] > #identity-box.verifiedDomain > #connection-icon@selectorSuffix@,
@selectorPrefix@#urlbar[pageproxystate="valid"] > #identity-box.verifiedIdentity > #connection-icon@selectorSuffix@,
@selectorPrefix@#urlbar[pageproxystate="valid"] > #identity-box.mixedActiveBlocked > #connection-icon@selectorSuffix@ {
list-style-image: url(chrome://browser/skin/connection-secure.svg);
visibility: visible;
}
@selectorPrefix@#urlbar[pageproxystate="valid"] > #identity-box.certUserOverridden > #connection-icon@selectorSuffix@ {
list-style-image: url(chrome://browser/skin/connection-mixed-passive-loaded.svg#icon@iconVariant@);
visibility: visible;
}
@selectorPrefix@#urlbar[pageproxystate="valid"] > #identity-box.insecureLoginForms > #connection-icon@selectorSuffix@,
@selectorPrefix@#urlbar[pageproxystate="valid"] > #identity-box.mixedActiveContent > #connection-icon@selectorSuffix@ {
list-style-image: url(chrome://browser/skin/connection-mixed-active-loaded.svg#icon@iconVariant@);
visibility: visible;
}
@selectorPrefix@#urlbar[pageproxystate="valid"] > #identity-box.weakCipher > #connection-icon@selectorSuffix@,
@selectorPrefix@#urlbar[pageproxystate="valid"] > #identity-box.mixedDisplayContent > #connection-icon@selectorSuffix@,
@selectorPrefix@#urlbar[pageproxystate="valid"] > #identity-box.mixedDisplayContentLoadedActiveBlocked > #connection-icon@selectorSuffix@ {
list-style-image: url(chrome://browser/skin/connection-mixed-passive-loaded.svg#icon@iconVariant@);
visibility: visible;
}

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

@ -4,6 +4,18 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
%endif
%filter substitution
%define selectorPrefix
%define selectorSuffix
%define iconVariant
%include icons.inc.css
%define selectorPrefix
%define selectorSuffix :-moz-lwtheme
%define iconVariant -black
%include icons.inc.css
#identity-box {
font-size: .9em;
padding: 3px 5px;
@ -52,39 +64,8 @@
/* MAIN IDENTITY ICON */
#identity-icon {
--identity-icon-normal: url(chrome://browser/skin/identity-icon.svg#normal);
--identity-icon-hover: url(chrome://browser/skin/identity-icon.svg#hover);
--identity-icon-notice: url(chrome://browser/skin/identity-icon.svg#notice);
--identity-icon-notice-hover: url(chrome://browser/skin/identity-icon.svg#notice-hover);
width: 16px;
height: 16px;
list-style-image: var(--identity-icon-normal);
}
#identity-icon:-moz-lwtheme {
--identity-icon-normal: url(chrome://browser/skin/identity-icon.svg#normal-black);
--identity-icon-hover: url(chrome://browser/skin/identity-icon.svg#hover-black);
--identity-icon-notice: url(chrome://browser/skin/identity-icon.svg#notice-black);
--identity-icon-notice-hover: url(chrome://browser/skin/identity-icon.svg#notice-hover-black);
}
#identity-box:hover > #identity-icon:not(.no-hover),
#identity-box[open=true] > #identity-icon {
list-style-image: var(--identity-icon-hover);
}
#identity-box.grantedPermissions > #identity-icon {
list-style-image: var(--identity-icon-notice);
}
#identity-box.grantedPermissions:hover > #identity-icon:not(.no-hover),
#identity-box.grantedPermissions[open=true] > #identity-icon {
list-style-image: var(--identity-icon-notice-hover);
}
#urlbar[pageproxystate="valid"] > #identity-box.chromeUI > #identity-icon {
list-style-image: url(chrome://branding/content/identity-icons-brand.svg);
}
#urlbar[pageproxystate="invalid"] > #identity-box > #identity-icon {
@ -142,23 +123,10 @@
/* TRACKING PROTECTION ICON */
#tracking-protection-icon {
--tracking-protection-icon-enabled: url(chrome://browser/skin/tracking-protection-16.svg#enabled);
--tracking-protection-icon-disabled: url(chrome://browser/skin/tracking-protection-16.svg#disabled);
width: 16px;
height: 16px;
margin-inline-start: 2px;
margin-inline-end: 0;
list-style-image: var(--tracking-protection-icon-enabled);
}
#tracking-protection-icon:-moz-lwtheme {
--tracking-protection-icon-enabled: url(chrome://browser/skin/tracking-protection-16.svg#enabled-black);
--tracking-protection-icon-disabled: url(chrome://browser/skin/tracking-protection-16.svg#disabled-black);
}
#tracking-protection-icon[state="loaded-tracking-content"] {
list-style-image: var(--tracking-protection-icon-disabled);
}
#tracking-protection-icon[animate] {
@ -184,37 +152,5 @@
height: 16px;
margin-inline-start: 2px;
visibility: collapse;
--connection-icon-mixed-passive-loaded: url(chrome://browser/skin/connection-mixed-passive-loaded.svg#icon);
--connection-icon-mixed-active-loaded: url(chrome://browser/skin/connection-mixed-active-loaded.svg#icon);
}
#connection-icon:-moz-lwtheme {
--connection-icon-mixed-passive-loaded: url(chrome://browser/skin/connection-mixed-passive-loaded.svg#icon-black);
--connection-icon-mixed-active-loaded: url(chrome://browser/skin/connection-mixed-active-loaded.svg#icon-black);
}
#urlbar[pageproxystate="valid"] > #identity-box.verifiedDomain > #connection-icon,
#urlbar[pageproxystate="valid"] > #identity-box.verifiedIdentity > #connection-icon,
#urlbar[pageproxystate="valid"] > #identity-box.mixedActiveBlocked > #connection-icon {
list-style-image: url(chrome://browser/skin/connection-secure.svg);
visibility: visible;
}
#urlbar[pageproxystate="valid"] > #identity-box.certUserOverridden > #connection-icon {
list-style-image: var(--connection-icon-mixed-passive-loaded);
visibility: visible;
}
#urlbar[pageproxystate="valid"] > #identity-box.insecureLoginForms > #connection-icon,
#urlbar[pageproxystate="valid"] > #identity-box.mixedActiveContent > #connection-icon {
list-style-image: var(--connection-icon-mixed-active-loaded);
visibility: visible;
}
#urlbar[pageproxystate="valid"] > #identity-box.weakCipher > #connection-icon,
#urlbar[pageproxystate="valid"] > #identity-box.mixedDisplayContent > #connection-icon,
#urlbar[pageproxystate="valid"] > #identity-box.mixedDisplayContentLoadedActiveBlocked > #connection-icon {
list-style-image: var(--connection-icon-mixed-passive-loaded);
visibility: visible;
}

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

@ -27,7 +27,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=995943
SimpleTest.waitForExplicitFinish();
SimpleTest.requestCompleteLog();
if (navigator.userAgent.indexOf("Mac OS X 10.10") != -1)
SimpleTest.expectAssertions(6, 9); // See bug 1067022
SimpleTest.expectAssertions(5, 9); // See bug 1067022
else if (Services.appinfo.OS == "WINNT")
SimpleTest.expectAssertions(0, 1); // See bug 1067022

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

@ -0,0 +1,63 @@
# vim: set ts=8 sts=4 et sw=4 tw=99:
# 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/.
#----------------------------------------------------------------------------
# This script checks encoding of the files that define JSErrorFormatStrings.
#
# JSErrorFormatString.format member should be in ASCII encoding.
#----------------------------------------------------------------------------
from __future__ import print_function
import os
import sys
from check_utils import get_all_toplevel_filenames
scriptname = os.path.basename(__file__);
expected_encoding = 'ascii'
# The following files don't define JSErrorFormatString.
ignore_files = [
'dom/base/domerr.msg',
'js/xpconnect/src/xpc.msg',
]
def log_pass(filename, text):
print('TEST-PASS | {} | {} | {}'.format(scriptname, filename, text))
def log_fail(filename, text):
print('TEST-UNEXPECTED-FAIL | {} | {} | {}'.format(scriptname, filename,
text))
def check_single_file(filename):
with open(filename, 'rb') as f:
data = f.read()
try:
data.decode(expected_encoding)
except:
log_fail(filename, 'not in {} encoding'.format(expected_encoding))
log_pass(filename, 'ok')
return True
def check_files():
result = True
for filename in get_all_toplevel_filenames():
if filename.endswith('.msg'):
if filename not in ignore_files:
if not check_single_file(filename):
result = False
return result
def main():
if not check_files():
sys.exit(1)
sys.exit(0)
if __name__ == '__main__':
main()

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

@ -934,9 +934,12 @@ cargo_build_flags += --verbose
# We need to run cargo unconditionally, because cargo is the only thing that
# has full visibility into how changes in Rust sources might affect the final
# build.
#
# XXX: We're passing `-C debuginfo=1` to rustc to work around an llvm-dsymutil
# crash (bug 1301751). This should be temporary until we upgrade to Rust 1.12.
force-cargo-build:
$(REPORT_BUILD)
env CARGO_TARGET_DIR=. RUSTC=$(RUSTC) $(CARGO) build $(cargo_build_flags) --
env CARGO_TARGET_DIR=. RUSTC=$(RUSTC) RUSTFLAGS='-C debuginfo=1' $(CARGO) build $(cargo_build_flags) --
$(RUST_LIBRARY_FILE): force-cargo-build
endif # CARGO_FILE

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

@ -60,7 +60,9 @@ function pushPrefEnv() {
let options = {
"set": [
["security.mixed_content.block_active_content", true],
["security.mixed_content.block_display_content", true]
["security.mixed_content.block_display_content", true],
["security.mixed_content.use_hsts", false],
["security.mixed_content.send_hsts_priming", false],
]
};
SpecialPowers.pushPrefEnv(options, deferred.resolve);

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

@ -94,6 +94,13 @@ function testXhrWarn() {
});
let lastRequest = yield waitForFinishedRequest(XHR_WARN_REQUEST_PREDICATE);
if (lastRequest.request.method == "HEAD") {
// in non-e10s, we get the HEAD request that priming sends, so make sure
// a priming request should be sent, and then get the actual request
is(Services.prefs.getBoolPref("security.mixed_content.send_hsts_priming"),
true, "Found HSTS Priming Request");
lastRequest = yield waitForFinishedRequest(XHR_WARN_REQUEST_PREDICATE);
}
ok(lastRequest, "testXhrWarn() was logged");
is(lastRequest.request.method, "GET", "Method is correct");

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

@ -380,7 +380,8 @@ exports.defineLazyGetter(this, "NetworkHelper", () => {
* - window: the window to get the loadGroup from
* - charset: the charset to use if the channel doesn't provide one
* - principal: the principal to use, if omitted, the request is loaded
* with the system principal
* with a codebase principal corresponding to the url being
* loaded, using the origin attributes of the window, if any.
* - cacheKey: when loading from cache, use this key to retrieve a cache
* specific to a given SHEntry. (Allows loading POST
* requests from cache)
@ -526,51 +527,44 @@ function mainThreadFetch(aURL, aOptions = { loadFromCache: true,
*/
function newChannelForURL(url, { policy, window, principal }) {
var securityFlags = Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL;
if (window) {
// Respect private browsing.
var req = window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocumentLoader)
.loadGroup;
if (req) {
var nc = req.notificationCallbacks;
if (nc) {
try {
var lc = nc.getInterface(Ci.nsILoadContext);
if (lc) {
if (lc.usePrivateBrowsing) {
securityFlags |= Ci.nsILoadInfo.SEC_FORCE_PRIVATE_BROWSING;
}
}
} catch (ex) {}
}
}
}
let channelOptions = {
contentPolicyType: policy,
securityFlags: securityFlags,
uri: url
};
if (principal) {
// contentPolicyType is required when loading with a custom principal
if (!channelOptions.contentPolicyType) {
channelOptions.contentPolicyType = Ci.nsIContentPolicy.TYPE_OTHER;
}
channelOptions.loadingPrincipal = principal;
} else {
channelOptions.loadUsingSystemPrincipal = true;
}
let uri;
try {
return NetUtil.newChannel(channelOptions);
uri = Services.io.newURI(url, null, null);
} catch (e) {
// In the xpcshell tests, the script url is the absolute path of the test
// file, which will make a malformed URI error be thrown. Add the file
// scheme to see if it helps.
channelOptions.uri = "file://" + url;
uri = Services.io.newURI("file://" + url, null, null);
}
let channelOptions = {
contentPolicyType: policy,
securityFlags: securityFlags,
uri: uri
};
let prin = principal;
if (!prin) {
let oa = {};
if (window) {
oa = window.document.nodePrincipal.originAttributes;
}
prin = Services.scriptSecurityManager
.createCodebasePrincipal(uri, oa);
}
// contentPolicyType is required when specifying a principal
if (!channelOptions.contentPolicyType) {
channelOptions.contentPolicyType = Ci.nsIContentPolicy.TYPE_OTHER;
}
channelOptions.loadingPrincipal = prin;
try {
return NetUtil.newChannel(channelOptions);
} catch (e) {
// In xpcshell tests on Windows, nsExternalProtocolHandler::NewChannel()
// can throw NS_ERROR_UNKNOWN_PROTOCOL if the external protocol isn't
// supported by Windows, so we also need to handle the exception here if
// parsing the URL above doesn't throw.
return newChannelForURL("file://" + url, { policy, window, principal });
}
}

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

@ -4986,10 +4986,10 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI* aURI,
do_GetService(NS_SSSERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HSTS, aURI,
flags, &isStsHost);
flags, nullptr, &isStsHost);
NS_ENSURE_SUCCESS(rv, rv);
rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HPKP, aURI,
flags, &isPinnedHost);
flags, nullptr, &isPinnedHost);
NS_ENSURE_SUCCESS(rv, rv);
} else {
mozilla::dom::ContentChild* cc =
@ -9862,6 +9862,25 @@ nsDocShell::InternalLoad(nsIURI* aURI,
return NS_ERROR_CONTENT_BLOCKED;
}
// If HSTS priming was set by nsMixedContentBlocker::ShouldLoad, and we
// would block due to mixed content, go ahead and block here. If we try to
// proceed with priming, we will error out later on.
nsCOMPtr<nsIDocShell> docShell = NS_CP_GetDocShellFromContext(context);
NS_ENSURE_TRUE(docShell, NS_OK);
if (docShell) {
nsIDocument* document = docShell->GetDocument();
NS_ENSURE_TRUE(document, NS_OK);
HSTSPrimingState state = document->GetHSTSPrimingStateForLocation(aURI);
if (state == HSTSPrimingState::eHSTS_PRIMING_BLOCK) {
// HSTS Priming currently disabled for InternalLoad, so we need to clear
// the location that was added by nsMixedContentBlocker::ShouldLoad
// Bug 1269815 will address images loaded via InternalLoad
document->ClearHSTSPrimingLocation(aURI);
return NS_ERROR_CONTENT_BLOCKED;
}
}
nsCOMPtr<nsIPrincipal> principalToInherit = aPrincipalToInherit;
//
// Get a principal from the current document if necessary. Note that we only
@ -10838,10 +10857,6 @@ nsDocShell::DoURILoad(nsIURI* aURI,
securityFlags |= nsILoadInfo::SEC_SANDBOXED;
}
if (UsePrivateBrowsing()) {
securityFlags |= nsILoadInfo::SEC_FORCE_PRIVATE_BROWSING;
}
nsCOMPtr<nsILoadInfo> loadInfo =
(aContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT) ?
new LoadInfo(loadingWindow, triggeringPrincipal,

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

@ -21,7 +21,8 @@
#include "nsIUUIDGenerator.h"
#include "nsPIDOMWindow.h" // for use in inline functions
#include "nsPropertyTable.h" // for member
#include "nsTHashtable.h" // for member
#include "nsDataHashtable.h" // for member
#include "nsURIHashKey.h" // for member
#include "mozilla/net/ReferrerPolicy.h" // for member
#include "nsWeakReference.h"
#include "mozilla/UseCounter.h"
@ -175,6 +176,13 @@ enum DocumentFlavor {
DocumentFlavorPlain, // Just a Document
};
// Enum for HSTS priming states
enum class HSTSPrimingState {
eNO_HSTS_PRIMING = 0, // don't do HSTS Priming
eHSTS_PRIMING_ALLOW = 1, // if HSTS priming fails, allow the load to proceed
eHSTS_PRIMING_BLOCK = 2 // if HSTS priming fails, block the load
};
// Document states
// RTL locale: specific to the XUL localedir attribute
@ -364,6 +372,34 @@ public:
mReferrer = aReferrer;
}
/**
* Check to see if a subresource we want to load requires HSTS priming
* to be done.
*/
HSTSPrimingState GetHSTSPrimingStateForLocation(nsIURI* aContentLocation) const
{
HSTSPrimingState state;
if (mHSTSPrimingURIList.Get(aContentLocation, &state)) {
return state;
}
return HSTSPrimingState::eNO_HSTS_PRIMING;
}
/**
* Add a subresource to the HSTS priming list. If this URI is
* not in the HSTS cache, it will trigger an HSTS priming request
* when we try to load it.
*/
void AddHSTSPrimingLocation(nsIURI* aContentLocation, HSTSPrimingState aState)
{
mHSTSPrimingURIList.Put(aContentLocation, aState);
}
void ClearHSTSPrimingLocation(nsIURI* aContentLocation)
{
mHSTSPrimingURIList.Remove(aContentLocation);
}
/**
* Set the principal responsible for this document.
*/
@ -2768,16 +2804,6 @@ public:
return mHasScrollLinkedEffect;
}
bool MayHavePluginFramesForPrinting()
{
return mMayHavePluginFramesForPrinting;
}
void SetMayHavePluginFramesForPrinting()
{
mMayHavePluginFramesForPrinting = true;
}
protected:
bool GetUseCounter(mozilla::UseCounter aUseCounter)
{
@ -2866,6 +2892,11 @@ protected:
bool mUpgradeInsecureRequests;
bool mUpgradeInsecurePreloads;
// if nsMixedContentBlocker requires sending an HSTS priming request,
// temporarily store that in the document so that it can be propogated to the
// LoadInfo and eventually the HTTP Channel
nsDataHashtable<nsURIHashKey, HSTSPrimingState> mHSTSPrimingURIList;
mozilla::WeakPtr<nsDocShell> mDocumentContainer;
nsCString mCharacterSet;
@ -3074,10 +3105,6 @@ protected:
// True is document has ever been in a foreground window.
bool mEverInForeground : 1;
// True if this document is a static clone for printing and may
// have elements referring to plugins in the original document.
bool mMayHavePluginFramesForPrinting : 1;
enum Type {
eUnknown, // should never be used
eHTML,

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

@ -1765,7 +1765,8 @@ nsINode::Before(const Sequence<OwningNodeOrString>& aNodes,
return;
}
nsINode* viablePreviousSibling = FindViablePreviousSibling(*this, aNodes);
nsCOMPtr<nsINode> viablePreviousSibling =
FindViablePreviousSibling(*this, aNodes);
nsCOMPtr<nsINode> node =
ConvertNodesOrStringsIntoNode(aNodes, OwnerDoc(), aRv);
@ -1788,7 +1789,7 @@ nsINode::After(const Sequence<OwningNodeOrString>& aNodes,
return;
}
nsINode* viableNextSibling = FindViableNextSibling(*this, aNodes);
nsCOMPtr<nsINode> viableNextSibling = FindViableNextSibling(*this, aNodes);
nsCOMPtr<nsINode> node =
ConvertNodesOrStringsIntoNode(aNodes, OwnerDoc(), aRv);
@ -1808,7 +1809,7 @@ nsINode::ReplaceWith(const Sequence<OwningNodeOrString>& aNodes,
return;
}
nsINode* viableNextSibling = FindViableNextSibling(*this, aNodes);
nsCOMPtr<nsINode> viableNextSibling = FindViableNextSibling(*this, aNodes);
nsCOMPtr<nsINode> node =
ConvertNodesOrStringsIntoNode(aNodes, OwnerDoc(), aRv);

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

@ -2907,13 +2907,9 @@ nsObjectLoadingContent::CreateStaticClone(nsObjectLoadingContent* aDest) const
aDest->mPrintFrame = const_cast<nsObjectLoadingContent*>(this)->GetExistingFrame();
}
nsCOMPtr<nsIContent> content =
do_QueryInterface(static_cast<nsIImageLoadingContent*>(aDest));
if (aDest->mPrintFrame) {
content->OwnerDoc()->SetMayHavePluginFramesForPrinting();
}
if (mFrameLoader) {
nsCOMPtr<nsIContent> content =
do_QueryInterface(static_cast<nsIImageLoadingContent*>(aDest));
nsFrameLoader* fl = nsFrameLoader::Create(content->AsElement(), false);
if (fl) {
aDest->mFrameLoader = fl;

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

@ -194,6 +194,12 @@ function createPolicyTest(policy, optionalEarlierPolicy) {
}
function handleRequest(request, response) {
if (request.method == 'HEAD') {
// respond to a HEAD request with a 418 so that we can easily distinguish
// HSTS priming responses and ignore them
response.setStatusLine('1.1', 418, "I'm a teapot");
return;
}
var sharedKey = 'bug704320.sjs';
var params = request.queryString.split('&');
var action = params[0].split('=')[1];

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

@ -25,6 +25,9 @@ function doXHR(url, onSuccess, onFail) {
xhr.onload = function () {
if (xhr.status == 200) {
onSuccess(xhr);
} else if (xhr.status == 418) {
// Ignore HSTS priming responses
return;
} else {
onFail(xhr);
}

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

@ -94,7 +94,7 @@ MSG_DEF(MSG_SW_INSTALL_ERROR, 2, JSEXN_TYPEERR, "ServiceWorker script at {0} for
MSG_DEF(MSG_SW_SCRIPT_THREW, 2, JSEXN_TYPEERR, "ServiceWorker script at {0} for scope {1} threw an exception during script evaluation.")
MSG_DEF(MSG_TYPEDARRAY_IS_SHARED, 1, JSEXN_TYPEERR, "{0} can't be a typed array on SharedArrayBuffer")
MSG_DEF(MSG_CACHE_ADD_FAILED_RESPONSE, 3, JSEXN_TYPEERR, "Cache got {0} response with bad status {1} while trying to add request {2}")
MSG_DEF(MSG_SW_UPDATE_BAD_REGISTRATION, 2, JSEXN_TYPEERR, "Failed to update the ServiceWorker for scope {0] because the registration has been {1} since the update was scheduled.")
MSG_DEF(MSG_SW_UPDATE_BAD_REGISTRATION, 2, JSEXN_TYPEERR, "Failed to update the ServiceWorker for scope {0} because the registration has been {1} since the update was scheduled.")
MSG_DEF(MSG_INVALID_DURATION_ERROR, 1, JSEXN_TYPEERR, "Invalid duration '{0}'.")
MSG_DEF(MSG_INVALID_EASING_ERROR, 1, JSEXN_TYPEERR, "Invalid easing '{0}'.")
MSG_DEF(MSG_INVALID_SPACING_MODE_ERROR, 1, JSEXN_TYPEERR, "Invalid spacing '{0}'.")

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

@ -5768,6 +5768,8 @@ CanvasRenderingContext2D::PutImageData_explicit(int32_t aX, int32_t aY, uint32_t
//uint8_t *src = aArray->Data();
uint8_t *dst = imgsurf->Data();
uint8_t* srcLine = aArray->Data() + copyY * (aW * 4) + copyX * 4;
// For opaque canvases, we must still premultiply the RGB components, but write the alpha as opaque.
uint8_t alphaMask = mOpaque ? 255 : 0;
#if 0
printf("PutImageData_explicit: dirty x=%d y=%d w=%d h=%d copy x=%d y=%d w=%d h=%d ext x=%d y=%d w=%d h=%d\n",
dirtyRect.x, dirtyRect.y, copyWidth, copyHeight,
@ -5787,9 +5789,9 @@ CanvasRenderingContext2D::PutImageData_explicit(int32_t aX, int32_t aY, uint32_t
*dst++ = gfxUtils::sPremultiplyTable[a * 256 + b];
*dst++ = gfxUtils::sPremultiplyTable[a * 256 + g];
*dst++ = gfxUtils::sPremultiplyTable[a * 256 + r];
*dst++ = a;
*dst++ = a | alphaMask;
#else
*dst++ = a;
*dst++ = a | alphaMask;
*dst++ = gfxUtils::sPremultiplyTable[a * 256 + r];
*dst++ = gfxUtils::sPremultiplyTable[a * 256 + g];
*dst++ = gfxUtils::sPremultiplyTable[a * 256 + b];

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

@ -569,7 +569,7 @@ BaseCaps(const WebGLContextOptions& options, WebGLContext* webgl)
if (!forwarder)
break;
baseCaps.surfaceAllocator = static_cast<layers::ISurfaceAllocator*>(forwarder);
baseCaps.surfaceAllocator = forwarder->GetTextureForwarder();
} while (false);
#endif

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

@ -0,0 +1,5 @@
<canvas id='cid'></canvas>
<script>
var x=document.getElementById('cid').getContext('2d',{alpha: false});
x.putImageData(x.createImageData(250,27434.63),Number.MAX_SAFE_INTEGER,23);
</script>

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

@ -37,4 +37,5 @@ load 1290628-1.html
load 1283113-1.html
load 1286458-1.html
load 1299062-1.html
load 1305312-1.html

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

@ -3442,7 +3442,7 @@ HTMLInputElement::Focus(ErrorResult& aError)
return;
}
#if defined(XP_WIN) || defined(XP_LINUX)
#if !defined(ANDROID) && !defined(XP_MACOSX)
bool
HTMLInputElement::IsNodeApzAwareInternal() const
{
@ -4538,7 +4538,7 @@ HTMLInputElement::PostHandleEvent(EventChainPostVisitor& aVisitor)
}
break;
}
#if defined(XP_WIN) || defined(XP_LINUX)
#if !defined(ANDROID) && !defined(XP_MACOSX)
case eWheel: {
// Handle wheel events as increasing / decreasing the input element's
// value when it's focused and it's type is number or range.
@ -6203,7 +6203,7 @@ FireEventForAccessibility(nsIDOMHTMLInputElement* aTarget,
void
HTMLInputElement::UpdateApzAwareFlag()
{
#if defined(XP_WIN) || defined(XP_LINUX)
#if !defined(ANDROID) && !defined(XP_MACOSX)
if ((mType == NS_FORM_INPUT_NUMBER) || (mType == NS_FORM_INPUT_RANGE)) {
SetMayBeApzAware();
}

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

@ -135,7 +135,7 @@ public:
virtual void Focus(ErrorResult& aError) override;
// nsINode
#if defined(XP_WIN) || defined(XP_LINUX)
#if !defined(ANDROID) && !defined(XP_MACOSX)
virtual bool IsNodeApzAwareInternal() const override;
#endif

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

@ -565,16 +565,6 @@ public:
? nsIContentPolicy::TYPE_INTERNAL_AUDIO :
nsIContentPolicy::TYPE_INTERNAL_VIDEO;
nsCOMPtr<nsIDocShell> docShell = aElement->OwnerDoc()->GetDocShell();
if (docShell) {
nsDocShell* docShellPtr = nsDocShell::Cast(docShell);
bool privateBrowsing;
docShellPtr->GetUsePrivateBrowsing(&privateBrowsing);
if (privateBrowsing) {
securityFlags |= nsILoadInfo::SEC_FORCE_PRIVATE_BROWSING;
}
}
nsCOMPtr<nsILoadGroup> loadGroup = aElement->GetDocumentLoadGroup();
nsCOMPtr<nsIChannel> channel;
nsresult rv = NS_NewChannel(getter_AddRefs(channel),

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

@ -622,11 +622,11 @@ skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android'
[test_bug1250401.html]
[test_bug1260664.html]
[test_bug1261673.html]
skip-if = (os != 'win' && os != 'linux')
skip-if = (os == 'android' || os == 'mac')
[test_bug1261674-1.html]
skip-if = (os != 'win' && os != 'linux')
skip-if = (os == 'android' || os == 'mac')
[test_bug1261674-2.html]
skip-if = (os != 'win' && os != 'linux')
skip-if = (os == 'android' || os == 'mac')
[test_bug1260704.html]
[test_allowMedia.html]
[test_bug1292522_same_domain_with_different_port_number.html]

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

@ -41,11 +41,14 @@ let tests = [
Services.prefs.setBoolPref("browser.send_pings", true);
Services.prefs.setIntPref("browser.send_pings.max_per_link", -1);
Services.prefs.setBoolPref("security.mixed_content.block_active_content", false);
// The server we create can't handle the priming HEAD requests
Services.prefs.setBoolPref("security.mixed_content.send_hsts_priming", false);
SimpleTest.registerCleanupFunction(() => {
Services.prefs.clearUserPref("browser.send_pings");
Services.prefs.clearUserPref("browser.send_pings.max_per_link");
Services.prefs.clearUserPref("security.mixed_content.block_active_content");
Services.prefs.clearUserPref("security.mixed_content.send_hsts_priming");
});
},

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

@ -5314,7 +5314,7 @@ private:
struct IdleThreadInfo;
struct ThreadInfo;
class ThreadRunnable;
struct TransactionInfo;
class TransactionInfo;
struct TransactionInfoPair;
// This mutex guards mDatabases, see below.
@ -5713,10 +5713,14 @@ private:
NS_DECL_NSIRUNNABLE
};
struct ConnectionPool::TransactionInfo final
class ConnectionPool::TransactionInfo final
{
friend class nsAutoPtr<TransactionInfo>;
nsTHashtable<nsPtrHashKey<TransactionInfo>> mBlocking;
nsTArray<TransactionInfo*> mBlockingOrdered;
public:
DatabaseInfo* mDatabaseInfo;
const nsID mBackgroundChildLoggingId;
const nsCString mDatabaseId;
@ -5724,7 +5728,6 @@ struct ConnectionPool::TransactionInfo final
const int64_t mLoggingSerialNumber;
const nsTArray<nsString> mObjectStoreNames;
nsTHashtable<nsPtrHashKey<TransactionInfo>> mBlockedOn;
nsTHashtable<nsPtrHashKey<TransactionInfo>> mBlocking;
nsTArray<nsCOMPtr<nsIRunnable>> mQueuedRunnables;
const bool mIsWriteTransaction;
bool mRunning;
@ -5743,10 +5746,16 @@ struct ConnectionPool::TransactionInfo final
TransactionDatabaseOperationBase* aTransactionOp);
void
Schedule();
AddBlockingTransaction(TransactionInfo* aTransactionInfo);
void
RemoveBlockingTransactions();
private:
~TransactionInfo();
void
MaybeUnblock(TransactionInfo* aTransactionInfo);
};
struct ConnectionPool::TransactionInfoPair final
@ -11745,7 +11754,7 @@ ConnectionPool::Start(const nsID& aBackgroundChildLoggingId,
// Mark what we are blocking on.
if (TransactionInfo* blockingRead = blockInfo->mLastBlockingReads) {
transactionInfo->mBlockedOn.PutEntry(blockingRead);
blockingRead->mBlocking.PutEntry(transactionInfo);
blockingRead->AddBlockingTransaction(transactionInfo);
}
if (aIsWriteTransaction) {
@ -11756,7 +11765,7 @@ ConnectionPool::Start(const nsID& aBackgroundChildLoggingId,
MOZ_ASSERT(blockingWrite);
transactionInfo->mBlockedOn.PutEntry(blockingWrite);
blockingWrite->mBlocking.PutEntry(transactionInfo);
blockingWrite->AddBlockingTransaction(transactionInfo);
}
}
@ -12288,18 +12297,7 @@ ConnectionPool::NoteFinishedTransaction(uint64_t aTransactionId)
blockInfo->mLastBlockingWrites.RemoveElement(transactionInfo);
}
for (auto iter = transactionInfo->mBlocking.Iter();
!iter.Done();
iter.Next()) {
TransactionInfo* blockedInfo = iter.Get()->GetKey();
MOZ_ASSERT(blockedInfo);
MOZ_ASSERT(blockedInfo->mBlockedOn.Contains(transactionInfo));
blockedInfo->mBlockedOn.RemoveEntry(transactionInfo);
if (!blockedInfo->mBlockedOn.Count()) {
blockedInfo->Schedule();
}
}
transactionInfo->RemoveBlockingTransactions();
if (transactionInfo->mIsWriteTransaction) {
MOZ_ASSERT(dbInfo->mWriteTransactionCount);
@ -13068,18 +13066,55 @@ TransactionInfo::~TransactionInfo()
void
ConnectionPool::
TransactionInfo::Schedule()
TransactionInfo::AddBlockingTransaction(TransactionInfo* aTransactionInfo)
{
AssertIsOnBackgroundThread();
MOZ_ASSERT(mDatabaseInfo);
MOZ_ASSERT(aTransactionInfo);
ConnectionPool* connectionPool = mDatabaseInfo->mConnectionPool;
MOZ_ASSERT(connectionPool);
connectionPool->AssertIsOnOwningThread();
if (!mBlocking.Contains(aTransactionInfo)) {
mBlocking.PutEntry(aTransactionInfo);
mBlockingOrdered.AppendElement(aTransactionInfo);
}
}
Unused <<
connectionPool->ScheduleTransaction(this,
/* aFromQueuedTransactions */ false);
void
ConnectionPool::
TransactionInfo::RemoveBlockingTransactions()
{
AssertIsOnBackgroundThread();
for (uint32_t index = 0, count = mBlockingOrdered.Length();
index < count;
index++) {
TransactionInfo* blockedInfo = mBlockingOrdered[index];
MOZ_ASSERT(blockedInfo);
blockedInfo->MaybeUnblock(this);
}
mBlocking.Clear();
mBlockingOrdered.Clear();
}
void
ConnectionPool::
TransactionInfo::MaybeUnblock(TransactionInfo* aTransactionInfo)
{
AssertIsOnBackgroundThread();
MOZ_ASSERT(mBlockedOn.Contains(aTransactionInfo));
mBlockedOn.RemoveEntry(aTransactionInfo);
if (!mBlockedOn.Count()) {
MOZ_ASSERT(mDatabaseInfo);
ConnectionPool* connectionPool = mDatabaseInfo->mConnectionPool;
MOZ_ASSERT(connectionPool);
connectionPool->AssertIsOnOwningThread();
Unused <<
connectionPool->ScheduleTransaction(this,
/* aFromQueuedTransactions */ false);
}
}
ConnectionPool::

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

@ -1554,7 +1554,8 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(IDBObjectStore)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTransaction)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIndexes);
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIndexes)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDeletedIndexes)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(IDBObjectStore)
@ -1562,7 +1563,8 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(IDBObjectStore)
// Don't unlink mTransaction!
NS_IMPL_CYCLE_COLLECTION_UNLINK(mIndexes);
NS_IMPL_CYCLE_COLLECTION_UNLINK(mIndexes)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDeletedIndexes)
tmp->mCachedKeyPath.setUndefined();
@ -1774,13 +1776,11 @@ IDBObjectStore::CreateIndex(const nsAString& aName,
}
IDBTransaction* transaction = IDBTransaction::GetCurrent();
if (!transaction || transaction != mTransaction) {
if (!transaction || transaction != mTransaction || !transaction->IsOpen()) {
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
return nullptr;
}
MOZ_ASSERT(transaction->IsOpen());
auto& indexes = const_cast<nsTArray<IndexMetadata>&>(mSpec->indexes());
for (uint32_t count = indexes.Length(), index = 0;
index < count;
@ -1888,13 +1888,11 @@ IDBObjectStore::DeleteIndex(const nsAString& aName, ErrorResult& aRv)
}
IDBTransaction* transaction = IDBTransaction::GetCurrent();
if (!transaction || transaction != mTransaction) {
if (!transaction || transaction != mTransaction || !transaction->IsOpen()) {
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
return;
}
MOZ_ASSERT(transaction->IsOpen());
auto& metadataArray = const_cast<nsTArray<IndexMetadata>&>(mSpec->indexes());
int64_t foundId = 0;
@ -1916,6 +1914,11 @@ IDBObjectStore::DeleteIndex(const nsAString& aName, ErrorResult& aRv)
if (index->Id() == foundId) {
index->NoteDeletion();
RefPtr<IDBIndex>* deletedIndex =
mDeletedIndexes.AppendElement();
deletedIndex->swap(mIndexes[indexIndex]);
mIndexes.RemoveElementAt(indexIndex);
break;
}
@ -2130,6 +2133,12 @@ IDBObjectStore::RefreshSpec(bool aMayDelete)
mIndexes[idxIndex]->RefreshMetadata(aMayDelete);
}
for (uint32_t idxCount = mDeletedIndexes.Length(), idxIndex = 0;
idxIndex < idxCount;
idxIndex++) {
mDeletedIndexes[idxIndex]->RefreshMetadata(false);
}
found = true;
break;
}
@ -2202,13 +2211,11 @@ IDBObjectStore::SetName(const nsAString& aName, ErrorResult& aRv)
}
IDBTransaction* transaction = IDBTransaction::GetCurrent();
if (!transaction || transaction != mTransaction) {
if (!transaction || transaction != mTransaction || !transaction->IsOpen()) {
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
return;
}
MOZ_ASSERT(transaction->IsOpen());
if (aName == mSpec->metadata().name()) {
return;
}

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

@ -67,6 +67,7 @@ class IDBObjectStore final
nsAutoPtr<ObjectStoreSpec> mDeletedSpec;
nsTArray<RefPtr<IDBIndex>> mIndexes;
nsTArray<RefPtr<IDBIndex>> mDeletedIndexes;
const int64_t mId;
bool mRooted;

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

@ -653,6 +653,12 @@ IDBTransaction::AbortInternal(nsresult aAbortCode,
mDatabase->RevertToPreviousState();
}
// We do the reversion only for the mObjectStores/mDeletedObjectStores but
// not for the mIndexes/mDeletedIndexes of each IDBObjectStore because it's
// time-consuming(O(m*n)) and mIndexes/mDeletedIndexes won't be used anymore
// in IDBObjectStore::(Create|Delete)Index() and IDBObjectStore::Index() in
// which all the executions are returned earlier by !transaction->IsOpen().
const nsTArray<ObjectStoreSpec>& specArray =
mDatabase->Spec()->objectStores();

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

@ -19,6 +19,8 @@ support-files =
service_worker_client.html
third_party_iframe1.html
third_party_iframe2.html
unit/test_abort_deleted_index.js
unit/test_abort_deleted_objectStore.js
unit/test_add_put.js
unit/test_add_twice_failure.js
unit/test_advance.js
@ -115,6 +117,10 @@ support-files =
webapp_clearBrowserData_appFrame.html
webapp_clearBrowserData_browserFrame.html
[test_abort_deleted_index.html]
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
[test_abort_deleted_objectStore.html]
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
[test_add_put.html]
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
[test_add_twice_failure.html]

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

@ -0,0 +1,19 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>Indexed Database Abort Deleted Index Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript;version=1.7" src="unit/test_abort_deleted_index.js"></script>
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>

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

@ -0,0 +1,19 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>Indexed Database Abort Deleted ObjectStore Test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript;version=1.7" src="unit/test_abort_deleted_objectStore.js"></script>
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>

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

@ -0,0 +1,78 @@
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
var testGenerator = testSteps();
function testSteps()
{
const name = this.window ? window.location.pathname : "Splendid Test";
const storeName = "test store";
const indexName_ToBeDeleted = "test index to be deleted";
info("Create index in v1.");
let request = indexedDB.open(name, 1);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = unexpectedSuccessHandler;
let event = yield undefined;
let db = event.target.result;
let txn = event.target.transaction;
is(db.objectStoreNames.length, 0, "Correct objectStoreNames list");
let objectStore = db.createObjectStore(storeName, { keyPath: "foo" });
is(db.objectStoreNames.length, 1, "Correct objectStoreNames list");
is(db.objectStoreNames.item(0), objectStore.name, "Correct object store name");
// create index to be deleted later in v2.
objectStore.createIndex(indexName_ToBeDeleted, "foo");
ok(objectStore.index(indexName_ToBeDeleted), "Index created.");
txn.oncomplete = continueToNextStepSync;
yield undefined;
request.onsuccess = continueToNextStep;
yield undefined;
db.close();
info("Delete index in v2.");
request = indexedDB.open(name, 2);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = unexpectedSuccessHandler;
event = yield undefined;
db = event.target.result;
txn = event.target.transaction;
objectStore = txn.objectStore(storeName);
let index = objectStore.index(indexName_ToBeDeleted);
ok(index, "index is valid.");
objectStore.deleteIndex(indexName_ToBeDeleted);
// Aborting the transaction.
request.onerror = expectedErrorHandler("AbortError");
txn.abort();
try {
index.get('foo');
ok(false, "TransactionInactiveError shall be thrown right after a deletion of an index is aborted.");
} catch (e) {
ok(e instanceof DOMException, "got a database exception");
is(e.name, "TransactionInactiveError", "TransactionInactiveError shall be thrown right after a deletion of an index is aborted.");
}
yield undefined;
try {
index.get('foo');
ok(false, "TransactionInactiveError shall be thrown after the transaction is inactive.");
} catch (e) {
ok(e instanceof DOMException, "got a database exception");
is(e.name, "TransactionInactiveError", "TransactionInactiveError shall be thrown after the transaction is inactive.");
}
finishTest();
yield undefined;
}

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

@ -0,0 +1,74 @@
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
var testGenerator = testSteps();
function testSteps()
{
const name = this.window ? window.location.pathname : "Splendid Test";
const storeName_ToBeDeleted = "test store to be deleted";
info("Create objectStore in v1.");
let request = indexedDB.open(name, 1);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = unexpectedSuccessHandler;
let event = yield undefined;
let db = event.target.result;
let txn = event.target.transaction;
is(db.objectStoreNames.length, 0, "Correct objectStoreNames list");
// create objectstore to be deleted later in v2.
db.createObjectStore(storeName_ToBeDeleted, { keyPath: "foo" });
is(db.objectStoreNames.length, 1, "Correct objectStoreNames list");
ok(db.objectStoreNames.contains(storeName_ToBeDeleted), "Correct name");
txn.oncomplete = continueToNextStepSync;
yield undefined;
request.onsuccess = continueToNextStep;
yield undefined;
db.close();
info("Delete objectStore in v2.");
request = indexedDB.open(name, 2);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = unexpectedSuccessHandler;
event = yield undefined;
db = event.target.result;
txn = event.target.transaction;
let objectStore = txn.objectStore(storeName_ToBeDeleted);
ok(objectStore, "objectStore is available");
db.deleteObjectStore(storeName_ToBeDeleted);
// Aborting the transaction.
request.onerror = expectedErrorHandler("AbortError");
txn.abort();
try {
objectStore.get('foo');
ok(false, "TransactionInactiveError shall be thrown if the transaction is inactive.");
} catch (e) {
ok(e instanceof DOMException, "got a database exception");
is(e.name, "TransactionInactiveError", "correct error");
}
yield undefined;
try {
objectStore.get('foo');
ok(false, "TransactionInactiveError shall be thrown if the transaction is inactive.");
} catch (e) {
ok(e instanceof DOMException, "got a database exception");
is(e.name, "TransactionInactiveError", "correct error");
}
finishTest();
yield undefined;
}

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

@ -2,6 +2,8 @@
# 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/.
[test_abort_deleted_index.js]
[test_abort_deleted_objectStore.js]
[test_add_put.js]
[test_add_twice_failure.js]
[test_advance.js]

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

@ -3574,10 +3574,7 @@ BlobChild::SetMysteryBlobInfo(const nsString& aContentType, uint64_t aLength)
MOZ_ASSERT(mBlobImpl);
MOZ_ASSERT(mRemoteBlobImpl);
nsString voidString;
voidString.SetIsVoid(true);
mBlobImpl->SetLazyData(voidString, aContentType, aLength, INT64_MAX);
mBlobImpl->SetLazyData(NullString(), aContentType, aLength, INT64_MAX);
NormalBlobConstructorParams params(aContentType,
aLength,
@ -4400,10 +4397,7 @@ BlobParent::RecvResolveMystery(const ResolveMysteryParams& aParams)
return false;
}
nsString voidString;
voidString.SetIsVoid(true);
mBlobImpl->SetLazyData(voidString,
mBlobImpl->SetLazyData(NullString(),
params.contentType(),
params.length(),
INT64_MAX);

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

@ -822,14 +822,15 @@ ContentChild::ProvideWindowCommon(TabChild* aTabOpener,
renderFrame = nullptr;
}
ShowInfo showInfo(EmptyString(), false, false, true, false, 0, 0);
ShowInfo showInfo(EmptyString(), false, false, true, false, 0, 0, 0);
auto* opener = nsPIDOMWindowOuter::From(aParent);
nsIDocShell* openerShell;
if (opener && (openerShell = opener->GetDocShell())) {
nsCOMPtr<nsILoadContext> context = do_QueryInterface(openerShell);
showInfo = ShowInfo(EmptyString(), false,
context->UsePrivateBrowsing(), true, false,
aTabOpener->mDPI, aTabOpener->mDefaultScale);
aTabOpener->mDPI, aTabOpener->mRounding,
aTabOpener->mDefaultScale);
}
// Unfortunately we don't get a window unless we've shown the frame. That's

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

@ -3901,18 +3901,18 @@ ContentParent::RecvIsSecureURI(const uint32_t& type,
if (!ourURI) {
return false;
}
nsresult rv = sss->IsSecureURI(type, ourURI, flags, isSecureURI);
nsresult rv = sss->IsSecureURI(type, ourURI, flags, nullptr, isSecureURI);
return NS_SUCCEEDED(rv);
}
bool
ContentParent::RecvAccumulateMixedContentHSTS(const URIParams& aURI, const bool& aActive)
ContentParent::RecvAccumulateMixedContentHSTS(const URIParams& aURI, const bool& aActive, const bool& aHSTSPriming)
{
nsCOMPtr<nsIURI> ourURI = DeserializeURI(aURI);
if (!ourURI) {
return false;
}
nsMixedContentBlocker::AccumulateMixedContentHSTS(ourURI, aActive);
nsMixedContentBlocker::AccumulateMixedContentHSTS(ourURI, aActive, aHSTSPriming);
return true;
}

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

@ -789,7 +789,8 @@ private:
const uint32_t& aFlags, bool* aIsSecureURI) override;
virtual bool RecvAccumulateMixedContentHSTS(const URIParams& aURI,
const bool& aActive) override;
const bool& aActive,
const bool& aHSTSPriming) override;
virtual bool DeallocPHalParent(PHalParent*) override;

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

@ -101,6 +101,7 @@ struct ShowInfo
bool fakeShowInfo;
bool isTransparent;
float dpi;
int32_t widgetRounding;
double defaultScale;
};
@ -375,6 +376,11 @@ parent:
*/
sync GetDefaultScale() returns (double value);
/**
* Gets the rounding of coordinates in the widget.
*/
sync GetWidgetRounding() returns (int32_t value);
/**
* Gets maximum of touch points at current device.
*/
@ -793,7 +799,7 @@ child:
* value (-1) but in the majority of the cases this saves us from two
* sync requests from the child to the parent.
*/
async UIResolutionChanged(float dpi, double scale);
async UIResolutionChanged(float dpi, int32_t rounding, double scale);
/**
* Tell the child that the system theme has changed, and that a repaint

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

@ -838,7 +838,7 @@ parent:
sync IsSecureURI(uint32_t type, URIParams uri, uint32_t flags)
returns (bool isSecureURI);
async AccumulateMixedContentHSTS(URIParams uri, bool active);
async AccumulateMixedContentHSTS(URIParams uri, bool active, bool hasHSTSPriming);
sync GetLookAndFeelCache()
returns (LookAndFeelInt[] lookAndFeelIntCache);

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

@ -541,6 +541,7 @@ TabChild::TabChild(nsIContentChild* aManager,
, mDestroyed(false)
, mUniqueId(aTabId)
, mDPI(0)
, mRounding(0)
, mDefaultScale(0)
, mIsTransparent(false)
, mIPCOpen(false)
@ -1549,6 +1550,7 @@ TabChild::ApplyShowInfo(const ShowInfo& aInfo)
}
}
mDPI = aInfo.dpi();
mRounding = aInfo.widgetRounding();
mDefaultScale = aInfo.defaultScale();
mIsTransparent = aInfo.isTransparent();
}
@ -2942,6 +2944,22 @@ TabChild::GetDefaultScale(double* aScale)
SendGetDefaultScale(aScale);
}
void
TabChild::GetWidgetRounding(int32_t* aRounding)
{
*aRounding = 1;
if (!mRemoteFrame) {
return;
}
if (mRounding > 0) {
*aRounding = mRounding;
return;
}
// Fallback to a sync call if needed.
SendGetWidgetRounding(aRounding);
}
void
TabChild::GetMaxTouchPoints(uint32_t* aTouchPoints)
{
@ -3285,12 +3303,15 @@ TabChild::RecvRequestNotifyAfterRemotePaint()
}
bool
TabChild::RecvUIResolutionChanged(const float& aDpi, const double& aScale)
TabChild::RecvUIResolutionChanged(const float& aDpi,
const int32_t& aRounding,
const double& aScale)
{
ScreenIntSize oldScreenSize = GetInnerSize();
mDPI = 0;
mRounding = 0;
mDefaultScale = 0;
static_cast<PuppetWidget*>(mPuppetWidget.get())->UpdateBackingScaleCache(aDpi, aScale);
static_cast<PuppetWidget*>(mPuppetWidget.get())->UpdateBackingScaleCache(aDpi, aRounding, aScale);
nsCOMPtr<nsIDocument> document(GetDocument());
nsCOMPtr<nsIPresShell> presShell = document->GetShell();
if (presShell) {

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

@ -484,6 +484,8 @@ public:
void GetDefaultScale(double *aScale);
void GetWidgetRounding(int32_t* aRounding);
bool IsTransparent() const { return mIsTransparent; }
void GetMaxTouchPoints(uint32_t* aTouchPoints);
@ -572,6 +574,7 @@ public:
}
virtual bool RecvUIResolutionChanged(const float& aDpi,
const int32_t& aRounding,
const double& aScale) override;
virtual bool
@ -777,6 +780,7 @@ private:
friend class ContentChild;
float mDPI;
int32_t mRounding;
double mDefaultScale;
bool mIsTransparent;

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

@ -277,6 +277,7 @@ TabParent::TabParent(nsIContentParent* aManager,
, mDimensions(0, 0)
, mOrientation(0)
, mDPI(0)
, mRounding(0)
, mDefaultScale(0)
, mUpdatedDimensions(false)
, mSizeMode(nsSizeMode_Normal)
@ -1030,7 +1031,8 @@ TabParent::UIResolutionChanged()
// fails to cache the values, then mDefaultScale.scale might be invalid.
// We don't want to send that value to content. Just send -1 for it too in
// that case.
Unused << SendUIResolutionChanged(mDPI, mDPI < 0 ? -1.0 : mDefaultScale.scale);
Unused << SendUIResolutionChanged(mDPI, mRounding,
mDPI < 0 ? -1.0 : mDefaultScale.scale);
}
}
@ -2499,6 +2501,17 @@ TabParent::RecvGetDefaultScale(double* aValue)
return true;
}
bool
TabParent::RecvGetWidgetRounding(int32_t* aValue)
{
TryCacheDPIAndScale();
MOZ_ASSERT(mRounding > 0,
"Must not ask for rounding before OwnerElement is received!");
*aValue = mRounding;
return true;
}
bool
TabParent::RecvGetMaxTouchPoints(uint32_t* aTouchPoints)
{
@ -2766,6 +2779,7 @@ TabParent::TryCacheDPIAndScale()
if (widget) {
mDPI = widget->GetDPI();
mRounding = widget->RoundsWidgetCoordinatesTo();
mDefaultScale = widget->GetDefaultScale();
}
}
@ -3374,11 +3388,11 @@ TabParent::GetShowInfo()
nsContentUtils::IsChromeDoc(mFrameElement->OwnerDoc()) &&
mFrameElement->HasAttr(kNameSpaceID_None, nsGkAtoms::transparent);
return ShowInfo(name, allowFullscreen, isPrivate, false,
isTransparent, mDPI, mDefaultScale.scale);
isTransparent, mDPI, mRounding, mDefaultScale.scale);
}
return ShowInfo(EmptyString(), false, false, false,
false, mDPI, mDefaultScale.scale);
false, mDPI, mRounding, mDefaultScale.scale);
}
void

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

@ -321,6 +321,8 @@ public:
virtual bool RecvGetDefaultScale(double* aValue) override;
virtual bool RecvGetWidgetRounding(int32_t* aValue) override;
virtual bool RecvGetMaxTouchPoints(uint32_t* aTouchPoints) override;
virtual bool RecvGetWidgetNativeData(WindowsHandle* aValue) override;
@ -635,6 +637,7 @@ protected:
ScreenIntSize mDimensions;
ScreenOrientationInternal mOrientation;
float mDPI;
int32_t mRounding;
CSSToLayoutDeviceScale mDefaultScale;
bool mUpdatedDimensions;
nsSizeMode mSizeMode;

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

@ -70,7 +70,6 @@ nsJSON::Encode(JS::Handle<JS::Value> aValue, JSContext* cx, uint8_t aArgc,
return rv;
if (aArgc == 0) {
aJSON.Truncate();
aJSON.SetIsVoid(true);
return NS_OK;
}
@ -83,7 +82,6 @@ nsJSON::Encode(JS::Handle<JS::Value> aValue, JSContext* cx, uint8_t aArgc,
rv = NS_OK;
// if we didn't consume anything, it's not JSON, so return null
if (!writer.DidWrite()) {
aJSON.Truncate();
aJSON.SetIsVoid(true);
} else {
writer.FlushBuffer();

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

@ -365,7 +365,8 @@ AudioStream::OpenCubeb(cubeb* aContext, cubeb_stream_params& aParams,
cubeb_stream* stream = nullptr;
/* Convert from milliseconds to frames. */
uint32_t latency_frames = CubebUtils::GetCubebLatency() * aParams.rate / 1000;
uint32_t latency_frames =
CubebUtils::GetCubebPlaybackLatencyInMilliseconds() * aParams.rate / 1000;
if (cubeb_stream_init(aContext, &stream, "AudioStream",
nullptr, nullptr, nullptr, &aParams,
latency_frames,

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

@ -19,7 +19,8 @@
#include "prdtoa.h"
#define PREF_VOLUME_SCALE "media.volume_scale"
#define PREF_CUBEB_LATENCY "media.cubeb_latency_ms"
#define PREF_CUBEB_LATENCY_PLAYBACK "media.cubeb_latency_playback_ms"
#define PREF_CUBEB_LATENCY_MSG "media.cubeb_latency_msg_frames"
namespace mozilla {
@ -34,8 +35,10 @@ enum class CubebState {
} sCubebState = CubebState::Uninitialized;
cubeb* sCubebContext;
double sVolumeScale;
uint32_t sCubebLatency;
bool sCubebLatencyPrefSet;
uint32_t sCubebPlaybackLatencyInMilliseconds;
uint32_t sCubebMSGLatencyInFrames;
bool sCubebPlaybackLatencyPrefSet;
bool sCubebMSGLatencyPrefSet;
bool sAudioStreamInitEverSucceeded = false;
StaticAutoPtr<char> sBrandName;
@ -81,6 +84,8 @@ uint32_t sPreferredSampleRate;
extern LazyLogModule gAudioStreamLog;
static const uint32_t CUBEB_NORMAL_LATENCY_MS = 100;
// Consevative default that can work on all platforms.
static const uint32_t CUBEB_NORMAL_LATENCY_FRAMES = 1024;
namespace CubebUtils {
@ -95,14 +100,23 @@ void PrefChanged(const char* aPref, void* aClosure)
NS_ConvertUTF16toUTF8 utf8(value);
sVolumeScale = std::max<double>(0, PR_strtod(utf8.get(), nullptr));
}
} else if (strcmp(aPref, PREF_CUBEB_LATENCY) == 0) {
} else if (strcmp(aPref, PREF_CUBEB_LATENCY_PLAYBACK) == 0) {
// Arbitrary default stream latency of 100ms. The higher this
// value, the longer stream volume changes will take to become
// audible.
sCubebLatencyPrefSet = Preferences::HasUserValue(aPref);
sCubebPlaybackLatencyPrefSet = Preferences::HasUserValue(aPref);
uint32_t value = Preferences::GetUint(aPref, CUBEB_NORMAL_LATENCY_MS);
StaticMutexAutoLock lock(sMutex);
sCubebLatency = std::min<uint32_t>(std::max<uint32_t>(value, 1), 1000);
sCubebPlaybackLatencyInMilliseconds = std::min<uint32_t>(std::max<uint32_t>(value, 1), 1000);
} else if (strcmp(aPref, PREF_CUBEB_LATENCY_MSG) == 0) {
sCubebMSGLatencyPrefSet = Preferences::HasUserValue(aPref);
uint32_t value = Preferences::GetUint(aPref, CUBEB_NORMAL_LATENCY_FRAMES);
StaticMutexAutoLock lock(sMutex);
// 128 is the block size for the Web Audio API, which limits how low the
// latency can be here.
// We don't want to limit the upper limit too much, so that people can
// experiment.
sCubebMSGLatencyInFrames = std::min<uint32_t>(std::max<uint32_t>(value, 128), 1e6);
}
}
@ -238,24 +252,42 @@ void ReportCubebStreamInitFailure(bool aIsFirst)
: CUBEB_BACKEND_INIT_FAILURE_OTHER);
}
uint32_t GetCubebLatency()
uint32_t GetCubebPlaybackLatencyInMilliseconds()
{
StaticMutexAutoLock lock(sMutex);
return sCubebLatency;
return sCubebPlaybackLatencyInMilliseconds;
}
bool CubebLatencyPrefSet()
bool CubebPlaybackLatencyPrefSet()
{
StaticMutexAutoLock lock(sMutex);
return sCubebLatencyPrefSet;
return sCubebPlaybackLatencyPrefSet;
}
bool CubebMSGLatencyPrefSet()
{
StaticMutexAutoLock lock(sMutex);
return sCubebMSGLatencyPrefSet;
}
Maybe<uint32_t> GetCubebMSGLatencyInFrames()
{
StaticMutexAutoLock lock(sMutex);
if (!sCubebMSGLatencyPrefSet) {
return Maybe<uint32_t>();
}
MOZ_ASSERT(sCubebMSGLatencyInFrames > 0);
return Some(sCubebMSGLatencyInFrames);
}
void InitLibrary()
{
PrefChanged(PREF_VOLUME_SCALE, nullptr);
Preferences::RegisterCallback(PrefChanged, PREF_VOLUME_SCALE);
PrefChanged(PREF_CUBEB_LATENCY, nullptr);
Preferences::RegisterCallback(PrefChanged, PREF_CUBEB_LATENCY);
PrefChanged(PREF_CUBEB_LATENCY_PLAYBACK, nullptr);
PrefChanged(PREF_CUBEB_LATENCY_MSG, nullptr);
Preferences::RegisterCallback(PrefChanged, PREF_CUBEB_LATENCY_PLAYBACK);
Preferences::RegisterCallback(PrefChanged, PREF_CUBEB_LATENCY_MSG);
#ifndef MOZ_WIDGET_ANDROID
NS_DispatchToMainThread(NS_NewRunnableFunction(&InitBrandName));
#endif
@ -264,7 +296,8 @@ void InitLibrary()
void ShutdownLibrary()
{
Preferences::UnregisterCallback(PrefChanged, PREF_VOLUME_SCALE);
Preferences::UnregisterCallback(PrefChanged, PREF_CUBEB_LATENCY);
Preferences::UnregisterCallback(PrefChanged, PREF_CUBEB_LATENCY_PLAYBACK);
Preferences::UnregisterCallback(PrefChanged, PREF_CUBEB_LATENCY_MSG);
StaticMutexAutoLock lock(sMutex);
if (sCubebContext) {

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

@ -9,6 +9,7 @@
#include "cubeb/cubeb.h"
#include "mozilla/dom/AudioChannelBinding.h"
#include "mozilla/Maybe.h"
namespace mozilla {
namespace CubebUtils {
@ -36,7 +37,8 @@ cubeb* GetCubebContext();
cubeb* GetCubebContextUnlocked();
void ReportCubebStreamInitFailure(bool aIsFirstStream);
void ReportCubebBackendUsed();
uint32_t GetCubebLatency();
uint32_t GetCubebPlaybackLatencyInMilliseconds();
Maybe<uint32_t> GetCubebMSGLatencyInFrames();
bool CubebLatencyPrefSet();
#if defined(__ANDROID__) && defined(MOZ_B2G)
cubeb_stream_type ConvertChannelToCubebType(dom::AudioChannel aChannel);

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

@ -628,9 +628,14 @@ AudioCallbackDriver::Init()
output.format = CUBEB_SAMPLE_FLOAT32NE;
}
if (cubeb_get_min_latency(cubebContext, output, &latency_frames) != CUBEB_OK) {
NS_WARNING("Could not get minimal latency from cubeb.");
return;
Maybe<uint32_t> latencyPref = CubebUtils::GetCubebMSGLatencyInFrames();
if (latencyPref) {
latency_frames = latencyPref.value();
} else {
if (cubeb_get_min_latency(cubebContext, output, &latency_frames) != CUBEB_OK) {
NS_WARNING("Could not get minimal latency from cubeb.");
return;
}
}
input = output;

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

@ -72,7 +72,6 @@ MediaFormatReader::MediaFormatReader(AbstractMediaDecoder* aDecoder,
, mPreviousDecodedKeyframeTime_us(sNoPreviousDecodedKeyframe)
, mLayersBackendType(aLayersBackend)
, mInitDone(false)
, mIsEncrypted(false)
, mTrackDemuxersMayBlock(false)
, mDemuxOnly(false)
, mSeekScheduled(false)
@ -337,9 +336,6 @@ MediaFormatReader::OnDemuxerInitDone(nsresult)
}
UniquePtr<EncryptionInfo> crypto = mDemuxer->GetCrypto();
mIsEncrypted = crypto && crypto->IsEncrypted();
if (mDecoder && crypto && crypto->IsEncrypted()) {
#ifdef MOZ_EME
// Try and dispatch 'encrypted'. Won't go if ready state still HAVE_NOTHING.
@ -375,6 +371,13 @@ MediaFormatReader::OnDemuxerInitDone(nsresult)
mMetadataPromise.Resolve(metadata, __func__);
}
bool
MediaFormatReader::IsEncrypted() const
{
return (HasAudio() && mInfo.mAudio.mCrypto.mValid) ||
(HasVideo() && mInfo.mVideo.mCrypto.mValid);
}
void
MediaFormatReader::OnDemuxerInitFailed(const MediaResult& aError)
{

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

@ -105,8 +105,8 @@ public:
private:
bool HasVideo() { return mVideo.mTrackDemuxer; }
bool HasAudio() { return mAudio.mTrackDemuxer; }
bool HasVideo() const { return mVideo.mTrackDemuxer; }
bool HasAudio() const { return mAudio.mTrackDemuxer; }
bool IsWaitingOnCDMResource();
@ -528,11 +528,7 @@ private:
// True if we've read the streams' metadata.
bool mInitDone;
MozPromiseHolder<MetadataPromise> mMetadataPromise;
bool IsEncrypted()
{
return mIsEncrypted;
}
bool mIsEncrypted;
bool IsEncrypted() const;
// Set to true if any of our track buffers may be blocking.
bool mTrackDemuxersMayBlock;

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

@ -154,4 +154,17 @@ IsClearkeyKeySystem(const nsAString& aKeySystem)
return !CompareUTF8toUTF16(kEMEKeySystemClearkey, aKeySystem);
}
CDMType
ToCDMTypeTelemetryEnum(const nsString& aKeySystem)
{
if (!CompareUTF8toUTF16(kEMEKeySystemWidevine, aKeySystem)) {
return CDMType::eWidevine;
} else if (!CompareUTF8toUTF16(kEMEKeySystemClearkey, aKeySystem)) {
return CDMType::eClearKey;
} else if (!CompareUTF8toUTF16(kEMEKeySystemPrimetime, aKeySystem)) {
return CDMType::ePrimetime;
}
return CDMType::eUnknown;
}
} // namespace mozilla

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

@ -106,6 +106,16 @@ KeySystemToGMPName(const nsAString& aKeySystem);
bool
IsClearkeyKeySystem(const nsAString& aKeySystem);
enum CDMType {
eClearKey = 0,
ePrimetime = 1,
eWidevine = 2,
eUnknown = 3
};
CDMType
ToCDMTypeTelemetryEnum(const nsString& aKeySystem);
} // namespace mozilla
#endif // EME_LOG_H_

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

@ -199,6 +199,9 @@ MediaKeySession::GenerateRequest(const nsAString& aInitDataType,
return promise.forget();
}
Telemetry::Accumulate(Telemetry::VIDEO_CDM_GENERATE_REQUEST_CALLED,
ToCDMTypeTelemetryEnum(mKeySystem));
// Convert initData to base64 for easier logging.
// Note: CreateSession() Move()s the data out of the array, so we have
// to copy it here.

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

@ -401,26 +401,6 @@ MediaKeys::Init(ErrorResult& aRv)
return promise.forget();
}
enum CDMCreatedType {
eClearKey = 0,
ePrimetime = 1,
eWidevine = 2,
eUnknown = 3
};
static CDMCreatedType
ToCDMCreatedTelemetryEnum(const nsString& aKeySystem)
{
if (!CompareUTF8toUTF16(kEMEKeySystemWidevine, aKeySystem)) {
return CDMCreatedType::eWidevine;
} else if (!CompareUTF8toUTF16(kEMEKeySystemClearkey, aKeySystem)) {
return CDMCreatedType::eClearKey;
} else if (!CompareUTF8toUTF16(kEMEKeySystemPrimetime, aKeySystem)) {
return CDMCreatedType::ePrimetime;
}
return CDMCreatedType::eUnknown;
}
void
MediaKeys::OnCDMCreated(PromiseId aId, const nsACString& aNodeId, const uint32_t aPluginId)
{
@ -440,7 +420,7 @@ MediaKeys::OnCDMCreated(PromiseId aId, const nsACString& aNodeId, const uint32_t
mKeySystem,
MediaKeySystemStatus::Cdm_created);
Telemetry::Accumulate(Telemetry::VIDEO_CDM_CREATED, ToCDMCreatedTelemetryEnum(mKeySystem));
Telemetry::Accumulate(Telemetry::VIDEO_CDM_CREATED, ToCDMTypeTelemetryEnum(mKeySystem));
}
already_AddRefed<MediaKeySession>

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

@ -1075,7 +1075,6 @@ TrackBuffersManager::OnDemuxerInitDone(nsresult)
// We clear our crypto init data array, so the MediaFormatReader will
// not emit an encrypted event for the same init data again.
info.mCrypto.mInitDatas.Clear();
mEncrypted = true;
}
{

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

@ -240,7 +240,6 @@ private:
void OnDemuxerInitFailed(const MediaResult& aFailure);
void OnDemuxerResetDone(nsresult);
MozPromiseRequestHolder<MediaDataDemuxer::InitPromise> mDemuxerInitRequest;
bool mEncrypted;
void OnDemuxFailed(TrackType aTrack, const MediaResult& aError);
void DoDemuxVideo();

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

@ -29,33 +29,6 @@ using namespace mozilla::gl;
using namespace mozilla::java::sdk;
using media::TimeUnit;
namespace {
template<class T>
mozilla::jni::ByteArray::LocalRef
CreateAndInitJByteArray(const T& data, jsize length)
{
JNIEnv* const jenv = mozilla::jni::GetEnvForThread();
jbyteArray result = jenv->NewByteArray(length);
MOZ_CATCH_JNI_EXCEPTION(jenv);
jenv->SetByteArrayRegion(result, 0, length, reinterpret_cast<const jbyte*>(const_cast<T>(data)));
MOZ_CATCH_JNI_EXCEPTION(jenv);
return mozilla::jni::ByteArray::LocalRef::Adopt(jenv, result);
}
template<class T>
mozilla::jni::IntArray::LocalRef
CreateAndInitJIntArray(const T& data, jsize length)
{
JNIEnv* const jenv = mozilla::jni::GetEnvForThread();
jintArray result = jenv->NewIntArray(length);
MOZ_CATCH_JNI_EXCEPTION(jenv);
jenv->SetIntArrayRegion(result, 0, length, reinterpret_cast<const jint*>(const_cast<T>(data)));
MOZ_CATCH_JNI_EXCEPTION(jenv);
return mozilla::jni::IntArray::LocalRef::Adopt(jenv, result);
}
}
namespace mozilla {
mozilla::LazyLogModule sAndroidDecoderModuleLog("AndroidDecoderModule");
@ -125,11 +98,17 @@ GetCryptoInfoFromSample(const MediaRawData* aSample)
tempIV.AppendElement(0);
}
auto numBytesOfPlainData = CreateAndInitJIntArray(&plainSizes[0], plainSizes.Length());
auto numBytesOfEncryptedData = CreateAndInitJIntArray(&cryptoObj.mEncryptedSizes[0],
cryptoObj.mEncryptedSizes.Length());
auto iv = CreateAndInitJByteArray(&tempIV[0], tempIV.Length());
auto keyId = CreateAndInitJByteArray(&cryptoObj.mKeyId[0], cryptoObj.mKeyId.Length());
auto numBytesOfPlainData = mozilla::jni::IntArray::New(
reinterpret_cast<int32_t*>(&plainSizes[0]),
plainSizes.Length());
auto numBytesOfEncryptedData =
mozilla::jni::IntArray::New(reinterpret_cast<const int32_t*>(&cryptoObj.mEncryptedSizes[0]),
cryptoObj.mEncryptedSizes.Length());
auto iv = mozilla::jni::ByteArray::New(reinterpret_cast<int8_t*>(&tempIV[0]),
tempIV.Length());
auto keyId = mozilla::jni::ByteArray::New(reinterpret_cast<const int8_t*>(&cryptoObj.mKeyId[0]),
cryptoObj.mKeyId.Length());
cryptoInfo->Set(numSubSamples,
numBytesOfPlainData,
numBytesOfEncryptedData,

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

@ -52,7 +52,7 @@ public:
, mGrallocFormat(aGrallocFormat)
{}
already_AddRefed<TextureClient> Allocate(TextureForwarder* aAllocator) override
already_AddRefed<TextureClient> Allocate(KnowsCompositor* aAllocator) override
{
uint32_t usage = android::GraphicBuffer::USAGE_SW_READ_OFTEN |
android::GraphicBuffer::USAGE_SW_WRITE_OFTEN |
@ -60,7 +60,7 @@ public:
GrallocTextureData* texData = GrallocTextureData::Create(mSize, mGrallocFormat,
gfx::BackendType::NONE,
usage, aAllocator);
usage, aAllocator->GetTextureForwarder());
if (!texData) {
return nullptr;
}
@ -69,7 +69,7 @@ public:
return nullptr;
}
RefPtr<TextureClient> textureClient =
TextureClient::CreateWithData(texData, TextureFlags::DEALLOCATE_CLIENT, aAllocator);
TextureClient::CreateWithData(texData, TextureFlags::DEALLOCATE_CLIENT, aAllocator->GetTextureForwarder());
return textureClient.forget();
}

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

@ -930,3 +930,4 @@ tags = suspend
tags = suspend
[test_background_video_no_suspend_disabled.html]
tags = suspend
[test_temporary_file_blob_video_plays.html]

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

@ -0,0 +1,73 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test MediaRecorder Recording canvas stream</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/dom/canvas/test/captureStream_common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test">
<div id="content">
</div>
<script class="testbody" type="text/javascript">
function startTest() {
var canvas = document.createElement("canvas");
canvas.width = canvas.height = 100;
document.getElementById("content").appendChild(canvas);
var helper = new CaptureStreamTestHelper2D(100, 100);
helper.drawColor(canvas, helper.red);
var stream = canvas.captureStream(0);
var blob;
mediaRecorder = new MediaRecorder(stream);
is(mediaRecorder.stream, stream,
"Media recorder stream = canvas stream at the start of recording");
mediaRecorder.onwarning = () => ok(false, "warning unexpectedly fired");
mediaRecorder.onerror = () => ok(false, "Recording failed");
mediaRecorder.ondataavailable = ev => {
is(blob, undefined, "Should only get one dataavailable event");
blob = ev.data;
};
mediaRecorder.onstart = () => {
info("Got 'start' event");
// We just want one frame encoded, to see that the recorder produces something readable.
mediaRecorder.stop();
};
mediaRecorder.onstop = () => {
info("Got 'stop' event");
ok(blob, "Should have gotten a data blob");
var video = document.createElement("video");
video.id = "recorded-video";
video.src = URL.createObjectURL(blob);
video.play();
video.onerror = err => {
ok(false, "Should be able to play the recording. Got error. code=" + video.error.code);
SimpleTest.finish();
};
document.getElementById("content").appendChild(video);
helper.waitForPixelColor(video, helper.red, 128, "Should become red")
.then(SimpleTest.finish);
};
mediaRecorder.start();
is(mediaRecorder.state, "recording", "Media recorder should be recording");
}
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({set:[["media.recorder.max_memory", 1]]}, startTest);
</script>
</pre>
</body>
</html>

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

@ -253,9 +253,7 @@ inline nsCString
NullableString(const char* aString)
{
if (!aString) {
nsCString str;
str.SetIsVoid(true);
return str;
return NullCString();
}
return nsCString(aString);
}

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

@ -20,6 +20,7 @@ EXPORTS.mozilla.dom += [
EXPORTS += [
'nsContentSecurityManager.h',
'nsMixedContentBlocker.h',
]
UNIFIED_SOURCES += [

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

@ -6,6 +6,8 @@
#include "nsContentUtils.h"
#include "nsCORSListenerProxy.h"
#include "nsIStreamListener.h"
#include "nsIDocument.h"
#include "nsMixedContentBlocker.h"
#include "mozilla/dom/Element.h"
@ -381,6 +383,14 @@ DoContentSecurityChecks(nsIChannel* aChannel, nsILoadInfo* aLoadInfo)
if (NS_CP_REJECTED(shouldLoad)) {
return NS_ERROR_CONTENT_BLOCKED;
}
if (nsMixedContentBlocker::sSendHSTSPriming) {
rv = nsMixedContentBlocker::MarkLoadInfoForPriming(uri,
requestingContext,
aLoadInfo);
return rv;
}
return NS_OK;
}
@ -489,7 +499,7 @@ nsContentSecurityManager::AsyncOnChannelRedirect(nsIChannel* aOldChannel,
rv = nsContentUtils::GetSecurityManager()->
CheckLoadURIWithPrincipal(oldPrincipal, newOriginalURI, flags);
}
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_SUCCESS(rv, rv);
aCb->OnRedirectVerifyCallback(NS_OK);
return NS_OK;

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

@ -54,6 +54,11 @@ bool nsMixedContentBlocker::sBlockMixedScript = false;
// Is mixed display content blocking (images, audio, video, <a ping>) enabled?
bool nsMixedContentBlocker::sBlockMixedDisplay = false;
// Do we move HSTS before mixed-content
bool nsMixedContentBlocker::sUseHSTS = false;
// Do we send an HSTS priming request
bool nsMixedContentBlocker::sSendHSTSPriming = false;
// Fired at the document that attempted to load mixed content. The UI could
// handle this event, for example, by displaying an info bar that offers the
// choice to reload the page with mixed content permitted.
@ -195,6 +200,14 @@ nsMixedContentBlocker::nsMixedContentBlocker()
// Cache the pref for mixed display blocking
Preferences::AddBoolVarCache(&sBlockMixedDisplay,
"security.mixed_content.block_display_content");
// Cache the pref for HSTS
Preferences::AddBoolVarCache(&sUseHSTS,
"security.mixed_content.use_hsts");
// Cache the pref for sending HSTS priming
Preferences::AddBoolVarCache(&sSendHSTSPriming,
"security.mixed_content.send_hsts_priming");
}
nsMixedContentBlocker::~nsMixedContentBlocker()
@ -238,8 +251,6 @@ LogMixedContentMessage(MixedContentTypes aClassification,
messageLookupKey.get(), strings, ArrayLength(strings));
}
/* nsIChannelEventSink implementation
* This code is called when a request is redirected.
* We check the channel associated with the new uri is allowed to load
@ -309,17 +320,35 @@ nsMixedContentBlocker::AsyncOnChannelRedirect(nsIChannel* aOldChannel,
NS_ENSURE_SUCCESS(rv, rv);
}
nsCOMPtr<nsISupports> requestingContext = loadInfo->LoadingNode();
int16_t decision = REJECT_REQUEST;
rv = ShouldLoad(contentPolicyType,
newUri,
requestingLocation,
loadInfo->LoadingNode(),
requestingContext,
EmptyCString(), // aMimeGuess
nullptr, // aExtra
requestingPrincipal,
&decision);
NS_ENSURE_SUCCESS(rv, rv);
if (nsMixedContentBlocker::sSendHSTSPriming) {
// The LoadInfo passed in is for the original channel, HSTS priming needs to
// be set on the new channel, if required. If the redirect changes
// http->https, or vice-versa, the need for priming may change.
nsCOMPtr<nsILoadInfo> newLoadInfo;
rv = aNewChannel->GetLoadInfo(getter_AddRefs(newLoadInfo));
NS_ENSURE_SUCCESS(rv, rv);
rv = nsMixedContentBlocker::MarkLoadInfoForPriming(newUri,
requestingContext,
newLoadInfo);
if (NS_FAILED(rv)) {
decision = REJECT_REQUEST;
newLoadInfo->ClearHSTSPriming();
}
}
// If the channel is about to load mixed content, abort the channel
if (!NS_CP_ACCEPTED(decision)) {
autoCallback.DontCallback();
@ -463,7 +492,6 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect,
*aDecision = ACCEPT;
return NS_OK;
// Static display content is considered moderate risk for mixed content so
// these will be blocked according to the mixed display preference
case TYPE_IMAGE:
@ -497,7 +525,6 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect,
// This content policy works as a whitelist.
default:
MOZ_ASSERT(false, "Mixed content of unknown type");
break;
}
// Make sure to get the URI the load started with. No need to check
@ -677,7 +704,9 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect,
bool isHttpScheme = false;
rv = innerContentLocation->SchemeIs("http", &isHttpScheme);
NS_ENSURE_SUCCESS(rv, rv);
if (isHttpScheme && docShell->GetDocument()->GetUpgradeInsecureRequests(isPreload)) {
nsIDocument* document = docShell->GetDocument();
MOZ_ASSERT(document, "Expected a document");
if (isHttpScheme && document->GetUpgradeInsecureRequests(isPreload)) {
*aDecision = ACCEPT;
return NS_OK;
}
@ -688,7 +717,7 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect,
// Block all non secure loads in case the CSP directive is present. Please note
// that at this point we already know, based on |schemeSecure| that the load is
// not secure, so we can bail out early at this point.
if (docShell->GetDocument()->GetBlockAllMixedContent(isPreload)) {
if (document->GetBlockAllMixedContent(isPreload)) {
// log a message to the console before returning.
nsAutoCString spec;
rv = aContentLocation->GetSpec(spec);
@ -703,7 +732,7 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect,
0, // aLineNumber
0, // aColumnNumber
nsIScriptError::errorFlag, "CSP",
docShell->GetDocument()->InnerWindowID());
document->InnerWindowID());
*aDecision = REJECT_REQUEST;
return NS_OK;
}
@ -796,6 +825,34 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect,
}
nsresult stateRV = securityUI->GetState(&state);
bool doHSTSPriming = false;
if (isHttpScheme) {
bool hsts = false;
bool cached = false;
nsCOMPtr<nsISiteSecurityService> sss =
do_GetService(NS_SSSERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HSTS, aContentLocation,
0, &cached, &hsts);
NS_ENSURE_SUCCESS(rv, rv);
if (hsts && sUseHSTS) {
// assume we will be upgraded later
*aDecision = ACCEPT;
return NS_OK;
}
// Send a priming request if the result is not already cached and priming
// requests are allowed
if (!cached && sSendHSTSPriming) {
// add this URI as a priming location
doHSTSPriming = true;
document->AddHSTSPrimingLocation(innerContentLocation,
HSTSPrimingState::eHSTS_PRIMING_ALLOW);
*aDecision = ACCEPT;
}
}
// At this point we know that the request is mixed content, and the only
// question is whether we block it. Record telemetry at this point as to
// whether HSTS would have fixed things by making the content location
@ -811,14 +868,14 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect,
bool active = (classification == eMixedScript);
if (!aHadInsecureImageRedirect) {
if (XRE_IsParentProcess()) {
AccumulateMixedContentHSTS(innerContentLocation, active);
AccumulateMixedContentHSTS(innerContentLocation, active, doHSTSPriming);
} else {
// Ask the parent process to do the same call
mozilla::dom::ContentChild* cc = mozilla::dom::ContentChild::GetSingleton();
if (cc) {
mozilla::ipc::URIParams uri;
SerializeURI(innerContentLocation, uri);
cc->SendAccumulateMixedContentHSTS(uri, active);
cc->SendAccumulateMixedContentHSTS(uri, active, doHSTSPriming);
}
}
}
@ -861,7 +918,13 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect,
}
}
} else {
*aDecision = nsIContentPolicy::REJECT_REQUEST;
if (doHSTSPriming) {
document->AddHSTSPrimingLocation(innerContentLocation,
HSTSPrimingState::eHSTS_PRIMING_BLOCK);
*aDecision = nsIContentPolicy::ACCEPT;
} else {
*aDecision = nsIContentPolicy::REJECT_REQUEST;
}
LogMixedContentMessage(classification, aContentLocation, rootDoc, eBlocked);
if (!rootDoc->GetHasMixedDisplayContentBlocked() && NS_SUCCEEDED(stateRV)) {
rootDoc->SetHasMixedDisplayContentBlocked(true);
@ -907,7 +970,13 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect,
}
} else {
//User has not overriden the pref by Disabling protection. Reject the request and update the security state.
*aDecision = nsIContentPolicy::REJECT_REQUEST;
if (doHSTSPriming) {
document->AddHSTSPrimingLocation(innerContentLocation,
HSTSPrimingState::eHSTS_PRIMING_BLOCK);
*aDecision = nsIContentPolicy::ACCEPT;
} else {
*aDecision = nsIContentPolicy::REJECT_REQUEST;
}
LogMixedContentMessage(classification, aContentLocation, rootDoc, eBlocked);
// See if the pref will change here. If it will, only then do we need to call OnSecurityChange() to update the UI.
if (rootDoc->GetHasMixedActiveContentBlocked()) {
@ -922,7 +991,6 @@ nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect,
}
return NS_OK;
}
} else {
// The content is not blocked by the mixed content prefs.
@ -973,10 +1041,24 @@ enum MixedContentHSTSState {
MCB_HSTS_ACTIVE_WITH_HSTS = 3
};
// Similar to the existing mixed-content HSTS, except MCB_HSTS_*_NO_HSTS is
// broken into two distinct states, indicating whether we plan to send a priming
// request or not. If we decided not go send a priming request, it could be
// because it is a type we do not support, or because we cached a previous
// negative response.
enum MixedContentHSTSPrimingState {
eMCB_HSTS_PASSIVE_WITH_HSTS = 0,
eMCB_HSTS_ACTIVE_WITH_HSTS = 1,
eMCB_HSTS_PASSIVE_NO_PRIMING = 2,
eMCB_HSTS_PASSIVE_DO_PRIMING = 3,
eMCB_HSTS_ACTIVE_NO_PRIMING = 4,
eMCB_HSTS_ACTIVE_DO_PRIMING = 5
};
// Record information on when HSTS would have made mixed content not mixed
// content (regardless of whether it was actually blocked)
void
nsMixedContentBlocker::AccumulateMixedContentHSTS(nsIURI* aURI, bool aActive)
nsMixedContentBlocker::AccumulateMixedContentHSTS(nsIURI* aURI, bool aActive, bool aHasHSTSPriming)
{
// This method must only be called in the parent, because
// nsSiteSecurityService is only available in the parent
@ -991,28 +1073,113 @@ nsMixedContentBlocker::AccumulateMixedContentHSTS(nsIURI* aURI, bool aActive)
if (NS_FAILED(rv)) {
return;
}
rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HSTS, aURI, 0, &hsts);
rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HSTS, aURI, 0, nullptr, &hsts);
if (NS_FAILED(rv)) {
return;
}
// states: would upgrade, would prime, hsts info cached
// active, passive
//
if (!aActive) {
if (!hsts) {
Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS,
MCB_HSTS_PASSIVE_NO_HSTS);
if (aHasHSTSPriming) {
Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS_PRIMING,
eMCB_HSTS_PASSIVE_DO_PRIMING);
} else {
Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS_PRIMING,
eMCB_HSTS_PASSIVE_NO_PRIMING);
}
}
else {
Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS,
MCB_HSTS_PASSIVE_WITH_HSTS);
Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS_PRIMING,
eMCB_HSTS_PASSIVE_WITH_HSTS);
}
} else {
if (!hsts) {
Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS,
MCB_HSTS_ACTIVE_NO_HSTS);
if (aHasHSTSPriming) {
Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS_PRIMING,
eMCB_HSTS_ACTIVE_DO_PRIMING);
} else {
Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS_PRIMING,
eMCB_HSTS_ACTIVE_NO_PRIMING);
}
}
else {
Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS,
MCB_HSTS_ACTIVE_WITH_HSTS);
Telemetry::Accumulate(Telemetry::MIXED_CONTENT_HSTS_PRIMING,
eMCB_HSTS_ACTIVE_WITH_HSTS);
}
}
}
//static
nsresult
nsMixedContentBlocker::MarkLoadInfoForPriming(nsIURI* aURI,
nsISupports* aRequestingContext,
nsILoadInfo* aLoadInfo)
{
nsresult rv;
bool sendPriming = false;
bool mixedContentWouldBlock = false;
rv = GetHSTSPrimingFromRequestingContext(aURI,
aRequestingContext,
&sendPriming,
&mixedContentWouldBlock);
NS_ENSURE_SUCCESS(rv, rv);
if (sendPriming) {
aLoadInfo->SetHSTSPriming(mixedContentWouldBlock);
}
return NS_OK;
}
//static
nsresult
nsMixedContentBlocker::GetHSTSPrimingFromRequestingContext(nsIURI* aURI,
nsISupports* aRequestingContext,
bool* aSendPrimingRequest,
bool* aMixedContentWouldBlock)
{
*aSendPrimingRequest = false;
*aMixedContentWouldBlock = false;
// If we marked for priming, we used the innermost URI, so get that
nsCOMPtr<nsIURI> innerURI = NS_GetInnermostURI(aURI);
if (!innerURI) {
NS_ERROR("Can't get innerURI from aContentLocation");
return NS_ERROR_CONTENT_BLOCKED;
}
bool isHttp = false;
innerURI->SchemeIs("http", &isHttp);
if (!isHttp) {
// there is nothign to do
return NS_OK;
}
// If the DocShell was marked for HSTS priming, propagate that to the LoadInfo
nsCOMPtr<nsIDocShell> docShell = NS_CP_GetDocShellFromContext(aRequestingContext);
if (!docShell) {
return NS_OK;
}
nsCOMPtr<nsIDocument> document = docShell->GetDocument();
if (!document) {
return NS_OK;
}
HSTSPrimingState status = document->GetHSTSPrimingStateForLocation(innerURI);
if (status != HSTSPrimingState::eNO_HSTS_PRIMING) {
*aSendPrimingRequest = (status != HSTSPrimingState::eNO_HSTS_PRIMING);
*aMixedContentWouldBlock = (status == HSTSPrimingState::eHSTS_PRIMING_BLOCK);
}
return NS_OK;
}

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

@ -28,6 +28,8 @@ enum MixedContentTypes {
#include "nsIChannelEventSink.h"
#include "imgRequest.h"
class nsILoadInfo; // forward declaration
class nsMixedContentBlocker : public nsIContentPolicy,
public nsIChannelEventSink
{
@ -59,9 +61,41 @@ public:
nsISupports* aExtra,
nsIPrincipal* aRequestPrincipal,
int16_t* aDecision);
static void AccumulateMixedContentHSTS(nsIURI* aURI, bool aActive);
static void AccumulateMixedContentHSTS(nsIURI* aURI,
bool aActive,
bool aHasHSTSPriming);
/* If the document associated with aRequestingContext requires priming for
* aURI, propagate that to the LoadInfo so the HttpChannel will find out about
* it.
*
* @param aURI The URI associated with the load
* @param aRequestingContext the requesting context passed to ShouldLoad
* @param aLoadInfo the LoadInfo for the load
*/
static nsresult MarkLoadInfoForPriming(nsIURI* aURI,
nsISupports* aRequestingContext,
nsILoadInfo* aLoadInfo);
/* Given a context, return whether HSTS was marked on the document associated
* with the load for the given URI. This is used by MarkLoadInfoForPriming and
* directly by the image loader to determine whether to allow a load to occur
* from the cache.
*
* @param aURI The URI associated with the load
* @param aRequestingContext the requesting context passed to ShouldLoad
* @param aSendPrimingRequest out true if priming is required on the channel
* @param aMixedContentWouldBlock out true if mixed content would block
*/
static nsresult GetHSTSPrimingFromRequestingContext(nsIURI* aURI,
nsISupports* aRequestingContext,
bool* aSendPrimingRequest,
bool* aMixedContentWouldBlock);
static bool sBlockMixedScript;
static bool sBlockMixedDisplay;
static bool sUseHSTS;
static bool sSendHSTSPriming;
};
#endif /* nsMixedContentBlocker_h___ */

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

@ -0,0 +1,9 @@
[DEFAULT]
support-files =
file_priming-top.html
file_testserver.sjs
file_1x1.png
file_priming.js
file_stylesheet.css
[browser_hsts-priming_main.js]

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

@ -0,0 +1,296 @@
/*
* Description of the test:
* Check that HSTS priming occurs correctly with mixed content
*
* This test uses three hostnames, each of which treats an HSTS priming
* request differently.
* * no-ssl never returns an ssl response
* * reject-upgrade returns an ssl response, but with no STS header
* * prime-hsts returns an ssl response with the appropriate STS header
*
* For each server, test that it response appropriately when the we allow
* or block active or display content, as well as when we send an hsts priming
* request, but do not change the order of mixed-content and HSTS.
*
* This test uses http-on-examine-response, so must be run in browser context.
*/
'use strict';
var TOP_URI = "https://example.com/browser/dom/security/test/hsts/file_priming-top.html";
var test_servers = {
// a test server that does not support TLS
'no-ssl': {
host: 'example.co.jp',
response: false,
id: 'no-ssl',
},
// a test server which does not support STS upgrade
'reject-upgrade': {
host: 'example.org',
response: true,
id: 'reject-upgrade',
},
// a test server when sends an STS header when priming
'prime-hsts': {
host: 'test1.example.com',
response: true,
id: 'prime-hsts'
},
};
// The number of priming responses we expect to see
var priming_count = 2;
var test_settings = {
// mixed active content is allowed, priming will upgrade
allow_active: {
block_active: false,
block_display: false,
use_hsts: true,
send_hsts_priming: true,
type: 'script',
result: {
'no-ssl': 'insecure',
'reject-upgrade': 'insecure',
'prime-hsts': 'secure',
},
},
// mixed active content is blocked, priming will upgrade
block_active: {
block_active: true,
block_display: false,
use_hsts: true,
send_hsts_priming: true,
type: 'script',
result: {
'no-ssl': 'blocked',
'reject-upgrade': 'blocked',
'prime-hsts': 'secure',
},
},
// keep the original order of mixed-content and HSTS, but send
// priming requests
hsts_after_mixed: {
block_active: true,
block_display: false,
use_hsts: false,
send_hsts_priming: true,
type: 'script',
result: {
'no-ssl': 'blocked',
'reject-upgrade': 'blocked',
'prime-hsts': 'blocked',
},
},
// mixed display content is allowed, priming will upgrade
allow_display: {
block_active: true,
block_display: false,
use_hsts: true,
send_hsts_priming: true,
type: 'img',
result: {
'no-ssl': 'insecure',
'reject-upgrade': 'insecure',
'prime-hsts': 'secure',
},
},
// mixed display content is blocked, priming will upgrade
block_display: {
block_active: true,
block_display: true,
use_hsts: true,
send_hsts_priming: true,
type: 'img',
result: {
'no-ssl': 'blocked',
'reject-upgrade': 'blocked',
'prime-hsts': 'secure',
},
},
// mixed active content is blocked, priming will upgrade (css)
block_active_css: {
block_active: true,
block_display: false,
use_hsts: true,
send_hsts_priming: true,
type: 'css',
result: {
'no-ssl': 'blocked',
'reject-upgrade': 'blocked',
'prime-hsts': 'secure',
},
},
// mixed active content is blocked, priming will upgrade
// redirect to the same host
block_active_with_redir_same: {
block_active: true,
block_display: false,
use_hsts: true,
send_hsts_priming: true,
type: 'script',
redir: 'same',
result: {
'no-ssl': 'blocked',
'reject-upgrade': 'blocked',
'prime-hsts': 'secure',
},
},
}
// track which test we are on
var which_test = "";
const Observer = {
observe: function (subject, topic, data) {
switch (topic) {
case 'console-api-log-event':
return Observer.console_api_log_event(subject, topic, data);
case 'http-on-examine-response':
return Observer.http_on_examine_response(subject, topic, data);
}
throw "Can't handle topic "+topic;
},
// When a load is blocked which results in an error event within a page, the
// test logs to the console.
console_api_log_event: function (subject, topic, data) {
var message = subject.wrappedJSObject.arguments[0];
// when we are blocked, this will match the message we sent to the console,
// ignore everything else.
var re = RegExp(/^HSTS_PRIMING: Blocked ([-\w]+).*$/);
if (!re.test(message)) {
return;
}
let id = message.replace(re, '$1');
let curTest =test_servers[id];
if (!curTest) {
ok(false, "HSTS priming got a console message blocked, "+
"but doesn't match expectations "+id+" (msg="+message);
return;
}
is("blocked", test_settings[which_test].result[curTest.id], "HSTS priming "+
which_test+":"+curTest.id+" expected "+
test_settings[which_test].result[curTest.id]+", got blocked");
test_settings[which_test].finished[curTest.id] = "blocked";
},
// When we see a response come back, peek at the response and test it is secure
// or insecure as needed. Addtionally, watch the response for priming requests.
http_on_examine_response: function (subject, topic, data) {
let curTest = null;
let channel = subject.QueryInterface(Ci.nsIHttpChannel);
for (let item in test_servers) {
let re = RegExp('https?://'+test_servers[item].host);
if (re.test(channel.URI.asciiSpec)) {
curTest = test_servers[item];
break;
}
}
if (!curTest) {
return;
}
let result = (channel.URI.asciiSpec.startsWith('https:')) ? "secure" : "insecure";
// This is a priming request, go ahead and validate we were supposed to see
// a response from the server
if (channel.requestMethod == 'HEAD') {
is(true, curTest.response, "HSTS priming response found " + curTest.id);
test_settings[which_test].priming[curTest.id] = true;
return;
}
// This is the response to our query, make sure it matches
is(result, test_settings[which_test].result[curTest.id],
"HSTS priming result " + which_test + ":" + curTest.id);
test_settings[which_test].finished[curTest.id] = result;
},
};
// opens `uri' in a new tab and focuses it.
// returns the newly opened tab
function openTab(uri) {
let tab = gBrowser.addTab(uri);
// select tab and make sure its browser is focused
gBrowser.selectedTab = tab;
tab.ownerDocument.defaultView.focus();
return tab;
}
function clear_sts_data() {
for (let test in test_servers) {
SpecialPowers.cleanUpSTSData('http://'+test_servers[test].host);
}
}
function do_cleanup() {
clear_sts_data();
Services.obs.removeObserver(Observer, "console-api-log-event");
Services.obs.removeObserver(Observer, "http-on-examine-response");
}
function SetupPrefTestEnvironment(which) {
which_test = which;
clear_sts_data();
var settings = test_settings[which];
// priming counts how many priming requests we saw
settings.priming = {};
// priming counts how many tests were finished
settings.finished= {};
SpecialPowers.pushPrefEnv({'set': [["security.mixed_content.block_active_content",
settings.block_active],
["security.mixed_content.block_display_content",
settings.block_display],
["security.mixed_content.use_hsts",
settings.use_hsts],
["security.mixed_content.send_hsts_priming",
settings.send_hsts_priming]]});
}
// make the top-level test uri
function build_test_uri(base_uri, host, test_id, type) {
return base_uri +
"?host=" + escape(host) +
"&id=" + escape(test_id) +
"&type=" + escape(type);
}
// open a new tab, load the test, and wait for it to finish
function execute_test(test, mimetype) {
var src = build_test_uri(TOP_URI, test_servers[test].host,
test, test_settings[which_test].type);
let tab = openTab(src);
test_servers[test]['tab'] = tab;
let browser = gBrowser.getBrowserForTab(tab);
yield BrowserTestUtils.browserLoaded(browser);
yield BrowserTestUtils.removeTab(tab);
}
//jscs:disable
add_task(function*() {
//jscs:enable
Services.obs.addObserver(Observer, "console-api-log-event", false);
Services.obs.addObserver(Observer, "http-on-examine-response", false);
registerCleanupFunction(do_cleanup);
requestLongerTimeout(4);
for (let which of Object.keys(test_settings)) {
SetupPrefTestEnvironment(which);
for (let server of Object.keys(test_servers)) {
yield execute_test(server, test_settings[which].mimetype);
}
SpecialPowers.popPrefEnv();
}
});

Двоичные данные
dom/security/test/hsts/file_1x1.png Normal file

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

После

Ширина:  |  Высота:  |  Размер: 17 KiB

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

@ -0,0 +1,84 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Bug 1246540</title>
<meta http-equiv='content-type' content="text/html;charset=utf-8" />
</head>
<body>
<p id="display"></p>
<div id="content" style="visibility: hidden">
</div>
<script type="text/javascript">
/*
* Description of the test:
* Attempt to load an insecure resource. If the resource responds to HSTS
* priming with an STS header, the load should continue securely.
* If it does not, the load should continue be blocked or continue insecurely.
*/
function parse_query_string() {
var q = {};
document.location.search.substr(1).
split('&').forEach(function (item, idx, ar) {
let [k, v] = item.split('=');
q[k] = unescape(v);
});
return q;
}
var args = parse_query_string();
var subresources = {
css: { mimetype: 'text/css', file: 'file_stylesheet.css' },
img: { mimetype: 'image/png', file: 'file_1x1.png' },
script: { mimetype: 'text/javascript', file: 'file_priming.js' },
};
function handler(ev) {
console.log("HSTS_PRIMING: Blocked "+args.id);
}
function loadCss(src) {
let head = document.getElementsByTagName("head")[0];
let link = document.createElement("link");
link.setAttribute("rel", "stylesheet");
link.setAttribute("type", subresources[args.type].mimetype);
link.setAttribute("href", src);
head.appendChild(link);
}
function loadResource(src) {
let content = document.getElementById("content");
let testElem = document.createElement(args.type);
testElem.setAttribute("id", args.id);
testElem.setAttribute("charset", "UTF-8");
testElem.onerror = handler;
content.appendChild(testElem);
testElem.src = src;
}
function loadTest() {
let subresource = subresources[args.type];
let src = "http://"
+ args.host
+ "/browser/dom/security/test/hsts/file_testserver.sjs"
+ "?file=" +escape("browser/dom/security/test/hsts/" + subresource.file)
+ "&primer=" + escape(args.id)
+ "&mimetype=" + escape(subresource.mimetype)
;
if (args.type == 'css') {
loadCss(src);
return;
}
loadResource(src);
}
// start running the tests
loadTest();
</script>
</body>
</html>

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

@ -0,0 +1,4 @@
function completed() {
return;
}
completed();

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

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

@ -0,0 +1,66 @@
// SJS file for HSTS mochitests
Components.utils.import("resource://gre/modules/NetUtil.jsm");
Components.utils.importGlobalProperties(["URLSearchParams"]);
function loadFromFile(path) {
// Load the HTML to return in the response from file.
// Since it's relative to the cwd of the test runner, we start there and
// append to get to the actual path of the file.
var testFile =
Components.classes["@mozilla.org/file/directory_service;1"].
getService(Components.interfaces.nsIProperties).
get("CurWorkD", Components.interfaces.nsILocalFile);
var dirs = path.split("/");
for (var i = 0; i < dirs.length; i++) {
testFile.append(dirs[i]);
}
var testFileStream =
Components.classes["@mozilla.org/network/file-input-stream;1"].
createInstance(Components.interfaces.nsIFileInputStream);
testFileStream.init(testFile, -1, 0, 0);
var test = NetUtil.readInputStreamToString(testFileStream, testFileStream.available());
return test;
}
function handleRequest(request, response)
{
const query = new URLSearchParams(request.queryString);
redir = query.get('redir');
if (redir == 'same') {
query.delete("redir");
response.setStatus(302);
let newURI = request.uri;
newURI.queryString = query.serialize();
response.setHeader("Location", newURI.spec)
}
// avoid confusing cache behaviors
response.setHeader("Cache-Control", "no-cache", false);
// if we have a priming header, check for required behavior
// and set header appropriately
if (request.hasHeader('Upgrade-Insecure-Requests')) {
var expected = query.get('primer');
if (expected == 'prime-hsts') {
// set it for 5 minutes
response.setHeader("Strict-Transport-Security", "max-age="+(60*5), false);
} else if (expected == 'reject-upgrade') {
response.setHeader("Strict-Transport-Security", "max-age=0", false);
}
response.write('');
return;
}
var file = query.get('file');
if (file) {
var mimetype = unescape(query.get('mimetype'));
response.setHeader("Content-Type", mimetype, false);
response.write(loadFromFile(unescape(file)));
return;
}
response.setHeader("Content-Type", "application/json", false);
response.write('{}');
}

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

@ -162,6 +162,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=62178
}
function startTest() {
// Set prefs to use mixed-content before HSTS
SpecialPowers.pushPrefEnv({'set': [["security.mixed_content.use_hsts", false],
["security.mixed_content.send_hsts_priming", false]]});
//Set the first set of mixed content settings and increment the counter.
//Enable <picture> and <img srcset> for the test.
changePrefs([[ "dom.image.srcset.enabled", true ], [ "dom.image.picture.enabled", true ]],

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

@ -27,4 +27,5 @@ MOCHITEST_CHROME_MANIFESTS += [
BROWSER_CHROME_MANIFESTS += [
'contentverifier/browser.ini',
'csp/browser.ini',
'hsts/browser.ini',
]

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

@ -1,47 +0,0 @@
// Keep track of one in-flight XHR by allowing secondary ones to
// tell us when the client has received a Progress event and wants
// more data or to stop the in-flight XHR.
const STATE_NAME = "bug918719_loading_event_test";
const CHUNK_DATA = "chunk";
function setReq(req) {
setObjectState(STATE_NAME, req);
}
function getReq() {
let req;
getObjectState(STATE_NAME, function(v) {
req = v;
});
return req;
}
function handleRequest(request, response)
{
var pairs = request.queryString.split("&");
var command = pairs.shift();
response.setHeader("Content-Type", "text/plain");
response.setHeader("Cache-Control", "no-cache", false);
switch(command) {
case "more":
getReq().write(CHUNK_DATA);
break;
case "done":
getReq().finish();
setReq(null);
break;
default:
response.processAsync();
response.write(CHUNK_DATA);
setReq(response);
return;
}
response.setHeader("Content-Length", "2", false);
response.write("ok");
}

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

@ -7,7 +7,6 @@ support-files =
bug346659-parent-echoer.html
bug346659-parent.html
bug458091_child.html
bug918719.sjs
child_bug260264.html
devicemotion_inner.html
devicemotion_outer.html
@ -156,7 +155,6 @@ skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop spec
[test_bug857555.html]
[test_bug862540.html]
[test_bug876098.html]
[test_bug918719.html]
[test_bug927901.html]
[test_devicemotion_multiple_listeners.html]
skip-if = toolkit == 'android' #bug 775227

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

@ -1,89 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=918719
-->
<head>
<title>Test for Bug 918719</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=918719">Mozilla Bug 918719</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
const SERVER_URL = "bug918719.sjs";
function sendCommand(cmd) {
let xhr = new XMLHttpRequest();
xhr.open("get", SERVER_URL + "?" + cmd);
xhr.send();
}
function runTest() {
// Manipulate one in-flight XHR using secondary command XHRs, to guarantee
// that multiple OnDataAvailable events are triggered (which are where
// LOADING readystatechanges are triggered). We return a promise that will
// resolve with a count of the number of LOADING events that were detected.
return new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest();
let numProgressEvents = 0;
let numLoadingEvents = 0;
xhr.onreadystatechange = e => {
if (xhr.readyState === xhr.LOADING) {
++numLoadingEvents;
}
};
xhr.onprogress = e => {
if (++numProgressEvents < 2) {
sendCommand("more");
} else {
sendCommand("done");
}
};
xhr.onerror = e => {
reject(e);
};
xhr.onloadend = e => {
resolve(numLoadingEvents);
};
xhr.open("GET", SERVER_URL);
xhr.send();
});
}
function prefChangePromise(args) {
return new Promise(function(resolve) {
SpecialPowers.pushPrefEnv(args, resolve);
});
}
runTest().then(function(count) {
ok(count === 1, "Only one loading readystatechange event should have been fired with the pref off.");
}).then(function() {
return prefChangePromise({"set": [["dom.fire_extra_xhr_loading_readystatechanges", true]]});
}).then(function() {
return runTest();
}).then(function(count) {
ok(count > 1, "Multiple loading readystatechange events should have been fired with the pref on.");
SimpleTest.finish();
});
</script>
</pre>
</body>
</html>

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

@ -3,4 +3,4 @@
<pre id=log>Hello World</pre>
<script>
var worker = new SharedWorker('sharedWorker_fetch.js');
</script>
</script>

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

@ -1,10 +1,8 @@
addEventListener('fetch', function(event) {
if (event.request.url.indexOf("fail.html") !== -1) {
event.respondWith(fetch("serviceworker.html", {"integrity": "abc"}));
event.respondWith(fetch("hello.html", {"integrity": "abc"}));
} else if (event.request.url.indexOf("fake.html") !== -1) {
event.respondWith(fetch("serviceworker.html"));
} else {
event.respondWith(new Response("Hello world"));
event.respondWith(fetch("hello.html"));
}
});

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

@ -0,0 +1,9 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body>
Hello.
</body>
<html>

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

@ -210,7 +210,7 @@ support-files =
sw_bad_mime_type.js^headers^
error_reporting_helpers.js
fetch.js
serviceworker.html
hello.html
create_another_sharedWorker.html
sharedWorker_fetch.js

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

@ -27,5 +27,3 @@ onconnect = function(e) {
}
}
}

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

@ -175,4 +175,4 @@ add_task(function* test_integrity_sharedWorker() {
</script>
</body>
</html>
</html>

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

@ -169,7 +169,6 @@ XMLHttpRequestMainThread::XMLHttpRequestMainThread()
mFlagSyncLooping(false), mFlagBackgroundRequest(false),
mFlagHadUploadListenersOnSend(false), mFlagACwithCredentials(false),
mFlagTimedOut(false), mFlagDeleted(false), mFlagSend(false),
mSendExtraLoadingEvents(Preferences::GetBool("dom.fire_extra_xhr_loading_readystatechanges", true)),
mUploadTransferred(0), mUploadTotal(0), mUploadComplete(true),
mProgressSinceLastProgressEvent(false),
mRequestSentTime(0), mTimeoutMilliseconds(0),
@ -1715,9 +1714,7 @@ XMLHttpRequestMainThread::OnDataAvailable(nsIRequest *request,
mDataAvailable += totalRead;
if (mState == State::headers_received || mSendExtraLoadingEvents) {
ChangeState(State::loading);
}
ChangeState(State::loading);
if (!mFlagSynchronous && !mProgressTimerIsActive) {
StartProgressEventTimer();
@ -2414,6 +2411,27 @@ XMLHttpRequestMainThread::CreateChannel()
secFlags |= nsILoadInfo::SEC_COOKIES_OMIT;
}
nsCOMPtr<nsIExpandedPrincipal> ep = do_QueryInterface(mPrincipal);
if (ep) {
// If we have an expanded principal, instead of using that, select the
// principal in the whitelist which can load our URL, and use that instead.
nsTArray<nsCOMPtr<nsIPrincipal>>* whitelist = nullptr;
ep->GetWhiteList(&whitelist);
if (!whitelist) {
return NS_ERROR_FAILURE;
}
MOZ_ASSERT(!(secFlags & nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS));
bool dataInherits = (secFlags &
(nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS |
nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS)) != 0;
for (const auto& principal : *whitelist) {
if (NS_SUCCEEDED(principal->CheckMayLoad(mRequestURL, false, dataInherits))) {
mPrincipal = principal;
break;
}
}
}
// Use the responsibleDocument if we have it, except for dedicated workers
// where it will be the parent document, which is not the one we want to use.
nsresult rv;

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

@ -686,14 +686,6 @@ protected:
// late, and ensure the XHR only handles one in-flight request at once.
bool mFlagSend;
// Before ProgressEvents were a thing, multiple readystatechange events were
// fired during the loading state to give sites a way to monitor XHR progress.
// The XHR spec now has proper progress events and dictates that only one
// "loading" readystatechange should be fired per send. However, it's possible
// that some content still relies on this old behavior, so we're keeping it
// (behind a preference) for now. See bug 918719.
bool mSendExtraLoadingEvents;
RefPtr<XMLHttpRequestUpload> mUpload;
int64_t mUploadTransferred;
int64_t mUploadTotal;

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

@ -1,4 +1,4 @@
52342
52343
0/nm
0th/pt
1/n1
@ -13747,6 +13747,7 @@ adolescence/SM
adolescent/SM
adopt/AGVDS
adoptable
adoptee/MS
adopter/MS
adoption/SM
adorableness/M

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

@ -823,7 +823,7 @@ GLContextGLX::CreateGLContext(CreateContextFlags flags, const SurfaceCaps& caps,
RefPtr<GLContextGLX> glContext;
bool error;
ScopedXErrorHandler xErrorHandler;
OffMainThreadScopedXErrorHandler xErrorHandler;
do {
error = false;
@ -1311,7 +1311,7 @@ CreateOffscreenPixmapContext(CreateContextFlags flags, const IntSize& size,
int depth;
FindVisualAndDepth(display, visid, &visual, &depth);
ScopedXErrorHandler xErrorHandler;
OffMainThreadScopedXErrorHandler xErrorHandler;
bool error = false;
Drawable drawable;

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

@ -5,7 +5,7 @@
#include "SurfaceTypes.h"
#include "mozilla/layers/ISurfaceAllocator.h"
#include "mozilla/layers/TextureForwarder.h"
namespace mozilla {
namespace gl {

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

@ -12,7 +12,7 @@
namespace mozilla {
namespace layers {
class ISurfaceAllocator;
class LayersIPCChannel;
} // namespace layers
namespace gl {
@ -29,7 +29,7 @@ struct SurfaceCaps final
// The surface allocator that we want to create this
// for. May be null.
RefPtr<layers::ISurfaceAllocator> surfaceAllocator;
RefPtr<layers::LayersIPCChannel> surfaceAllocator;
SurfaceCaps();
SurfaceCaps(const SurfaceCaps& other);

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