[e10s] Deleting a login via autocomplete doesn't work (tries to use storage from the content process)

RESOLVED FIXED in Firefox 48

Status

()

Toolkit
Password Manager
RESOLVED FIXED
2 years ago
a year ago

People

(Reporter: MattN, Assigned: mrbkap)

Tracking

({regression})

33 Branch
mozilla48
regression
Points:
---
Dependency tree / graph
Bug Flags:
in-testsuite +

Firefox Tracking Flags

(e10sm9+, firefox46 wontfix, firefox47 wontfix, firefox48 fixed)

Details

Attachments

(1 attachment, 2 obsolete attachments)

While making test_basic_form_autocomplete.html work in e10s (bug 1258860), it became obvious that deletion from autocomplete doesn't work properly.

STR:
1) Go to a form with a saved login
2) Delete (Windows/Linux) or Shift-Delete (OS X) to delete the login

Expected result:
Login is deleted from the autocomplete popup and storage

Actual result:
Login is removed from the autocomplete popup but not storage. The following error occurs in the Browser Console (at least with signon.debug=true):
> Removing login nsLoginManager.js:312
> TypeError: this._storage is null nsLoginManager.js:313:5
> NS_ERROR_XPC_JAVASCRIPT_ERROR_WITH_DETAILS: [JavaScript Error: "this._storage is null" {file: "file:///Users/matthew/repos/fx-team/obj-fx-opt/dist/Nightly.app/Contents/Resources/components/nsLoginManager.js" line: 313}]'[JavaScript Error: "this._storage is null" {file: "file:///Users/matthew/repos/fx-team/obj-fx-opt/dist/Nightly.app/Contents/Resources/components/nsLoginManager.js" line: 313}]' when calling method: [nsILoginManager::removeLogin] LoginManagerContent.jsm:1259
It's trying to use the login manager storage from the content process which is wrong.
Flags: in-testsuite+
Has Regression Range: --- → irrelevant
Has STR: --- → yes

Updated

2 years ago
Assignee: nobody → mrbkap
tracking-e10s: ? → m9+

Updated

2 years ago
status-firefox46: affected → wontfix
status-firefox47: affected → wontfix
(Assignee)

Comment 1

2 years ago
Created attachment 8735598 [details] [diff] [review]
Patch v1

This was pretty straightforward. I'm assuming that bug 1258860 will add a mochitest for this case.
Attachment #8735598 - Flags: review?(MattN+bmo)

Updated

2 years ago
status-firefox47: wontfix → affected
(Assignee)

Comment 2

2 years ago
Created attachment 8736046 [details] [diff] [review]
Patch v1.1

I forgot that LoginManagerContent is used in the parent process as well.

https://treeherder.mozilla.org/#/jobs?repo=try&revision=cc2eaee83428
Attachment #8736046 - Flags: review?(MattN+bmo)
(Assignee)

Updated

2 years ago
Attachment #8735598 - Attachment is obsolete: true
Attachment #8735598 - Flags: review?(MattN+bmo)
Sorry for the delay but I wanted to double check that the deletion won't race with the changing of results. Perhaps it may be okay because we do synchronous storage queries now but I haven't had time to audit it fully yet
Comment on attachment 8736046 [details] [diff] [review]
Patch v1.1

Review of attachment 8736046 [details] [diff] [review]:
-----------------------------------------------------------------

My main concern is potential for races between result changes and removals. Is the ordering of messages guaranteed in both directions? e.g.

=> RemoteLogins:autoCompleteLogins for "ab"
<= RemoteLogins:loginsAutoCompleted for "ab"
=> RemoteLogins:autoCompleteLogins for "abc"
=> RemoteLogins:removeValueAt 0 – Will this delete index 0 from the results for "ab" or "abc"? 
<= RemoteLogins:loginsAutoCompleted for "abc"

The user will be expecting the deletion from "ab" as that's what they see but in the parent the results for "abc" may be what gets deleted from. Can you help me understand if this can't happen?

https://wiki.mozilla.org/File:PasswordManagerRelationships.svg may be useful (though somewhat out of date since it hasn't been update in ~ 1 year).

::: toolkit/components/passwordmgr/LoginManagerContent.jsm
@@ +1177,5 @@
>    },
>  };
>  
>  // nsIAutoCompleteResult implementation
> +function UserAutoCompleteResult (aSearchString, matchingLogins, messageManager) {

Make it clear that the messageManager argument is optional: `messageManager = null`

@@ +1260,5 @@
>      if (this.defaultIndex > this.logins.length)
>        this.defaultIndex--;
>  
>      if (removeFromDB) {
> +      if (this._messageManager) {

I really wish this was handled properly by an e10s-compatible Autocomplete implementation. The current implementation seems like a band-aid over the proper architecture. I think it's okay for now as long as we aren't going to be racing. I may be touching autocomplete soon for another reason and maybe I'll find a way to simplify.

@@ +1261,5 @@
>        this.defaultIndex--;
>  
>      if (removeFromDB) {
> +      if (this._messageManager) {
> +        this._messageManager.sendAsyncMessage("RemoteLogins:removeValueAt",

Is there a reason we aren't just sending "FormAutoComplete:RemoveEntry"? It seems like we end up just forwarding to the same code. This autocomplete e10s situation is so confusing/messy that it really needs some rewriting like we talked about before.
Attachment #8736046 - Flags: review?(MattN+bmo)
Comment on attachment 8736046 [details] [diff] [review]
Patch v1.1

Review of attachment 8736046 [details] [diff] [review]:
-----------------------------------------------------------------

::: toolkit/components/passwordmgr/LoginManagerParent.jsm
@@ +290,5 @@
>      });
>    },
>  
> +  removeAutocompletedValueAt(index) {
> +    AutoCompleteE10S.removeEntry(index);

Also, why not inline this in the `case`?
(Assignee)

Comment 6

2 years ago
(In reply to Matthew N. [:MattN] from comment #4)
> The user will be expecting the deletion from "ab" as that's what they see
> but in the parent the results for "abc" may be what gets deleted from. Can
> you help me understand if this can't happen?

It looks like this can happen. We update the autocomplete result cache in the parent when we send loginsAutoCompleted, so there's a window where the parent and child are out of sync. I'll try to write a testcase for this tomorrow. The only fix I can think of is to add another message from the child to the parent: showAutoCompleteResults that shows the popup and updates the result cache in the parent.

> I really wish this was handled properly by an e10s-compatible Autocomplete
> implementation. The current implementation seems like a band-aid over the
> proper architecture. I think it's okay for now as long as we aren't going to
> be racing. I may be touching autocomplete soon for another reason and maybe
> I'll find a way to simplify.

Me too. The problem with the current setup is that nsAutoCompleteController expects to be able to control both the input element and the autocomplete popup at the same time. I briefly looked into fixing this a while back and didn't make too much headway.

> Is there a reason we aren't just sending "FormAutoComplete:RemoveEntry"? It
> seems like we end up just forwarding to the same code. This autocomplete

We keep the results in both processes: in AutoCompleteE10S._resultCache in the parent and in nsAutoCompleteController::mResults in the child. We have to remove the result's index in both of them in order to make sure they stay in sync. Otherwise, it'd be nice to avoid having to forward to basically the same code (though in a different process).

> e10s situation is so confusing/messy that it really needs some rewriting
> like we talked about before.

No argument from me here :-).

(In reply to Matthew N. [:MattN] from comment #5)
> Also, why not inline this in the `case`?

I'll do this. I was aiming for consistency with the other cases originally.
(In reply to Blake Kaplan (:mrbkap) (please use needinfo!) from comment #6)
> (In reply to Matthew N. [:MattN] from comment #4)
> > The user will be expecting the deletion from "ab" as that's what they see
> > but in the parent the results for "abc" may be what gets deleted from. Can
> > you help me understand if this can't happen?
> 
> It looks like this can happen. We update the autocomplete result cache in
> the parent when we send loginsAutoCompleted, so there's a window where the
> parent and child are out of sync. I'll try to write a testcase for this
> tomorrow. The only fix I can think of is to add another message from the
> child to the parent: showAutoCompleteResults that shows the popup and
> updates the result cache in the parent.

What I'll be changing shortly is for autocomplete to actually know which login an autocomplete entry refers to (instead of just the username text with the origins).

The preferred fix (which I haven't looked into the feasibility of) would be to have the child send the login ID or GUID to delete instead of an index. Then we don't need to care about the result cache at all in the parent or child (assuming the ID/GUID is tied to the entry being deleted).
Status: NEW → ASSIGNED
If bug 1258860 lands first, toolkit/components/passwordmgr/test/mochitest/test_basic_form_autocomplete.html should be enabled on e10s.
(Assignee)

Comment 9

2 years ago
Created attachment 8739606 [details] [diff] [review]
Patch v2

This patch grew a bit since I wanted to deal with nsILoginInfos outside of IPC on both sides of the IPC barrier. It's also unfortunate that guid is on nsILoginMetaData since that led to a bunch of QIs in various places.

With this patch, we do the DB deletion based on the GUID and then re-find the index in the parent (since it could have changed).

Try run: https://treeherder.mozilla.org/#/jobs?repo=try&revision=ae46fe6a1a62
Attachment #8739606 - Flags: review?(MattN+bmo)
(Assignee)

Updated

2 years ago
Attachment #8736046 - Attachment is obsolete: true
Comment on attachment 8739606 [details] [diff] [review]
Patch v2

Review of attachment 8739606 [details] [diff] [review]:
-----------------------------------------------------------------

Don't forget to enable the test test_basic_form_autocomplete.html for e10s.

r=me but if we can always use "RemoteLogins:removeLogin" I would prefer it.

::: toolkit/components/passwordmgr/LoginHelper.jsm
@@ +408,5 @@
> +   * sending over IPC.
> +   *
> +   * NB: All members of nsILoginInfo and nsILoginMetaInfo are strings.
> +   */
> +  loginsToVanillaObjects(logins) {

Thanks for moving the helpers here

::: toolkit/components/passwordmgr/LoginManagerContent.jsm
@@ +1264,5 @@
> +        let vanilla = LoginHelper.loginToVanillaObject(removedLogin);
> +        this._messageManager.sendAsyncMessage("RemoteLogins:removeLogin",
> +                                              { login: vanilla });
> +      } else {
> +        Services.logins.removeLogin(removedLogin);

Why can't we always use the e10s path? Then we wouldn't need the `Services.appinfo.processType === Services.appinfo.PROCESS_TYPE_CONTENT` code either
Attachment #8739606 - Flags: review?(MattN+bmo) → review+
(Assignee)

Comment 11

2 years ago
(In reply to Matthew N. [:MattN] (behind on reviews) from comment #10)
> Why can't we always use the e10s path? Then we wouldn't need the
> `Services.appinfo.processType === Services.appinfo.PROCESS_TYPE_CONTENT`
> code either

I looked into doing this and it doesn't really make sense. The difference is that in e10s, when we're in UserAutoCompleteResult.removeValueAt, we have to remove the value both in the child process's array and in the parent's array (as well as from the database). In the parent, we only have to do the work once, in one place (and we'd have to manually grab the autocomplete controller and avoid recurring over and over). Once we figure out how to get rid of AutoCompleteE10S, we could do this.

Comment 12

2 years ago
https://hg.mozilla.org/integration/mozilla-inbound/rev/04db9fe12e08

Comment 13

2 years ago
bugherder
https://hg.mozilla.org/mozilla-central/rev/04db9fe12e08
Status: ASSIGNED → RESOLVED
Last Resolved: 2 years ago
status-firefox48: affected → fixed
Resolution: --- → FIXED
Target Milestone: --- → mozilla48
(Quoting Matthew N. [:MattN] (behind on reviews) from comment #10)
> Don't forget to enable the test test_basic_form_autocomplete.html for e10s.

Looks like you forgot after all…

https://hg.mozilla.org/integration/fx-team/rev/07e1879a0c09
Backed out in https://hg.mozilla.org/integration/fx-team/rev/59fe5c482a55 for test failures like https://treeherder.mozilla.org/logviewer.html#?job_id=8806419&repo=fx-team
Flags: needinfo?(mrbkap)

Comment 16

2 years ago
https://hg.mozilla.org/integration/fx-team/rev/ea364e7948e2
That was my follow-up test patch that bounced in comment 15
Flags: needinfo?(mrbkap)

Comment 18

2 years ago
bugherder
https://hg.mozilla.org/mozilla-central/rev/ea364e7948e2
Marking status-firefox47=wontfix unless Matt thinks we should uplift his e10s passwordmgr test fix to 47.
status-firefox47: affected → wontfix
Version: unspecified → 33 Branch
You need to log in before you can comment on or make changes to this bug.