Bug 201289 - <input type="file"> is not kept alive during file picker, if it gets GC'd file selection has no affect
Summary: <input type="file"> is not kept alive during file picker, if it gets GC'd fil...
Status: NEW
Alias: None
Product: WebKit
Classification: Unclassified
Component: Forms (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Nobody
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-08-28 23:56 PDT by Joseph Pecoraro
Modified: 2019-08-30 09:32 PDT (History)
5 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Joseph Pecoraro 2019-08-28 23:56:04 PDT
A `<input type="file">` can get GC'd while the dialog is up if the element is not in the DOM.

When the Element is GC'd the FileChooser get's invalidated and the file selection gets dropped on the floor.

Should we try to guarantee the element is kept around while the picker is showing (at least not collected)? Note, Web Content has a workaround, but seems weird.

Test:
```
<button id="x">Click</button>
<script>
document.getElementById("x").addEventListener("click", () => {
    let inputElement = document.createElement("input");
    inputElement.type = "file";
    inputElement.multiple = true;
    inputElement.addEventListener("change", (event) => {
        alert('change');
    });
    inputElement.click();
});
</script>
```

Steps to reproduce:
1. Inspect test page
2. Click the button to show the File picker
3. While the file picker is showing trigger a Garbage Collection in Inspector's Console
4. Complete the file picker dialog with a file
  => Alert doesn't happen

Notes:
• I was able to reproduce the issue in Chrome once. Unable to try Firefox.
Comment 1 Joseph Pecoraro 2019-08-29 00:07:26 PDT
Worked around this in Web Inspector: Bug 201289

But I wonder if this could affect a real page.
Comment 2 Ryosuke Niwa 2019-08-29 10:08:26 PDT
This is a weird one. Technically, JS no longer has access to the file element because it had lost access to all its references (it's not a part of the document). But perhaps there is an expectation that the event will fire when the user dismisses the dialog or picks a file.

The way to fix this problem is to deploy GCReachableRef<HTMLInputElement> I added.
Comment 3 Alexey Proskuryakov 2019-08-29 19:26:53 PDT
It’s also similar to media elements and Fetch, whose wrappers stay alive in the expectation of callback making them visible again.
Comment 4 Ryosuke Niwa 2019-08-29 21:39:21 PDT
(In reply to Alexey Proskuryakov from comment #3)
> It’s also similar to media elements and Fetch, whose wrappers stay alive in
> the expectation of callback making them visible again.

Yeah, in that sense, perhaps HTMLInputElement should be an ActiveDOMObject with a pending activity whenever there is a dialog popped up.
Comment 5 Chris Dumez 2019-08-30 09:32:49 PDT
(In reply to Ryosuke Niwa from comment #4)
> (In reply to Alexey Proskuryakov from comment #3)
> > It’s also similar to media elements and Fetch, whose wrappers stay alive in
> > the expectation of callback making them visible again.
> 
> Yeah, in that sense, perhaps HTMLInputElement should be an ActiveDOMObject
> with a pending activity whenever there is a dialog popped up.

That sounds about right.