Backed out 5 changesets (bug 1304001) for dom/html/test/test_bug430351.html failures CLOSED TREE

Backed out changeset 275c3744e059 (bug 1304001)
Backed out changeset c9628639b5e1 (bug 1304001)
Backed out changeset 7d8f97779a35 (bug 1304001)
Backed out changeset a5644de3c2f5 (bug 1304001)
Backed out changeset e23ef4dbbc7f (bug 1304001)
This commit is contained in:
Bogdan Tara 2019-02-22 05:05:56 +02:00
parent 2a0c67f00f
commit de6fb7d842
7 changed files with 121 additions and 125 deletions

View File

@ -45,7 +45,7 @@ addEventListener("DOMFormHasPassword", function(event) {
if (shouldIgnoreLoginManagerEvent(event)) {
return;
}
LoginManagerContent.onDOMFormHasPassword(event);
LoginManagerContent.onDOMFormHasPassword(event, content);
let formLike = LoginFormFactory.createFromForm(event.originalTarget);
InsecurePasswordUtils.reportInsecurePasswords(formLike);
});
@ -53,7 +53,7 @@ addEventListener("DOMInputPasswordAdded", function(event) {
if (shouldIgnoreLoginManagerEvent(event)) {
return;
}
LoginManagerContent.onDOMInputPasswordAdded(event);
LoginManagerContent.onDOMInputPasswordAdded(event, content);
let formLike = LoginFormFactory.createFromField(event.originalTarget);
InsecurePasswordUtils.reportInsecurePasswords(formLike);
});

View File

@ -718,9 +718,8 @@ nsContextMenu.prototype = {
// don't want to show the form fill option.
let showFill = loginFillInfo && loginFillInfo.passwordField.found;
// Disable the fill option if the user hasn't unlocked with their master password
// Disable the fill option if the user has set a master password
// or if the password field or target field are disabled.
// XXX: Bug 1529025 to respect signon.rememberSignons
let disableFill = !loginFillInfo ||
!Services.logins ||
!Services.logins.isLoggedIn ||

View File

@ -230,14 +230,14 @@ BrowserCLH.prototype = {
if (shouldIgnoreLoginManagerEvent(event)) {
return;
}
this.LoginManagerContent.onDOMFormHasPassword(event);
this.LoginManagerContent.onDOMFormHasPassword(event, event.target.ownerGlobal.top);
}, options);
aWindow.addEventListener("DOMInputPasswordAdded", event => {
if (shouldIgnoreLoginManagerEvent(event)) {
return;
}
this.LoginManagerContent.onDOMInputPasswordAdded(event);
this.LoginManagerContent.onDOMInputPasswordAdded(event, event.target.ownerGlobal.top);
}, options);
aWindow.addEventListener("DOMAutoComplete", event => {
@ -250,7 +250,7 @@ BrowserCLH.prototype = {
aWindow.addEventListener("pageshow", event => {
// XXXbz what about non-HTML documents??
if (ChromeUtils.getClassName(event.target) == "HTMLDocument") {
this.LoginManagerContent.onPageShow(event);
this.LoginManagerContent.onPageShow(event, event.target.defaultView.top);
}
}, options);
},

View File

@ -21,57 +21,49 @@ var EXPORTED_SYMBOLS = [
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
// LoginHelper
/**
* Contains functions shared by different Login Manager components.
*/
var LoginHelper = {
debug: null,
enabled: null,
formlessCaptureEnabled: null,
schemeUpgrades: null,
insecureAutofill: null,
privateBrowsingCaptureEnabled: null,
init() {
// Watch for pref changes to update cached pref values.
Services.prefs.addObserver("signon.", () => this.updateSignonPrefs());
this.updateSignonPrefs();
},
updateSignonPrefs() {
this.autofillForms = Services.prefs.getBoolPref("signon.autofillForms");
this.debug = Services.prefs.getBoolPref("signon.debug");
this.enabled = Services.prefs.getBoolPref("signon.rememberSignons");
this.formlessCaptureEnabled = Services.prefs.getBoolPref("signon.formlessCapture.enabled");
this.insecureAutofill = Services.prefs.getBoolPref("signon.autofillForms.http");
this.privateBrowsingCaptureEnabled =
Services.prefs.getBoolPref("signon.privateBrowsingCapture.enabled");
this.schemeUpgrades = Services.prefs.getBoolPref("signon.schemeUpgrades");
this.storeWhenAutocompleteOff = Services.prefs.getBoolPref("signon.storeWhenAutocompleteOff");
},
/**
* Warning: these only update if a logger was created.
*/
debug: Services.prefs.getBoolPref("signon.debug"),
formlessCaptureEnabled: Services.prefs.getBoolPref("signon.formlessCapture.enabled"),
schemeUpgrades: Services.prefs.getBoolPref("signon.schemeUpgrades"),
insecureAutofill: Services.prefs.getBoolPref("signon.autofillForms.http"),
privateBrowsingCaptureEnabled:
Services.prefs.getBoolPref("signon.privateBrowsingCapture.enabled"),
createLogger(aLogPrefix) {
let getMaxLogLevel = () => {
return this.debug ? "Debug" : "Warn";
return this.debug ? "debug" : "warn";
};
let logger;
function getConsole() {
if (!logger) {
// Create a new instance of the ConsoleAPI so we can control the maxLogLevel with a pref.
let ConsoleAPI = ChromeUtils.import("resource://gre/modules/Console.jsm", {}).ConsoleAPI;
let consoleOptions = {
maxLogLevel: getMaxLogLevel(),
prefix: aLogPrefix,
};
logger = console.createInstance(consoleOptions);
logger = new ConsoleAPI(consoleOptions);
}
return logger;
}
// Watch for pref changes and update this.debug and the maxLogLevel for created loggers
Services.prefs.addObserver("signon.debug", () => {
Services.prefs.addObserver("signon.", () => {
this.debug = Services.prefs.getBoolPref("signon.debug");
this.formlessCaptureEnabled = Services.prefs.getBoolPref("signon.formlessCapture.enabled");
this.schemeUpgrades = Services.prefs.getBoolPref("signon.schemeUpgrades");
this.insecureAutofill = Services.prefs.getBoolPref("signon.autofillForms.http");
this.privateBrowsingCaptureEnabled =
Services.prefs.getBoolPref("signon.privateBrowsingCapture.enabled");
if (logger) {
logger.maxLogLevel = getMaxLogLevel();
}
@ -218,43 +210,6 @@ var LoginHelper = {
return aURL;
},
/**
* Get the parts of the URL we want for identification.
* Strip out things like the userPass portion and handle javascript:.
*/
getLoginOrigin(uriString, allowJS) {
let realm = "";
try {
let uri = Services.io.newURI(uriString);
if (allowJS && uri.scheme == "javascript") {
return "javascript:";
}
// Build this manually instead of using prePath to avoid including the userPass portion.
realm = uri.scheme + "://" + uri.displayHostPort;
} catch (e) {
// bug 159484 - disallow url types that don't support a hostPort.
// (although we handle "javascript:..." as a special case above.)
log.warn("Couldn't parse origin for", uriString, e);
realm = null;
}
return realm;
},
getFormActionOrigin(form) {
let uriString = form.action;
// A blank or missing action submits to where it came from.
if (uriString == "") {
// ala bug 297761
uriString = form.baseURI;
}
return this.getLoginOrigin(uriString, true);
},
/**
* @param {String} aLoginOrigin - An origin value from a stored login's
* hostname or formSubmitURL properties.
@ -831,8 +786,6 @@ var LoginHelper = {
},
};
LoginHelper.init();
XPCOMUtils.defineLazyPreferenceGetter(LoginHelper, "showInsecureFieldWarning",
"security.insecure_field_warning.contextual.enabled");

View File

@ -2,13 +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/. */
/**
* Module doing most of the content process work for the password manager.
*/
// Disable use-ownerGlobal since FormLike don't have it.
/* eslint-disable mozilla/use-ownerGlobal */
"use strict";
var EXPORTED_SYMBOLS = [ "LoginManagerContent",
@ -47,6 +40,8 @@ Services.cpmm.addMessageListener("clearRecipeCache", () => {
LoginRecipesContent._clearRecipeCache();
});
// These mirror signon.* prefs.
var gEnabled, gAutofillForms, gStoreWhenAutocompleteOff;
var gLastRightClickTimeStamp = Number.NEGATIVE_INFINITY;
var observer = {
@ -73,6 +68,12 @@ var observer = {
return true; // Always return true, or form submit will be canceled.
},
onPrefChange() {
gEnabled = Services.prefs.getBoolPref("signon.rememberSignons");
gAutofillForms = Services.prefs.getBoolPref("signon.autofillForms");
gStoreWhenAutocompleteOff = Services.prefs.getBoolPref("signon.storeWhenAutocompleteOff");
},
// nsIWebProgressListener
onLocationChange(aWebProgress, aRequest, aLocation, aFlags) {
// Only handle pushState/replaceState here.
@ -117,7 +118,7 @@ var observer = {
return;
}
if (!LoginHelper.enabled) {
if (!gEnabled) {
return;
}
@ -146,6 +147,11 @@ var observer = {
};
Services.obs.addObserver(observer, "earlyformsubmit");
var prefBranch = Services.prefs.getBranch("signon.");
prefBranch.addObserver("", observer.onPrefChange);
observer.onPrefChange(); // read initial values
// This object maps to the "child" process (even in the single-process case).
var LoginManagerContent = {
@ -164,10 +170,8 @@ var LoginManagerContent = {
.getService(Ci.nsIUUIDGenerator).generateUUID().toString();
},
_messages: [
"RemoteLogins:loginsFound",
"RemoteLogins:loginsAutoCompleted",
],
_messages: [ "RemoteLogins:loginsFound",
"RemoteLogins:loginsAutoCompleted" ],
/**
* WeakMap of the root element of a FormLike to the FormLike representing its fields.
@ -243,10 +247,10 @@ var LoginManagerContent = {
return deferred.promise;
},
receiveMessage(msg, topWindow) {
receiveMessage(msg, window) {
if (msg.name == "RemoteLogins:fillForm") {
this.fillForm({
topDocument: topWindow.document,
topDocument: window.document,
loginFormOrigin: msg.data.loginFormOrigin,
loginsFound: LoginHelper.vanillaObjectsToLogins(msg.data.logins),
recipes: msg.data.recipes,
@ -268,7 +272,8 @@ var LoginManagerContent = {
}
case "RemoteLogins:loginsAutoCompleted": {
let loginsFound = LoginHelper.vanillaObjectsToLogins(msg.data.logins);
let loginsFound =
LoginHelper.vanillaObjectsToLogins(msg.data.logins);
let messageManager = msg.target;
request.promise.resolve({ logins: loginsFound, messageManager });
break;
@ -287,11 +292,11 @@ var LoginManagerContent = {
let doc = form.ownerDocument;
let win = doc.defaultView;
let formOrigin = LoginHelper.getLoginOrigin(doc.documentURI);
let formOrigin = LoginUtils._getPasswordOrigin(doc.documentURI);
if (!formOrigin) {
return Promise.reject("_getLoginDataFromParent: A form origin is required");
}
let actionOrigin = LoginHelper.getFormActionOrigin(form);
let actionOrigin = LoginUtils._getActionOrigin(form);
let messageManager = win.docShell.messageManager;
@ -312,8 +317,8 @@ var LoginManagerContent = {
let form = LoginFormFactory.createFromField(aElement);
let win = doc.defaultView;
let formOrigin = LoginHelper.getLoginOrigin(doc.documentURI);
let actionOrigin = LoginHelper.getFormActionOrigin(form);
let formOrigin = LoginUtils._getPasswordOrigin(doc.documentURI);
let actionOrigin = LoginUtils._getActionOrigin(form);
let messageManager = win.docShell.messageManager;
@ -339,7 +344,7 @@ var LoginManagerContent = {
setupEventListeners(global) {
global.addEventListener("pageshow", (event) => {
this.onPageShow(event);
this.onPageShow(event, global.content);
});
global.addEventListener("blur", (event) => {
this.onUsernameInput(event);
@ -363,7 +368,7 @@ var LoginManagerContent = {
}
},
onDOMFormHasPassword(event) {
onDOMFormHasPassword(event, window) {
if (!event.isTrusted) {
return;
}
@ -371,10 +376,10 @@ var LoginManagerContent = {
let form = event.target;
let formLike = LoginFormFactory.createFromForm(form);
log("onDOMFormHasPassword:", form, formLike);
this._fetchLoginsFromParentAndFillForm(formLike);
this._fetchLoginsFromParentAndFillForm(formLike, window);
},
onDOMInputPasswordAdded(event) {
onDOMInputPasswordAdded(event, window) {
if (!event.isTrusted) {
return;
}
@ -385,7 +390,6 @@ var LoginManagerContent = {
return;
}
let window = pwField.ownerGlobal;
// Only setup the listener for formless inputs.
// Capture within a <form> but without a submit event is bug 1287202.
this.setupProgressListener(window);
@ -404,7 +408,7 @@ var LoginManagerContent = {
let formLike2 = this._formLikeByRootElement.get(formLike.rootElement);
log("Running deferred processing of onDOMInputPasswordAdded", formLike2);
this._deferredPasswordAddedTasksByRootElement.delete(formLike2.rootElement);
this._fetchLoginsFromParentAndFillForm(formLike2);
this._fetchLoginsFromParentAndFillForm(formLike2, window);
}, PASSWORD_INPUT_ADDED_COALESCING_THRESHOLD_MS, 0);
this._deferredPasswordAddedTasksByRootElement.set(formLike.rootElement, deferredTask);
@ -430,15 +434,15 @@ var LoginManagerContent = {
* Fetch logins from the parent for a given form and then attempt to fill it.
*
* @param {FormLike} form to fetch the logins for then try autofill.
* @param {Window} window
*/
_fetchLoginsFromParentAndFillForm(form) {
let window = form.ownerDocument.defaultView;
this._detectInsecureFormLikes(window.top);
_fetchLoginsFromParentAndFillForm(form, window) {
this._detectInsecureFormLikes(window);
let messageManager = window.docShell.messageManager;
messageManager.sendAsyncMessage("LoginStats:LoginEncountered");
if (!LoginHelper.enabled) {
if (!gEnabled) {
return;
}
@ -447,8 +451,7 @@ var LoginManagerContent = {
.catch(Cu.reportError);
},
onPageShow(event) {
let window = event.target.ownerGlobal;
onPageShow(event, window) {
this._detectInsecureFormLikes(window);
},
@ -530,10 +533,10 @@ var LoginManagerContent = {
log("fillForm: No input element specified");
return;
}
if (LoginHelper.getLoginOrigin(topDocument.documentURI) != loginFormOrigin) {
if (LoginUtils._getPasswordOrigin(topDocument.documentURI) != loginFormOrigin) {
if (!inputElement ||
LoginHelper.getLoginOrigin(inputElement.ownerDocument.documentURI) != loginFormOrigin) {
log("fillForm: The requested origin doesn't match the one from the",
LoginUtils._getPasswordOrigin(inputElement.ownerDocument.documentURI) != loginFormOrigin) {
log("fillForm: The requested origin doesn't match the one form the",
"document. This may mean we navigated to a document from a different",
"site before we had a chance to indicate this change in the user",
"interface.");
@ -558,9 +561,9 @@ var LoginManagerContent = {
loginsFound({ form, loginsFound, recipes }) {
let doc = form.ownerDocument;
let autofillForm = LoginHelper.autofillForms && !PrivateBrowsingUtils.isContentWindowPrivate(doc.defaultView);
let autofillForm = gAutofillForms && !PrivateBrowsingUtils.isContentWindowPrivate(doc.defaultView);
let formOrigin = LoginHelper.getLoginOrigin(doc.documentURI);
let formOrigin = LoginUtils._getPasswordOrigin(doc.documentURI);
LoginRecipesContent.cacheRecipes(formOrigin, doc.defaultView, recipes);
this._fillForm(form, loginsFound, recipes, {autofillForm});
@ -610,7 +613,7 @@ var LoginManagerContent = {
return;
}
if (!LoginHelper.enabled) {
if (!gEnabled) {
return;
}
@ -647,7 +650,7 @@ var LoginManagerContent = {
let acForm = LoginFormFactory.createFromField(acInputField);
let doc = acForm.ownerDocument;
let formOrigin = LoginHelper.getLoginOrigin(doc.documentURI);
let formOrigin = LoginUtils._getPasswordOrigin(doc.documentURI);
let recipes = LoginRecipesContent.getRecipes(formOrigin, doc.defaultView);
// Make sure the username field fillForm will use is the
@ -938,18 +941,18 @@ var LoginManagerContent = {
return;
}
// If password saving is disabled globally, bail out now.
if (!LoginHelper.enabled) {
// If password saving is disabled (globally or for host), bail out now.
if (!gEnabled) {
return;
}
var hostname = LoginHelper.getLoginOrigin(doc.documentURI);
var hostname = LoginUtils._getPasswordOrigin(doc.documentURI);
if (!hostname) {
log("(form submission ignored -- invalid hostname)");
return;
}
let formSubmitURL = LoginHelper.getFormActionOrigin(form);
let formSubmitURL = LoginUtils._getActionOrigin(form);
let messageManager = win.docShell.messageManager;
let recipes = LoginRecipesContent.getRecipes(hostname, win);
@ -971,7 +974,7 @@ var LoginManagerContent = {
this._isAutocompleteDisabled(usernameField) ||
this._isAutocompleteDisabled(newPasswordField) ||
this._isAutocompleteDisabled(oldPasswordField)) &&
!LoginHelper.storeWhenAutocompleteOff) {
!gStoreWhenAutocompleteOff) {
log("(form submission ignored -- autocomplete=off found)");
return;
}
@ -1404,7 +1407,7 @@ var LoginManagerContent = {
let form = LoginFormFactory.createFromField(aField);
let doc = aField.ownerDocument;
let formOrigin = LoginHelper.getLoginOrigin(doc.documentURI);
let formOrigin = LoginUtils._getPasswordOrigin(doc.documentURI);
let recipes = LoginRecipesContent.getRecipes(formOrigin, doc.defaultView);
return this._getFormFields(form, false, recipes);
@ -1452,6 +1455,44 @@ var LoginManagerContent = {
},
};
var LoginUtils = {
/**
* Get the parts of the URL we want for identification.
* Strip out things like the userPass portion
*/
_getPasswordOrigin(uriString, allowJS) {
var realm = "";
try {
var uri = Services.io.newURI(uriString);
if (allowJS && uri.scheme == "javascript") {
return "javascript:";
}
// Build this manually instead of using prePath to avoid including the userPass portion.
realm = uri.scheme + "://" + uri.displayHostPort;
} catch (e) {
// bug 159484 - disallow url types that don't support a hostPort.
// (although we handle "javascript:..." as a special case above.)
log("Couldn't parse origin for", uriString, e);
realm = null;
}
return realm;
},
_getActionOrigin(form) {
var uriString = form.action;
// A blank or missing action submits to where it came from.
if (uriString == "") {
uriString = form.baseURI;
} // ala bug 297761
return this._getPasswordOrigin(uriString, true);
},
};
// nsIAutoCompleteResult implementation
function UserAutoCompleteResult(aSearchString, matchingLogins, {isSecure, messageManager, isPasswordField}) {
function loginSort(a, b) {
@ -1631,7 +1672,7 @@ var LoginFormFactory = {
*/
createFromForm(aForm) {
let formLike = FormLikeFactory.createFromForm(aForm);
formLike.action = LoginHelper.getFormActionOrigin(aForm);
formLike.action = LoginUtils._getActionOrigin(aForm);
let state = LoginManagerContent.stateForDocument(formLike.ownerDocument);
state.loginFormRootElements.add(formLike.rootElement);
@ -1669,7 +1710,7 @@ var LoginFormFactory = {
}
let formLike = FormLikeFactory.createFromField(aField);
formLike.action = LoginHelper.getLoginOrigin(aField.ownerDocument.baseURI);
formLike.action = LoginUtils._getPasswordOrigin(aField.ownerDocument.baseURI);
log("Created non-form FormLike for rootElement:", aField.ownerDocument.documentElement);
let state = LoginManagerContent.stateForDocument(formLike.ownerDocument);

View File

@ -1,9 +1,10 @@
/**
* Test for LoginHelper.getLoginOrigin
/*
* Test for LoginUtils._getPasswordOrigin
*/
"use strict";
const LMCBackstagePass = ChromeUtils.import("resource://gre/modules/LoginManagerContent.jsm", null);
const TESTCASES = [
["javascript:void(0);", null],
["javascript:void(0);", "javascript:", true],
@ -22,6 +23,6 @@ const TESTCASES = [
];
for (let [input, expected, allowJS] of TESTCASES) {
let actual = LoginHelper.getLoginOrigin(input, allowJS);
let actual = LMCBackstagePass.LoginUtils._getPasswordOrigin(input, allowJS);
Assert.strictEqual(actual, expected, "Checking: " + input);
}

View File

@ -1,9 +1,11 @@
/**
/*
* Test for LoginManagerContent.getUserNameAndPasswordFields
*/
"use strict";
// Services.prefs.setBoolPref("signon.debug", true);
XPCOMUtils.defineLazyGlobalGetters(this, ["URL"]);
const LMCBackstagePass = ChromeUtils.import("resource://gre/modules/LoginManagerContent.jsm", null);
@ -93,7 +95,7 @@ for (let tc of TESTCASES) {
Object.defineProperty(document, "defaultView", {
value: win,
});
let formOrigin = LoginHelper.getLoginOrigin(document.documentURI);
let formOrigin = LMCBackstagePass.LoginUtils._getPasswordOrigin(document.documentURI);
LoginRecipesContent.cacheRecipes(formOrigin, win, new Set());
let actual = LoginManagerContent.getUserNameAndPasswordFields(input);