Merge m-c to b2g-inbound a=merge

This commit is contained in:
Wes Kocher 2014-11-18 18:38:12 -08:00
Родитель b166365411 7c47e9fc4e
Коммит 767aa6440d
273 изменённых файлов: 5250 добавлений и 1976 удалений

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

@ -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;
}

Двоичные данные
browser/components/loop/content/shared/img/02.png Normal file

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

После

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

Двоичные данные
browser/components/loop/content/shared/img/02@2x.png Normal file

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

После

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

Двоичные данные
browser/components/loop/content/shared/img/movistar.png Normal file

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

После

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

Двоичные данные
browser/components/loop/content/shared/img/movistar@2x.png Normal file

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

После

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

Двоичные данные
browser/components/loop/content/shared/img/telefonica.png Normal file

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

После

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

Двоичные данные
browser/components/loop/content/shared/img/telefonica@2x.png Normal file

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

После

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

Двоичные данные
browser/components/loop/content/shared/img/vivo.png Normal file

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

После

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

Двоичные данные
browser/components/loop/content/shared/img/vivo@2x.png Normal file

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

После

Ширина:  |  Высота:  |  Размер: 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

269
dom/base/test/bug704320.sjs Normal file
Просмотреть файл

@ -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 attributes
// 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);

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