Merge m-c to b2g-inbound a=merge
|
@ -2,6 +2,6 @@
|
|||
# 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/.
|
||||
|
||||
ANDROID_PACKAGE_NAME=org.mozilla.b2g_`echo $USER`
|
||||
ANDROID_PACKAGE_NAME=org.mozilla.b2g_`echo $USER | sed 's/-/_/g'`
|
||||
MOZ_APP_DISPLAYNAME=B2G
|
||||
MOZ_UPDATER=
|
||||
|
|
|
@ -31,6 +31,6 @@ externalProtocolChkMsg=Remember my choice for all links of this type.
|
|||
externalProtocolLaunchBtn=Launch application
|
||||
malwareBlocked=The site at %S has been reported as an attack site and has been blocked based on your security preferences.
|
||||
phishingBlocked=The website at %S has been reported as a web forgery designed to trick users into sharing personal or financial information.
|
||||
cspFrameAncestorBlocked=This page has a content security policy that prevents it from being embedded in this way.
|
||||
cspBlocked=This page has a content security policy that prevents it from being loaded in this way.
|
||||
corruptedContentError=The page you are trying to view cannot be shown because an error in the data transmission was detected.
|
||||
remoteXUL=This page uses an unsupported technology that is no longer available by default in Firefox.
|
||||
|
|
|
@ -1644,6 +1644,8 @@ pref("image.mem.max_decoded_image_kb", 256000);
|
|||
pref("loop.enabled", true);
|
||||
pref("loop.server", "https://loop.services.mozilla.com");
|
||||
pref("loop.seenToS", "unseen");
|
||||
pref("loop.gettingStarted.seen", false);
|
||||
pref("loop.gettingStarted.url", "https://bugzilla.mozilla.org/show_bug.cgi?id=1099462");
|
||||
pref("loop.learnMoreUrl", "https://www.firefox.com/hello/");
|
||||
pref("loop.legal.ToS_url", "https://hello.firefox.com/legal/terms/");
|
||||
pref("loop.legal.privacy_url", "https://www.mozilla.org/privacy/");
|
||||
|
|
|
@ -186,8 +186,8 @@
|
|||
document.getElementById("errorTryAgain").style.display = "none";
|
||||
}
|
||||
|
||||
if (err == "cspFrameAncestorBlocked") {
|
||||
// Remove the "Try again" button for CSP frame ancestors violation, since it's
|
||||
if (err == "cspBlocked") {
|
||||
// Remove the "Try again" button for CSP violations, since it's
|
||||
// almost certainly useless. (Bug 553180)
|
||||
document.getElementById("errorTryAgain").style.display = "none";
|
||||
}
|
||||
|
@ -353,7 +353,7 @@
|
|||
<h1 id="et_nssFailure2">&nssFailure2.title;</h1>
|
||||
<h1 id="et_nssBadCert">&nssBadCert.title;</h1>
|
||||
<h1 id="et_malwareBlocked">&malwareBlocked.title;</h1>
|
||||
<h1 id="et_cspFrameAncestorBlocked">&cspFrameAncestorBlocked.title;</h1>
|
||||
<h1 id="et_cspBlocked">&cspBlocked.title;</h1>
|
||||
<h1 id="et_remoteXUL">&remoteXUL.title;</h1>
|
||||
<h1 id="et_corruptedContentError">&corruptedContentError.title;</h1>
|
||||
</div>
|
||||
|
@ -379,7 +379,7 @@
|
|||
<div id="ed_nssFailure2">&nssFailure2.longDesc2;</div>
|
||||
<div id="ed_nssBadCert">&nssBadCert.longDesc2;</div>
|
||||
<div id="ed_malwareBlocked">&malwareBlocked.longDesc;</div>
|
||||
<div id="ed_cspFrameAncestorBlocked">&cspFrameAncestorBlocked.longDesc;</div>
|
||||
<div id="ed_cspBlocked">&cspBlocked.longDesc;</div>
|
||||
<div id="ed_remoteXUL">&remoteXUL.longDesc;</div>
|
||||
<div id="ed_corruptedContentError">&corruptedContentError.longDesc;</div>
|
||||
</div>
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
<command id="cmd_newNavigatorTab" oncommand="BrowserOpenNewTabOrWindow(event);"/>
|
||||
<command id="Browser:OpenFile" oncommand="BrowserOpenFileWindow();"/>
|
||||
<command id="Browser:SavePage" oncommand="saveDocument(window.content.document);"/>
|
||||
<command id="Browser:SavePage" oncommand="saveDocument(gBrowser.selectedBrowser.contentDocumentAsCPOW);"/>
|
||||
|
||||
<command id="Browser:SendLink"
|
||||
oncommand="MailIntegration.sendLinkForWindow(window.content);"/>
|
||||
|
|
|
@ -1743,7 +1743,7 @@ function HandleAppCommandEvent(evt) {
|
|||
gBrowser.selectedBrowser);
|
||||
break;
|
||||
case "Save":
|
||||
saveDocument(window.content.document);
|
||||
saveDocument(gBrowser.selectedBrowser.contentDocumentAsCPOW);
|
||||
break;
|
||||
case "SendMail":
|
||||
MailIntegration.sendLinkForWindow(window.content);
|
||||
|
|
|
@ -120,7 +120,6 @@ skip-if = os == "linux" || e10s # Bug 1073339 - Investigate autocomplete test un
|
|||
[browser_search_favicon.js]
|
||||
skip-if = os == "linux" || e10s # Bug 1073339 - Investigate autocomplete test unreliability on Linux/e10s
|
||||
[browser_alltabslistener.js]
|
||||
skip-if = os == "linux" || e10s # Linux: Intermittent failures, bug 951680; e10s: Bug 1093594 - notifications for tabs come in in the wrong order / unexpectedly
|
||||
[browser_autocomplete_a11y_label.js]
|
||||
skip-if = e10s # Bug ????? - no e10s switch-to-tab support yet
|
||||
[browser_backButtonFitts.js]
|
||||
|
@ -161,7 +160,6 @@ skip-if = e10s # Bug 1093155 - tries to use context menu from browser-chrome and
|
|||
[browser_bug427559.js]
|
||||
skip-if = e10s # Bug ?????? - "content window is focused - Got [object ChromeWindow], expected [object XrayWrapper [object Window]]"
|
||||
[browser_bug431826.js]
|
||||
skip-if = e10s # Bug ?????? - test directly manipulates content (eg, var expertDiv = gBrowser.contentDocument.getElementById("expertContent");)
|
||||
[browser_bug432599.js]
|
||||
[browser_bug435035.js]
|
||||
[browser_bug435325.js]
|
||||
|
@ -227,7 +225,6 @@ skip-if = e10s
|
|||
skip-if = e10s # Bug 1056146 - zoom tests use FullZoomHelper and break in e10s
|
||||
[browser_bug577121.js]
|
||||
[browser_bug578534.js]
|
||||
skip-if = e10s # Bug ?????? - test directly manipulates content
|
||||
[browser_bug579872.js]
|
||||
[browser_bug580638.js]
|
||||
[browser_bug580956.js]
|
||||
|
@ -279,7 +276,6 @@ skip-if = e10s
|
|||
[browser_bug767836_perwindowpb.js]
|
||||
skip-if = e10s # Bug ?????? - test reports a leaked nsGlobalWindow with e10s enabled.
|
||||
[browser_bug771331.js]
|
||||
skip-if = e10s # Bug ?????? - test directly manipulates content
|
||||
[browser_bug783614.js]
|
||||
[browser_bug816527.js]
|
||||
skip-if = e10s # Bug 1093373 - relies on browser.sessionHistory
|
||||
|
@ -340,7 +336,6 @@ skip-if = e10s # Bug ?????? - this test fails for obscure reasons on non-windows
|
|||
[browser_keywordSearch.js]
|
||||
skip-if = e10s # Bug 921957 - remote webprogress doesn't supply cancel method on the request object
|
||||
[browser_keywordSearch_postData.js]
|
||||
skip-if = e10s # Bug ?????? - test directly manipulates content (gBrowser.contentDocument.body.textContent)
|
||||
[browser_lastAccessedTab.js]
|
||||
skip-if = toolkit == "windows" # Disabled on Windows due to frequent failures (bug 969405)
|
||||
[browser_locationBarCommand.js]
|
||||
|
@ -362,7 +357,6 @@ skip-if = buildapp == 'mulet' || e10s # Bug 1093603 - test breaks with PopupNoti
|
|||
[browser_pageInfo.js]
|
||||
skip-if = buildapp == 'mulet' || e10s # Bug 866413 - PageInfo doesn't work in e10s
|
||||
[browser_page_style_menu.js]
|
||||
skip-if = e10s # Bug ?????? - test directly manipulates content
|
||||
|
||||
[browser_parsable_css.js]
|
||||
skip-if = e10s
|
||||
|
|
|
@ -94,7 +94,11 @@ function test() {
|
|||
|
||||
// We must wait until the about:blank page has completed loading before
|
||||
// starting tests or we get notifications from that
|
||||
gForegroundBrowser.addEventListener("load", startTests, true);
|
||||
let promises = [
|
||||
waitForDocLoadComplete(gBackgroundBrowser),
|
||||
waitForDocLoadComplete(gForegroundBrowser)
|
||||
];
|
||||
Promise.all(promises).then(startTest1);
|
||||
}
|
||||
|
||||
function runTest(browser, url, next) {
|
||||
|
@ -105,11 +109,6 @@ function runTest(browser, url, next) {
|
|||
browser.loadURI(url);
|
||||
}
|
||||
|
||||
function startTests() {
|
||||
gForegroundBrowser.removeEventListener("load", startTests, true);
|
||||
executeSoon(startTest1);
|
||||
}
|
||||
|
||||
function startTest1() {
|
||||
info("\nTest 1");
|
||||
gBrowser.addProgressListener(gFrontProgressListener);
|
||||
|
|
|
@ -308,7 +308,7 @@ const CustomizableWidgets = [
|
|||
aEvent.target.ownerDocument &&
|
||||
aEvent.target.ownerDocument.defaultView;
|
||||
if (win && typeof win.saveDocument == "function") {
|
||||
win.saveDocument(win.content.document);
|
||||
win.saveDocument(win.gBrowser.selectedBrowser.contentDocumentAsCPOW);
|
||||
}
|
||||
}
|
||||
}, {
|
||||
|
|
|
@ -451,6 +451,23 @@ function injectLoopAPI(targetWindow) {
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Set any boolean preference under "loop."
|
||||
*
|
||||
* @param {String} prefName The name of the pref without the preceding "loop."
|
||||
* @param {bool} value The value to set.
|
||||
*
|
||||
* Any errors thrown by the Mozilla pref API are logged to the console
|
||||
* and cause false to be returned.
|
||||
*/
|
||||
setLoopBoolPref: {
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
value: function(prefName, value) {
|
||||
MozLoopService.setLoopBoolPref(prefName, value);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Return any preference under "loop." that's coercible to a boolean
|
||||
* preference.
|
||||
|
@ -596,6 +613,17 @@ function injectLoopAPI(targetWindow) {
|
|||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* Opens the Getting Started tour in the browser.
|
||||
*/
|
||||
openGettingStartedTour: {
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
value: function() {
|
||||
return MozLoopService.openGettingStartedTour();
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* Copies passed string onto the system clipboard.
|
||||
*
|
||||
|
|
|
@ -1259,6 +1259,23 @@ this.MozLoopService = {
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Set any boolean preference under "loop.".
|
||||
*
|
||||
* @param {String} prefName The name of the pref without the preceding "loop."
|
||||
* @param {boolean} value The value to set.
|
||||
*
|
||||
* Any errors thrown by the Mozilla pref API are logged to the console.
|
||||
*/
|
||||
setLoopBoolPref: function(prefName, value) {
|
||||
try {
|
||||
Services.prefs.setBoolPref("loop." + prefName, value);
|
||||
} catch (ex) {
|
||||
log.error("setLoopCharPref had trouble setting " + prefName +
|
||||
"; exception: " + ex);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Return any preference under "loop." that's coercible to a character
|
||||
* preference.
|
||||
|
@ -1387,6 +1404,19 @@ this.MozLoopService = {
|
|||
}
|
||||
}),
|
||||
|
||||
/**
|
||||
* Opens the Getting Started tour in the browser.
|
||||
*/
|
||||
openGettingStartedTour: Task.async(function() {
|
||||
try {
|
||||
let url = Services.prefs.getCharPref("loop.gettingStarted.url");
|
||||
let win = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
win.switchToTabHavingURI(url, true);
|
||||
} catch (ex) {
|
||||
log.error("Error opening Getting Started tour", ex);
|
||||
}
|
||||
}),
|
||||
|
||||
/**
|
||||
* Performs a hawk based request to the loop server.
|
||||
*
|
||||
|
|
|
@ -20,7 +20,6 @@ loop.panel = (function(_, mozL10n) {
|
|||
var ButtonGroup = sharedViews.ButtonGroup;
|
||||
var ContactsList = loop.contacts.ContactsList;
|
||||
var ContactDetailsForm = loop.contacts.ContactDetailsForm;
|
||||
var __ = mozL10n.get; // aliasing translation function as __ for concision
|
||||
|
||||
var TabView = React.createClass({displayName: 'TabView',
|
||||
propTypes: {
|
||||
|
@ -138,8 +137,8 @@ loop.panel = (function(_, mozL10n) {
|
|||
'hide': !this.state.showMenu
|
||||
});
|
||||
var availabilityText = this.state.doNotDisturb ?
|
||||
__("display_name_dnd_status") :
|
||||
__("display_name_available_status");
|
||||
mozL10n.get("display_name_dnd_status") :
|
||||
mozL10n.get("display_name_available_status");
|
||||
|
||||
return (
|
||||
React.DOM.div({className: "dropdown"},
|
||||
|
@ -152,12 +151,12 @@ loop.panel = (function(_, mozL10n) {
|
|||
React.DOM.li({onClick: this.changeAvailability("available"),
|
||||
className: "dropdown-menu-item dnd-make-available"},
|
||||
React.DOM.i({className: "status status-available"}),
|
||||
React.DOM.span(null, __("display_name_available_status"))
|
||||
React.DOM.span(null, mozL10n.get("display_name_available_status"))
|
||||
),
|
||||
React.DOM.li({onClick: this.changeAvailability("do-not-disturb"),
|
||||
className: "dropdown-menu-item dnd-make-unavailable"},
|
||||
React.DOM.i({className: "status status-dnd"}),
|
||||
React.DOM.span(null, __("display_name_dnd_status"))
|
||||
React.DOM.span(null, mozL10n.get("display_name_dnd_status"))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
@ -165,6 +164,34 @@ loop.panel = (function(_, mozL10n) {
|
|||
}
|
||||
});
|
||||
|
||||
var GettingStartedView = React.createClass({displayName: 'GettingStartedView',
|
||||
componentDidMount: function() {
|
||||
navigator.mozLoop.setLoopBoolPref("gettingStarted.seen", true);
|
||||
},
|
||||
|
||||
handleButtonClick: function() {
|
||||
navigator.mozLoop.openGettingStartedTour();
|
||||
},
|
||||
|
||||
render: function() {
|
||||
if (navigator.mozLoop.getLoopBoolPref("gettingStarted.seen")) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
React.DOM.div({id: "fte-getstarted"},
|
||||
React.DOM.header({id: "fte-title"},
|
||||
mozL10n.get("first_time_experience_title", {
|
||||
"clientShortname": mozL10n.get("clientShortname2")
|
||||
})
|
||||
),
|
||||
Button({htmlId: "fte-button",
|
||||
onClick: this.handleButtonClick,
|
||||
caption: mozL10n.get("first_time_experience_button_label")})
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var ToSView = React.createClass({displayName: 'ToSView',
|
||||
getInitialState: function() {
|
||||
return {seenToS: navigator.mozLoop.getLoopCharPref('seenToS')};
|
||||
|
@ -172,23 +199,31 @@ loop.panel = (function(_, mozL10n) {
|
|||
|
||||
render: function() {
|
||||
if (this.state.seenToS == "unseen") {
|
||||
var locale = mozL10n.getLanguage();
|
||||
var terms_of_use_url = navigator.mozLoop.getLoopCharPref('legal.ToS_url');
|
||||
var privacy_notice_url = navigator.mozLoop.getLoopCharPref('legal.privacy_url');
|
||||
var tosHTML = __("legal_text_and_links3", {
|
||||
"clientShortname": __("clientShortname2"),
|
||||
var tosHTML = mozL10n.get("legal_text_and_links3", {
|
||||
"clientShortname": mozL10n.get("clientShortname2"),
|
||||
"terms_of_use": React.renderComponentToStaticMarkup(
|
||||
React.DOM.a({href: terms_of_use_url, target: "_blank"},
|
||||
__("legal_text_tos")
|
||||
mozL10n.get("legal_text_tos")
|
||||
)
|
||||
),
|
||||
"privacy_notice": React.renderComponentToStaticMarkup(
|
||||
React.DOM.a({href: privacy_notice_url, target: "_blank"},
|
||||
__("legal_text_privacy")
|
||||
mozL10n.get("legal_text_privacy")
|
||||
)
|
||||
),
|
||||
});
|
||||
return React.DOM.p({className: "terms-service",
|
||||
dangerouslySetInnerHTML: {__html: tosHTML}});
|
||||
return React.DOM.div(null,
|
||||
React.DOM.p({id: "powered-by"},
|
||||
mozL10n.get("powered_by_beforeLogo"),
|
||||
React.DOM.img({id: "powered-by-logo", className: locale}),
|
||||
mozL10n.get("powered_by_afterLogo")
|
||||
),
|
||||
React.DOM.p({className: "terms-service",
|
||||
dangerouslySetInnerHTML: {__html: tosHTML}})
|
||||
);
|
||||
} else {
|
||||
return React.DOM.div(null);
|
||||
}
|
||||
|
@ -262,20 +297,20 @@ loop.panel = (function(_, mozL10n) {
|
|||
return (
|
||||
React.DOM.div({className: "settings-menu dropdown"},
|
||||
React.DOM.a({className: "button-settings", onClick: this.showDropdownMenu,
|
||||
title: __("settings_menu_button_tooltip")}),
|
||||
title: mozL10n.get("settings_menu_button_tooltip")}),
|
||||
React.DOM.ul({className: cx({"dropdown-menu": true, hide: !this.state.showMenu}),
|
||||
onMouseLeave: this.hideDropdownMenu},
|
||||
SettingsDropdownEntry({label: __("settings_menu_item_settings"),
|
||||
SettingsDropdownEntry({label: mozL10n.get("settings_menu_item_settings"),
|
||||
onClick: this.handleClickSettingsEntry,
|
||||
displayed: false,
|
||||
icon: "settings"}),
|
||||
SettingsDropdownEntry({label: __("settings_menu_item_account"),
|
||||
SettingsDropdownEntry({label: mozL10n.get("settings_menu_item_account"),
|
||||
onClick: this.handleClickAccountEntry,
|
||||
icon: "account",
|
||||
displayed: this._isSignedIn()}),
|
||||
SettingsDropdownEntry({label: this._isSignedIn() ?
|
||||
__("settings_menu_item_signout") :
|
||||
__("settings_menu_item_signin"),
|
||||
mozL10n.get("settings_menu_item_signout") :
|
||||
mozL10n.get("settings_menu_item_signin"),
|
||||
onClick: this.handleClickAuthEntry,
|
||||
displayed: navigator.mozLoop.fxAEnabled,
|
||||
icon: this._isSignedIn() ? "signout" : "signin"})
|
||||
|
@ -407,7 +442,7 @@ loop.panel = (function(_, mozL10n) {
|
|||
var cx = React.addons.classSet;
|
||||
return (
|
||||
React.DOM.div({className: "generate-url"},
|
||||
React.DOM.header(null, __("share_link_header_text")),
|
||||
React.DOM.header({id: "share-link-header"}, mozL10n.get("share_link_header_text")),
|
||||
React.DOM.div({className: "generate-url-stack"},
|
||||
React.DOM.input({type: "url", value: this.state.callUrl, readOnly: "true",
|
||||
onCopy: this.handleLinkExfiltration,
|
||||
|
@ -451,7 +486,7 @@ loop.panel = (function(_, mozL10n) {
|
|||
return (
|
||||
React.DOM.p({className: "signin-link"},
|
||||
React.DOM.a({href: "#", onClick: this.handleSignUpLinkClick},
|
||||
__("panel_footer_signin_or_signup_link")
|
||||
mozL10n.get("panel_footer_signin_or_signup_link")
|
||||
)
|
||||
)
|
||||
);
|
||||
|
@ -709,6 +744,7 @@ loop.panel = (function(_, mozL10n) {
|
|||
return (
|
||||
Tab({name: "call"},
|
||||
React.DOM.div({className: "content-area"},
|
||||
GettingStartedView(null),
|
||||
CallUrlResult({client: this.props.client,
|
||||
notifications: this.props.notifications,
|
||||
callUrl: this.props.callUrl}),
|
||||
|
@ -720,6 +756,7 @@ loop.panel = (function(_, mozL10n) {
|
|||
|
||||
return (
|
||||
Tab({name: "rooms"},
|
||||
GettingStartedView(null),
|
||||
RoomList({dispatcher: this.props.dispatcher,
|
||||
store: this.props.roomStore,
|
||||
userDisplayName: this._getUserDisplayName()}),
|
||||
|
@ -751,7 +788,7 @@ loop.panel = (function(_, mozL10n) {
|
|||
|
||||
_getUserDisplayName: function() {
|
||||
return this.state.userProfile && this.state.userProfile.email ||
|
||||
__("display_name_guest");
|
||||
mozL10n.get("display_name_guest");
|
||||
},
|
||||
|
||||
render: function() {
|
||||
|
@ -830,15 +867,16 @@ loop.panel = (function(_, mozL10n) {
|
|||
|
||||
return {
|
||||
init: init,
|
||||
UserIdentity: UserIdentity,
|
||||
AuthLink: AuthLink,
|
||||
AvailabilityDropdown: AvailabilityDropdown,
|
||||
CallUrlResult: CallUrlResult,
|
||||
GettingStartedView: GettingStartedView,
|
||||
PanelView: PanelView,
|
||||
RoomEntry: RoomEntry,
|
||||
RoomList: RoomList,
|
||||
SettingsDropdown: SettingsDropdown,
|
||||
ToSView: ToSView
|
||||
ToSView: ToSView,
|
||||
UserIdentity: UserIdentity,
|
||||
};
|
||||
})(_, document.mozL10n);
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@ loop.panel = (function(_, mozL10n) {
|
|||
var ButtonGroup = sharedViews.ButtonGroup;
|
||||
var ContactsList = loop.contacts.ContactsList;
|
||||
var ContactDetailsForm = loop.contacts.ContactDetailsForm;
|
||||
var __ = mozL10n.get; // aliasing translation function as __ for concision
|
||||
|
||||
var TabView = React.createClass({
|
||||
propTypes: {
|
||||
|
@ -138,8 +137,8 @@ loop.panel = (function(_, mozL10n) {
|
|||
'hide': !this.state.showMenu
|
||||
});
|
||||
var availabilityText = this.state.doNotDisturb ?
|
||||
__("display_name_dnd_status") :
|
||||
__("display_name_available_status");
|
||||
mozL10n.get("display_name_dnd_status") :
|
||||
mozL10n.get("display_name_available_status");
|
||||
|
||||
return (
|
||||
<div className="dropdown">
|
||||
|
@ -152,12 +151,12 @@ loop.panel = (function(_, mozL10n) {
|
|||
<li onClick={this.changeAvailability("available")}
|
||||
className="dropdown-menu-item dnd-make-available">
|
||||
<i className="status status-available"></i>
|
||||
<span>{__("display_name_available_status")}</span>
|
||||
<span>{mozL10n.get("display_name_available_status")}</span>
|
||||
</li>
|
||||
<li onClick={this.changeAvailability("do-not-disturb")}
|
||||
className="dropdown-menu-item dnd-make-unavailable">
|
||||
<i className="status status-dnd"></i>
|
||||
<span>{__("display_name_dnd_status")}</span>
|
||||
<span>{mozL10n.get("display_name_dnd_status")}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -165,6 +164,34 @@ loop.panel = (function(_, mozL10n) {
|
|||
}
|
||||
});
|
||||
|
||||
var GettingStartedView = React.createClass({
|
||||
componentDidMount: function() {
|
||||
navigator.mozLoop.setLoopBoolPref("gettingStarted.seen", true);
|
||||
},
|
||||
|
||||
handleButtonClick: function() {
|
||||
navigator.mozLoop.openGettingStartedTour();
|
||||
},
|
||||
|
||||
render: function() {
|
||||
if (navigator.mozLoop.getLoopBoolPref("gettingStarted.seen")) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<div id="fte-getstarted">
|
||||
<header id="fte-title">
|
||||
{mozL10n.get("first_time_experience_title", {
|
||||
"clientShortname": mozL10n.get("clientShortname2")
|
||||
})}
|
||||
</header>
|
||||
<Button htmlId="fte-button"
|
||||
onClick={this.handleButtonClick}
|
||||
caption={mozL10n.get("first_time_experience_button_label")} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var ToSView = React.createClass({
|
||||
getInitialState: function() {
|
||||
return {seenToS: navigator.mozLoop.getLoopCharPref('seenToS')};
|
||||
|
@ -172,23 +199,31 @@ loop.panel = (function(_, mozL10n) {
|
|||
|
||||
render: function() {
|
||||
if (this.state.seenToS == "unseen") {
|
||||
var locale = mozL10n.getLanguage();
|
||||
var terms_of_use_url = navigator.mozLoop.getLoopCharPref('legal.ToS_url');
|
||||
var privacy_notice_url = navigator.mozLoop.getLoopCharPref('legal.privacy_url');
|
||||
var tosHTML = __("legal_text_and_links3", {
|
||||
"clientShortname": __("clientShortname2"),
|
||||
var tosHTML = mozL10n.get("legal_text_and_links3", {
|
||||
"clientShortname": mozL10n.get("clientShortname2"),
|
||||
"terms_of_use": React.renderComponentToStaticMarkup(
|
||||
<a href={terms_of_use_url} target="_blank">
|
||||
{__("legal_text_tos")}
|
||||
{mozL10n.get("legal_text_tos")}
|
||||
</a>
|
||||
),
|
||||
"privacy_notice": React.renderComponentToStaticMarkup(
|
||||
<a href={privacy_notice_url} target="_blank">
|
||||
{__("legal_text_privacy")}
|
||||
{mozL10n.get("legal_text_privacy")}
|
||||
</a>
|
||||
),
|
||||
});
|
||||
return <p className="terms-service"
|
||||
dangerouslySetInnerHTML={{__html: tosHTML}}></p>;
|
||||
return <div>
|
||||
<p id="powered-by">
|
||||
{mozL10n.get("powered_by_beforeLogo")}
|
||||
<img id="powered-by-logo" className={locale} />
|
||||
{mozL10n.get("powered_by_afterLogo")}
|
||||
</p>
|
||||
<p className="terms-service"
|
||||
dangerouslySetInnerHTML={{__html: tosHTML}}></p>
|
||||
</div>;
|
||||
} else {
|
||||
return <div />;
|
||||
}
|
||||
|
@ -262,20 +297,20 @@ loop.panel = (function(_, mozL10n) {
|
|||
return (
|
||||
<div className="settings-menu dropdown">
|
||||
<a className="button-settings" onClick={this.showDropdownMenu}
|
||||
title={__("settings_menu_button_tooltip")} />
|
||||
title={mozL10n.get("settings_menu_button_tooltip")} />
|
||||
<ul className={cx({"dropdown-menu": true, hide: !this.state.showMenu})}
|
||||
onMouseLeave={this.hideDropdownMenu}>
|
||||
<SettingsDropdownEntry label={__("settings_menu_item_settings")}
|
||||
<SettingsDropdownEntry label={mozL10n.get("settings_menu_item_settings")}
|
||||
onClick={this.handleClickSettingsEntry}
|
||||
displayed={false}
|
||||
icon="settings" />
|
||||
<SettingsDropdownEntry label={__("settings_menu_item_account")}
|
||||
<SettingsDropdownEntry label={mozL10n.get("settings_menu_item_account")}
|
||||
onClick={this.handleClickAccountEntry}
|
||||
icon="account"
|
||||
displayed={this._isSignedIn()} />
|
||||
<SettingsDropdownEntry label={this._isSignedIn() ?
|
||||
__("settings_menu_item_signout") :
|
||||
__("settings_menu_item_signin")}
|
||||
mozL10n.get("settings_menu_item_signout") :
|
||||
mozL10n.get("settings_menu_item_signin")}
|
||||
onClick={this.handleClickAuthEntry}
|
||||
displayed={navigator.mozLoop.fxAEnabled}
|
||||
icon={this._isSignedIn() ? "signout" : "signin"} />
|
||||
|
@ -407,7 +442,7 @@ loop.panel = (function(_, mozL10n) {
|
|||
var cx = React.addons.classSet;
|
||||
return (
|
||||
<div className="generate-url">
|
||||
<header>{__("share_link_header_text")}</header>
|
||||
<header id="share-link-header">{mozL10n.get("share_link_header_text")}</header>
|
||||
<div className="generate-url-stack">
|
||||
<input type="url" value={this.state.callUrl} readOnly="true"
|
||||
onCopy={this.handleLinkExfiltration}
|
||||
|
@ -451,7 +486,7 @@ loop.panel = (function(_, mozL10n) {
|
|||
return (
|
||||
<p className="signin-link">
|
||||
<a href="#" onClick={this.handleSignUpLinkClick}>
|
||||
{__("panel_footer_signin_or_signup_link")}
|
||||
{mozL10n.get("panel_footer_signin_or_signup_link")}
|
||||
</a>
|
||||
</p>
|
||||
);
|
||||
|
@ -709,6 +744,7 @@ loop.panel = (function(_, mozL10n) {
|
|||
return (
|
||||
<Tab name="call">
|
||||
<div className="content-area">
|
||||
<GettingStartedView />
|
||||
<CallUrlResult client={this.props.client}
|
||||
notifications={this.props.notifications}
|
||||
callUrl={this.props.callUrl} />
|
||||
|
@ -720,6 +756,7 @@ loop.panel = (function(_, mozL10n) {
|
|||
|
||||
return (
|
||||
<Tab name="rooms">
|
||||
<GettingStartedView />
|
||||
<RoomList dispatcher={this.props.dispatcher}
|
||||
store={this.props.roomStore}
|
||||
userDisplayName={this._getUserDisplayName()}/>
|
||||
|
@ -751,7 +788,7 @@ loop.panel = (function(_, mozL10n) {
|
|||
|
||||
_getUserDisplayName: function() {
|
||||
return this.state.userProfile && this.state.userProfile.email ||
|
||||
__("display_name_guest");
|
||||
mozL10n.get("display_name_guest");
|
||||
},
|
||||
|
||||
render: function() {
|
||||
|
@ -830,15 +867,16 @@ loop.panel = (function(_, mozL10n) {
|
|||
|
||||
return {
|
||||
init: init,
|
||||
UserIdentity: UserIdentity,
|
||||
AuthLink: AuthLink,
|
||||
AvailabilityDropdown: AvailabilityDropdown,
|
||||
CallUrlResult: CallUrlResult,
|
||||
GettingStartedView: GettingStartedView,
|
||||
PanelView: PanelView,
|
||||
RoomEntry: RoomEntry,
|
||||
RoomList: RoomList,
|
||||
SettingsDropdown: SettingsDropdown,
|
||||
ToSView: ToSView
|
||||
ToSView: ToSView,
|
||||
UserIdentity: UserIdentity,
|
||||
};
|
||||
})(_, document.mozL10n);
|
||||
|
||||
|
|
|
@ -102,10 +102,36 @@ body {
|
|||
|
||||
.content-area header {
|
||||
font-weight: 700;
|
||||
-moz-padding-start: 20px;
|
||||
}
|
||||
|
||||
.tab-view + .tab .content-area header {
|
||||
#fte-getstarted {
|
||||
padding-top: 1em;
|
||||
padding-bottom: 1em;
|
||||
border-bottom: 1px solid #ccc;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
#fte-title {
|
||||
text-align: center;
|
||||
margin-bottom: .5em;
|
||||
}
|
||||
|
||||
#fte-button {
|
||||
width: 50%;
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
font-size: 1rem;
|
||||
padding: .5rem 1rem;
|
||||
height: auto; /* Needed to override .button's height:26px; */
|
||||
}
|
||||
|
||||
/* Need to remove when these rules when the Beta tag is removed */
|
||||
#share-link-header {
|
||||
-moz-padding-start: 20px;
|
||||
}
|
||||
#fte-getstarted + .generate-url > #share-link-header,
|
||||
.tab-view + .tab .content-area > .generate-url > #share-link-header {
|
||||
/* The header shouldn't be indented if the tabs are present. */
|
||||
-moz-padding-start: 0;
|
||||
}
|
||||
|
@ -434,6 +460,7 @@ body[dir=rtl] .generate-url-spinner {
|
|||
right: auto;
|
||||
}
|
||||
|
||||
#fte-button,
|
||||
.generate-url .button {
|
||||
background-color: #0096dd;
|
||||
border-color: #0096dd;
|
||||
|
@ -446,13 +473,73 @@ body[dir=rtl] .generate-url-spinner {
|
|||
color: #fff;
|
||||
}
|
||||
|
||||
#powered-by,
|
||||
.terms-service {
|
||||
color: #888;
|
||||
text-align: center;
|
||||
font-size: .9em;
|
||||
}
|
||||
|
||||
.terms-service a {
|
||||
#powered-by {
|
||||
border-top: 1px solid #ccc;
|
||||
padding-top: 1em;
|
||||
margin-left: -14px;
|
||||
margin-right: -14px;
|
||||
}
|
||||
|
||||
#powered-by-logo {
|
||||
display: inline-block;
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
vertical-align: middle;
|
||||
background-image: url("../img/telefonica.png");
|
||||
background-size: 72px 20px;
|
||||
width: 72px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
#powered-by-logo.en-GB,
|
||||
#powered-by-logo.de-DE {
|
||||
background-image: url("../img/02.png");
|
||||
background-size: 21px 20px;
|
||||
width: 21px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
#powered-by-logo.pt-BR {
|
||||
background-image: url("../img/vivo.png");
|
||||
background-size: 53px 26px;
|
||||
width: 53px;
|
||||
height: 26px;
|
||||
}
|
||||
|
||||
#powered-by-logo[class^="es-"] {
|
||||
background-image: url("../img/movistar.png");
|
||||
background-size: 92px 20px;
|
||||
width: 92px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
@media (min-resolution: 2dppx) {
|
||||
#powered-by-logo {
|
||||
background-image: url("../img/telefonica@2x.png");
|
||||
}
|
||||
|
||||
#powered-by-logo.en-GB,
|
||||
#powered-by-logo.de-DE {
|
||||
background-image: url("../img/02@2x.png");
|
||||
}
|
||||
|
||||
#powered-by-logo.pt-BR {
|
||||
background-image: url("../img/vivo@2x.png");
|
||||
}
|
||||
|
||||
#powered-by-logo[class^="es-"] {
|
||||
background-image: url("../img/movistar@2x.png");
|
||||
}
|
||||
}
|
||||
|
||||
.terms-service > a {
|
||||
color: #00caee;
|
||||
}
|
||||
|
||||
|
|
После Ширина: | Высота: | Размер: 2.3 KiB |
После Ширина: | Высота: | Размер: 4.6 KiB |
После Ширина: | Высота: | Размер: 5.5 KiB |
После Ширина: | Высота: | Размер: 14 KiB |
После Ширина: | Высота: | Размер: 19 KiB |
После Ширина: | Высота: | Размер: 4.9 KiB |
После Ширина: | Высота: | Размер: 18 KiB |
После Ширина: | Высота: | Размер: 22 KiB |
|
@ -718,12 +718,14 @@ loop.shared.views = (function(_, OT, l10n) {
|
|||
onClick: React.PropTypes.func.isRequired,
|
||||
disabled: React.PropTypes.bool,
|
||||
additionalClass: React.PropTypes.string,
|
||||
htmlId: React.PropTypes.string,
|
||||
},
|
||||
|
||||
getDefaultProps: function() {
|
||||
return {
|
||||
disabled: false,
|
||||
additionalClass: "",
|
||||
htmlId: "",
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -736,6 +738,7 @@ loop.shared.views = (function(_, OT, l10n) {
|
|||
return (
|
||||
React.DOM.button({onClick: this.props.onClick,
|
||||
disabled: this.props.disabled,
|
||||
id: this.props.htmlId,
|
||||
className: cx(classObject)},
|
||||
React.DOM.span({className: "button-caption"}, this.props.caption),
|
||||
this.props.children
|
||||
|
|
|
@ -718,12 +718,14 @@ loop.shared.views = (function(_, OT, l10n) {
|
|||
onClick: React.PropTypes.func.isRequired,
|
||||
disabled: React.PropTypes.bool,
|
||||
additionalClass: React.PropTypes.string,
|
||||
htmlId: React.PropTypes.string,
|
||||
},
|
||||
|
||||
getDefaultProps: function() {
|
||||
return {
|
||||
disabled: false,
|
||||
additionalClass: "",
|
||||
htmlId: "",
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -736,6 +738,7 @@ loop.shared.views = (function(_, OT, l10n) {
|
|||
return (
|
||||
<button onClick={this.props.onClick}
|
||||
disabled={this.props.disabled}
|
||||
id={this.props.htmlId}
|
||||
className={cx(classObject)}>
|
||||
<span className="button-caption">{this.props.caption}</span>
|
||||
{this.props.children}
|
||||
|
|
|
@ -55,6 +55,14 @@ browser.jar:
|
|||
content/browser/loop/shared/img/icons-10x10.svg (content/shared/img/icons-10x10.svg)
|
||||
content/browser/loop/shared/img/icons-14x14.svg (content/shared/img/icons-14x14.svg)
|
||||
content/browser/loop/shared/img/icons-16x16.svg (content/shared/img/icons-16x16.svg)
|
||||
content/browser/loop/shared/img/movistar.png (content/shared/img/movistar.png)
|
||||
content/browser/loop/shared/img/movistar@2x.png (content/shared/img/movistar@2x.png)
|
||||
content/browser/loop/shared/img/vivo.png (content/shared/img/vivo.png)
|
||||
content/browser/loop/shared/img/vivo@2x.png (content/shared/img/vivo@2x.png)
|
||||
content/browser/loop/shared/img/02.png (content/shared/img/02.png)
|
||||
content/browser/loop/shared/img/02@2x.png (content/shared/img/02@2x.png)
|
||||
content/browser/loop/shared/img/telefonica.png (content/shared/img/telefonica.png)
|
||||
content/browser/loop/shared/img/telefonica@2x.png (content/shared/img/telefonica@2x.png)
|
||||
|
||||
# Shared scripts
|
||||
content/browser/loop/shared/js/actions.js (content/shared/js/actions.js)
|
||||
|
|
|
@ -34,9 +34,10 @@ describe("loop.panel", function() {
|
|||
get locale() {
|
||||
return "en-US";
|
||||
},
|
||||
getLoopBoolPref: sandbox.stub(),
|
||||
setLoopCharPref: sandbox.stub(),
|
||||
getLoopCharPref: sandbox.stub().returns("unseen"),
|
||||
getLoopBoolPref: sandbox.stub(),
|
||||
setLoopBoolPref: sandbox.stub(),
|
||||
getPluralForm: function() {
|
||||
return "fakeText";
|
||||
},
|
||||
|
@ -361,6 +362,37 @@ describe("loop.panel", function() {
|
|||
|
||||
TestUtils.findRenderedComponentWithType(view, loop.panel.ToSView);
|
||||
});
|
||||
|
||||
it("should not render a ToSView when the view has been 'seen'", function() {
|
||||
navigator.mozLoop.getLoopCharPref = function() {
|
||||
return "seen";
|
||||
};
|
||||
var view = createTestPanelView();
|
||||
|
||||
try {
|
||||
TestUtils.findRenderedComponentWithType(view, loop.panel.ToSView);
|
||||
sinon.assert.fail("Should not find the ToSView if it has been 'seen'");
|
||||
} catch (ex) {}
|
||||
});
|
||||
|
||||
it("should render a GettingStarted view", function() {
|
||||
var view = createTestPanelView();
|
||||
|
||||
TestUtils.findRenderedComponentWithType(view, loop.panel.GettingStartedView);
|
||||
});
|
||||
|
||||
it("should not render a GettingStartedView when the view has been seen", function() {
|
||||
navigator.mozLoop.getLoopBoolPref = function() {
|
||||
return true;
|
||||
};
|
||||
var view = createTestPanelView();
|
||||
|
||||
try {
|
||||
TestUtils.findRenderedComponentWithType(view, loop.panel.GettingStartedView);
|
||||
sinon.assert.fail("Should not find the GettingStartedView if it has been seen");
|
||||
} catch (ex) {}
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -187,8 +187,10 @@ let SessionHistoryInternal = {
|
|||
|
||||
// We will include the property only if it's truthy to save a couple of
|
||||
// bytes when the resulting object is stringified and saved to disk.
|
||||
if (shEntry.referrerURI)
|
||||
if (shEntry.referrerURI) {
|
||||
entry.referrer = shEntry.referrerURI.spec;
|
||||
entry.referrerPolicy = shEntry.referrerPolicy;
|
||||
}
|
||||
|
||||
if (shEntry.srcdocData)
|
||||
entry.srcdocData = shEntry.srcdocData;
|
||||
|
@ -340,8 +342,10 @@ let SessionHistoryInternal = {
|
|||
shEntry.loadType = Ci.nsIDocShellLoadInfo.loadHistory;
|
||||
if (entry.contentType)
|
||||
shEntry.contentType = entry.contentType;
|
||||
if (entry.referrer)
|
||||
if (entry.referrer) {
|
||||
shEntry.referrerURI = Utils.makeURI(entry.referrer);
|
||||
shEntry.referrerPolicy = entry.referrerPolicy;
|
||||
}
|
||||
if (entry.isSrcdocEntry)
|
||||
shEntry.srcdocData = entry.srcdocData;
|
||||
if (entry.baseURI)
|
||||
|
|
|
@ -82,7 +82,7 @@ addEventListener("MozStorageChanged", function () {
|
|||
// content-sessionStore.js. We run ours a little later to make sure
|
||||
// that the session store code has seen the event before we allow
|
||||
// the test to proceed.
|
||||
executeSoon(() => sendSyncMessage("ss-test:MozStorageChanged"));
|
||||
executeSoon(() => sendAsyncMessage("ss-test:MozStorageChanged"));
|
||||
}, true);
|
||||
|
||||
addMessageListener("ss-test:modifySessionStorage", function (msg) {
|
||||
|
|
|
@ -205,7 +205,9 @@ nsMacShellService::SetDesktopBackground(nsIDOMElement* aElement,
|
|||
loadContext = do_QueryInterface(docShell);
|
||||
}
|
||||
|
||||
return wbp->SaveURI(imageURI, nullptr, docURI, nullptr, nullptr,
|
||||
return wbp->SaveURI(imageURI, nullptr,
|
||||
docURI, content->OwnerDoc()->GetReferrerPolicy(),
|
||||
nullptr, nullptr,
|
||||
mBackgroundFile, loadContext);
|
||||
}
|
||||
|
||||
|
|
|
@ -120,6 +120,13 @@ BINPATH = bin
|
|||
endif
|
||||
DEFINES += -DBINPATH=$(BINPATH)
|
||||
|
||||
ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
|
||||
RESPATH = $(_APPNAME)/Contents/Resources
|
||||
else
|
||||
RESPATH = $(BINPATH)
|
||||
endif
|
||||
DEFINES += -DRESPATH=$(RESPATH)
|
||||
|
||||
AB = $(firstword $(subst -, ,$(AB_CD)))
|
||||
DEFINES += -DAB=$(AB)
|
||||
|
||||
|
|
|
@ -31,6 +31,6 @@ externalProtocolChkMsg=Remember my choice for all links of this type.
|
|||
externalProtocolLaunchBtn=Launch application
|
||||
malwareBlocked=The site at %S has been reported as an attack site and has been blocked based on your security preferences.
|
||||
phishingBlocked=The website at %S has been reported as a web forgery designed to trick users into sharing personal or financial information.
|
||||
cspFrameAncestorBlocked=This page has a content security policy that prevents it from being embedded in this way.
|
||||
cspBlocked=This page has a content security policy that prevents it from being loaded in this way.
|
||||
corruptedContentError=The page you are trying to view cannot be shown because an error in the data transmission was detected.
|
||||
remoteXUL=This page uses an unsupported technology that is no longer available by default in Firefox.
|
||||
|
|
|
@ -170,8 +170,8 @@ be temporary, and you can try again later.</li>
|
|||
<p>These types of web forgeries are used in scams known as phishing attacks, in which fraudulent web pages and emails are used to imitate sources you may trust.</p>
|
||||
">
|
||||
|
||||
<!ENTITY cspFrameAncestorBlocked.title "Blocked by Content Security Policy">
|
||||
<!ENTITY cspFrameAncestorBlocked.longDesc "<p>&brandShortName; prevented this page from loading in this way because the page has a content security policy that disallows it.</p>">
|
||||
<!ENTITY cspBlocked.title "Blocked by Content Security Policy">
|
||||
<!ENTITY cspBlocked.longDesc "<p>&brandShortName; prevented this page from loading in this way because the page has a content security policy that disallows it.</p>">
|
||||
|
||||
<!ENTITY corruptedContentError.title "Corrupted Content Error">
|
||||
<!ENTITY corruptedContentError.longDesc "<p>The page you are trying to view cannot be shown because an error in the data transmission was detected.</p><ul><li>Please contact the website owners to inform them of this problem.</li></ul>">
|
||||
|
|
|
@ -156,8 +156,8 @@
|
|||
document.getElementById("errorTryAgain").style.display = "none";
|
||||
}
|
||||
|
||||
if (err == "cspFrameAncestorBlocked") {
|
||||
// Remove the "Try again" button for CSP frame ancestors violation, since it's
|
||||
if (err == "cspBlocked") {
|
||||
// Remove the "Try again" button for CSP violations, since it's
|
||||
// almost certainly useless. (Bug 553180)
|
||||
document.getElementById("errorTryAgain").style.display = "none";
|
||||
}
|
||||
|
@ -291,7 +291,7 @@
|
|||
<h1 id="et_unsafeContentType">&unsafeContentType.title;</h1>
|
||||
<h1 id="et_nssFailure2">&nssFailure2.title;</h1>
|
||||
<h1 id="et_nssBadCert">&nssBadCert.title;</h1>
|
||||
<h1 id="et_cspFrameAncestorBlocked">&cspFrameAncestorBlocked.title;</h1>
|
||||
<h1 id="et_cspBlocked">&cspBlocked.title;</h1>
|
||||
<h1 id="et_remoteXUL">&remoteXUL.title;</h1>
|
||||
<h1 id="et_corruptedContentError">&corruptedContentError.title;</h1>
|
||||
</div>
|
||||
|
@ -316,7 +316,7 @@
|
|||
<div id="ed_unsafeContentType">&unsafeContentType.longDesc;</div>
|
||||
<div id="ed_nssFailure2">&nssFailure2.longDesc2;</div>
|
||||
<div id="ed_nssBadCert">&nssBadCert.longDesc2;</div>
|
||||
<div id="ed_cspFrameAncestorBlocked">&cspFrameAncestorBlocked.longDesc;</div>
|
||||
<div id="ed_cspBlocked">&cspBlocked.longDesc;</div>
|
||||
<div id="ed_remoteXUL">&remoteXUL.longDesc;</div>
|
||||
<div id="ed_corruptedContentError">&corruptedContentError.longDesc;</div>
|
||||
</div>
|
||||
|
|
|
@ -806,7 +806,7 @@ SessionStore.prototype = {
|
|||
|
||||
let persist = Cc["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"].createInstance(Ci.nsIWebBrowserPersist);
|
||||
persist.persistFlags = Ci.nsIWebBrowserPersist.PERSIST_FLAGS_REPLACE_EXISTING_FILES | Ci.nsIWebBrowserPersist.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION;
|
||||
persist.saveURI(source, null, null, null, null, file);
|
||||
persist.saveURI(source, null, null, 0, null, null, file);
|
||||
|
||||
aStringValue = target.spec;
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "nsDocShellCID.h"
|
||||
#include "nsDOMCID.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "mozilla/net/ReferrerPolicy.h"
|
||||
#include "nsRect.h"
|
||||
#include "prenv.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
|
@ -554,6 +555,7 @@ struct SendPingInfo {
|
|||
bool requireSameHost;
|
||||
nsIURI *target;
|
||||
nsIURI *referrer;
|
||||
uint32_t referrerPolicy;
|
||||
};
|
||||
|
||||
static void
|
||||
|
@ -633,7 +635,7 @@ SendPing(void *closure, nsIContent *content, nsIURI *uri, nsIIOService *ios)
|
|||
// over an encrypted connection and its address does not have the same
|
||||
// origin as "ping URL", send a referrer.
|
||||
if (!sameOrigin && !referrerIsSecure)
|
||||
httpChan->SetReferrer(info->referrer);
|
||||
httpChan->SetReferrerWithPolicy(info->referrer, info->referrerPolicy);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIUploadChannel2> uploadChan = do_QueryInterface(httpChan);
|
||||
|
@ -691,7 +693,10 @@ SendPing(void *closure, nsIContent *content, nsIURI *uri, nsIIOService *ios)
|
|||
|
||||
// Spec: http://whatwg.org/specs/web-apps/current-work/#ping
|
||||
static void
|
||||
DispatchPings(nsIContent *content, nsIURI *target, nsIURI *referrer)
|
||||
DispatchPings(nsIContent *content,
|
||||
nsIURI *target,
|
||||
nsIURI *referrer,
|
||||
uint32_t referrerPolicy)
|
||||
{
|
||||
SendPingInfo info;
|
||||
|
||||
|
@ -703,6 +708,7 @@ DispatchPings(nsIContent *content, nsIURI *target, nsIURI *referrer)
|
|||
info.numPings = 0;
|
||||
info.target = target;
|
||||
info.referrer = referrer;
|
||||
info.referrerPolicy = referrerPolicy;
|
||||
|
||||
ForEachPing(content, SendPing, &info);
|
||||
}
|
||||
|
@ -1346,6 +1352,7 @@ nsDocShell::LoadURI(nsIURI * aURI,
|
|||
bool inheritOwner = false;
|
||||
bool ownerIsExplicit = false;
|
||||
bool sendReferrer = true;
|
||||
uint32_t referrerPolicy = mozilla::net::RP_Default;
|
||||
bool isSrcdoc = false;
|
||||
nsCOMPtr<nsISHEntry> shEntry;
|
||||
nsXPIDLString target;
|
||||
|
@ -1379,6 +1386,7 @@ nsDocShell::LoadURI(nsIURI * aURI,
|
|||
aLoadInfo->GetPostDataStream(getter_AddRefs(postStream));
|
||||
aLoadInfo->GetHeadersStream(getter_AddRefs(headersStream));
|
||||
aLoadInfo->GetSendReferrer(&sendReferrer);
|
||||
aLoadInfo->GetReferrerPolicy(&referrerPolicy);
|
||||
aLoadInfo->GetIsSrcdocLoad(&isSrcdoc);
|
||||
aLoadInfo->GetSrcdocData(srcdoc);
|
||||
aLoadInfo->GetSourceDocShell(getter_AddRefs(sourceDocShell));
|
||||
|
@ -1602,6 +1610,7 @@ nsDocShell::LoadURI(nsIURI * aURI,
|
|||
|
||||
return InternalLoad(aURI,
|
||||
referrer,
|
||||
referrerPolicy,
|
||||
owner,
|
||||
flags,
|
||||
target.get(),
|
||||
|
@ -4865,10 +4874,11 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI *aURI,
|
|||
formatStrCount = 1;
|
||||
error.AssignLiteral("netTimeout");
|
||||
}
|
||||
else if (NS_ERROR_CSP_FRAME_ANCESTOR_VIOLATION == aError) {
|
||||
else if (NS_ERROR_CSP_FRAME_ANCESTOR_VIOLATION == aError ||
|
||||
NS_ERROR_CSP_FORM_ACTION_VIOLATION == aError) {
|
||||
// CSP error
|
||||
cssClass.AssignLiteral("neterror");
|
||||
error.AssignLiteral("cspFrameAncestorBlocked");
|
||||
error.AssignLiteral("cspBlocked");
|
||||
}
|
||||
else if (NS_ERROR_GET_MODULE(aError) == NS_ERROR_MODULE_SECURITY) {
|
||||
nsCOMPtr<nsINSSErrorsService> nsserr =
|
||||
|
@ -5264,8 +5274,8 @@ nsDocShell::LoadErrorPage(nsIURI *aURI, const char16_t *aURL,
|
|||
rv = NS_NewURI(getter_AddRefs(errorPageURI), errorPageUrl);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return InternalLoad(errorPageURI, nullptr, nullptr,
|
||||
INTERNAL_LOAD_FLAGS_INHERIT_OWNER, nullptr, nullptr,
|
||||
return InternalLoad(errorPageURI, nullptr, mozilla::net::RP_Default,
|
||||
nullptr, INTERNAL_LOAD_FLAGS_INHERIT_OWNER, nullptr, nullptr,
|
||||
NullString(), nullptr, nullptr, LOAD_ERROR_PAGE,
|
||||
nullptr, true, NullString(), this, nullptr, nullptr,
|
||||
nullptr);
|
||||
|
@ -5327,6 +5337,7 @@ nsDocShell::Reload(uint32_t aReloadFlags)
|
|||
}
|
||||
rv = InternalLoad(mCurrentURI,
|
||||
mReferrerURI,
|
||||
mReferrerPolicy,
|
||||
principal,
|
||||
flags,
|
||||
nullptr, // No window target
|
||||
|
@ -9229,7 +9240,8 @@ void CopyFavicon(nsIURI *aOldURI, nsIURI *aNewURI, bool inPrivateBrowsing)
|
|||
class InternalLoadEvent : public nsRunnable
|
||||
{
|
||||
public:
|
||||
InternalLoadEvent(nsDocShell* aDocShell, nsIURI * aURI, nsIURI * aReferrer,
|
||||
InternalLoadEvent(nsDocShell* aDocShell, nsIURI * aURI,
|
||||
nsIURI * aReferrer, uint32_t aReferrerPolicy,
|
||||
nsISupports * aOwner, uint32_t aFlags,
|
||||
const char* aTypeHint, nsIInputStream * aPostData,
|
||||
nsIInputStream * aHeadersData, uint32_t aLoadType,
|
||||
|
@ -9240,6 +9252,7 @@ public:
|
|||
mDocShell(aDocShell),
|
||||
mURI(aURI),
|
||||
mReferrer(aReferrer),
|
||||
mReferrerPolicy(aReferrerPolicy),
|
||||
mOwner(aOwner),
|
||||
mPostData(aPostData),
|
||||
mHeadersData(aHeadersData),
|
||||
|
@ -9257,7 +9270,9 @@ public:
|
|||
}
|
||||
|
||||
NS_IMETHOD Run() {
|
||||
return mDocShell->InternalLoad(mURI, mReferrer, mOwner, mFlags,
|
||||
return mDocShell->InternalLoad(mURI, mReferrer,
|
||||
mReferrerPolicy,
|
||||
mOwner, mFlags,
|
||||
nullptr, mTypeHint.get(),
|
||||
NullString(), mPostData, mHeadersData,
|
||||
mLoadType, mSHEntry, mFirstParty,
|
||||
|
@ -9275,6 +9290,7 @@ private:
|
|||
nsRefPtr<nsDocShell> mDocShell;
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
nsCOMPtr<nsIURI> mReferrer;
|
||||
uint32_t mReferrerPolicy;
|
||||
nsCOMPtr<nsISupports> mOwner;
|
||||
nsCOMPtr<nsIInputStream> mPostData;
|
||||
nsCOMPtr<nsIInputStream> mHeadersData;
|
||||
|
@ -9329,6 +9345,7 @@ nsDocShell::CreatePrincipalFromReferrer(nsIURI* aReferrer,
|
|||
NS_IMETHODIMP
|
||||
nsDocShell::InternalLoad(nsIURI * aURI,
|
||||
nsIURI * aReferrer,
|
||||
uint32_t aReferrerPolicy,
|
||||
nsISupports * aOwner,
|
||||
uint32_t aFlags,
|
||||
const char16_t *aWindowTarget,
|
||||
|
@ -9585,6 +9602,7 @@ nsDocShell::InternalLoad(nsIURI * aURI,
|
|||
if (NS_SUCCEEDED(rv) && targetDocShell) {
|
||||
rv = targetDocShell->InternalLoad(aURI,
|
||||
aReferrer,
|
||||
aReferrerPolicy,
|
||||
owner,
|
||||
aFlags,
|
||||
nullptr, // No window target
|
||||
|
@ -9665,7 +9683,8 @@ nsDocShell::InternalLoad(nsIURI * aURI,
|
|||
|
||||
// Do this asynchronously
|
||||
nsCOMPtr<nsIRunnable> ev =
|
||||
new InternalLoadEvent(this, aURI, aReferrer, aOwner, aFlags,
|
||||
new InternalLoadEvent(this, aURI, aReferrer,
|
||||
aReferrerPolicy, aOwner, aFlags,
|
||||
aTypeHint, aPostData, aHeadersData,
|
||||
aLoadType, aSHEntry, aFirstParty, aSrcdoc,
|
||||
aSourceDocShell, aBaseURI);
|
||||
|
@ -10117,6 +10136,7 @@ nsDocShell::InternalLoad(nsIURI * aURI,
|
|||
nsCOMPtr<nsIRequest> req;
|
||||
rv = DoURILoad(aURI, aReferrer,
|
||||
!(aFlags & INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER),
|
||||
aReferrerPolicy,
|
||||
owner, aTypeHint, aFileName, aPostData, aHeadersData,
|
||||
aFirstParty, aDocShell, getter_AddRefs(req),
|
||||
(aFlags & INTERNAL_LOAD_FLAGS_FIRST_LOAD) != 0,
|
||||
|
@ -10190,6 +10210,7 @@ nsresult
|
|||
nsDocShell::DoURILoad(nsIURI * aURI,
|
||||
nsIURI * aReferrerURI,
|
||||
bool aSendReferrer,
|
||||
uint32_t aReferrerPolicy,
|
||||
nsISupports * aOwner,
|
||||
const char * aTypeHint,
|
||||
const nsAString & aFileName,
|
||||
|
@ -10519,7 +10540,7 @@ nsDocShell::DoURILoad(nsIURI * aURI,
|
|||
// Set the referrer explicitly
|
||||
if (aReferrerURI && aSendReferrer) {
|
||||
// Referrer is currenly only set for link clicks here.
|
||||
httpChannel->SetReferrer(aReferrerURI);
|
||||
httpChannel->SetReferrerWithPolicy(aReferrerURI, aReferrerPolicy);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10855,6 +10876,11 @@ nsDocShell::SetupReferrerFromChannel(nsIChannel * aChannel)
|
|||
if (NS_SUCCEEDED(rv)) {
|
||||
SetReferrerURI(referrer);
|
||||
}
|
||||
uint32_t referrerPolicy;
|
||||
rv = httpChannel->GetReferrerPolicy(&referrerPolicy);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
SetReferrerPolicy(referrerPolicy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11122,6 +11148,12 @@ nsDocShell::SetReferrerURI(nsIURI * aURI)
|
|||
mReferrerURI = aURI; // This assigment addrefs
|
||||
}
|
||||
|
||||
void
|
||||
nsDocShell::SetReferrerPolicy(uint32_t referrerPolicy)
|
||||
{
|
||||
mReferrerPolicy = referrerPolicy;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// nsDocShell: Session History
|
||||
//*****************************************************************************
|
||||
|
@ -11551,6 +11583,7 @@ nsDocShell::AddToSessionHistory(nsIURI * aURI, nsIChannel * aChannel,
|
|||
// Get the post data & referrer
|
||||
nsCOMPtr<nsIInputStream> inputStream;
|
||||
nsCOMPtr<nsIURI> referrerURI;
|
||||
uint32_t referrerPolicy = mozilla::net::RP_Default;
|
||||
nsCOMPtr<nsISupports> cacheKey;
|
||||
nsCOMPtr<nsISupports> owner = aOwner;
|
||||
bool expired = false;
|
||||
|
@ -11577,6 +11610,7 @@ nsDocShell::AddToSessionHistory(nsIURI * aURI, nsIChannel * aChannel,
|
|||
uploadChannel->GetUploadStream(getter_AddRefs(inputStream));
|
||||
}
|
||||
httpChannel->GetReferrer(getter_AddRefs(referrerURI));
|
||||
httpChannel->GetReferrerPolicy(&referrerPolicy);
|
||||
|
||||
discardLayoutState = ShouldDiscardLayoutState(httpChannel);
|
||||
}
|
||||
|
@ -11607,6 +11641,7 @@ nsDocShell::AddToSessionHistory(nsIURI * aURI, nsIChannel * aChannel,
|
|||
mHistoryID,
|
||||
mDynamicallyCreated);
|
||||
entry->SetReferrerURI(referrerURI);
|
||||
entry->SetReferrerPolicy(referrerPolicy);
|
||||
nsCOMPtr<nsIInputStreamChannel> inStrmChan = do_QueryInterface(aChannel);
|
||||
if (inStrmChan) {
|
||||
bool isSrcdocChannel;
|
||||
|
@ -11706,6 +11741,7 @@ nsDocShell::LoadHistoryEntry(nsISHEntry * aEntry, uint32_t aLoadType)
|
|||
nsCOMPtr<nsIURI> uri;
|
||||
nsCOMPtr<nsIInputStream> postData;
|
||||
nsCOMPtr<nsIURI> referrerURI;
|
||||
uint32_t referrerPolicy;
|
||||
nsAutoCString contentType;
|
||||
nsCOMPtr<nsISupports> owner;
|
||||
|
||||
|
@ -11714,6 +11750,8 @@ nsDocShell::LoadHistoryEntry(nsISHEntry * aEntry, uint32_t aLoadType)
|
|||
NS_ENSURE_SUCCESS(aEntry->GetURI(getter_AddRefs(uri)), NS_ERROR_FAILURE);
|
||||
NS_ENSURE_SUCCESS(aEntry->GetReferrerURI(getter_AddRefs(referrerURI)),
|
||||
NS_ERROR_FAILURE);
|
||||
NS_ENSURE_SUCCESS(aEntry->GetReferrerPolicy(&referrerPolicy),
|
||||
NS_ERROR_FAILURE);
|
||||
NS_ENSURE_SUCCESS(aEntry->GetPostData(getter_AddRefs(postData)),
|
||||
NS_ERROR_FAILURE);
|
||||
NS_ENSURE_SUCCESS(aEntry->GetContentType(contentType), NS_ERROR_FAILURE);
|
||||
|
@ -11790,6 +11828,7 @@ nsDocShell::LoadHistoryEntry(nsISHEntry * aEntry, uint32_t aLoadType)
|
|||
// first created. bug 947716 has been created to address this issue.
|
||||
rv = InternalLoad(uri,
|
||||
referrerURI,
|
||||
referrerPolicy,
|
||||
owner,
|
||||
flags,
|
||||
nullptr, // No window target
|
||||
|
@ -13191,6 +13230,7 @@ nsDocShell::OnLinkClickSync(nsIContent *aContent,
|
|||
}
|
||||
|
||||
nsCOMPtr<nsIURI> referer = refererDoc->GetDocumentURI();
|
||||
uint32_t refererPolicy = refererDoc->GetReferrerPolicy();
|
||||
|
||||
// referer could be null here in some odd cases, but that's ok,
|
||||
// we'll just load the link w/o sending a referer in those cases.
|
||||
|
@ -13219,6 +13259,7 @@ nsDocShell::OnLinkClickSync(nsIContent *aContent,
|
|||
|
||||
nsresult rv = InternalLoad(clonedURI, // New URI
|
||||
referer, // Referer URI
|
||||
refererPolicy, // Referer policy
|
||||
aContent->NodePrincipal(), // Owner is our node's
|
||||
// principal
|
||||
flags,
|
||||
|
@ -13236,7 +13277,7 @@ nsDocShell::OnLinkClickSync(nsIContent *aContent,
|
|||
aDocShell, // DocShell out-param
|
||||
aRequest); // Request out-param
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
DispatchPings(aContent, aURI, referer);
|
||||
DispatchPings(aContent, aURI, referer, refererPolicy);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -310,6 +310,7 @@ protected:
|
|||
virtual nsresult DoURILoad(nsIURI * aURI,
|
||||
nsIURI * aReferrer,
|
||||
bool aSendReferrer,
|
||||
uint32_t aReferrerPolicy,
|
||||
nsISupports * aOwner,
|
||||
const char * aTypeHint,
|
||||
const nsAString & aFileName,
|
||||
|
@ -358,6 +359,7 @@ protected:
|
|||
bool aCloneSHChildren);
|
||||
|
||||
virtual void SetReferrerURI(nsIURI * aURI);
|
||||
virtual void SetReferrerPolicy(uint32_t referrerPolicy);
|
||||
|
||||
// Session History
|
||||
virtual bool ShouldAddToSessionHistory(nsIURI * aURI);
|
||||
|
@ -752,6 +754,7 @@ protected:
|
|||
// mCurrentURI should be marked immutable on set if possible.
|
||||
nsCOMPtr<nsIURI> mCurrentURI;
|
||||
nsCOMPtr<nsIURI> mReferrerURI;
|
||||
uint32_t mReferrerPolicy;
|
||||
nsRefPtr<nsGlobalWindow> mScriptGlobal;
|
||||
nsCOMPtr<nsISHistory> mSessionHistory;
|
||||
nsCOMPtr<nsIGlobalHistory2> mGlobalHistory;
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "nsIInputStream.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "mozilla/net/ReferrerPolicy.h"
|
||||
|
||||
//*****************************************************************************
|
||||
//*** nsDocShellLoadInfo: Object Management
|
||||
|
@ -19,6 +20,7 @@ nsDocShellLoadInfo::nsDocShellLoadInfo()
|
|||
: mInheritOwner(false),
|
||||
mOwnerIsExplicit(false),
|
||||
mSendReferrer(true),
|
||||
mReferrerPolicy(mozilla::net::RP_Default),
|
||||
mLoadType(nsIDocShellLoadInfo::loadNormal),
|
||||
mIsSrcdocLoad(false)
|
||||
{
|
||||
|
@ -192,6 +194,18 @@ NS_IMETHODIMP nsDocShellLoadInfo::SetSendReferrer(bool aSendReferrer)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDocShellLoadInfo::GetReferrerPolicy(nsDocShellInfoReferrerPolicy* aReferrerPolicy)
|
||||
{
|
||||
*aReferrerPolicy = mReferrerPolicy;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDocShellLoadInfo::SetReferrerPolicy(nsDocShellInfoReferrerPolicy aReferrerPolicy)
|
||||
{
|
||||
mReferrerPolicy = aReferrerPolicy;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDocShellLoadInfo::GetIsSrcdocLoad(bool* aIsSrcdocLoad)
|
||||
{
|
||||
*aIsSrcdocLoad = mIsSrcdocLoad;
|
||||
|
|
|
@ -37,6 +37,7 @@ protected:
|
|||
bool mInheritOwner;
|
||||
bool mOwnerIsExplicit;
|
||||
bool mSendReferrer;
|
||||
nsDocShellInfoReferrerPolicy mReferrerPolicy;
|
||||
nsDocShellInfoLoadType mLoadType;
|
||||
nsCOMPtr<nsISHEntry> mSHEntry;
|
||||
nsString mTarget;
|
||||
|
|
|
@ -54,7 +54,7 @@ interface nsITabParent;
|
|||
|
||||
typedef unsigned long nsLoadFlags;
|
||||
|
||||
[scriptable, builtinclass, uuid(4e3de242-0b2a-4cf0-81b5-a5fe8628431c)]
|
||||
[scriptable, builtinclass, uuid(c2756385-bc54-417b-9ae4-c5a40053a2a3)]
|
||||
interface nsIDocShell : nsIDocShellTreeItem
|
||||
{
|
||||
/**
|
||||
|
@ -132,6 +132,7 @@ interface nsIDocShell : nsIDocShellTreeItem
|
|||
*
|
||||
* @param aURI - The URI to load.
|
||||
* @param aReferrer - Referring URI
|
||||
* @param aReferrerPolicy - Referrer policy
|
||||
* @param aOwner - Owner (security principal)
|
||||
* @param aInheritOwner - Flag indicating whether the owner of the current
|
||||
* document should be inherited if aOwner is null.
|
||||
|
@ -157,6 +158,7 @@ interface nsIDocShell : nsIDocShellTreeItem
|
|||
*/
|
||||
[noscript]void internalLoad(in nsIURI aURI,
|
||||
in nsIURI aReferrer,
|
||||
in unsigned long aReferrerPolicy,
|
||||
in nsISupports aOwner,
|
||||
in uint32_t aFlags,
|
||||
in wstring aWindowTarget,
|
||||
|
|
|
@ -17,8 +17,9 @@ interface nsISHEntry;
|
|||
interface nsIDocShell;
|
||||
|
||||
typedef long nsDocShellInfoLoadType;
|
||||
typedef unsigned long nsDocShellInfoReferrerPolicy;
|
||||
|
||||
[scriptable, uuid(c8d3b1e1-565a-427e-9d68-b109910ce9b7)]
|
||||
[scriptable, uuid(c63e9d64-490d-48bf-8013-b5d8ee4dbc25)]
|
||||
interface nsIDocShellLoadInfo : nsISupports
|
||||
{
|
||||
/** This is the referrer for the load. */
|
||||
|
@ -85,6 +86,11 @@ interface nsIDocShellLoadInfo : nsISupports
|
|||
*/
|
||||
attribute boolean sendReferrer;
|
||||
|
||||
/** Referrer policy for the load. This attribute holds one of
|
||||
* the values (REFERRER_POLICY_*) defined in nsIHttpChannel.
|
||||
*/
|
||||
attribute nsDocShellInfoReferrerPolicy referrerPolicy;
|
||||
|
||||
/** True if the docshell has been created to load an iframe where the
|
||||
* srcdoc attribute has been set. Set when srcdocData is specified.
|
||||
*/
|
||||
|
|
|
@ -155,8 +155,8 @@
|
|||
document.getElementById("errorTryAgain").style.display = "none";
|
||||
}
|
||||
|
||||
if (err == "cspFrameAncestorBlocked") {
|
||||
// Remove the "Try again" button for CSP frame ancestors violation, since it's
|
||||
if (err == "cspBlocked") {
|
||||
// Remove the "Try again" button for CSP violations, since it's
|
||||
// almost certainly useless. (Bug 553180)
|
||||
document.getElementById("errorTryAgain").style.display = "none";
|
||||
}
|
||||
|
@ -291,7 +291,7 @@
|
|||
<h1 id="et_nssFailure2">&nssFailure2.title;</h1>
|
||||
<h1 id="et_nssBadCert">&nssBadCert.title;</h1>
|
||||
<h1 id="et_malwareBlocked">&malwareBlocked.title;</h1>
|
||||
<h1 id="et_cspFrameAncestorBlocked">&cspFrameAncestorBlocked.title;</h1>
|
||||
<h1 id="et_cspBlocked">&cspBlocked.title;</h1>
|
||||
<h1 id="et_remoteXUL">&remoteXUL.title;</h1>
|
||||
<h1 id="et_corruptedContentError">&corruptedContentError.title;</h1>
|
||||
</div>
|
||||
|
@ -317,7 +317,7 @@
|
|||
<div id="ed_nssFailure2">&nssFailure2.longDesc2;</div>
|
||||
<div id="ed_nssBadCert">&nssBadCert.longDesc2;</div>
|
||||
<div id="ed_malwareBlocked">&malwareBlocked.longDesc;</div>
|
||||
<div id="ed_cspFrameAncestorBlocked">&cspFrameAncestorBlocked.longDesc;</div>
|
||||
<div id="ed_cspBlocked">&cspBlocked.longDesc;</div>
|
||||
<div id="ed_remoteXUL">&remoteXUL.longDesc;</div>
|
||||
<div id="ed_corruptedContentError">&corruptedContentError.longDesc;</div>
|
||||
</div>
|
||||
|
|
|
@ -30,7 +30,7 @@ class nsSHEntryShared;
|
|||
[ptr] native nsDocShellEditorDataPtr(nsDocShellEditorData);
|
||||
[ptr] native nsSHEntryShared(nsSHEntryShared);
|
||||
|
||||
[scriptable, uuid(9eed7e92-1121-46f2-95e5-2f5c0dca46f0)]
|
||||
[scriptable, uuid(d5fbeb10-f373-4677-b69a-2694aa706cac)]
|
||||
interface nsISHEntry : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -64,6 +64,11 @@ interface nsISHEntry : nsISupports
|
|||
/** Referrer URI */
|
||||
attribute nsIURI referrerURI;
|
||||
|
||||
/** Referrer policy, holding one of the values (REFERRER_POLICY_*)
|
||||
* defined in nsIHttpChannel.
|
||||
*/
|
||||
attribute unsigned long referrerPolicy;
|
||||
|
||||
/** Content viewer, for fast restoration of presentation */
|
||||
attribute nsIContentViewer contentViewer;
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "nsIStructuredCloneContainer.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIURI.h"
|
||||
#include "mozilla/net/ReferrerPolicy.h"
|
||||
#include <algorithm>
|
||||
|
||||
namespace dom = mozilla::dom;
|
||||
|
@ -27,7 +28,8 @@ static uint32_t gEntryID = 0;
|
|||
|
||||
|
||||
nsSHEntry::nsSHEntry()
|
||||
: mLoadType(0)
|
||||
: mReferrerPolicy(mozilla::net::RP_Default)
|
||||
, mLoadType(0)
|
||||
, mID(gEntryID++)
|
||||
, mScrollPositionX(0)
|
||||
, mScrollPositionY(0)
|
||||
|
@ -42,6 +44,7 @@ nsSHEntry::nsSHEntry(const nsSHEntry &other)
|
|||
: mShared(other.mShared)
|
||||
, mURI(other.mURI)
|
||||
, mReferrerURI(other.mReferrerURI)
|
||||
, mReferrerPolicy(other.mReferrerPolicy)
|
||||
, mTitle(other.mTitle)
|
||||
, mPostData(other.mPostData)
|
||||
, mLoadType(0) // XXX why not copy?
|
||||
|
@ -134,6 +137,18 @@ NS_IMETHODIMP nsSHEntry::SetReferrerURI(nsIURI *aReferrerURI)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsSHEntry::GetReferrerPolicy(uint32_t *aReferrerPolicy)
|
||||
{
|
||||
*aReferrerPolicy = mReferrerPolicy;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsSHEntry::SetReferrerPolicy(uint32_t aReferrerPolicy)
|
||||
{
|
||||
mReferrerPolicy = aReferrerPolicy;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::SetContentViewer(nsIContentViewer *aViewer)
|
||||
{
|
||||
|
|
|
@ -50,6 +50,7 @@ private:
|
|||
// See nsSHEntry.idl for comments on these members.
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
nsCOMPtr<nsIURI> mReferrerURI;
|
||||
uint32_t mReferrerPolicy;
|
||||
nsString mTitle;
|
||||
nsCOMPtr<nsIInputStream> mPostData;
|
||||
uint32_t mLoadType;
|
||||
|
|
|
@ -700,6 +700,17 @@ EventSource::GetBaseURI(nsIURI **aBaseURI)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
net::ReferrerPolicy
|
||||
EventSource::GetReferrerPolicy()
|
||||
{
|
||||
nsresult rv;
|
||||
nsIScriptContext* sc = GetContextForEventHandlers(&rv);
|
||||
NS_ENSURE_SUCCESS(rv, mozilla::net::RP_Default);
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = nsContentUtils::GetDocumentFromScriptContext(sc);
|
||||
return doc ? doc->GetReferrerPolicy() : mozilla::net::RP_Default;
|
||||
}
|
||||
|
||||
nsresult
|
||||
EventSource::SetupHttpChannel()
|
||||
{
|
||||
|
@ -720,7 +731,7 @@ EventSource::SetupHttpChannel()
|
|||
nsCOMPtr<nsIURI> codebase;
|
||||
nsresult rv = GetBaseURI(getter_AddRefs(codebase));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = mHttpChannel->SetReferrer(codebase);
|
||||
rv = mHttpChannel->SetReferrerWithPolicy(codebase, this->GetReferrerPolicy());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
|
|
|
@ -109,6 +109,8 @@ protected:
|
|||
|
||||
nsresult GetBaseURI(nsIURI **aBaseURI);
|
||||
|
||||
net::ReferrerPolicy GetReferrerPolicy();
|
||||
|
||||
nsresult SetupHttpChannel();
|
||||
nsresult InitChannelAndRequestEventSource();
|
||||
nsresult ResetConnection();
|
||||
|
|
|
@ -158,7 +158,10 @@ nsContentAreaDragDropDataProvider::SaveURIToFile(nsAString& inSourceURIString,
|
|||
|
||||
persist->SetPersistFlags(nsIWebBrowserPersist::PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION);
|
||||
|
||||
return persist->SavePrivacyAwareURI(sourceURI, nullptr, nullptr, nullptr, nullptr,
|
||||
// referrer policy can be anything since the referrer is nullptr
|
||||
return persist->SavePrivacyAwareURI(sourceURI, nullptr, nullptr,
|
||||
mozilla::net::RP_Default,
|
||||
nullptr, nullptr,
|
||||
inDestFile, isPrivate);
|
||||
}
|
||||
|
||||
|
|
|
@ -736,7 +736,7 @@ nsContentSink::ProcessStyleLink(nsIContent* aElement,
|
|||
// We don't support CORS for processing instructions
|
||||
bool isAlternate;
|
||||
rv = mCSSLoader->LoadStyleLink(aElement, url, aTitle, aMedia, aAlternate,
|
||||
CORS_NONE,
|
||||
CORS_NONE, mDocument->GetReferrerPolicy(),
|
||||
mRunsToCompletion ? nullptr : this, &isAlternate);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
|
|
@ -2985,6 +2985,7 @@ nsContentUtils::IsImageInCache(nsIURI* aURI, nsIDocument* aDocument)
|
|||
nsresult
|
||||
nsContentUtils::LoadImage(nsIURI* aURI, nsIDocument* aLoadingDocument,
|
||||
nsIPrincipal* aLoadingPrincipal, nsIURI* aReferrer,
|
||||
net::ReferrerPolicy aReferrerPolicy,
|
||||
imgINotificationObserver* aObserver, int32_t aLoadFlags,
|
||||
const nsAString& initiatorType,
|
||||
imgRequestProxy** aRequest,
|
||||
|
@ -3016,6 +3017,7 @@ nsContentUtils::LoadImage(nsIURI* aURI, nsIDocument* aLoadingDocument,
|
|||
return imgLoader->LoadImage(aURI, /* uri to load */
|
||||
documentURI, /* initialDocumentURI */
|
||||
aReferrer, /* referrer */
|
||||
aReferrerPolicy, /* referrer policy */
|
||||
aLoadingPrincipal, /* loading principal */
|
||||
loadGroup, /* loadgroup */
|
||||
aObserver, /* imgINotificationObserver */
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "mozilla/dom/AutocompleteInfoBinding.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "mozilla/FloatingPoint.h"
|
||||
#include "mozilla/net/ReferrerPolicy.h"
|
||||
#include "nsIContentPolicy.h"
|
||||
|
||||
#if defined(XP_WIN)
|
||||
|
@ -619,6 +620,8 @@ public:
|
|||
* @param aLoadingDocument the document we belong to
|
||||
* @param aLoadingPrincipal the principal doing the load
|
||||
* @param aReferrer the referrer URI
|
||||
* @param aReferrerPolicy the referrer-sending policy to use on channel
|
||||
* creation
|
||||
* @param aObserver the observer for the image load
|
||||
* @param aLoadFlags the load flags to use. See nsIRequest
|
||||
* @param [aContentPolicyType=nsIContentPolicy::TYPE_IMAGE] (Optional)
|
||||
|
@ -629,6 +632,7 @@ public:
|
|||
nsIDocument* aLoadingDocument,
|
||||
nsIPrincipal* aLoadingPrincipal,
|
||||
nsIURI* aReferrer,
|
||||
mozilla::net::ReferrerPolicy aReferrerPolicy,
|
||||
imgINotificationObserver* aObserver,
|
||||
int32_t aLoadFlags,
|
||||
const nsAString& initiatorType,
|
||||
|
|
|
@ -1539,6 +1539,8 @@ static already_AddRefed<mozilla::dom::NodeInfo> nullNodeInfo;
|
|||
// ==================================================================
|
||||
nsIDocument::nsIDocument()
|
||||
: nsINode(nullNodeInfo),
|
||||
mReferrerPolicySet(false),
|
||||
mReferrerPolicy(mozilla::net::RP_Default),
|
||||
mCharacterSet(NS_LITERAL_CSTRING("ISO-8859-1")),
|
||||
mNodeInfoManager(nullptr),
|
||||
mCompatMode(eCompatibility_FullStandards),
|
||||
|
@ -3701,6 +3703,20 @@ nsDocument::SetHeaderData(nsIAtom* aHeaderField, const nsAString& aData)
|
|||
aHeaderField == nsGkAtoms::viewport_user_scalable) {
|
||||
mViewportType = Unknown;
|
||||
}
|
||||
|
||||
// Referrer policy spec says to ignore any empty referrer policies.
|
||||
if (aHeaderField == nsGkAtoms::referrer && !aData.IsEmpty()) {
|
||||
ReferrerPolicy policy = mozilla::net::ReferrerPolicyFromString(aData);
|
||||
|
||||
// Referrer policy spec (section 6.1) says that once the referrer policy
|
||||
// is set, any future attempts to change it result in No-Referrer.
|
||||
if (!mReferrerPolicySet) {
|
||||
mReferrerPolicy = policy;
|
||||
mReferrerPolicySet = true;
|
||||
} else if (mReferrerPolicy != policy) {
|
||||
mReferrerPolicy = mozilla::net::RP_No_Referrer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -9485,7 +9501,8 @@ FireOrClearDelayedEvents(nsTArray<nsCOMPtr<nsIDocument> >& aDocuments,
|
|||
}
|
||||
|
||||
void
|
||||
nsDocument::MaybePreLoadImage(nsIURI* uri, const nsAString &aCrossOriginAttr)
|
||||
nsDocument::MaybePreLoadImage(nsIURI* uri, const nsAString &aCrossOriginAttr,
|
||||
ReferrerPolicy aReferrerPolicy)
|
||||
{
|
||||
// Early exit if the img is already present in the img-cache
|
||||
// which indicates that the "real" load has already started and
|
||||
|
@ -9519,6 +9536,7 @@ nsDocument::MaybePreLoadImage(nsIURI* uri, const nsAString &aCrossOriginAttr)
|
|||
this,
|
||||
NodePrincipal(),
|
||||
mDocumentURI, // uri of document used as referrer
|
||||
aReferrerPolicy,
|
||||
nullptr, // no observer
|
||||
loadFlags,
|
||||
NS_LITERAL_STRING("img"),
|
||||
|
@ -9574,7 +9592,8 @@ NS_IMPL_ISUPPORTS(StubCSSLoaderObserver, nsICSSLoaderObserver)
|
|||
|
||||
void
|
||||
nsDocument::PreloadStyle(nsIURI* uri, const nsAString& charset,
|
||||
const nsAString& aCrossOriginAttr)
|
||||
const nsAString& aCrossOriginAttr,
|
||||
const ReferrerPolicy aReferrerPolicy)
|
||||
{
|
||||
// The CSSLoader will retain this object after we return.
|
||||
nsCOMPtr<nsICSSLoaderObserver> obs = new StubCSSLoaderObserver();
|
||||
|
@ -9583,7 +9602,8 @@ nsDocument::PreloadStyle(nsIURI* uri, const nsAString& charset,
|
|||
CSSLoader()->LoadSheet(uri, NodePrincipal(),
|
||||
NS_LossyConvertUTF16toASCII(charset),
|
||||
obs,
|
||||
Element::StringToCORSMode(aCrossOriginAttr));
|
||||
Element::StringToCORSMode(aCrossOriginAttr),
|
||||
aReferrerPolicy);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -120,6 +120,7 @@ class nsIdentifierMapEntry : public nsStringHashKey
|
|||
{
|
||||
public:
|
||||
typedef mozilla::dom::Element Element;
|
||||
typedef mozilla::net::ReferrerPolicy ReferrerPolicy;
|
||||
|
||||
explicit nsIdentifierMapEntry(const nsAString& aKey) :
|
||||
nsStringHashKey(&aKey), mNameContentList(nullptr)
|
||||
|
@ -1091,10 +1092,12 @@ public:
|
|||
void MaybeEndOutermostXBLUpdate();
|
||||
|
||||
virtual void MaybePreLoadImage(nsIURI* uri,
|
||||
const nsAString &aCrossOriginAttr) MOZ_OVERRIDE;
|
||||
const nsAString &aCrossOriginAttr,
|
||||
ReferrerPolicy aReferrerPolicy) MOZ_OVERRIDE;
|
||||
|
||||
virtual void PreloadStyle(nsIURI* uri, const nsAString& charset,
|
||||
const nsAString& aCrossOriginAttr) MOZ_OVERRIDE;
|
||||
const nsAString& aCrossOriginAttr,
|
||||
ReferrerPolicy aReferrerPolicy) MOZ_OVERRIDE;
|
||||
|
||||
virtual nsresult LoadChromeSheetSync(nsIURI* uri, bool isAgentSheet,
|
||||
mozilla::CSSStyleSheet** sheet) MOZ_OVERRIDE;
|
||||
|
|
|
@ -432,6 +432,8 @@ nsFrameLoader::ReallyStartLoadingInternal()
|
|||
}
|
||||
}
|
||||
|
||||
loadInfo->SetReferrerPolicy(mOwnerContent->OwnerDoc()->GetReferrerPolicy());
|
||||
|
||||
// Default flags:
|
||||
int32_t flags = nsIWebNavigation::LOAD_FLAGS_NONE;
|
||||
|
||||
|
|
|
@ -976,6 +976,7 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
|
|||
nsIGlobalObject* nativeGlobal =
|
||||
xpc::NativeGlobal(js::GetGlobalForObjectCrossCompartment(wrappedJS->GetJSObject()));
|
||||
AutoEntryScript aes(nativeGlobal);
|
||||
aes.TakeOwnershipOfErrorReporting();
|
||||
JSContext* cx = aes.cx();
|
||||
JS::Rooted<JSObject*> object(cx, wrappedJS->GetJSObject());
|
||||
|
||||
|
@ -1017,23 +1018,31 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
|
|||
aMessage.Length()));
|
||||
NS_ENSURE_TRUE(jsMessage, NS_ERROR_OUT_OF_MEMORY);
|
||||
JS::Rooted<JS::Value> syncv(cx, JS::BooleanValue(aIsSync));
|
||||
JS_DefineProperty(cx, param, "target", targetv, JSPROP_ENUMERATE);
|
||||
JS_DefineProperty(cx, param, "name", jsMessage, JSPROP_ENUMERATE);
|
||||
JS_DefineProperty(cx, param, "sync", syncv, JSPROP_ENUMERATE);
|
||||
JS_DefineProperty(cx, param, "json", json, JSPROP_ENUMERATE); // deprecated
|
||||
JS_DefineProperty(cx, param, "data", json, JSPROP_ENUMERATE);
|
||||
JS_DefineProperty(cx, param, "objects", cpowsv, JSPROP_ENUMERATE);
|
||||
bool ok = JS_DefineProperty(cx, param, "target", targetv, JSPROP_ENUMERATE) &&
|
||||
JS_DefineProperty(cx, param, "name", jsMessage, JSPROP_ENUMERATE) &&
|
||||
JS_DefineProperty(cx, param, "sync", syncv, JSPROP_ENUMERATE) &&
|
||||
JS_DefineProperty(cx, param, "json", json, JSPROP_ENUMERATE) && // deprecated
|
||||
JS_DefineProperty(cx, param, "data", json, JSPROP_ENUMERATE) &&
|
||||
JS_DefineProperty(cx, param, "objects", cpowsv, JSPROP_ENUMERATE);
|
||||
NS_ENSURE_TRUE(ok, NS_ERROR_UNEXPECTED);
|
||||
|
||||
// message.principal == null
|
||||
if (!aPrincipal) {
|
||||
JS_DefineProperty(cx, param, "principal", JS::UndefinedHandleValue, JSPROP_ENUMERATE);
|
||||
bool ok = JS_DefineProperty(cx, param, "principal",
|
||||
JS::UndefinedHandleValue, JSPROP_ENUMERATE);
|
||||
NS_ENSURE_TRUE(ok, NS_ERROR_UNEXPECTED);
|
||||
}
|
||||
|
||||
// message.principal = the principal
|
||||
else {
|
||||
JS::Rooted<JS::Value> principalValue(cx);
|
||||
rv = nsContentUtils::WrapNative(cx, aPrincipal, &NS_GET_IID(nsIPrincipal), &principalValue);
|
||||
JS_DefineProperty(cx, param, "principal", principalValue, JSPROP_ENUMERATE);
|
||||
nsresult rv = nsContentUtils::WrapNative(cx, aPrincipal,
|
||||
&NS_GET_IID(nsIPrincipal),
|
||||
&principalValue);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
bool ok = JS_DefineProperty(cx, param, "principal", principalValue,
|
||||
JSPROP_ENUMERATE);
|
||||
NS_ENSURE_TRUE(ok, NS_ERROR_UNEXPECTED);
|
||||
}
|
||||
|
||||
JS::Rooted<JS::Value> thisValue(cx, JS::UndefinedValue());
|
||||
|
@ -1057,8 +1066,9 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
|
|||
} else {
|
||||
// If the listener is a JS object which has receiveMessage function:
|
||||
if (!JS_GetProperty(cx, object, "receiveMessage", &funval) ||
|
||||
!funval.isObject())
|
||||
!funval.isObject()) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
// Check if the object is even callable.
|
||||
NS_ENSURE_STATE(JS::IsCallable(&funval.toObject()));
|
||||
|
@ -1076,15 +1086,14 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
|
|||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
if (!JS_CallFunctionValue(cx, thisObject, funval, JS::HandleValueArray(argv), &rval)) {
|
||||
nsJSUtils::ReportPendingException(cx);
|
||||
if (!JS_CallFunctionValue(cx, thisObject, funval,
|
||||
JS::HandleValueArray(argv), &rval)) {
|
||||
continue;
|
||||
}
|
||||
if (aJSONRetVal) {
|
||||
nsString json;
|
||||
if (!JS_Stringify(cx, &rval, JS::NullPtr(), JS::NullHandleValue,
|
||||
JSONCreator, &json)) {
|
||||
nsJSUtils::ReportPendingException(cx);
|
||||
continue;
|
||||
}
|
||||
aJSONRetVal->AppendElement(json);
|
||||
|
|
|
@ -582,6 +582,7 @@ GK_ATOM(menupopup, "menupopup")
|
|||
GK_ATOM(menuseparator, "menuseparator")
|
||||
GK_ATOM(message, "message")
|
||||
GK_ATOM(meta, "meta")
|
||||
GK_ATOM(referrer, "referrer")
|
||||
GK_ATOM(meter, "meter")
|
||||
GK_ATOM(method, "method")
|
||||
GK_ATOM(microdataProperties, "microdataProperties")
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "nsPIDOMWindow.h" // for use in inline functions
|
||||
#include "nsPropertyTable.h" // for member
|
||||
#include "nsTHashtable.h" // for member
|
||||
#include "mozilla/net/ReferrerPolicy.h" // for member
|
||||
#include "nsWeakReference.h"
|
||||
#include "mozilla/dom/DocumentBinding.h"
|
||||
#include "mozilla/WeakPtr.h"
|
||||
|
@ -169,6 +170,7 @@ class nsIDocument : public nsINode
|
|||
{
|
||||
typedef mozilla::dom::GlobalObject GlobalObject;
|
||||
public:
|
||||
typedef mozilla::net::ReferrerPolicy ReferrerPolicy;
|
||||
typedef mozilla::dom::Element Element;
|
||||
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IDOCUMENT_IID)
|
||||
|
@ -271,6 +273,15 @@ public:
|
|||
*/
|
||||
virtual void SetChromeXHRDocBaseURI(nsIURI* aURI) = 0;
|
||||
|
||||
/**
|
||||
* Return the referrer policy of the document. Return "default" if there's no
|
||||
* valid meta referrer tag found in the document.
|
||||
*/
|
||||
ReferrerPolicy GetReferrerPolicy() const
|
||||
{
|
||||
return mReferrerPolicy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the principal responsible for this document.
|
||||
*/
|
||||
|
@ -1886,7 +1897,8 @@ public:
|
|||
* be a void string if the attr is not present.
|
||||
*/
|
||||
virtual void MaybePreLoadImage(nsIURI* uri,
|
||||
const nsAString& aCrossOriginAttr) = 0;
|
||||
const nsAString& aCrossOriginAttr,
|
||||
ReferrerPolicy aReferrerPolicy) = 0;
|
||||
|
||||
/**
|
||||
* Called by nsParser to preload style sheets. Can also be merged into the
|
||||
|
@ -1894,7 +1906,8 @@ public:
|
|||
* should be a void string if the attr is not present.
|
||||
*/
|
||||
virtual void PreloadStyle(nsIURI* aURI, const nsAString& aCharset,
|
||||
const nsAString& aCrossOriginAttr) = 0;
|
||||
const nsAString& aCrossOriginAttr,
|
||||
ReferrerPolicy aReferrerPolicy) = 0;
|
||||
|
||||
/**
|
||||
* Called by the chrome registry to load style sheets. Can be put
|
||||
|
@ -2468,6 +2481,9 @@ protected:
|
|||
|
||||
nsWeakPtr mDocumentLoadGroup;
|
||||
|
||||
bool mReferrerPolicySet;
|
||||
ReferrerPolicy mReferrerPolicy;
|
||||
|
||||
mozilla::WeakPtr<nsDocShell> mDocumentContainer;
|
||||
|
||||
nsCString mCharacterSet;
|
||||
|
|
|
@ -887,6 +887,7 @@ nsImageLoadingContent::LoadImage(nsIURI* aNewURI,
|
|||
rv = nsContentUtils::LoadImage(aNewURI, aDocument,
|
||||
aDocument->NodePrincipal(),
|
||||
aDocument->GetDocumentURI(),
|
||||
aDocument->GetReferrerPolicy(),
|
||||
this, loadFlags,
|
||||
content->LocalName(),
|
||||
getter_AddRefs(req),
|
||||
|
|
|
@ -169,14 +169,13 @@ nsJSUtils::EvaluateString(JSContext* aCx,
|
|||
JS::Handle<JSObject*> aEvaluationGlobal,
|
||||
JS::CompileOptions& aCompileOptions,
|
||||
const EvaluateOptions& aEvaluateOptions,
|
||||
JS::MutableHandle<JS::Value> aRetValue,
|
||||
void **aOffThreadToken)
|
||||
JS::MutableHandle<JS::Value> aRetValue)
|
||||
{
|
||||
const nsPromiseFlatString& flatScript = PromiseFlatString(aScript);
|
||||
JS::SourceBufferHolder srcBuf(flatScript.get(), aScript.Length(),
|
||||
JS::SourceBufferHolder::NoOwnership);
|
||||
return EvaluateString(aCx, srcBuf, aEvaluationGlobal, aCompileOptions,
|
||||
aEvaluateOptions, aRetValue, aOffThreadToken);
|
||||
aEvaluateOptions, aRetValue, nullptr);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -193,19 +192,22 @@ nsJSUtils::EvaluateString(JSContext* aCx,
|
|||
|
||||
MOZ_ASSERT_IF(aCompileOptions.versionSet,
|
||||
aCompileOptions.version != JSVERSION_UNKNOWN);
|
||||
MOZ_ASSERT_IF(aEvaluateOptions.coerceToString, aEvaluateOptions.needResult);
|
||||
MOZ_ASSERT_IF(!aEvaluateOptions.reportUncaught, aEvaluateOptions.needResult);
|
||||
MOZ_ASSERT_IF(aEvaluateOptions.coerceToString, !aCompileOptions.noScriptRval);
|
||||
MOZ_ASSERT_IF(!aEvaluateOptions.reportUncaught, !aCompileOptions.noScriptRval);
|
||||
// Note that the above assert means that if aCompileOptions.noScriptRval then
|
||||
// also aEvaluateOptions.reportUncaught.
|
||||
MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
|
||||
MOZ_ASSERT(aSrcBuf.get());
|
||||
MOZ_ASSERT(js::GetGlobalForObjectCrossCompartment(aEvaluationGlobal) ==
|
||||
aEvaluationGlobal);
|
||||
MOZ_ASSERT_IF(aOffThreadToken, aCompileOptions.noScriptRval);
|
||||
|
||||
// Unfortunately, the JS engine actually compiles scripts with a return value
|
||||
// in a different, less efficient way. Furthermore, it can't JIT them in many
|
||||
// cases. So we need to be explicitly told whether the caller cares about the
|
||||
// return value. Callers can do this by calling the other overload of
|
||||
// EvaluateString() which calls this function with aEvaluateOptions.needResult
|
||||
// set to false.
|
||||
// EvaluateString() which calls this function with
|
||||
// aCompileOptions.noScriptRval set to true.
|
||||
aRetValue.setUndefined();
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
@ -246,16 +248,12 @@ nsJSUtils::EvaluateString(JSContext* aCx,
|
|||
script(aCx, JS::FinishOffThreadScript(aCx, JS_GetRuntime(aCx), *aOffThreadToken));
|
||||
*aOffThreadToken = nullptr; // Mark the token as having been finished.
|
||||
if (script) {
|
||||
if (aEvaluateOptions.needResult) {
|
||||
ok = JS_ExecuteScript(aCx, scopeChain, script, aRetValue);
|
||||
} else {
|
||||
ok = JS_ExecuteScript(aCx, scopeChain, script);
|
||||
}
|
||||
ok = JS_ExecuteScript(aCx, scopeChain, script);
|
||||
} else {
|
||||
ok = false;
|
||||
}
|
||||
} else if (ok) {
|
||||
if (aEvaluateOptions.needResult) {
|
||||
if (!aCompileOptions.noScriptRval) {
|
||||
ok = JS::Evaluate(aCx, scopeChain, aCompileOptions, aSrcBuf, aRetValue);
|
||||
} else {
|
||||
ok = JS::Evaluate(aCx, scopeChain, aCompileOptions, aSrcBuf);
|
||||
|
@ -273,7 +271,7 @@ nsJSUtils::EvaluateString(JSContext* aCx,
|
|||
if (!ok) {
|
||||
if (aEvaluateOptions.reportUncaught) {
|
||||
ReportPendingException(aCx);
|
||||
if (aEvaluateOptions.needResult) {
|
||||
if (!aCompileOptions.noScriptRval) {
|
||||
aRetValue.setUndefined();
|
||||
}
|
||||
} else {
|
||||
|
@ -281,36 +279,44 @@ nsJSUtils::EvaluateString(JSContext* aCx,
|
|||
: NS_ERROR_OUT_OF_MEMORY;
|
||||
JS::Rooted<JS::Value> exn(aCx);
|
||||
JS_GetPendingException(aCx, &exn);
|
||||
if (aEvaluateOptions.needResult) {
|
||||
aRetValue.set(exn);
|
||||
}
|
||||
MOZ_ASSERT(!aCompileOptions.noScriptRval); // we asserted this on entry
|
||||
aRetValue.set(exn);
|
||||
JS_ClearPendingException(aCx);
|
||||
}
|
||||
}
|
||||
|
||||
// Wrap the return value into whatever compartment aCx was in.
|
||||
if (aEvaluateOptions.needResult) {
|
||||
JS::Rooted<JS::Value> v(aCx, aRetValue);
|
||||
if (!JS_WrapValue(aCx, &v)) {
|
||||
if (!aCompileOptions.noScriptRval) {
|
||||
if (!JS_WrapValue(aCx, aRetValue)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
aRetValue.set(v);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsJSUtils::EvaluateString(JSContext* aCx,
|
||||
const nsAString& aScript,
|
||||
JS::SourceBufferHolder& aSrcBuf,
|
||||
JS::Handle<JSObject*> aEvaluationGlobal,
|
||||
JS::CompileOptions& aCompileOptions,
|
||||
void **aOffThreadToken)
|
||||
const EvaluateOptions& aEvaluateOptions,
|
||||
JS::MutableHandle<JS::Value> aRetValue)
|
||||
{
|
||||
return EvaluateString(aCx, aSrcBuf, aEvaluationGlobal, aCompileOptions,
|
||||
aEvaluateOptions, aRetValue, nullptr);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsJSUtils::EvaluateString(JSContext* aCx,
|
||||
const nsAString& aScript,
|
||||
JS::Handle<JSObject*> aEvaluationGlobal,
|
||||
JS::CompileOptions& aCompileOptions)
|
||||
{
|
||||
EvaluateOptions options(aCx);
|
||||
options.setNeedResult(false);
|
||||
aCompileOptions.setNoScriptRval(true);
|
||||
JS::RootedValue unused(aCx);
|
||||
return EvaluateString(aCx, aScript, aEvaluationGlobal, aCompileOptions,
|
||||
options, &unused, aOffThreadToken);
|
||||
options, &unused);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -321,7 +327,7 @@ nsJSUtils::EvaluateString(JSContext* aCx,
|
|||
void **aOffThreadToken)
|
||||
{
|
||||
EvaluateOptions options(aCx);
|
||||
options.setNeedResult(false);
|
||||
aCompileOptions.setNoScriptRval(true);
|
||||
JS::RootedValue unused(aCx);
|
||||
return EvaluateString(aCx, aSrcBuf, aEvaluationGlobal, aCompileOptions,
|
||||
options, &unused, aOffThreadToken);
|
||||
|
|
|
@ -68,13 +68,11 @@ public:
|
|||
struct MOZ_STACK_CLASS EvaluateOptions {
|
||||
bool coerceToString;
|
||||
bool reportUncaught;
|
||||
bool needResult;
|
||||
JS::AutoObjectVector scopeChain;
|
||||
|
||||
explicit EvaluateOptions(JSContext* cx)
|
||||
: coerceToString(false)
|
||||
, reportUncaught(true)
|
||||
, needResult(true)
|
||||
, scopeChain(cx)
|
||||
{}
|
||||
|
||||
|
@ -87,11 +85,6 @@ public:
|
|||
reportUncaught = aReport;
|
||||
return *this;
|
||||
}
|
||||
|
||||
EvaluateOptions& setNeedResult(bool aNeedResult) {
|
||||
needResult = aNeedResult;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
// aEvaluationGlobal is the global to evaluate in. The return value
|
||||
|
@ -102,35 +95,41 @@ public:
|
|||
JS::Handle<JSObject*> aEvaluationGlobal,
|
||||
JS::CompileOptions &aCompileOptions,
|
||||
const EvaluateOptions& aEvaluateOptions,
|
||||
JS::MutableHandle<JS::Value> aRetValue,
|
||||
void **aOffThreadToken = nullptr);
|
||||
JS::MutableHandle<JS::Value> aRetValue);
|
||||
|
||||
static nsresult EvaluateString(JSContext* aCx,
|
||||
JS::SourceBufferHolder& aSrcBuf,
|
||||
JS::Handle<JSObject*> aEvaluationGlobal,
|
||||
JS::CompileOptions &aCompileOptions,
|
||||
const EvaluateOptions& aEvaluateOptions,
|
||||
JS::MutableHandle<JS::Value> aRetValue,
|
||||
void **aOffThreadToken = nullptr);
|
||||
JS::MutableHandle<JS::Value> aRetValue);
|
||||
|
||||
|
||||
static nsresult EvaluateString(JSContext* aCx,
|
||||
const nsAString& aScript,
|
||||
JS::Handle<JSObject*> aEvaluationGlobal,
|
||||
JS::CompileOptions &aCompileOptions,
|
||||
void **aOffThreadToken = nullptr);
|
||||
JS::CompileOptions &aCompileOptions);
|
||||
|
||||
static nsresult EvaluateString(JSContext* aCx,
|
||||
JS::SourceBufferHolder& aSrcBuf,
|
||||
JS::Handle<JSObject*> aEvaluationGlobal,
|
||||
JS::CompileOptions &aCompileOptions,
|
||||
void **aOffThreadToken = nullptr);
|
||||
void **aOffThreadToken);
|
||||
|
||||
// Returns false if an exception got thrown on aCx. Passing a null
|
||||
// aElement is allowed; that wil produce an empty aScopeChain.
|
||||
static bool GetScopeChainForElement(JSContext* aCx,
|
||||
mozilla::dom::Element* aElement,
|
||||
JS::AutoObjectVector& aScopeChain);
|
||||
private:
|
||||
// Implementation for our EvaluateString bits
|
||||
static nsresult EvaluateString(JSContext* aCx,
|
||||
JS::SourceBufferHolder& aSrcBuf,
|
||||
JS::Handle<JSObject*> aEvaluationGlobal,
|
||||
JS::CompileOptions& aCompileOptions,
|
||||
const EvaluateOptions& aEvaluateOptions,
|
||||
JS::MutableHandle<JS::Value> aRetValue,
|
||||
void **aOffThreadToken);
|
||||
};
|
||||
|
||||
class MOZ_STACK_CLASS AutoDontReportUncaught {
|
||||
|
|
|
@ -114,6 +114,7 @@ nsLocation::CheckURL(nsIURI* aURI, nsIDocShellLoadInfo** aLoadInfo)
|
|||
|
||||
nsCOMPtr<nsISupports> owner;
|
||||
nsCOMPtr<nsIURI> sourceURI;
|
||||
net::ReferrerPolicy referrerPolicy = net::RP_Default;
|
||||
|
||||
if (JSContext *cx = nsContentUtils::GetCurrentJSContext()) {
|
||||
// No cx means that there's no JS running, or at least no JS that
|
||||
|
@ -149,6 +150,7 @@ nsLocation::CheckURL(nsIURI* aURI, nsIDocShellLoadInfo** aLoadInfo)
|
|||
docCurrentURI = doc->GetDocumentURI();
|
||||
rv = doc->NodePrincipal()->GetURI(getter_AddRefs(principalURI));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
referrerPolicy = doc->GetReferrerPolicy();
|
||||
}
|
||||
|
||||
bool urisEqual = false;
|
||||
|
@ -186,6 +188,7 @@ nsLocation::CheckURL(nsIURI* aURI, nsIDocShellLoadInfo** aLoadInfo)
|
|||
|
||||
if (sourceURI) {
|
||||
loadInfo->SetReferrer(sourceURI);
|
||||
loadInfo->SetReferrerPolicy(referrerPolicy);
|
||||
}
|
||||
|
||||
loadInfo.swap(*aLoadInfo);
|
||||
|
|
|
@ -2510,7 +2510,8 @@ nsObjectLoadingContent::OpenChannel()
|
|||
// Referrer
|
||||
nsCOMPtr<nsIHttpChannel> httpChan(do_QueryInterface(chan));
|
||||
if (httpChan) {
|
||||
httpChan->SetReferrer(doc->GetDocumentURI());
|
||||
httpChan->SetReferrerWithPolicy(doc->GetDocumentURI(),
|
||||
doc->GetReferrerPolicy());
|
||||
|
||||
// Set the initiator type
|
||||
nsCOMPtr<nsITimedChannel> timedChannel(do_QueryInterface(httpChan));
|
||||
|
|
|
@ -83,7 +83,8 @@ public:
|
|||
mScriptTextLength(0),
|
||||
mJSVersion(aVersion),
|
||||
mLineNo(1),
|
||||
mCORSMode(aCORSMode)
|
||||
mCORSMode(aCORSMode),
|
||||
mReferrerPolicy(mozilla::net::RP_Default)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -116,6 +117,7 @@ public:
|
|||
nsAutoCString mURL; // Keep the URI's filename alive during off thread parsing.
|
||||
int32_t mLineNo;
|
||||
const CORSMode mCORSMode;
|
||||
mozilla::net::ReferrerPolicy mReferrerPolicy;
|
||||
};
|
||||
|
||||
// The nsScriptLoadRequest is passed as the context to necko, and thus
|
||||
|
@ -340,7 +342,8 @@ nsScriptLoader::StartLoad(nsScriptLoadRequest *aRequest, const nsAString &aType,
|
|||
httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
|
||||
NS_LITERAL_CSTRING("*/*"),
|
||||
false);
|
||||
httpChannel->SetReferrer(mDocument->GetDocumentURI());
|
||||
httpChannel->SetReferrerWithPolicy(mDocument->GetDocumentURI(),
|
||||
aRequest->mReferrerPolicy);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsILoadContext> loadContext(do_QueryInterface(docshell));
|
||||
|
@ -594,6 +597,9 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
|
|||
&nsIScriptElement::FireErrorEvent));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Double-check that the preload matches what we're asked to load now.
|
||||
mozilla::net::ReferrerPolicy ourRefPolicy = mDocument->GetReferrerPolicy();
|
||||
CORSMode ourCORSMode = aElement->GetCORSMode();
|
||||
nsTArray<PreloadInfo>::index_type i =
|
||||
mPreloads.IndexOf(scriptURI.get(), 0, PreloadURIComparator());
|
||||
|
@ -610,7 +616,8 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
|
|||
nsAutoString elementCharset;
|
||||
aElement->GetScriptCharset(elementCharset);
|
||||
if (elementCharset.Equals(preloadCharset) &&
|
||||
ourCORSMode == request->mCORSMode) {
|
||||
ourCORSMode == request->mCORSMode &&
|
||||
ourRefPolicy == request->mReferrerPolicy) {
|
||||
rv = CheckContentPolicy(mDocument, aElement, request->mURI, type);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
} else {
|
||||
|
@ -625,6 +632,7 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
|
|||
request->mURI = scriptURI;
|
||||
request->mIsInline = false;
|
||||
request->mLoading = true;
|
||||
request->mReferrerPolicy = ourRefPolicy;
|
||||
|
||||
// set aScriptFromHead to false so we don't treat non preloaded scripts as
|
||||
// blockers for full page load. See bug 792438.
|
||||
|
@ -1040,6 +1048,9 @@ nsScriptLoader::FillCompileOptionsForRequest(const AutoJSAPI &jsapi,
|
|||
aOptions->setFileAndLine(aRequest->mURL.get(), aRequest->mLineNo);
|
||||
aOptions->setVersion(JSVersion(aRequest->mJSVersion));
|
||||
aOptions->setCompileAndGo(JS_IsGlobalObject(aScopeChain));
|
||||
// We only need the setNoScriptRval bit when compiling off-thread here, since
|
||||
// otherwise nsJSUtils::EvaluateString will set it up for us.
|
||||
aOptions->setNoScriptRval(true);
|
||||
if (aRequest->mHasSourceMapURL) {
|
||||
aOptions->setSourceMapURL(aRequest->mSourceMapURL.get());
|
||||
}
|
||||
|
@ -1556,7 +1567,8 @@ void
|
|||
nsScriptLoader::PreloadURI(nsIURI *aURI, const nsAString &aCharset,
|
||||
const nsAString &aType,
|
||||
const nsAString &aCrossOrigin,
|
||||
bool aScriptFromHead)
|
||||
bool aScriptFromHead,
|
||||
const mozilla::net::ReferrerPolicy aReferrerPolicy)
|
||||
{
|
||||
// Check to see if scripts has been turned off.
|
||||
if (!mEnabled || !mDocument->IsScriptEnabled()) {
|
||||
|
@ -1569,6 +1581,8 @@ nsScriptLoader::PreloadURI(nsIURI *aURI, const nsAString &aCharset,
|
|||
request->mURI = aURI;
|
||||
request->mIsInline = false;
|
||||
request->mLoading = true;
|
||||
request->mReferrerPolicy = aReferrerPolicy;
|
||||
|
||||
nsresult rv = StartLoad(request, aType, aScriptFromHead);
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "nsAutoPtr.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIStreamLoader.h"
|
||||
#include "mozilla/net/ReferrerPolicy.h"
|
||||
|
||||
class nsScriptLoadRequest;
|
||||
class nsIURI;
|
||||
|
@ -240,7 +241,8 @@ public:
|
|||
virtual void PreloadURI(nsIURI *aURI, const nsAString &aCharset,
|
||||
const nsAString &aType,
|
||||
const nsAString &aCrossOrigin,
|
||||
bool aScriptFromHead);
|
||||
bool aScriptFromHead,
|
||||
const mozilla::net::ReferrerPolicy aReferrerPolicy);
|
||||
|
||||
/**
|
||||
* Process a request that was deferred so that the script could be compiled
|
||||
|
|
|
@ -426,7 +426,8 @@ nsStyleLinkElement::DoUpdateStyleSheet(nsIDocument* aOldDocument,
|
|||
NS_ENSURE_TRUE(clonedURI, NS_ERROR_OUT_OF_MEMORY);
|
||||
rv = doc->CSSLoader()->
|
||||
LoadStyleLink(thisContent, clonedURI, title, media, isAlternate,
|
||||
GetCORSMode(), aObserver, &isAlternate);
|
||||
GetCORSMode(), doc->GetReferrerPolicy(),
|
||||
aObserver, &isAlternate);
|
||||
if (NS_FAILED(rv)) {
|
||||
// Don't propagate LoadStyleLink() errors further than this, since some
|
||||
// consumers (e.g. nsXMLContentSink) will completely abort on innocuous
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
#include "nsCrossSiteListenerProxy.h"
|
||||
#include <algorithm>
|
||||
|
||||
using mozilla::net::ReferrerPolicy;
|
||||
|
||||
/**
|
||||
* This class manages loading a single XML document
|
||||
*/
|
||||
|
@ -42,6 +44,7 @@ public:
|
|||
|
||||
nsresult LoadDocument(nsIChannel* aChannel, nsIPrincipal *aLoaderPrincipal,
|
||||
bool aChannelIsSync, bool aForceToXML,
|
||||
ReferrerPolicy aReferrerPolicy,
|
||||
nsIDOMDocument** aResult);
|
||||
|
||||
NS_FORWARD_NSISTREAMLISTENER(mListener->)
|
||||
|
@ -130,6 +133,7 @@ nsSyncLoader::LoadDocument(nsIChannel* aChannel,
|
|||
nsIPrincipal *aLoaderPrincipal,
|
||||
bool aChannelIsSync,
|
||||
bool aForceToXML,
|
||||
ReferrerPolicy aReferrerPolicy,
|
||||
nsIDOMDocument **aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
|
@ -144,11 +148,11 @@ nsSyncLoader::LoadDocument(nsIChannel* aChannel,
|
|||
mChannel = aChannel;
|
||||
nsCOMPtr<nsIHttpChannel> http = do_QueryInterface(mChannel);
|
||||
if (http) {
|
||||
http->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
|
||||
http->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
|
||||
NS_LITERAL_CSTRING("text/xml,application/xml,application/xhtml+xml,*/*;q=0.1"),
|
||||
false);
|
||||
if (loaderUri) {
|
||||
http->SetReferrer(loaderUri);
|
||||
http->SetReferrerWithPolicy(loaderUri, aReferrerPolicy);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -307,6 +311,7 @@ nsSyncLoader::GetInterface(const nsIID & aIID,
|
|||
nsresult
|
||||
nsSyncLoadService::LoadDocument(nsIURI *aURI, nsIPrincipal *aLoaderPrincipal,
|
||||
nsILoadGroup *aLoadGroup, bool aForceToXML,
|
||||
ReferrerPolicy aReferrerPolicy,
|
||||
nsIDOMDocument** aResult)
|
||||
{
|
||||
nsCOMPtr<nsIChannel> channel;
|
||||
|
@ -330,7 +335,7 @@ nsSyncLoadService::LoadDocument(nsIURI *aURI, nsIPrincipal *aLoaderPrincipal,
|
|||
|
||||
nsRefPtr<nsSyncLoader> loader = new nsSyncLoader();
|
||||
return loader->LoadDocument(channel, aLoaderPrincipal, isSync,
|
||||
aForceToXML, aResult);
|
||||
aForceToXML, aReferrerPolicy, aResult);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#define nsSyncLoadService_h__
|
||||
|
||||
#include "nscore.h"
|
||||
#include "mozilla/net/ReferrerPolicy.h"
|
||||
|
||||
class nsIInputStream;
|
||||
class nsILoadGroup;
|
||||
|
@ -33,10 +34,12 @@ public:
|
|||
* @param aLoadGroup The loadgroup to use for loading the document.
|
||||
* @param aForceToXML Whether to parse the document as XML, regardless of
|
||||
* content type.
|
||||
* @param referrerPolicy Referrer policy.
|
||||
* @param aResult [out] The document loaded from the URI.
|
||||
*/
|
||||
static nsresult LoadDocument(nsIURI *aURI, nsIPrincipal *aLoaderPrincipal,
|
||||
nsILoadGroup *aLoadGroup, bool aForceToXML,
|
||||
mozilla::net::ReferrerPolicy aReferrerPolicy,
|
||||
nsIDOMDocument** aResult);
|
||||
|
||||
/**
|
||||
|
|
|
@ -1095,7 +1095,7 @@ nsTreeSanitizer::SanitizeStyleSheet(const nsAString& aOriginal,
|
|||
// -moz-binding is blacklisted.
|
||||
bool didSanitize = false;
|
||||
// Create a sheet to hold the parsed CSS
|
||||
nsRefPtr<CSSStyleSheet> sheet = new CSSStyleSheet(CORS_NONE);
|
||||
nsRefPtr<CSSStyleSheet> sheet = new CSSStyleSheet(CORS_NONE, aDocument->GetReferrerPolicy());
|
||||
sheet->SetURIs(aDocument->GetDocumentURI(), nullptr, aBaseURI);
|
||||
sheet->SetPrincipal(aDocument->NodePrincipal());
|
||||
// Create the CSS parser, and parse the CSS text.
|
||||
|
|
|
@ -2722,9 +2722,12 @@ nsXMLHttpRequest::Send(nsIVariant* aVariant, const Nullable<RequestBody>& aBody)
|
|||
|
||||
nsCOMPtr<nsIURI> docCurURI;
|
||||
nsCOMPtr<nsIURI> docOrigURI;
|
||||
net::ReferrerPolicy referrerPolicy = net::RP_Default;
|
||||
|
||||
if (doc) {
|
||||
docCurURI = doc->GetDocumentURI();
|
||||
docOrigURI = doc->GetOriginalURI();
|
||||
referrerPolicy = doc->GetReferrerPolicy();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> referrerURI;
|
||||
|
@ -2740,7 +2743,7 @@ nsXMLHttpRequest::Send(nsIVariant* aVariant, const Nullable<RequestBody>& aBody)
|
|||
if (!referrerURI)
|
||||
referrerURI = principalURI;
|
||||
|
||||
httpChannel->SetReferrer(referrerURI);
|
||||
httpChannel->SetReferrerWithPolicy(referrerURI, referrerPolicy);
|
||||
}
|
||||
|
||||
// Some extensions override the http protocol handler and provide their own
|
||||
|
|
|
@ -0,0 +1,269 @@
|
|||
var BASE_URL = 'example.com/tests/dom/base/test/bug704320.sjs';
|
||||
|
||||
function createTestUrl(schemeFrom, schemeTo, policy, action, type) {
|
||||
return schemeTo + '://' + BASE_URL + '?' +
|
||||
'action=' + action + '&' +
|
||||
'scheme=' + schemeFrom + '-to-' + schemeTo + '&' +
|
||||
'policy=' + policy + '&' +
|
||||
'type=' + type;
|
||||
}
|
||||
|
||||
function create2ndLevelIframeUrl(schemeFrom, schemeTo, policy, type) {
|
||||
return schemeFrom + '://' + BASE_URL + '?' +
|
||||
'action=create-2nd-level-iframe&' +
|
||||
'scheme-from=' + schemeFrom + '&' +
|
||||
'scheme-to=' + schemeTo + '&' +
|
||||
'policy=' + policy + '&' +
|
||||
'type=' + type;
|
||||
}
|
||||
|
||||
// Creates the following test cases for the specified scheme and referrer
|
||||
// policy combination:
|
||||
// <link>
|
||||
// @import
|
||||
// font-face
|
||||
// bg-url
|
||||
// <script>
|
||||
// <img>
|
||||
// <iframe>
|
||||
// <audio>
|
||||
// <video>
|
||||
// <object type="bogus">
|
||||
// <object type="image/svg+xml">
|
||||
// <a>
|
||||
// <a ping>
|
||||
// <form>
|
||||
// window.location
|
||||
// window.open
|
||||
// XMLHttpRequest
|
||||
// EventSource
|
||||
// TODO: XSLT?
|
||||
//
|
||||
// This returns a page that loads all of the above resources and contains a
|
||||
// script that clicks a link after all resources are (hopefully)
|
||||
// loaded. The click triggers a redirection to file_bug704320_redirect.html,
|
||||
// which in turn notifies the main window that it's time to check the test
|
||||
// results.
|
||||
function createTest(schemeFrom, schemeTo, policy) {
|
||||
var _createTestUrl = createTestUrl.bind(
|
||||
null, schemeFrom, schemeTo, policy, 'test');
|
||||
|
||||
var _create2ndLevelIframeUrl = create2ndLevelIframeUrl.bind(
|
||||
null, schemeFrom, schemeTo, policy);
|
||||
|
||||
return '<!DOCTYPE HTML>\n\
|
||||
<html>\n\
|
||||
<head>\n\
|
||||
<meta name="referrer" content="' + policy + '">\n\
|
||||
<link rel="stylesheet" type="text/css" href="' + _createTestUrl('stylesheet') + '">\n\
|
||||
<style type="text/css">\n\
|
||||
@import "' + _createTestUrl('import-css') + '";\n\
|
||||
@font-face {\n\
|
||||
font-family: "Fake Serif Bold";\n\
|
||||
src: url("' + _createTestUrl('font-face') + '");\n\
|
||||
}\n\
|
||||
body {\n\
|
||||
font-family: "Fake Serif Bold", serif;\n\
|
||||
background: url("' + _createTestUrl('bg-url') + '");\n\
|
||||
}\n\
|
||||
</style>\n\
|
||||
</head>\n\
|
||||
<body>\n\
|
||||
<script src="' + _createTestUrl('script') + '"></script>\n\
|
||||
<img src="' + _createTestUrl('img') + '"></img>\n\
|
||||
<iframe src="' + _createTestUrl('iframe') + '"></iframe>\n\
|
||||
<audio src="' + _createTestUrl('audio') + '"></audio>\n\
|
||||
<video src="' + _createTestUrl('video') + '"></video>\n\
|
||||
<object type="bogus" data="' + _createTestUrl('object') + '"></object>\n\
|
||||
<object type="image/svg+xml" data="' + _createTestUrl('object-svg') + '"></object>\n\
|
||||
<a id="link" href="' + _createTestUrl('link') + '" ping="' + _createTestUrl('link-ping') + '"></a>\n\
|
||||
<iframe src="' + _create2ndLevelIframeUrl('form') + '"></iframe>\n\
|
||||
<iframe src="' + _create2ndLevelIframeUrl('window.location') + '"></iframe>\n\
|
||||
<script>\n\
|
||||
(function() {\n\
|
||||
var x = new XMLHttpRequest();\n\
|
||||
x.open("GET", "' + _createTestUrl('xmlhttprequest') + '");\n\
|
||||
x.send();\n\
|
||||
})();\n\
|
||||
(function() {\n\
|
||||
var eventSource = new EventSource("' + _createTestUrl('eventsource') + '");\n\
|
||||
})();' +
|
||||
|
||||
// LOAD EVENT (most of the tests)
|
||||
// fires when the resources for the page are loaded
|
||||
'var _isLoaded = false;\n\
|
||||
window.addEventListener("load", function() {\n\
|
||||
this._isLoaded = true;\n\
|
||||
this.checkForFinish();\n\
|
||||
}.bind(window), false);' +
|
||||
|
||||
// WINDOW.OPEN test
|
||||
// listen for incoming status from window.open, close the window
|
||||
// and check if we're done.
|
||||
'var _openedWindowLoaded = false;\n\
|
||||
window.addEventListener("message", function(message) {\n\
|
||||
if (message.data == "window.open") {\n\
|
||||
this._openedWindowLoaded = true;\n\
|
||||
this.win.close();\n\
|
||||
this.checkForFinish();\n\
|
||||
}\n\
|
||||
}.bind(window), false);\n\
|
||||
var win = window.open("' + _createTestUrl('window.open') + '", "");' +
|
||||
|
||||
// called by the two things that must complete: window.open page
|
||||
// and the window load event. When both are complete, this
|
||||
// "finishes" the iframe subtest by clicking the link.
|
||||
'function checkForFinish() {\n\
|
||||
if (window._isLoaded && window._openedWindowLoaded) {\n\
|
||||
document.getElementById("link").click();\n\
|
||||
}\n\
|
||||
}\n\
|
||||
</script>\n\
|
||||
</body>\n\
|
||||
</html>';
|
||||
}
|
||||
|
||||
function createIframedFormTest(schemeFrom, schemeTo, policy) {
|
||||
var actionUrl = schemeTo + '://' + BASE_URL;
|
||||
|
||||
return '<!DOCTYPE HTML>\n\
|
||||
<html>\n\
|
||||
<head>\n\
|
||||
<meta name="referrer" content="' + policy + '">\n\
|
||||
</head>\n\
|
||||
<body>\n\
|
||||
<form id="form" action="' + actionUrl + '">\n\
|
||||
<input type="hidden" name="action" value="test">\n\
|
||||
<input type="hidden" name="scheme" value="' + schemeFrom + '-to-' + schemeTo + '">\n\
|
||||
<input type="hidden" name="policy" value="' + policy + '">\n\
|
||||
<input type="hidden" name="type" value="form">\n\
|
||||
</form>\n\
|
||||
<script>\n\
|
||||
document.getElementById("form").submit();\n\
|
||||
</script>\n\
|
||||
</body>\n\
|
||||
</html>';
|
||||
}
|
||||
|
||||
function createIframedWindowLocationTest(schemeFrom, schemeTo, policy) {
|
||||
var url = createTestUrl(
|
||||
schemeFrom, schemeTo, policy, 'test', 'window.location');
|
||||
|
||||
return '<!DOCTYPE HTML>\n\
|
||||
<html>\n\
|
||||
<head>\n\
|
||||
<meta name="referrer" content="' + policy + '">\n\
|
||||
</head>\n\
|
||||
<body>\n\
|
||||
<script>\n\
|
||||
window.location = "' + url + '";\n\
|
||||
</script>\n\
|
||||
</body>\n\
|
||||
</html>';
|
||||
}
|
||||
|
||||
function createPolicyTest(refpol) {
|
||||
return '<!DOCTYPE HTML>\n\
|
||||
<html>\n\
|
||||
<head>\n\
|
||||
<meta name="referrer" content="' + refpol + '">\n\
|
||||
<script type="text/javascript" src="/tests/dom/base/test/file_bug704320_preload_common.js"></script>\n\
|
||||
</head>\n\
|
||||
<body>\n\
|
||||
<img src="/tests/dom/base/test/bug704320_counter.sjs?type=img"\n\
|
||||
onload="incrementLoad2(\'img\', 2);">\n\
|
||||
<img src="http://example.com/tests/dom/base/test/bug704320_counter.sjs?type=img"\n\
|
||||
onload="incrementLoad2(\'img\', 2);">\n\
|
||||
</body>\n\
|
||||
</html>';
|
||||
}
|
||||
|
||||
function handleRequest(request, response) {
|
||||
var sharedKey = 'bug704320.sjs';
|
||||
var params = request.queryString.split('&');
|
||||
var action = params[0].split('=')[1];
|
||||
|
||||
if (action === 'create-1st-level-iframe') {
|
||||
// ?action=create-1st-level-iframe&scheme-from=http&scheme-to=https&policy=origin
|
||||
var schemeFrom = params[1].split('=')[1];
|
||||
var schemeTo = params[2].split('=')[1];
|
||||
var policy = params[3].split('=')[1];
|
||||
|
||||
response.setHeader('Content-Type', 'text/html; charset=utf-8', false);
|
||||
response.setHeader('Cache-Control', 'no-cache', false);
|
||||
response.write(createTest(schemeFrom, schemeTo, policy));
|
||||
}
|
||||
else if (action === 'create-2nd-level-iframe') {
|
||||
// ?action=create-2nd-level-iframe&scheme-from=http&scheme-to=https&policy=origin&type=form"
|
||||
var schemeFrom = params[1].split('=')[1];
|
||||
var schemeTo = params[2].split('=')[1];
|
||||
var policy = params[3].split('=')[1];
|
||||
var type = params[4].split('=')[1];
|
||||
|
||||
response.setHeader('Content-Type', 'text/html; charset=utf-8', false);
|
||||
response.setHeader('Cache-Control', 'no-cache', false);
|
||||
|
||||
if (type === 'form') {
|
||||
response.write(createIframedFormTest(schemeFrom, schemeTo, policy));
|
||||
} else if (type === 'window.location') {
|
||||
response.write(createIframedWindowLocationTest(
|
||||
schemeFrom, schemeTo, policy));
|
||||
}
|
||||
}
|
||||
else if (action === 'test') {
|
||||
// ?action=test&scheme=http-to-https&policy=origin&type=img
|
||||
var scheme = params[1].split('=')[1];
|
||||
var policy = params[2].split('=')[1];
|
||||
var type = params[3].split('=')[1];
|
||||
var result = getSharedState(sharedKey);
|
||||
|
||||
if (result === '') {
|
||||
result = {};
|
||||
} else {
|
||||
result = JSON.parse(result);
|
||||
}
|
||||
|
||||
if (!result[type]) {
|
||||
result[type] = {};
|
||||
}
|
||||
|
||||
if (!result[type][scheme]) {
|
||||
result[type][scheme] = {};
|
||||
}
|
||||
|
||||
if (request.hasHeader('Referer')) {
|
||||
result[type][scheme][policy] = request.getHeader('Referer');
|
||||
} else {
|
||||
result[type][scheme][policy] = '';
|
||||
}
|
||||
|
||||
setSharedState(sharedKey, JSON.stringify(result));
|
||||
|
||||
if (type === 'link') {
|
||||
var loc = 'https://example.com/tests/dom/base/test/file_bug704320_redirect.html';
|
||||
response.setStatusLine('1.1', 302, 'Found');
|
||||
response.setHeader('Location', loc, false);
|
||||
}
|
||||
|
||||
if (type === 'window.open') {
|
||||
response.setHeader('Cache-Control', 'no-cache', false);
|
||||
response.setHeader('Content-Type', 'text/html', false);
|
||||
response.write('<html><body><script>'
|
||||
+ 'window.opener.postMessage("window.open", "*");'
|
||||
+ '</script></body></html>');
|
||||
}
|
||||
}
|
||||
else if (action === 'get-test-results') {
|
||||
// ?action=get-result
|
||||
response.setHeader('Cache-Control', 'no-cache', false);
|
||||
response.setHeader('Content-Type', 'text/plain', false);
|
||||
response.write(getSharedState(sharedKey));
|
||||
}
|
||||
else if (action === 'generate-policy-test') {
|
||||
// ?action=generate-policy-test&policy=b64-encoded-string
|
||||
response.setHeader('Cache-Control', 'no-cache', false);
|
||||
response.setHeader('Content-Type', 'text/html', false);
|
||||
var refpol = unescape(params[1].split('=')[1]);
|
||||
response.write(createPolicyTest(refpol));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
// Handle counting loads for bug 704320.
|
||||
|
||||
const SHARED_KEY="bug704320_counter";
|
||||
const DEFAULT_STATE = {'css': {'count': 0, 'referrers': []},
|
||||
'img': {'count': 0, 'referrers': []},
|
||||
'js': {'count': 0, 'referrers': []}};
|
||||
const TYPE_MAP = {'css': 'text/css',
|
||||
'js': 'application/javascript',
|
||||
'img': 'image/png',
|
||||
'html': 'text/html'};
|
||||
|
||||
// Writes an image to the response
|
||||
function WriteOutImage(response)
|
||||
{
|
||||
var file = Components.classes["@mozilla.org/file/directory_service;1"]
|
||||
.getService(Components.interfaces.nsIProperties)
|
||||
.get("CurWorkD", Components.interfaces.nsIFile);
|
||||
|
||||
file.append("tests");
|
||||
file.append("image");
|
||||
file.append("test");
|
||||
file.append("mochitest");
|
||||
file.append('blue.png');
|
||||
|
||||
var fileStream = Components.classes['@mozilla.org/network/file-input-stream;1']
|
||||
.createInstance(Components.interfaces.nsIFileInputStream);
|
||||
fileStream.init(file, 1, 0, false);
|
||||
response.bodyOutputStream.writeFrom(fileStream, fileStream.available());
|
||||
}
|
||||
|
||||
function handleRequest(request, response)
|
||||
{
|
||||
var query = {};
|
||||
request.queryString.split('&').forEach(function (val) {
|
||||
var [name, value] = val.split('=');
|
||||
query[name] = unescape(value);
|
||||
});
|
||||
|
||||
var referrerLevel = "none";
|
||||
if (request.hasHeader('Referer')) {
|
||||
let referrer = request.getHeader('Referer');
|
||||
if (referrer.indexOf("bug704320") > 0) {
|
||||
referrerLevel = "full";
|
||||
} else if (referrer == "http://mochi.test:8888") {
|
||||
referrerLevel = "origin";
|
||||
}
|
||||
}
|
||||
|
||||
var state = getSharedState(SHARED_KEY);
|
||||
if (state === '') {
|
||||
state = DEFAULT_STATE;
|
||||
} else {
|
||||
state = JSON.parse(state);
|
||||
}
|
||||
|
||||
response.setStatusLine(request.httpVersion, 200, "OK");
|
||||
|
||||
|
||||
//avoid confusing cache behaviors
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
|
||||
if ("reset" in query) {
|
||||
//reset server state
|
||||
setSharedState(SHARED_KEY, JSON.stringify(DEFAULT_STATE));
|
||||
//serve any CSS that we want to use.
|
||||
response.write("");
|
||||
return;
|
||||
}
|
||||
|
||||
if ("results" in query) {
|
||||
response.setHeader("Content-Type", "text/javascript", false);
|
||||
response.write(JSON.stringify(state));
|
||||
return;
|
||||
}
|
||||
|
||||
if ('type' in query) {
|
||||
state[query.type].count++;
|
||||
response.setHeader("Content-Type", TYPE_MAP[query.type], false);
|
||||
if (state[query.type].referrers.indexOf(referrerLevel) < 0) {
|
||||
state[query.type].referrers.push(referrerLevel);
|
||||
}
|
||||
|
||||
if (query.type == 'img') {
|
||||
WriteOutImage(response);
|
||||
}
|
||||
}
|
||||
|
||||
if ('content' in query) {
|
||||
response.write(unescape(query['content']));
|
||||
}
|
||||
|
||||
setSharedState(SHARED_KEY, JSON.stringify(state));
|
||||
return;
|
||||
}
|
|
@ -33,6 +33,7 @@ support-files =
|
|||
[test_bug549682.xul]
|
||||
[test_bug571390.xul]
|
||||
[test_bug574596.html]
|
||||
[test_bug1098074_throw_from_ReceiveMessage.xul]
|
||||
skip-if = buildapp == 'mulet'
|
||||
[test_bug599295.html]
|
||||
[test_bug616841.xul]
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
|
||||
<?xml-stylesheet type="text/css" href="/tests/SimpleTest/test.css"?>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1098074
|
||||
-->
|
||||
<window title="Mozilla Bug 1098074"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="start();">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
|
||||
<!-- test code goes here -->
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
/** Test for Bug 1098074 **/
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.expectUncaughtException();
|
||||
|
||||
// Tell the test to expect exactly one console error with the given parameters,
|
||||
// with SimpleTest.finish as a continuation function.
|
||||
SimpleTest.monitorConsole(SimpleTest.finish, [{errorMessage: new RegExp('acopia')}]);
|
||||
|
||||
var Cc = Components.classes;
|
||||
var Ci = Components.interfaces;
|
||||
var globalMM = Cc["@mozilla.org/globalmessagemanager;1"]
|
||||
.getService(Ci.nsIMessageListenerManager);
|
||||
globalMM.addMessageListener("flimfniffle", function onMessage(msg) {
|
||||
globalMM.removeMessageListener("flimfniffle", onMessage);
|
||||
is(msg.data, "teufeltor", "correct message");
|
||||
|
||||
// Cleanup the monitor after we throw.
|
||||
SimpleTest.executeSoon(SimpleTest.endMonitorConsole);
|
||||
|
||||
throw "acopia";
|
||||
});
|
||||
|
||||
function start() {
|
||||
globalMM.loadFrameScript("data:,sendAsyncMessage('flimfniffle', 'teufeltor')", true);
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<!-- test results are displayed in the html:body -->
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1098074"
|
||||
target="_blank">Mozilla Bug 1098074</a>
|
||||
</body>
|
||||
</window>
|
|
@ -0,0 +1,15 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 529697 - Test mapping of form submission to form-action</title>
|
||||
</head>
|
||||
<body>
|
||||
<form action="submit-form">
|
||||
<input id="submitButton" type="submit" value="Submit form">
|
||||
</form>
|
||||
<script type="text/javascript">
|
||||
var submitButton = document.getElementById('submitButton');
|
||||
submitButton.click();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -100,6 +100,7 @@ support-files =
|
|||
file_multi_policy_injection_bypass.html^headers^
|
||||
file_multi_policy_injection_bypass_2.html
|
||||
file_multi_policy_injection_bypass_2.html^headers^
|
||||
file_form-action.html
|
||||
|
||||
[test_base-uri.html]
|
||||
[test_connect-src.html]
|
||||
|
@ -124,6 +125,8 @@ skip-if = (buildapp == 'b2g' && (toolkit != 'gonk' || debug)) || toolkit == 'and
|
|||
[test_policyuri_regression_from_multipolicy.html]
|
||||
[test_nonce_source.html]
|
||||
[test_CSP_bug941404.html]
|
||||
[test_form-action.html]
|
||||
skip-if = e10s || buildapp == 'b2g' # http-on-opening-request observers are not available in child processes
|
||||
[test_hash_source.html]
|
||||
skip-if = e10s || buildapp == 'b2g' # can't compute hashes in child process (bug 958702)
|
||||
[test_self_none_as_hostname_confusion.html]
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 529697 - Test mapping of form submission to form-action</title>
|
||||
<!-- Including SimpleTest.js so we can use waitForExplicitFinish !-->
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="visibility: hidden">
|
||||
<iframe style="width:100%;" id="testframe"></iframe>
|
||||
</div>
|
||||
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
/*
|
||||
* Description of the test:
|
||||
* We load a page with a given CSP and verify that form submissions are correctly
|
||||
* evaluated through the "form-action" directive.
|
||||
*/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var tests = [
|
||||
{
|
||||
page : "file_form-action.html",
|
||||
result : "allowed",
|
||||
policy : "form-action 'self'"
|
||||
},
|
||||
{
|
||||
page : "file_form-action.html",
|
||||
result : "blocked",
|
||||
policy : "form-action 'none'"
|
||||
}
|
||||
];
|
||||
|
||||
// initializing to -1 so we start at index 0 when we start the test
|
||||
var counter = -1;
|
||||
|
||||
function checkResult(aResult) {
|
||||
is(aResult, tests[counter].result, "should be " + tests[counter].result + " in test " + counter + "!");
|
||||
loadNextTest();
|
||||
}
|
||||
|
||||
// We use the examiner to identify requests that hit the wire and requests
|
||||
// that are blocked by CSP and bubble up the result to the including iframe
|
||||
// document (parent).
|
||||
function examiner() {
|
||||
SpecialPowers.addObserver(this, "csp-on-violate-policy", false);
|
||||
SpecialPowers.addObserver(this, "specialpowers-http-notify-request", false);
|
||||
}
|
||||
examiner.prototype = {
|
||||
observe: function(subject, topic, data) {
|
||||
if (topic === "specialpowers-http-notify-request") {
|
||||
// making sure we do not bubble a result for something other
|
||||
// then the request in question.
|
||||
if (!data.contains("submit-form")) {
|
||||
return;
|
||||
}
|
||||
checkResult("allowed");
|
||||
}
|
||||
|
||||
if (topic === "csp-on-violate-policy") {
|
||||
// making sure we do not bubble a result for something other
|
||||
// then the request in question.
|
||||
var asciiSpec = SpecialPowers.getPrivilegedProps(
|
||||
SpecialPowers.do_QueryInterface(subject, "nsIURI"),
|
||||
"asciiSpec");
|
||||
if (!asciiSpec.contains("submit-form")) {
|
||||
return;
|
||||
}
|
||||
checkResult("blocked");
|
||||
}
|
||||
},
|
||||
remove: function() {
|
||||
SpecialPowers.removeObserver(this, "csp-on-violate-policy");
|
||||
SpecialPowers.removeObserver(this, "specialpowers-http-notify-request");
|
||||
}
|
||||
}
|
||||
window.FormActionExaminer = new examiner();
|
||||
|
||||
function loadNextTest() {
|
||||
counter++;
|
||||
if (counter == tests.length) {
|
||||
window.FormActionExaminer.remove();
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
var src = "file_csp_testserver.sjs";
|
||||
// append the file that should be served
|
||||
src += "?file=" + escape("tests/dom/base/test/csp/" + tests[counter].page);
|
||||
// append the CSP that should be used to serve the file
|
||||
src += "&csp=" + escape(tests[counter].policy);
|
||||
|
||||
document.getElementById("testframe").src = src;
|
||||
}
|
||||
|
||||
// start running the tests
|
||||
loadNextTest();
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,34 @@
|
|||
// Common code for the iframes used by bug704320_preload.
|
||||
|
||||
var loadCount = 0;
|
||||
|
||||
// Called by the various onload handlers to indicate that a resource has
|
||||
// been fully loaded. We require three loads to complete (img, script,
|
||||
// link) for this test.
|
||||
function incrementLoad(tag) {
|
||||
loadCount++;
|
||||
if (loadCount == 3) {
|
||||
window.parent.postMessage("childLoadComplete", window.location.origin);
|
||||
} else if (loadCount > 3) {
|
||||
document.write("<h1>Too Many Load Events!</h1>");
|
||||
window.parent.postMessage("childOverload", window.location.origin);
|
||||
}
|
||||
}
|
||||
|
||||
// This is same as incrementLoad, but the caller passes in the loadCount.
|
||||
function incrementLoad2(tag, expectedLoadCount) {
|
||||
loadCount++;
|
||||
if (loadCount == expectedLoadCount) {
|
||||
window.parent.postMessage("childLoadComplete", window.location.origin);
|
||||
} else if (loadCount > expectedLoadCount) {
|
||||
document.write("<h1>Too Many Load Events!</h1>");
|
||||
window.parent.postMessage("childOverload", window.location.origin);
|
||||
}
|
||||
}
|
||||
|
||||
// in case something fails to load, cause the test to fail.
|
||||
function postfail(msg) {
|
||||
window.parent.postMessage("fail-" + msg, window.location.origin);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
This is a spot check for whether the speculative parser reuses style, script or image loads after the referrer policy has changed.
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=704320
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<script type="text/javascript" src="file_bug704320_preload_common.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
// mess with parser speculation's choice of referrer policy
|
||||
document.write("<meta name='referrer' content='origin'>");
|
||||
</script>
|
||||
|
||||
<!-- preload happens with full referrer, but real load should happen with origin -->
|
||||
<script src="/tests/dom/base/test/bug704320_counter.sjs?type=js"
|
||||
onload="incrementLoad('script');"></script>
|
||||
|
||||
<!-- preload happens with full referrer, but real load should happen with origin -->
|
||||
<link rel="stylesheet"
|
||||
href="/tests/dom/base/test/bug704320_counter.sjs?type=css"
|
||||
onload="incrementLoad('link');"/>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- preload happens with full referrer, but real load should happen with origin -->
|
||||
<img src="/tests/dom/base/test/bug704320_counter.sjs?type=img"
|
||||
onload="incrementLoad('img');"
|
||||
onerror="postfail('image load caused an error in noreuse test');"/>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,31 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
This is a spot check for whether the speculative parser reuses style, script or image loads after the referrer policy has changed.
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=704320
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="referrer" content="origin">
|
||||
<script type="text/javascript" src="file_bug704320_preload_common.js"></script>
|
||||
<script language="javascript" type="text/javascript">
|
||||
// mess with parser speculation -- the loads here MAY be reused because the
|
||||
// referrer policy did not change.
|
||||
document.write("<meta name='referrer' content='origin'>");
|
||||
</script>
|
||||
|
||||
<script src="http://example.com/tests/dom/base/test/bug704320_counter.sjs?type=js"
|
||||
onload="incrementLoad('script');"></script>
|
||||
|
||||
<link rel="stylesheet"
|
||||
href="http://example.com/tests/dom/base/test/bug704320_counter.sjs?type=css"
|
||||
onload="incrementLoad('link');"/>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<img src="http://example.com/tests/dom/base/test/bug704320_counter.sjs?type=img"
|
||||
onload="incrementLoad('img');"
|
||||
onerror="postfail('image load caused an error in reuse test');"/>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,10 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script>
|
||||
parent.postMessage('', 'http://mochi.test:8888');
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
|
@ -52,6 +52,8 @@ support-files =
|
|||
bug696301-script-1.js
|
||||
bug696301-script-1.js^headers^
|
||||
bug696301-script-2.js
|
||||
bug704320.sjs
|
||||
bug704320_counter.sjs
|
||||
bug819051.sjs
|
||||
copypaste.js
|
||||
delayedServerEvents.sjs
|
||||
|
@ -138,6 +140,10 @@ support-files =
|
|||
file_bug687859-http.js^headers^
|
||||
file_bug687859-inherit.js
|
||||
file_bug692434.xml
|
||||
file_bug704320_preload_common.js
|
||||
file_bug704320_preload_reuse.html
|
||||
file_bug704320_preload_noreuse.html
|
||||
file_bug704320_redirect.html
|
||||
file_bug707142_baseline.json
|
||||
file_bug707142_bom.json
|
||||
file_bug707142_utf-16.json
|
||||
|
@ -593,6 +599,10 @@ skip-if = buildapp == 'b2g'
|
|||
[test_bug698381.html]
|
||||
[test_bug698384.html]
|
||||
[test_bug704063.html]
|
||||
[test_bug704320.html]
|
||||
skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s # b2g (Needs multiple window.open support) android(times out, bug 1100609) e10s(randomly fails, bug 1100362)
|
||||
[test_bug704320_policyset.html]
|
||||
[test_bug704320_preload.html]
|
||||
[test_bug707142.html]
|
||||
[test_bug708620.html]
|
||||
[test_bug711047.html]
|
||||
|
|
|
@ -0,0 +1,232 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=704320
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 704320</title>
|
||||
<script type="application/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=704320">Mozilla Bug 704320</a>
|
||||
<p id="display"></p>
|
||||
<pre id="content">
|
||||
</pre>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<script type="application/javascript">
|
||||
|
||||
|
||||
var testIframeUrls = [
|
||||
// HTTP to HTTP
|
||||
'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=http&policy=no-referrer-when-downgrade',
|
||||
'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=http&policy=no-referrer',
|
||||
'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=http&policy=unsafe-url',
|
||||
'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=http&policy=origin',
|
||||
// HTTP to HTTPS
|
||||
'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=https&policy=no-referrer-when-downgrade',
|
||||
'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=https&policy=no-referrer',
|
||||
'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=https&policy=unsafe-url',
|
||||
'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=https&policy=origin',
|
||||
// HTTPS to HTTP
|
||||
'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=https&scheme-to=http&policy=no-referrer-when-downgrade',
|
||||
'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=https&scheme-to=http&policy=no-referrer',
|
||||
'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=https&scheme-to=http&policy=unsafe-url',
|
||||
'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=https&scheme-to=http&policy=origin',
|
||||
// HTTPS to HTTPS
|
||||
'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=https&scheme-to=https&policy=no-referrer-when-downgrade',
|
||||
'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=https&scheme-to=https&policy=no-referrer',
|
||||
'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=https&scheme-to=https&policy=unsafe-url',
|
||||
'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=https&scheme-to=https&policy=origin'
|
||||
];
|
||||
|
||||
var expectedResults = {
|
||||
// From docshell/base/nsDocShell.cpp:
|
||||
// "If the document containing the hyperlink being audited was not retrieved
|
||||
// over an encrypted connection and its address does not have the same
|
||||
// origin as "ping URL", send a referrer."
|
||||
'link-ping': {
|
||||
// Same-origin
|
||||
'http-to-http': {
|
||||
'no-referrer': '',
|
||||
'unsafe-url': '',
|
||||
'origin': '',
|
||||
'no-referrer-when-downgrade': ''
|
||||
},
|
||||
'http-to-https': {
|
||||
'no-referrer': '',
|
||||
'unsafe-url': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=https&policy=unsafe-url',
|
||||
'origin': 'http://example.com',
|
||||
'no-referrer-when-downgrade': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=https&policy=no-referrer-when-downgrade'
|
||||
},
|
||||
// Encrypted and not same-origin
|
||||
'https-to-http': {
|
||||
'no-referrer': '',
|
||||
'unsafe-url': '',
|
||||
'origin': '',
|
||||
'no-referrer-when-downgrade': ''
|
||||
},
|
||||
// Encrypted
|
||||
'https-to-https': {
|
||||
'no-referrer': '',
|
||||
'unsafe-url': '',
|
||||
'origin': '',
|
||||
'no-referrer-when-downgrade': ''
|
||||
}
|
||||
},
|
||||
// form is tested in a 2nd level iframe.
|
||||
'form': {
|
||||
'http-to-http': {
|
||||
'no-referrer': '',
|
||||
'unsafe-url': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=http&policy=unsafe-url&type=form',
|
||||
'origin': 'http://example.com',
|
||||
'no-referrer-when-downgrade': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=http&policy=no-referrer-when-downgrade&type=form'
|
||||
},
|
||||
'http-to-https': {
|
||||
'no-referrer': '',
|
||||
'unsafe-url': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=https&policy=unsafe-url&type=form',
|
||||
'origin': 'http://example.com',
|
||||
'no-referrer-when-downgrade': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=https&policy=no-referrer-when-downgrade&type=form'
|
||||
},
|
||||
'https-to-http': {
|
||||
'no-referrer': '',
|
||||
'unsafe-url': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=http&policy=unsafe-url&type=form',
|
||||
'origin': 'https://example.com',
|
||||
'no-referrer-when-downgrade': ''
|
||||
},
|
||||
'https-to-https': {
|
||||
'no-referrer': '',
|
||||
'unsafe-url': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=https&policy=unsafe-url&type=form',
|
||||
'origin': 'https://example.com',
|
||||
'no-referrer-when-downgrade': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=https&policy=no-referrer-when-downgrade&type=form'
|
||||
}
|
||||
},
|
||||
// window.location is tested in a 2nd level iframe.
|
||||
'window.location': {
|
||||
'http-to-http': {
|
||||
'no-referrer': '',
|
||||
'unsafe-url': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=http&policy=unsafe-url&type=window.location',
|
||||
'origin': 'http://example.com',
|
||||
'no-referrer-when-downgrade': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=http&policy=no-referrer-when-downgrade&type=window.location'
|
||||
},
|
||||
'http-to-https': {
|
||||
'no-referrer': '',
|
||||
'unsafe-url': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=https&policy=unsafe-url&type=window.location',
|
||||
'origin': 'http://example.com',
|
||||
'no-referrer-when-downgrade': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=https&policy=no-referrer-when-downgrade&type=window.location'
|
||||
},
|
||||
'https-to-http': {
|
||||
'no-referrer': '',
|
||||
'unsafe-url': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=http&policy=unsafe-url&type=window.location',
|
||||
'origin': 'https://example.com',
|
||||
'no-referrer-when-downgrade': ''
|
||||
},
|
||||
'https-to-https': {
|
||||
'no-referrer': '',
|
||||
'unsafe-url': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=https&policy=unsafe-url&type=window.location',
|
||||
'origin': 'https://example.com',
|
||||
'no-referrer-when-downgrade': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=https&policy=no-referrer-when-downgrade&type=window.location'
|
||||
}
|
||||
},
|
||||
'default': {
|
||||
'http-to-http': {
|
||||
'no-referrer': '',
|
||||
'unsafe-url': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=http&policy=unsafe-url',
|
||||
'origin': 'http://example.com',
|
||||
'no-referrer-when-downgrade': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=http&policy=no-referrer-when-downgrade'
|
||||
},
|
||||
'http-to-https': {
|
||||
'no-referrer': '',
|
||||
'unsafe-url': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=https&policy=unsafe-url',
|
||||
'origin': 'http://example.com',
|
||||
'no-referrer-when-downgrade': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=https&policy=no-referrer-when-downgrade'
|
||||
},
|
||||
'https-to-http': {
|
||||
'no-referrer': '',
|
||||
'unsafe-url': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=https&scheme-to=http&policy=unsafe-url',
|
||||
'origin': 'https://example.com',
|
||||
'no-referrer-when-downgrade': ''
|
||||
},
|
||||
'https-to-https': {
|
||||
'no-referrer': '',
|
||||
'unsafe-url': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=https&scheme-to=https&policy=unsafe-url',
|
||||
'origin': 'https://example.com',
|
||||
'no-referrer-when-downgrade': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=https&scheme-to=https&policy=no-referrer-when-downgrade'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function runit() {
|
||||
var url = 'bug704320.sjs?action=get-test-results';
|
||||
var xhr = new XMLHttpRequest();
|
||||
|
||||
xhr.open('GET', url);
|
||||
xhr.onreadystatechange = function() {
|
||||
//dump("\n\n >>>>>>>>>>> XHR ReadyState change \n" + url + "\n\n\n\n");
|
||||
if (this.readyState == 4) {
|
||||
document.getElementById('content').textContent +=
|
||||
JSON.stringify(JSON.parse(this.response), null, 4);
|
||||
|
||||
//dump("\n\n >>>>>>>>>>> GOT RESPONSE: \n" + this.response + "\n\n\n\n");
|
||||
var response = JSON.parse(this.response);
|
||||
|
||||
for (type in response) {
|
||||
for (scheme in response[type]) {
|
||||
for (policy in response[type][scheme]) {
|
||||
var expectedResult = expectedResults[type] === undefined ?
|
||||
expectedResults['default'][scheme][policy] :
|
||||
expectedResults[type][scheme][policy];
|
||||
|
||||
is(response[type][scheme][policy], expectedResult,
|
||||
type + ' ' + scheme + ' ' + policy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
};
|
||||
xhr.send();
|
||||
}
|
||||
|
||||
// BEGIN
|
||||
// Currently triggers assertions on e10s due to bug 820466. If you try to run
|
||||
// this on e10s, you'll get some ssl-related assertions and should add this line:
|
||||
// SimpleTest.expectAssertions(0,15);
|
||||
// But this test is disabled on e10s for unexpected failures. See bug 1100362.
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({
|
||||
'set': [['security.mixed_content.block_active_content', false],
|
||||
['security.mixed_content.block_display_content', false],
|
||||
['browser.send_pings', true],
|
||||
['browser.send_pings.max_per_link', 1],
|
||||
['browser.send_pings.require_same_host', false]]
|
||||
},
|
||||
function() {
|
||||
var testContainer = document.getElementById('test');
|
||||
|
||||
testIframeUrls.forEach(function(url) {
|
||||
var iframe = document.createElement('iframe');
|
||||
iframe.setAttribute('class', 'test');
|
||||
iframe.src = url;
|
||||
testContainer.appendChild(iframe);
|
||||
});
|
||||
|
||||
var numFrames = testIframeUrls.length;
|
||||
var numFramesReady = 0;
|
||||
|
||||
window.addEventListener('message', function(event) {
|
||||
++numFramesReady;
|
||||
if (numFramesReady >= numFrames) {
|
||||
runit();
|
||||
}
|
||||
}, false);
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,179 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
This checks if the right policies are applied from a given string (including whitespace, invalid policy strings, etc). It doesn't do a complete check for all load types; that's done in another test.
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=704320
|
||||
-->
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test policies for Bug 704320</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
|
||||
<script type="application/javascript;version=1.7">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
var advance = function() { tests.next(); };
|
||||
|
||||
/**
|
||||
* Listen for notifications from the child.
|
||||
* These are sent in case of error, or when the loads we await have completed.
|
||||
*/
|
||||
window.addEventListener("message", function(event) {
|
||||
if (event.data == "childLoadComplete") {
|
||||
// all loads happen, continue the test.
|
||||
advance();
|
||||
} else if (event.data == "childOverload") {
|
||||
// too many loads happened in a test frame, abort.
|
||||
ok(false, "Too many load handlers called in test.");
|
||||
SimpleTest.finish();
|
||||
} else if (event.data.indexOf("fail-") == 0) {
|
||||
// something else failed in the test frame, abort.
|
||||
ok(false, "Child failed the test with error " + event.data.substr(5));
|
||||
SimpleTest.finish();
|
||||
}});
|
||||
|
||||
/**
|
||||
* This is the main test routine -- serialized by use of a generator.
|
||||
* It resets the counter, then performs two tests in sequence using
|
||||
* the same iframe.
|
||||
*/
|
||||
var tests = (function() {
|
||||
var iframe = document.getElementById("testframe");
|
||||
const sjs = "/tests/dom/base/test/bug704320.sjs?action=generate-policy-test";
|
||||
|
||||
|
||||
// basic calibration check
|
||||
// reset the counter
|
||||
yield resetCounter();
|
||||
|
||||
// load the first test frame
|
||||
// it will call back into this function via postMessage when it finishes loading.
|
||||
// and continue beyond the yield.
|
||||
yield iframe.src = sjs + "&policy=" + escape('default');
|
||||
|
||||
// check the first test (two images, no referrers)
|
||||
yield checkResults("default", ["full"]);
|
||||
|
||||
// check invalid policy
|
||||
// According to the spec section 6.4, if there is a policy token
|
||||
// and it is not one of the expected tokens, "No Referrer"
|
||||
// should be the policy used.
|
||||
yield resetCounter();
|
||||
yield iframe.src = sjs + "&policy=" + escape('invalid-policy');
|
||||
yield checkResults("invalid", ["none"]);
|
||||
|
||||
// whitespace checks.
|
||||
// according to the spec section 4.1, the content attribute's value
|
||||
// is fed to the token policy algorithm after stripping leading and
|
||||
// trailing whitespace.
|
||||
yield resetCounter();
|
||||
yield iframe.src = sjs + "&policy=" + escape('default ');
|
||||
yield checkResults("trailing whitespace", ["full"]);
|
||||
|
||||
yield resetCounter();
|
||||
yield iframe.src = sjs + "&policy=" + escape(' origin\f');
|
||||
yield checkResults("trailing form feed", ["origin"]);
|
||||
|
||||
yield resetCounter();
|
||||
yield iframe.src = sjs + "&policy=" + escape('\f origin');
|
||||
yield checkResults("leading form feed", ["origin"]);
|
||||
|
||||
// origin when cross-origin (trimming whitespace)
|
||||
yield resetCounter();
|
||||
yield iframe.src = sjs + "&policy=" + escape(' origin-when-crossorigin');
|
||||
yield checkResults("origin-when-crossorigin", ["origin", "full"]);
|
||||
|
||||
// according to the spec section 4.1:
|
||||
// "If the meta element lacks a content attribute, or if that attribute’s
|
||||
// value is the empty string, then abort these steps."
|
||||
// This means empty or missing content attribute means to ignore the meta
|
||||
// tag and use default policy.
|
||||
// Whitespace here is space, tab, LF, FF and CR.
|
||||
// http://www.w3.org/html/wg/drafts/html/CR/infrastructure.html#space-character
|
||||
yield resetCounter();
|
||||
yield iframe.src = sjs + "&policy=" + escape(' \t ');
|
||||
yield checkResults("basic whitespace only policy", ["full"]);
|
||||
|
||||
yield resetCounter();
|
||||
yield iframe.src = sjs + "&policy=" + escape(' \f\r\n\t ');
|
||||
yield checkResults("whitespace only policy", ["full"]);
|
||||
|
||||
// and double-check that no-referrer works.
|
||||
yield resetCounter();
|
||||
yield iframe.src = sjs + "&policy=" + escape('no-referrer');
|
||||
yield checkResults("no-referrer", ["none"]);
|
||||
|
||||
// complete. Be sure to yield so we don't call this twice.
|
||||
yield SimpleTest.finish();
|
||||
})();
|
||||
|
||||
// Helper functions below.
|
||||
|
||||
|
||||
/**
|
||||
* helper to perform an XHR.
|
||||
* Used by resetCounter() and checkResults().
|
||||
*/
|
||||
function doXHR(url, onSuccess, onFail) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.onload = function () {
|
||||
if (xhr.status == 200) {
|
||||
onSuccess(xhr);
|
||||
} else {
|
||||
onFail(xhr);
|
||||
}
|
||||
};
|
||||
xhr.open('GET', url, true);
|
||||
xhr.send(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* This triggers state-resetting on the counter server.
|
||||
*/
|
||||
function resetCounter() {
|
||||
doXHR('/tests/dom/base/test/bug704320_counter.sjs?reset',
|
||||
advance,
|
||||
function(xhr) {
|
||||
ok(false, "Need to be able to reset the request counter");
|
||||
SimpleTest.finish();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Grabs the results via XHR and passes to checker.
|
||||
*/
|
||||
function checkResults(testname, expected) {
|
||||
doXHR('/tests/dom/base/test/bug704320_counter.sjs?results',
|
||||
function(xhr) {
|
||||
var results = JSON.parse(xhr.responseText);
|
||||
info(xhr.responseText);
|
||||
|
||||
ok('img' in results,
|
||||
testname + " test: some image loads required in results object.");
|
||||
is(results['img'].count, 2,
|
||||
testname + " Test: Expected 2 loads for image requests.");
|
||||
|
||||
expected.forEach(function (ref) {
|
||||
ok(results['img'].referrers.indexOf(ref) >= 0,
|
||||
testname + " Test: Expected " + ref + " referrer policy in test, results were " +
|
||||
JSON.stringify(results['img'].referrers) +".");
|
||||
});
|
||||
advance();
|
||||
},
|
||||
function(xhr) {
|
||||
ok(false, "Can't get results from the counter server.");
|
||||
SimpleTest.finish();
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body onload="tests.next();">
|
||||
<iframe id="testframe"></iframe>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,189 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
This is a spot check for whether the speculative parser reuses style, script or image loads after the referrer policy has changed.
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=704320
|
||||
-->
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test preloads for Bug 704320</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
|
||||
<script type="application/javascript;version=1.7">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
var advance = function() { tests.next(); };
|
||||
|
||||
/**
|
||||
* Listen for notifications from the child.
|
||||
* These are sent in case of error, or when the loads we await have completed.
|
||||
*/
|
||||
window.addEventListener("message", function(event) {
|
||||
if (event.data == "childLoadComplete") {
|
||||
// all three loads happen, continue the test.
|
||||
advance();
|
||||
} else if (event.data == "childOverload") {
|
||||
// too many loads happened in a test frame, abort.
|
||||
ok(false, "Too many load handlers called in test.");
|
||||
SimpleTest.finish();
|
||||
} else if (event.data.indexOf("fail-") == 0) {
|
||||
// something else failed in the test frame, abort.
|
||||
ok(false, "Child failed the test with error " + event.data.substr(5));
|
||||
SimpleTest.finish();
|
||||
}});
|
||||
|
||||
/**
|
||||
* This is the main test routine -- serialized by use of a generator.
|
||||
* It resets the counter, then performs two tests in sequence using
|
||||
* the same iframe.
|
||||
*/
|
||||
var tests = (function() {
|
||||
var iframe = document.getElementById("testframe");
|
||||
|
||||
// reset the counter
|
||||
yield resetCounter();
|
||||
|
||||
// load the first test frame
|
||||
// it will call back into this function via postMessage when it finishes loading.
|
||||
// and continue beyond the yield.
|
||||
yield iframe.src = 'file_bug704320_preload_noreuse.html';
|
||||
|
||||
// check the first test
|
||||
yield checkResults(finalizePreloadNoreuse);
|
||||
|
||||
// reset the counter
|
||||
yield resetCounter();
|
||||
|
||||
// load the second test frame
|
||||
// it will call back into this function via postMessage when it finishes loading.
|
||||
// and continue beyond the yield.
|
||||
yield iframe.src = 'file_bug704320_preload_reuse.html';
|
||||
|
||||
// check the second test
|
||||
yield checkResults(finalizePreloadReuse);
|
||||
|
||||
// complete. Be sure to yield so we don't call this twice.
|
||||
yield SimpleTest.finish();
|
||||
})();
|
||||
|
||||
// Helper functions below.
|
||||
|
||||
/**
|
||||
* This checks the first test: a test where the preloads should not
|
||||
* be reused. * we expect two requests for each image, script, js request
|
||||
* since the referrer policy changed after speculative loads were started.
|
||||
* Problem is that the "origin"/revised loads won't necessarily happen,
|
||||
* so we test for one or two loads (both are OK) and make the 'origin'
|
||||
* referrer optional.
|
||||
*/
|
||||
function finalizePreloadNoreuse(results) {
|
||||
console.log("<br/><pre>" + JSON.stringify(results) + "</pre>");
|
||||
var expected = {'css': {'count': 2, 'referrers': ['full', 'origin']},
|
||||
'img': {'count': 2, 'referrers': ['full', 'origin']},
|
||||
'js': {'count': 2, 'referrers': ['full', 'origin']}};
|
||||
|
||||
for (var x in expected) {
|
||||
ok(x in results, "some " + x + " loads required in results object.");
|
||||
|
||||
ok(results[x].count == 1 || results[x].count == 2,
|
||||
"Expected 1-2 loads for " + x + " requests.");
|
||||
|
||||
// the 'full' preload is optional, but required if count > 1
|
||||
if (results[x].count > 1) {
|
||||
ok(results[x].referrers.indexOf('full') >= 0,
|
||||
"More than one load for " + x + ", so expected an 'full' referrer preload.")
|
||||
}
|
||||
|
||||
// 'origin' (final load) is required
|
||||
ok(results[x].referrers.indexOf('origin') >= 0,
|
||||
"One load for " + x + " should have had 'origin' referrer.");
|
||||
|
||||
// no other values should be in the referrers.
|
||||
is(results[x].referrers.indexOf('none'), -1,
|
||||
"No loads for " + x + " should have a missing referrer.");
|
||||
}
|
||||
|
||||
advance();
|
||||
}
|
||||
|
||||
/**
|
||||
* This checks the second test: a test where preloads SHOULD be reused.
|
||||
* We expect one request for each image, script, js request since
|
||||
* the referrer policy does not change after speculative loads.
|
||||
*/
|
||||
function finalizePreloadReuse(results) {
|
||||
var expected = {'css': {'count': 1, 'referrers': ['origin']},
|
||||
'img': {'count': 1, 'referrers': ['origin']},
|
||||
'js': {'count': 1, 'referrers': ['origin']}};
|
||||
|
||||
for (var x in expected) {
|
||||
ok(x in results, "some " + x + " loads required in results object.");
|
||||
|
||||
is(results[x].count, expected[x].count,
|
||||
"Expected " + expected[x].count + " loads for " + x + " requests.");
|
||||
|
||||
// 'origin' is required
|
||||
ok(results[x].referrers.indexOf('origin') >= 0,
|
||||
"One load for " + x + " should have had 'origin' referrer.");
|
||||
|
||||
// no other values should be in the referrers.
|
||||
is(results[x].referrers.indexOf('none'), -1,
|
||||
"No loads for " + x + " should have a missing referrer.");
|
||||
is(results[x].referrers.indexOf('full'), -1,
|
||||
"No loads for " + x + " should have an 'full' referrer.")
|
||||
}
|
||||
|
||||
advance();
|
||||
}
|
||||
|
||||
/**
|
||||
* helper to perform an XHR.
|
||||
* Used by resetCounter() and checkResults().
|
||||
*/
|
||||
function doXHR(url, onSuccess, onFail) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.onload = function () {
|
||||
if (xhr.status == 200) {
|
||||
onSuccess(xhr);
|
||||
} else {
|
||||
onFail(xhr);
|
||||
}
|
||||
};
|
||||
xhr.open('GET', url, true);
|
||||
xhr.send(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* This triggers state-resetting on the counter server.
|
||||
*/
|
||||
function resetCounter() {
|
||||
doXHR('/tests/dom/base/test/bug704320_counter.sjs?reset',
|
||||
advance,
|
||||
function(xhr) {
|
||||
ok(false, "Need to be able to reset the request counter");
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Grabs the results via XHR and passes to checker.
|
||||
*/
|
||||
function checkResults(checker) {
|
||||
doXHR('/tests/dom/base/test/bug704320_counter.sjs?results',
|
||||
function(xhr) {
|
||||
checker(JSON.parse(xhr.responseText));
|
||||
},
|
||||
function(xhr) {
|
||||
ok(false, "Can't get results from the counter server.");
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body onload="tests.next();">
|
||||
<iframe id="testframe"></iframe>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -61,6 +61,8 @@
|
|||
#include "nsIDOMHTMLButtonElement.h"
|
||||
#include "nsSandboxFlags.h"
|
||||
|
||||
#include "nsIContentSecurityPolicy.h"
|
||||
|
||||
// images
|
||||
#include "mozilla/dom/HTMLImageElement.h"
|
||||
|
||||
|
@ -1625,6 +1627,19 @@ HTMLFormElement::GetActionURL(nsIURI** aActionURL,
|
|||
nsIScriptSecurityManager::STANDARD);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Check if CSP allows this form-action
|
||||
nsCOMPtr<nsIContentSecurityPolicy> csp;
|
||||
rv = NodePrincipal()->GetCsp(getter_AddRefs(csp));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (csp) {
|
||||
bool permitsFormAction = true;
|
||||
rv = csp->PermitsFormAction(actionURL, &permitsFormAction);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!permitsFormAction) {
|
||||
rv = NS_ERROR_CSP_FORM_ACTION_VIOLATION;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Assign to the output
|
||||
//
|
||||
|
|
|
@ -3719,7 +3719,8 @@ void HTMLMediaElement::SetRequestHeaders(nsIHttpChannel* aChannel)
|
|||
EmptyCString(), false);
|
||||
|
||||
// Set the Referer header
|
||||
aChannel->SetReferrer(OwnerDoc()->GetDocumentURI());
|
||||
aChannel->SetReferrerWithPolicy(OwnerDoc()->GetDocumentURI(),
|
||||
OwnerDoc()->GetReferrerPolicy());
|
||||
}
|
||||
|
||||
void HTMLMediaElement::FireTimeUpdate(bool aPeriodic)
|
||||
|
|
|
@ -77,7 +77,21 @@ HTMLMetaElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
|||
nsAutoString content;
|
||||
rv = GetContent(content);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsContentUtils::ProcessViewportInfo(aDocument, content);
|
||||
nsContentUtils::ProcessViewportInfo(aDocument, content);
|
||||
}
|
||||
if (aDocument &&
|
||||
AttrValueIs(kNameSpaceID_None, nsGkAtoms::name, nsGkAtoms::referrer, eIgnoreCase)) {
|
||||
nsAutoString content;
|
||||
rv = GetContent(content);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Referrer Policy spec requires a <meta name="referrer" tag to be in the
|
||||
// <head> element.
|
||||
Element* headElt = aDocument->GetHeadElement();
|
||||
if (headElt && nsContentUtils::ContentIsDescendantOf(this, headElt)) {
|
||||
content = nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(content);
|
||||
aDocument->SetHeaderData(nsGkAtoms::referrer, content);
|
||||
}
|
||||
}
|
||||
CreateAndDispatchEvent(aDocument, NS_LITERAL_STRING("DOMMetaAdded"));
|
||||
return rv;
|
||||
|
|
|
@ -206,6 +206,15 @@ interface nsIContentSecurityPolicy : nsISerializable
|
|||
*/
|
||||
boolean permitsBaseURI(in nsIURI aURI);
|
||||
|
||||
/**
|
||||
* Whether this policy allows submitting HTML forms to a given URI.
|
||||
*
|
||||
* @return
|
||||
* Whether or not the provided URI is allowed to be used as a
|
||||
* form's action URI.
|
||||
*/
|
||||
boolean permitsFormAction(in nsIURI aURI);
|
||||
|
||||
/**
|
||||
* Delegate method called by the service when sub-elements of the protected
|
||||
* document are being loaded. Given a bit of information about the request,
|
||||
|
|
|
@ -30,6 +30,6 @@ externalProtocolChkMsg=Remember my choice for all links of this type.
|
|||
externalProtocolLaunchBtn=Launch application
|
||||
malwareBlocked=The site at %S has been reported as an attack site and has been blocked based on your security preferences.
|
||||
phishingBlocked=The website at %S has been reported as a web forgery designed to trick users into sharing personal or financial information.
|
||||
cspFrameAncestorBlocked=This page has a content security policy that prevents it from being embedded in this way.
|
||||
cspBlocked=This page has a content security policy that prevents it from being loaded in this way.
|
||||
corruptedContentError=The page you are trying to view cannot be shown because an error in the data transmission was detected.
|
||||
remoteXUL=This page uses an unsupported technology that is no longer available by default.
|
||||
|
|
|
@ -87,8 +87,8 @@
|
|||
<p>These types of web forgeries are used in scams known as phishing attacks, in which fraudulent web pages and emails are used to imitate sources you may trust.</p>
|
||||
">
|
||||
|
||||
<!ENTITY cspFrameAncestorBlocked.title "Blocked by Content Security Policy">
|
||||
<!ENTITY cspFrameAncestorBlocked.longDesc "<p>The browser prevented this page from loading in this way because the page has a content security policy that disallows it.</p>">
|
||||
<!ENTITY cspBlocked.title "Blocked by Content Security Policy">
|
||||
<!ENTITY cspBlocked.longDesc "<p>The browser prevented this page from loading in this way because the page has a content security policy that disallows it.</p>">
|
||||
|
||||
<!ENTITY corruptedContentError.title "Corrupted Content Error">
|
||||
<!ENTITY corruptedContentError.longDesc "<p>The page you are trying to view cannot be shown because an error in the data transmission was detected.</p><ul><li>Please contact the website owners to inform them of this problem.</li></ul>">
|
||||
|
|
|
@ -61,7 +61,7 @@ runWithMSE(function(ms, v) {
|
|||
});
|
||||
v.addEventListener("ended", function () {
|
||||
ok(Math.abs(v.duration - 4) < 0.1, "Video has correct duration. This fuzz factor is due to bug 1065207");
|
||||
is(v.currentTime, v.duration, "Video has correct current time: " + v.currentTime);
|
||||
ok(Math.abs(v.currentTime - 4) < 0.1, "Video has correct currentTime. See bug 1101062");
|
||||
ok(gotWaiting, "Received waiting event and playback continued after data added");
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
|
|
@ -3122,6 +3122,7 @@ nsresult nsPluginHost::NewPluginURLStream(const nsString& aURL,
|
|||
// errors about malformed requests if we include it in POSTs. See
|
||||
// bug 724465.
|
||||
nsCOMPtr<nsIURI> referer;
|
||||
net::ReferrerPolicy referrerPolicy = net::RP_Default;
|
||||
|
||||
nsCOMPtr<nsIObjectLoadingContent> olc = do_QueryInterface(element);
|
||||
if (olc)
|
||||
|
@ -3133,9 +3134,10 @@ nsresult nsPluginHost::NewPluginURLStream(const nsString& aURL,
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
referer = doc->GetDocumentURI();
|
||||
referrerPolicy = doc->GetReferrerPolicy();
|
||||
}
|
||||
|
||||
rv = httpChannel->SetReferrer(referer);
|
||||
rv = httpChannel->SetReferrerWithPolicy(referer, referrerPolicy);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
|
||||
|
|
|
@ -1102,7 +1102,7 @@ nsCSPContext::PermitsBaseURI(nsIURI* aURI, bool* outPermitsBaseURI)
|
|||
*outPermitsBaseURI = false;
|
||||
}
|
||||
nsAutoString violatedDirective;
|
||||
mPolicies[i]->getDirectiveStringForBaseURI(violatedDirective);
|
||||
mPolicies[i]->getDirectiveAsString(CSP_BASE_URI, violatedDirective);
|
||||
this->AsyncReportViolation(aURI,
|
||||
nullptr, /* originalURI in case of redirect */
|
||||
violatedDirective,
|
||||
|
@ -1127,6 +1127,48 @@ nsCSPContext::PermitsBaseURI(nsIURI* aURI, bool* outPermitsBaseURI)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCSPContext::PermitsFormAction(nsIURI* aURI, bool* outPermitsFormAction)
|
||||
{
|
||||
// Can't perform check without aURI
|
||||
if (!aURI) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
*outPermitsFormAction = true;
|
||||
|
||||
for (uint32_t i = 0; i < mPolicies.Length(); i++) {
|
||||
if (!mPolicies[i]->permitsFormAction(aURI)) {
|
||||
// policy is violated, report to caller if not report-only
|
||||
if (!mPolicies[i]->getReportOnlyFlag()) {
|
||||
*outPermitsFormAction = false;
|
||||
}
|
||||
nsAutoString violatedDirective;
|
||||
mPolicies[i]->getDirectiveAsString(CSP_FORM_ACTION, violatedDirective);
|
||||
this->AsyncReportViolation(aURI,
|
||||
mSelfURI,
|
||||
violatedDirective,
|
||||
i, /* policy index */
|
||||
EmptyString(), /* no observer subject */
|
||||
EmptyString(), /* no source file */
|
||||
EmptyString(), /* no script sample */
|
||||
0); /* no line number */
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
{
|
||||
nsAutoCString spec;
|
||||
aURI->GetSpec(spec);
|
||||
CSPCONTEXTLOG(("nsCSPContext::PermitsFormAction, aUri: %s, isAllowed: %s",
|
||||
spec.get(),
|
||||
*outPermitsFormAction ? "allow" : "deny"));
|
||||
}
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* ========== CSPViolationReportListener implementation ========== */
|
||||
|
||||
NS_IMPL_ISUPPORTS(CSPViolationReportListener, nsIStreamListener, nsIRequestObserver, nsISupports);
|
||||
|
|
|
@ -872,6 +872,30 @@ nsCSPPolicy::permitsBaseURI(nsIURI* aUri) const
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
nsCSPPolicy::permitsFormAction(nsIURI* aUri) const
|
||||
{
|
||||
#ifdef PR_LOGGING
|
||||
{
|
||||
nsAutoCString spec;
|
||||
aUri->GetSpec(spec);
|
||||
CSPUTILSLOG(("nsCSPPolicy::permitsFormAction, aUri: %s", spec.get()));
|
||||
}
|
||||
#endif
|
||||
|
||||
// Try to find a form-action directive
|
||||
for (uint32_t i = 0; i < mDirectives.Length(); i++) {
|
||||
if (mDirectives[i]->equals(CSP_FORM_ACTION)) {
|
||||
return mDirectives[i]->permits(aUri);
|
||||
}
|
||||
}
|
||||
|
||||
// form-action is only enforced if explicitly defined in the
|
||||
// policy - do *not* consult default-src, see:
|
||||
// http://www.w3.org/TR/CSP2/#directive-default-src
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
nsCSPPolicy::allows(nsContentPolicyType aContentType,
|
||||
enum CSPKeyword aKeyword,
|
||||
|
@ -975,10 +999,10 @@ nsCSPPolicy::getDirectiveStringForContentType(nsContentPolicyType aContentType,
|
|||
}
|
||||
|
||||
void
|
||||
nsCSPPolicy::getDirectiveStringForBaseURI(nsAString& outDirective) const
|
||||
nsCSPPolicy::getDirectiveAsString(enum CSPDirective aDir, nsAString& outDirective) const
|
||||
{
|
||||
for (uint32_t i = 0; i < mDirectives.Length(); i++) {
|
||||
if (mDirectives[i]->equals(CSP_BASE_URI)) {
|
||||
if (mDirectives[i]->equals(aDir)) {
|
||||
mDirectives[i]->toString(outDirective);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -72,6 +72,7 @@ enum CSPDirective {
|
|||
CSP_FRAME_ANCESTORS,
|
||||
CSP_REFLECTED_XSS,
|
||||
CSP_BASE_URI,
|
||||
CSP_FORM_ACTION,
|
||||
// CSP_LAST_DIRECTIVE_VALUE always needs to be the last element in the enum
|
||||
// because we use it to calculate the size for the char* array.
|
||||
CSP_LAST_DIRECTIVE_VALUE
|
||||
|
@ -90,7 +91,8 @@ static const char* CSPStrDirectives[] = {
|
|||
"report-uri", // CSP_REPORT_URI
|
||||
"frame-ancestors", // CSP_FRAME_ANCESTORS
|
||||
"reflected-xss", // CSP_REFLECTED_XSS
|
||||
"base-uri" // CSP_BASE_URI
|
||||
"base-uri", // CSP_BASE_URI
|
||||
"form-action" // CSP_FORM_ACTION
|
||||
};
|
||||
|
||||
inline const char* CSP_EnumToDirective(enum CSPDirective aDir)
|
||||
|
@ -333,6 +335,7 @@ class nsCSPPolicy {
|
|||
bool aWasRedirected,
|
||||
nsAString& outViolatedDirective) const;
|
||||
bool permitsBaseURI(nsIURI* aUri) const;
|
||||
bool permitsFormAction(nsIURI* aUri) const;
|
||||
bool allows(nsContentPolicyType aContentType,
|
||||
enum CSPKeyword aKeyword,
|
||||
const nsAString& aHashOrNonce) const;
|
||||
|
@ -356,7 +359,7 @@ class nsCSPPolicy {
|
|||
void getDirectiveStringForContentType(nsContentPolicyType aContentType,
|
||||
nsAString& outDirective) const;
|
||||
|
||||
void getDirectiveStringForBaseURI(nsAString& outDirective) const;
|
||||
void getDirectiveAsString(enum CSPDirective aDir, nsAString& outDirective) const;
|
||||
|
||||
inline uint32_t getNumDirectives() const
|
||||
{ return mDirectives.Length(); }
|
||||
|
|
|
@ -295,6 +295,7 @@ nsXBLProtoImplAnonymousMethod::Execute(nsIContent* aBoundElement, JSAddonId* aAd
|
|||
// We are going to run script via JS::Call, so we need a script entry point,
|
||||
// but as this is XBL related it does not appear in the HTML spec.
|
||||
dom::AutoEntryScript aes(global);
|
||||
aes.TakeOwnershipOfErrorReporting();
|
||||
JSContext* cx = aes.cx();
|
||||
|
||||
JS::Rooted<JSObject*> globalObject(cx, global->GetGlobalJSObject());
|
||||
|
@ -324,20 +325,12 @@ nsXBLProtoImplAnonymousMethod::Execute(nsIContent* aBoundElement, JSAddonId* aAd
|
|||
bool scriptAllowed = nsContentUtils::GetSecurityManager()->
|
||||
ScriptAllowed(js::GetGlobalForObjectCrossCompartment(method));
|
||||
|
||||
bool ok = true;
|
||||
if (scriptAllowed) {
|
||||
JS::Rooted<JS::Value> retval(cx);
|
||||
JS::Rooted<JS::Value> methodVal(cx, JS::ObjectValue(*method));
|
||||
ok = ::JS::Call(cx, scopeChain[0], methodVal, JS::HandleValueArray::empty(), &retval);
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
// If a constructor or destructor threw an exception, it doesn't stop
|
||||
// anything else. We just report it. Note that we need to set aside the
|
||||
// frame chain here, since the constructor invocation is not related to
|
||||
// whatever is on the stack right now, really.
|
||||
nsJSUtils::ReportPendingException(cx);
|
||||
return NS_ERROR_FAILURE;
|
||||
// No need to check the return here as AutoEntryScript has taken ownership
|
||||
// of error reporting.
|
||||
::JS::Call(cx, scopeChain[0], methodVal, JS::HandleValueArray::empty(), &retval);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
|
|
@ -120,7 +120,8 @@ nsXBLResourceLoader::LoadResources(bool* aResult)
|
|||
// Passing nullptr for pretty much everything -- cause we don't care!
|
||||
// XXX: initialDocumentURI is nullptr!
|
||||
nsRefPtr<imgRequestProxy> req;
|
||||
nsContentUtils::LoadImage(url, doc, docPrincipal, docURL, nullptr,
|
||||
nsContentUtils::LoadImage(url, doc, docPrincipal, docURL,
|
||||
doc->GetReferrerPolicy(), nullptr,
|
||||
nsIRequest::LOAD_BACKGROUND, EmptyString(),
|
||||
getter_AddRefs(req));
|
||||
}
|
||||
|
|
|
@ -42,3 +42,4 @@ skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop spec
|
|||
[test_bug946815.html]
|
||||
skip-if = toolkit != "gonk"
|
||||
[test_bug1086996.xhtml]
|
||||
[test_bug1098628_throw_from_construct.xhtml]
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1098628
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 1098628</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<bindings xmlns="http://www.mozilla.org/xbl">
|
||||
<binding id="test">
|
||||
<implementation>
|
||||
<constructor><![CDATA[
|
||||
throw "flimfniffle";
|
||||
]]></constructor>
|
||||
</implementation>
|
||||
</binding>
|
||||
</bindings>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1098628">Mozilla Bug 1098628</a>
|
||||
<p id="display" style="-moz-binding: url(#test)"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
<![CDATA[
|
||||
|
||||
/** Test for Bug 1098628 **/
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.expectUncaughtException();
|
||||
SimpleTest.monitorConsole(SimpleTest.finish, [{errorMessage: new RegExp('flimfniffle')}]);
|
||||
addLoadEvent(function() {
|
||||
SimpleTest.executeSoon(SimpleTest.endMonitorConsole);
|
||||
});
|
||||
]]>
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -102,7 +102,7 @@ nsXMLPrettyPrinter::PrettyPrint(nsIDocument* aDocument,
|
|||
|
||||
nsCOMPtr<nsIDOMDocument> xslDocument;
|
||||
rv = nsSyncLoadService::LoadDocument(xslUri, nsContentUtils::GetSystemPrincipal(),
|
||||
nullptr, true,
|
||||
nullptr, true, mozilla::net::RP_Default,
|
||||
getter_AddRefs(xslDocument));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
|