зеркало из https://github.com/mozilla/pjs.git
Bug 362576 - autocomplete="off" should prevent filling passwords in addition to remembering passwords. r=gavin, ui-r=mconnor, a1.9=mconnor
This commit is contained in:
Родитель
2d4376eda4
Коммит
64cba76577
|
@ -715,6 +715,20 @@ LoginManager.prototype = {
|
|||
},
|
||||
|
||||
|
||||
/*
|
||||
* _isAutoCompleteDisabled
|
||||
*
|
||||
* Returns true if the page requests autocomplete be disabled for the
|
||||
* specified form input.
|
||||
*/
|
||||
_isAutocompleteDisabled : function (element) {
|
||||
if (element && element.hasAttribute("autocomplete") &&
|
||||
element.getAttribute("autocomplete").toLowerCase() == "off")
|
||||
return true;
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
/*
|
||||
* _onFormSubmit
|
||||
*
|
||||
|
@ -725,15 +739,6 @@ LoginManager.prototype = {
|
|||
*/
|
||||
_onFormSubmit : function (form) {
|
||||
|
||||
// local helper function
|
||||
function autocompleteDisabled(element) {
|
||||
if (element && element.hasAttribute("autocomplete") &&
|
||||
element.getAttribute("autocomplete").toLowerCase() == "off")
|
||||
return true;
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
// local helper function
|
||||
function getPrompter(aWindow) {
|
||||
var prompterSvc = Cc["@mozilla.org/login-manager/prompter;1"].
|
||||
|
@ -769,10 +774,10 @@ LoginManager.prototype = {
|
|||
// Check for autocomplete=off attribute. We don't use it to prevent
|
||||
// autofilling (for existing logins), but won't save logins when it's
|
||||
// present.
|
||||
if (autocompleteDisabled(form) ||
|
||||
autocompleteDisabled(usernameField) ||
|
||||
autocompleteDisabled(newPasswordField) ||
|
||||
autocompleteDisabled(oldPasswordField)) {
|
||||
if (this._isAutocompleteDisabled(form) ||
|
||||
this._isAutocompleteDisabled(usernameField) ||
|
||||
this._isAutocompleteDisabled(newPasswordField) ||
|
||||
this._isAutocompleteDisabled(oldPasswordField)) {
|
||||
this.log("(form submission ignored -- autocomplete=off found)");
|
||||
return;
|
||||
}
|
||||
|
@ -1014,7 +1019,20 @@ LoginManager.prototype = {
|
|||
if (usernameField)
|
||||
this._attachToInput(usernameField);
|
||||
|
||||
if (autofillForm) {
|
||||
// If the form has an autocomplete=off attribute in play, don't
|
||||
// fill in the login automatically. We check this after attaching
|
||||
// the autocomplete stuff to the username field, so the user can
|
||||
// still manually select a login to be filled in.
|
||||
var isFormDisabled = false;
|
||||
if (this._isAutocompleteDisabled(form) ||
|
||||
this._isAutocompleteDisabled(usernameField) ||
|
||||
this._isAutocompleteDisabled(passwordField)) {
|
||||
|
||||
isFormDisabled = true;
|
||||
this.log("form[" + i + "]: not filled, has autocomplete=off");
|
||||
}
|
||||
|
||||
if (autofillForm && !isFormDisabled) {
|
||||
|
||||
if (usernameField && usernameField.value) {
|
||||
// If username was specified in the form, only fill in the
|
||||
|
|
|
@ -15,14 +15,44 @@ Login Manager test: multiple login autocomplete
|
|||
<!-- we presumably can't hide the content for this test. -->
|
||||
<div id="content">
|
||||
|
||||
<!-- form1 tests multiple matching logins -->
|
||||
<form id="form1" action="http://autocomplete:8888/formtest.js" onsubmit="return false;">
|
||||
<input type="text" name="uname">
|
||||
<input type="password" name="pword">
|
||||
|
||||
<button type="submit">Submit</button>
|
||||
<button type="reset"> Reset </button>
|
||||
</form>
|
||||
|
||||
<!-- other forms test single logins, with autocomplete=off set -->
|
||||
<form id="form2" action="http://autocomplete2" onsubmit="return false;">
|
||||
<input type="text" name="uname">
|
||||
<input type="password" name="pword" autocomplete="off">
|
||||
<button type="submit">Submit</button>
|
||||
</form>
|
||||
|
||||
<form id="form3" action="http://autocomplete2" onsubmit="return false;">
|
||||
<input type="text" name="uname" autocomplete="off">
|
||||
<input type="password" name="pword">
|
||||
<button type="submit">Submit</button>
|
||||
</form>
|
||||
|
||||
<form id="form4" action="http://autocomplete2" onsubmit="return false;" autocomplete="off">
|
||||
<input type="text" name="uname">
|
||||
<input type="password" name="pword">
|
||||
<button type="submit">Submit</button>
|
||||
</form>
|
||||
|
||||
<form id="form5" action="http://autocomplete2" onsubmit="return false;">
|
||||
<input type="text" name="uname" autocomplete="off">
|
||||
<input type="password" name="pword" autocomplete="off">
|
||||
<button type="submit">Submit</button>
|
||||
</form>
|
||||
|
||||
<!-- control -->
|
||||
<form id="form6" action="http://autocomplete2" onsubmit="return false;">
|
||||
<input type="text" name="uname">
|
||||
<input type="password" name="pword">
|
||||
<button type="submit">Submit</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<pre id="test">
|
||||
|
@ -68,12 +98,18 @@ var login4 = new nsLoginInfo(
|
|||
"http://localhost:8888", "http://autocomplete:8888", null,
|
||||
"zzzuser4", "zzzpass4", "uname", "pword");
|
||||
|
||||
// login 5 only used in the single-user forms
|
||||
var login5 = new nsLoginInfo(
|
||||
"http://localhost:8888", "http://autocomplete2", null,
|
||||
"singleuser5", "singlepass5", "uname", "pword");
|
||||
|
||||
// try/catch in case someone runs the tests manually, twice.
|
||||
try {
|
||||
pwmgr.addLogin(login1);
|
||||
pwmgr.addLogin(login2);
|
||||
pwmgr.addLogin(login3);
|
||||
pwmgr.addLogin(login4);
|
||||
pwmgr.addLogin(login5);
|
||||
} catch (e) {
|
||||
ok(false, "addLogin threw: " + e);
|
||||
}
|
||||
|
@ -89,8 +125,9 @@ function restoreForm() {
|
|||
|
||||
// Check for expected username/password in form.
|
||||
function checkACForm(expectedUsername, expectedPassword) {
|
||||
is(uname.value, expectedUsername, "Checking form username");
|
||||
is(pword.value, expectedPassword, "Checking form password");
|
||||
var formID = uname.parentNode.id;
|
||||
is(uname.value, expectedUsername, "Checking " + formID + " username");
|
||||
is(pword.value, expectedPassword, "Checking " + formID + " password");
|
||||
}
|
||||
|
||||
|
||||
|
@ -407,8 +444,100 @@ function runTest(testNum) {
|
|||
checkACForm("", "");
|
||||
numLogins = pwmgr.countLogins("http://localhost:8888", "http://autocomplete:8888", null);
|
||||
is(numLogins, 0, "Correct number of logins after deleting one");
|
||||
testNum = 99;
|
||||
break;
|
||||
|
||||
|
||||
/* Tests for single-user forms with autocomplete=off */
|
||||
|
||||
case 100:
|
||||
// Turn our attention to form2
|
||||
uname = $_(2, "uname");
|
||||
pword = $_(2, "pword");
|
||||
checkACForm("", "");
|
||||
|
||||
// Trigger autocomplete popup
|
||||
restoreForm();
|
||||
doKey("down");
|
||||
break;
|
||||
|
||||
case 101:
|
||||
// Check first entry
|
||||
doKey("down");
|
||||
checkACForm("", ""); // value shouldn't update
|
||||
doKey("return"); // not "enter"!
|
||||
checkACForm("singleuser5", "singlepass5");
|
||||
break;
|
||||
|
||||
case 102:
|
||||
// Turn our attention to form3
|
||||
uname = $_(3, "uname");
|
||||
pword = $_(3, "pword");
|
||||
checkACForm("", "");
|
||||
|
||||
// Trigger autocomplete popup
|
||||
restoreForm();
|
||||
doKey("down");
|
||||
break;
|
||||
|
||||
case 103:
|
||||
// Check first entry
|
||||
doKey("down");
|
||||
checkACForm("", ""); // value shouldn't update
|
||||
doKey("return"); // not "enter"!
|
||||
checkACForm("singleuser5", "singlepass5");
|
||||
break;
|
||||
|
||||
case 104:
|
||||
// Turn our attention to form4
|
||||
uname = $_(4, "uname");
|
||||
pword = $_(4, "pword");
|
||||
checkACForm("", "");
|
||||
|
||||
// Trigger autocomplete popup
|
||||
restoreForm();
|
||||
doKey("down");
|
||||
break;
|
||||
|
||||
case 105:
|
||||
// Check first entry
|
||||
doKey("down");
|
||||
checkACForm("", ""); // value shouldn't update
|
||||
doKey("return"); // not "enter"!
|
||||
checkACForm("singleuser5", "singlepass5");
|
||||
break;
|
||||
|
||||
case 106:
|
||||
// Turn our attention to form5
|
||||
uname = $_(5, "uname");
|
||||
pword = $_(5, "pword");
|
||||
checkACForm("", "");
|
||||
|
||||
// Trigger autocomplete popup
|
||||
restoreForm();
|
||||
doKey("down");
|
||||
break;
|
||||
|
||||
case 107:
|
||||
// Check first entry
|
||||
doKey("down");
|
||||
checkACForm("", ""); // value shouldn't update
|
||||
doKey("return"); // not "enter"!
|
||||
checkACForm("singleuser5", "singlepass5");
|
||||
break;
|
||||
|
||||
case 108:
|
||||
// Turn our attention to form6
|
||||
// (this is a control, w/o autocomplete=off, to ensure the login
|
||||
// that was being suppressed would have been filled in otherwise)
|
||||
uname = $_(6, "uname");
|
||||
pword = $_(6, "pword");
|
||||
checkACForm("singleuser5", "singlepass5");
|
||||
|
||||
/* FALLTHRU */
|
||||
|
||||
default:
|
||||
pwmgr.removeLogin(login5);
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -161,10 +161,13 @@ function startTest() {
|
|||
numStartingLogins = countLogins();
|
||||
ok(numStartingLogins > 0, "counting logins at start");
|
||||
|
||||
// Check first set of forms, which should be filled by pwmgr.
|
||||
// Check first set of forms, which should not be filled by pwmgr.
|
||||
for (var i = 1; i <= 7; i++) {
|
||||
is($_(i, "uname").value, "testuser", "Checking for filled username " + i);
|
||||
is($_(i, "pword").value, "testpass", "Checking for filled password " + i);
|
||||
is($_(i, "uname").value, "", "Checking for unfilled username " + i);
|
||||
is($_(i, "pword").value, "", "Checking for unfilled password " + i);
|
||||
// Set the field values to that of an existing login
|
||||
$_(i, "uname").value = "testuser";
|
||||
$_(i, "pword").value = "testpass";
|
||||
}
|
||||
|
||||
// Check second set of forms, which should have preset values (and are unknown to pwmgr).
|
||||
|
|
|
@ -608,15 +608,21 @@ nsFormFillController::Focus(nsIDOMEvent* aEvent)
|
|||
|
||||
nsAutoString autocomplete;
|
||||
input->GetAttribute(NS_LITERAL_STRING("autocomplete"), autocomplete);
|
||||
|
||||
PRInt32 dummy;
|
||||
PRBool isPwmgrInput = PR_FALSE;
|
||||
if (mPwmgrInputs.Get(input, &dummy))
|
||||
isPwmgrInput = PR_TRUE;
|
||||
|
||||
if (type.LowerCaseEqualsLiteral("text") && !isReadOnly &&
|
||||
!autocomplete.LowerCaseEqualsLiteral("off")) {
|
||||
(!autocomplete.LowerCaseEqualsLiteral("off") || isPwmgrInput)) {
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLFormElement> form;
|
||||
input->GetForm(getter_AddRefs(form));
|
||||
if (form)
|
||||
form->GetAttribute(NS_LITERAL_STRING("autocomplete"), autocomplete);
|
||||
|
||||
if (!form || !autocomplete.LowerCaseEqualsLiteral("off"))
|
||||
if (!form || !autocomplete.LowerCaseEqualsLiteral("off") || isPwmgrInput)
|
||||
StartControllingInput(input);
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче