A file picker and an alert can be shown at the same time, making the window unresponsive

RESOLVED FIXED in mozilla17

Status

()

Core
Widget
RESOLVED FIXED
6 years ago
a year ago

People

(Reporter: BenB, Assigned: karlt)

Tracking

({hang, pp, testcase})

Trunk
mozilla17
All
Linux
hang, pp, testcase
Points:
---
Dependency tree / graph
Bug Flags:
in-testsuite -

Firefox Tracking Flags

(Not tracked)

Details

(Whiteboard: [sg:dos])

Attachments

(3 attachments)

(Reporter)

Description

6 years ago
I am currently in a situation where I cannot close the native file picker dialog that opens for a <input type="file"> element on a webpage. I can use the dialog just fine, it's working, just the "Cancel" and "Open" buttons have no effect. I can still use other Firefox windows, luckily, but I cannot access the Firefox window that opened the dialog, I cannot close that Firefox window either. I am stuck.

I had pressed the "Open" button of the dialog before. The webpage, in the background, was opening an alert() (apparently) that shows an error message from the web app. This might be what is causing the deadlock.

I see nothing relevant on the error console.
The web app is the admin frontend of a phone system (gigaset IP).
(Reporter)

Comment 1

6 years ago
Created attachment 546124 [details]
Screenshot of deadlock: both File Upload dialog and alert() open at the same time
This has nothing to do with form submission; it sounds like an OS-specific event delivery issue...
Component: HTML: Form Submission → Widget: Gtk
QA Contact: form-submission → gtk
(Reporter)

Comment 3

6 years ago
In case you need me to check something, I still have the window open, but I'll have to close it some time.
Created attachment 546663 [details]
testcase (WARNING: will block the entire window!)

I managed to create a testcase for it. Would be nice to have someone reproducing that on Windows or MacOS X to check if that's really platform specific.
Keywords: testcase
Component: Widget: Gtk → DOM
OS: Linux → All
QA Contact: gtk → general
Hardware: x86 → All
Summary: "File upload" dialog cannot be closed in some situations → A file picker and an alert can be shown at the same time, making the window unresponsive
Actually, it breaks MacOS X and GTK but not Windows... and the way it breaks on MacOS X is different than GTK: the alert is never shown and the application is hanging when you click on OK or CANCEL.

Comment 6

6 years ago
FYI
If I set prompts.tab_modal.enabled to false, Browser does not hang on Nightly 8.0a1 of Windows and Linux.(not testing on MacOS)

Comment 7

5 years ago
Isn't it the same bug as #476541?

Comment 8

5 years ago
Soory for the missing link, it's bug 476541.
(In reply to Pierre Réveillon from comment #7)
> Isn't it the same bug as #476541?

On Mac yes. But it seems like it's reproducible using the GTK widget.
We could make this GTK though.
See Also: → bug 476541
(Reporter)

Comment 10

5 years ago
Per comment 2, back to GTK
Component: DOM → Widget: Gtk
QA Contact: general → gtk
(Reporter)

Updated

5 years ago
Keywords: pp
(Assignee)

Comment 11

5 years ago
Nested event loops are evil, and multiple nested event loops are more evil
(if there is such a thing).

The bug is in the nsIFilePicker::show interface because the "show" method
can't return until it knows what the user selects.  That means that either the
whole application needs pause while waiting for the response or the "show"
implementation needs to run a nested event loop. 

Further gtk_dialog_run doesn't hide the modal window.  It is not closed until
gtk_dialog_run returns which will not happen until the nested event loop
exits.

The tab-modal alert is implemented with another nested event loop.
That means that the gtk_dialog_run nested event loop can't return until the
tab-modal alert is dismissed.  The modal dialog prevents the tab-modal alert
from being dismissed.

We could adjust the GTK nsIFilePicker implementation to hide the dialog when
the buttons are pressed (instead of waiting for the event loop to exit), but
there would still be a bug:  The file would not be selected until the tab-modal
alert has been dismissed.

Bug 729720 comment 4 also wanted to make the filepicker interface async.
(Assignee)

Comment 12

5 years ago
A similar bug exists on Win7, although there is a race condition.
If the file picker opens before the alert, then the file picker can be dismissed and then the alert.

However, sometimes the file picker does not open but the window with the alert becomes unresponsive.
Component: Widget: Gtk → Widget
QA Contact: gtk → general
(Assignee)

Comment 13

5 years ago
Steven's work in bug 729720 comment 26 would go a long way in helping here.
Depends on: 729720
(Reporter)

Comment 14

5 years ago
Thanks for the reference, but I saw the bug on GTK.
No longer depends on: 729720
(Assignee)

Comment 15

5 years ago
Part of Steven's patchset is cross platform to provide an async show() method.
I think this bug should depend on bug 731307 instead.
Depends on: 731307

Updated

5 years ago
Blocks: 59314

Comment 17

5 years ago
Isn't this security-sensitive?
Those bugs where "sec:dos" before. How should they be marked now Jesse?

Comment 19

5 years ago
Keep using [sg:dos] for now. We might add a csec-dos keyword eventually.
(Reporter)

Updated

5 years ago
Whiteboard: [sg:dos]
This should have been fixed by bug 731307. Might be nice if that could be checked by QA using the latest Nightly.
Keywords: qawanted
(Assignee)

Comment 21

5 years ago
Bug 731307 added suitable API, and moves the nested event loop to run off an event, but, to fix the bug, we still need to not wait for the nested event loop to return.
Status: NEW → ASSIGNED
Keywords: qawanted
OS: All → Linux
QA Contact: karlt
(Assignee)

Comment 22

5 years ago
Created attachment 654062 [details] [diff] [review]
implement async nsIFilePicker::Open and make sync Show close window on response

Even the sync Show() variant doesn't demonstrate this lock-up any longer due to closing the window before waiting for the stack to unwind, but that method still has other bugs related to not unwinding the stack.  

gtk_window_set_destroy_with_parent is used to release the nsIFilePickerShownCallback (for the async variant) before XPCOM shutdown, when quitting from another window while the file dialog is still open.  (That is the only reason the "destroy" handler is required.)  The file picker would be of limited use without a parent anyway.
Attachment #654062 - Flags: review?(roc)
Comment on attachment 654062 [details] [diff] [review]
implement async nsIFilePicker::Open and make sync Show close window on response

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

cool!

::: widget/gtk2/nsFilePicker.cpp
@@ +377,5 @@
> +  nsresult rv = Open(nullptr);
> +  if (NS_FAILED(rv))
> +    return rv;
> +
> +  while(mRunning) {

space before (

::: widget/xpwidgets/nsBaseFilePicker.cpp
@@ +101,5 @@
>    nsCOMPtr<nsIRunnable> filePickerEvent =
>      new AsyncShowFilePicker(this, aCallback);
>    return NS_DispatchToMainThread(filePickerEvent);
>  }
> +#endif

Do we really need these #ifdefs? Seems to me we don't.
(Assignee)

Comment 24

5 years ago
The ifdefs were to help clarify which code in the override hierarchy actually gets used, but dead code is generally left in the build, so followed style there.

https://hg.mozilla.org/integration/mozilla-inbound/rev/d066131af975

There was a single try build here:
https://tbpl.mozilla.org/?tree=Try&rev=6bcd619f0b76
It is hard to test this as it is difficult to send events to native dialogs.
Flags: in-testsuite-
https://hg.mozilla.org/mozilla-central/rev/d066131af975
Status: ASSIGNED → RESOLVED
Last Resolved: 5 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla17

Comment 26

5 years ago
The bug appears to be fixed in FF17, however I am currently using FF17 and the test page above still blocks the entire window. Am I missing something?
(Assignee)

Updated

4 years ago
Assignee: nobody → karlt
QA Contact: karlt
Attachment #654062 - Flags: review?(roc)
You need to log in before you can comment on or make changes to this bug.