Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document leak on pages with text input forms such as google.com #13764

Merged
merged 1 commit into from May 12, 2023

Conversation

cdumez
Copy link
Contributor

@cdumez cdumez commented May 11, 2023

b9a32bf

Document leak on pages with text input forms such as google.com
https://bugs.webkit.org/show_bug.cgi?id=256404
rdar://108975202

Reviewed by Wenson Hsieh and Ryosuke Niwa.

When typing test in a text input field and then navigating away, the
text field's document would leak. It would be kept alive via a
WebUndoStep stored in the WebPage::m_undoStepMap map.

FrameLoader::closeURL() was calling Editor::clearUndoRedoOperations()
to clear those WebUndoSteps on the WebPage. However, it ended up being
a no-op because Editor::client() would return null because the document
was already detached from the frame and the EditorClient is stored on
the Page. This happens in particular when the previous page was put in
the back/forward cache.

To address the issue, I updated Editor to store a WeakPtr to the
EditorClient object so that it is always able to tell the client to
clear operations if the Page/EditorClient are still alive.

* Source/WebCore/editing/Editor.cpp:
(WebCore::Editor::client const):
(WebCore::Editor::Editor):
* Source/WebCore/editing/Editor.h:

Canonical link: https://commits.webkit.org/264022@main

54b53fa

Misc iOS, tvOS & watchOS macOS Linux Windows
βœ… πŸ§ͺ style βœ… πŸ›  ios βœ… πŸ›  mac βœ… πŸ›  wpe βœ… πŸ›  wincairo
βœ… πŸ§ͺ bindings βœ… πŸ›  ios-sim βœ… πŸ›  mac-AS-debug βœ… πŸ§ͺ wpe-wk2
βœ… πŸ§ͺ webkitperl βœ… πŸ§ͺ ios-wk2 βœ… πŸ§ͺ api-mac βœ… πŸ›  gtk
βœ… πŸ§ͺ ios-wk2-wpt βœ… πŸ§ͺ mac-wk1 βœ… πŸ§ͺ gtk-wk2
βœ… πŸ§ͺ api-ios βœ… πŸ§ͺ mac-wk2 βœ… πŸ§ͺ api-gtk
βœ… πŸ›  tv βœ… πŸ§ͺ mac-AS-debug-wk2
βœ… πŸ›  tv-sim βœ… πŸ§ͺ mac-wk2-stress
βœ… πŸ›  watch
βœ… πŸ›  πŸ§ͺ unsafe-merge βœ… πŸ›  watch-sim

@cdumez cdumez self-assigned this May 11, 2023
@cdumez cdumez added the Forms For bugs specific to form elements (checkboxes, buttons, text fields, etc.) label May 11, 2023
@cdumez cdumez requested review from whsieh and rreno May 11, 2023 19:14
@cdumez
Copy link
Contributor Author

cdumez commented May 11, 2023

I will try to write a layout test.

@cdumez cdumez force-pushed the 256404_UndoSteps_doc_leak branch from aff8850 to 36a95c9 Compare May 11, 2023 20:39
@cdumez
Copy link
Contributor Author

cdumez commented May 11, 2023

Added a layout test.

@rreno
Copy link
Member

rreno commented May 11, 2023

Should we also clear the state kept in the UIProcess? WebPageProxy::registerEditCommand adds a command proxy object for the undo steps we'll be clearing in the Web process. I didn't see the code path for clearing commands get hit in my manual tests.

@cdumez
Copy link
Contributor Author

cdumez commented May 11, 2023

Should we also clear the state kept in the UIProcess? WebPageProxy::registerEditCommand adds a command proxy object for the undo steps we'll be clearing in the Web process. I didn't see the code path for clearing commands get hit in my manual tests.

I'll check but Editor::clearUndoRedoOperations() actually ends up sending an IPC to the WebPageProxy in the UIProcess and then UIProcess then sends an IPC back to the WebProcess asking the WebPage to clear the undoSteps. I would assume the WebPageProxy clears them too given that we told it too.

@cdumez
Copy link
Contributor Author

cdumez commented May 11, 2023

Should we also clear the state kept in the UIProcess? WebPageProxy::registerEditCommand adds a command proxy object for the undo steps we'll be clearing in the Web process. I didn't see the code path for clearing commands get hit in my manual tests.

I'll check but Editor::clearUndoRedoOperations() actually ends up sending an IPC to the WebPageProxy in the UIProcess and then UIProcess then sends an IPC back to the WebProcess asking the WebPage to clear the undoSteps. I would assume the WebPageProxy clears them too given that we told it too.

With my patch, I see the WebEditCommandProxy destructor getting called in the UIProcess.

@cdumez cdumez marked this pull request as ready for review May 11, 2023 21:50
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label May 11, 2023
@cdumez cdumez removed the merging-blocked Applied to prevent a change from being merged label May 11, 2023
@cdumez cdumez force-pushed the 256404_UndoSteps_doc_leak branch from 36a95c9 to 62f95d5 Compare May 11, 2023 23:48
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label May 12, 2023
@cdumez cdumez removed the merging-blocked Applied to prevent a change from being merged label May 12, 2023
@cdumez cdumez force-pushed the 256404_UndoSteps_doc_leak branch from 62f95d5 to be62b9c Compare May 12, 2023 05:09
@cdumez cdumez requested a review from rniwa May 12, 2023 14:36
@cdumez
Copy link
Contributor Author

cdumez commented May 12, 2023

Re-requesting review as I had to make a few changes to make all tests pass.

@rreno
Copy link
Member

rreno commented May 12, 2023

Classic. Reverse member order destruction.
LGTM but you'll need an official r+ since I'm not a reviewer.

@cdumez
Copy link
Contributor Author

cdumez commented May 12, 2023

Classic. Reverse member order destruction. LGTM but you'll need an official r+ since I'm not a reviewer.

It is actually about construction. We need to make sure the EditorClient gets constructed before the main frame and thus its document. This is because the Document constructor will construct the "Editor" which now grabs the EditorClient from the Page.

@rreno
Copy link
Member

rreno commented May 12, 2023

Classic. Reverse member order destruction. LGTM but you'll need an official r+ since I'm not a reviewer.

It is actually about construction. We need to make sure the EditorClient gets constructed before the main frame and thus its document. This is because the Document constructor will construct the "Editor" which now grabs the EditorClient from the Page.

Ah I was looking at the crashes which looked like they asserted on the EditorClient having already been destroyed before we got to the Frame destructor.

Copy link
Member

@whsieh whsieh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with a question.

@cdumez cdumez force-pushed the 256404_UndoSteps_doc_leak branch from be62b9c to 54b53fa Compare May 12, 2023 17:31
if (Page* page = m_document.page())
return &page->editorClient();
return nullptr;
ASSERT(!m_client || !m_document.page() || m_client == &m_document.page()->editorClient());
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@whsieh I added the assertion here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense β€” thanks!

@cdumez cdumez added the unsafe-merge-queue Applied to send a pull request to merge-queue, but skip building and testing label May 12, 2023
https://bugs.webkit.org/show_bug.cgi?id=256404
rdar://108975202

Reviewed by Wenson Hsieh and Ryosuke Niwa.

When typing test in a text input field and then navigating away, the
text field's document would leak. It would be kept alive via a
WebUndoStep stored in the WebPage::m_undoStepMap map.

FrameLoader::closeURL() was calling Editor::clearUndoRedoOperations()
to clear those WebUndoSteps on the WebPage. However, it ended up being
a no-op because Editor::client() would return null because the document
was already detached from the frame and the EditorClient is stored on
the Page. This happens in particular when the previous page was put in
the back/forward cache.

To address the issue, I updated Editor to store a WeakPtr to the
EditorClient object so that it is always able to tell the client to
clear operations if the Page/EditorClient are still alive.

* Source/WebCore/editing/Editor.cpp:
(WebCore::Editor::client const):
(WebCore::Editor::Editor):
* Source/WebCore/editing/Editor.h:

Canonical link: https://commits.webkit.org/264022@main
@webkit-commit-queue
Copy link
Collaborator

Committed 264022@main (b9a32bf): https://commits.webkit.org/264022@main

Reviewed commits have been landed. Closing PR #13764 and removing active labels.

@webkit-commit-queue webkit-commit-queue merged commit b9a32bf into WebKit:main May 12, 2023
@webkit-commit-queue webkit-commit-queue removed the unsafe-merge-queue Applied to send a pull request to merge-queue, but skip building and testing label May 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Forms For bugs specific to form elements (checkboxes, buttons, text fields, etc.)
Projects
None yet
7 participants