Last Comment Bug 684618 - Deny requests for DOM full-screen when windowed plugins are present
: Deny requests for DOM full-screen when windowed plugins are present
Status: RESOLVED FIXED
:
Product: Core
Classification: Components
Component: Plug-ins (show other bugs)
: Trunk
: All All
: -- normal with 2 votes (vote)
: mozilla10
Assigned To: Chris Pearce (:cpearce)
:
Mentors:
Depends on: 701260
Blocks: 545812
  Show dependency treegraph
 
Reported: 2011-09-04 13:51 PDT by Chris Pearce (:cpearce)
Modified: 2011-11-09 18:13 PST (History)
11 users (show)
See Also:
Crash Signature:
(edit)
QA Whiteboard:
Iteration: ---
Points: ---
Has Regression Range: ---
Has STR: ---


Attachments
Patch: deny requests for full-screen when windowed plugins present (13.42 KB, patch)
2011-09-12 21:31 PDT, Chris Pearce (:cpearce)
no flags Details | Diff | Review
Patch v2 (15.12 KB, patch)
2011-09-13 21:47 PDT, Chris Pearce (:cpearce)
no flags Details | Diff | Review
Patch v3 (17.44 KB, patch)
2011-09-19 15:56 PDT, Chris Pearce (:cpearce)
roc: review+
Details | Diff | Review
Patch v4 - not based on bug 90268 (16.06 KB, patch)
2011-10-26 19:14 PDT, Chris Pearce (:cpearce)
roc: review+
Details | Diff | Review

Description Chris Pearce (:cpearce) 2011-09-04 13:51:41 PDT
We need to disable windowed plugins when we enter DOM full-screen mode (see bug 545812 for DOM full-screen mode). We exit DOM full-screen mode when a restricted key is pressed. However windowed plugins exist outside our event handling chain, so when in DOM full-screen mode they will still receive key events. This can then be used to phish logins etc.

We can't enable full-screen until this bug is fixed.
Comment 1 Chris Pearce (:cpearce) 2011-09-07 20:40:45 PDT
Change of plan. We'll deny requests for full-screen mode if any content document in the subtree being made full-screen contains a windowed plugin. We also need to exit DOM full-screen mode when a windowed plugin is created in a content document which is in DOM full-screen mode.
Comment 2 Chris Pearce (:cpearce) 2011-09-07 20:42:23 PDT
I'll base this on top of bug 90268, to reduce conflicts and make my life easier...
Comment 3 Benjamin Smedberg [:bsmedberg] 2011-09-09 07:17:40 PDT
Could we just use keyboard hooking to catch the relevant keystrokes?
Comment 4 Brian R. Bondy [:bbondy] 2011-09-09 09:34:42 PDT
Yes I think we could use a hook to detect these keys and then force exit DOM full-screen mode.
Comment 5 Robert O'Callahan (:roc) (Exited; email my personal email if necessary) 2011-09-10 05:46:47 PDT
We can on Windows, maybe. Can we do it for X11? Can we do it reliably for any child widgets the plugin widget may have? Can we make sure we get all relevant key events? Will it work for IME users?

We thought about trying to block key events to windowed plugins but it seemed like it might be a bit fragile.
Comment 6 Robert O'Callahan (:roc) (Exited; email my personal email if necessary) 2011-09-10 05:50:56 PDT
I think also getting it to work for out-of-process plugins was going to be a little bit painful.
Comment 7 Karl Tomlinson (ni?:karlt) 2011-09-11 17:17:39 PDT
On X11 at least, exiting DOM full-screen mode when a plugin takes focus may be simpler than filtering plugin key events, and perhaps this could be easier than detecting the presence of windowed plugins.  Doing so could lead to a surprise exit from full-screen when clicking on a plugin, though.

I think it would be possible to filter key events for X11 XEmbed plugins, or it may be possible to deny a plugin focus request.  Solutions here would rely a bit on the internal mechanisms of GtkSocket.

Xt plugin focus is complex (and doesn't work well).  We may be able to do a key event filter for Xt plugins, but that could be even more complex.  They are not prevalent enough to justify doing anything beyond a complete block of focus or key events (whichever is easier).
Comment 8 Chris Pearce (:cpearce) 2011-09-12 21:31:24 PDT
Created attachment 559930 [details] [diff] [review]
Patch: deny requests for full-screen when windowed plugins present

Deny requests for full-screen in documents containing windowed plugins. Exit full-screen when widget created for windowed plugin.
Comment 9 Chris Pearce (:cpearce) 2011-09-13 01:55:55 PDT
(In reply to Chris Pearce (:cpearce) (Mozilla Corporation) from comment #8)
> Created attachment 559930 [details] [diff] [review]
> Patch: deny requests for full-screen when windowed plugins present

I should also mention, this patch is based on top of the two patches in bug 90268.
Comment 10 Robert O'Callahan (:roc) (Exited; email my personal email if necessary) 2011-09-13 08:25:14 PDT
Comment on attachment 559930 [details] [diff] [review]
Patch: deny requests for full-screen when windowed plugins present

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

::: content/html/content/src/nsGenericHTMLElement.cpp
@@ +3423,5 @@
> +// Returns PR_TRUE if the doctree rooted at aDoc contains any plugins which
> +// we don't control event dispatch for. i.e. do any plugins in this doc tree
> +// receive key events outside of our control?
> +static PRBool
> +HasPluginsOutsideEventDispatch(nsIDocument* aDoc)

Move this to nsContentUtils I think. It's a bit unfortunate to have this code in nsGenericHTMLElement.

"OutsideEventDispatch" seems a bit unclear to me. Call it HasPluginWithUncontrolledEventDispatch, maybe?

::: content/html/content/test/file_fullscreen-plugins.html
@@ +83,5 @@
> +
> +var fullScreenChangeCount = 0;
> +
> +function macFullScreenChange(event) {
> +  switch (fullScreenChangeCount) {

I think we need to test that adding a windowed plugin does not exit full-screen mode on Mac.

::: dom/plugins/base/nsPluginInstanceOwner.cpp
@@ +2928,5 @@
>    mInstance->IsWindowless(&windowless);
> +  nsIDocument *doc = mContent ? mContent->GetOwnerDoc() : nsnull;
> +  if (!windowless && doc && doc->IsFullScreenDoc()) {
> +    NS_DispatchToCurrentThread(
> +      NS_NewRunnableMethod(doc, &nsIDocument::CancelFullScreen));

Does this work correctly on Mac? Without checking the code I'm not sure that IsWindowless always returns true on Mac. Hence my request for the test above.
Comment 11 Chris Pearce (:cpearce) 2011-09-13 14:52:42 PDT
(In reply to Robert O'Callahan (:roc) (Mozilla Corporation) from comment #10)
> Comment on attachment 559930 [details] [diff] [review]
> Patch: deny requests for full-screen when windowed plugins present
> 
>[...]
> ::: dom/plugins/base/nsPluginInstanceOwner.cpp
> @@ +2928,5 @@
> >    mInstance->IsWindowless(&windowless);
> > +  nsIDocument *doc = mContent ? mContent->GetOwnerDoc() : nsnull;
> > +  if (!windowless && doc && doc->IsFullScreenDoc()) {
> > +    NS_DispatchToCurrentThread(
> > +      NS_NewRunnableMethod(doc, &nsIDocument::CancelFullScreen));
> 
> Does this work correctly on Mac? Without checking the code I'm not sure that
> IsWindowless always returns true on Mac. Hence my request for the test above.

Oops, IsWindowless() appears to always report false on Mac. I'll just ifdef out this check on Mac, and add a test to ensure adding a windowed plugin doesn't exit full-screen mode on Mac.
Comment 12 Chris Pearce (:cpearce) 2011-09-13 21:47:01 PDT
Created attachment 560100 [details] [diff] [review]
Patch v2

Updated with review comments.
Comment 13 Robert O'Callahan (:roc) (Exited; email my personal email if necessary) 2011-09-14 00:44:41 PDT
Comment on attachment 560100 [details] [diff] [review]
Patch v2

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

::: content/base/src/nsContentUtils.cpp
@@ +5751,5 @@
> +static void
> +CheckForWindowedPlugins(nsIContent* aContent, void* aResult)
> +{
> +  if (!aContent->IsInDoc()) {
> +    return;

I don't think you should do this check. What if (post-bug-90268) a page creates a plugin element, doesn't put it in the document, goes full-screen, then adds it to the document? I think you end up with a windowed plugin in the full-screen document able to receive key events. Better add a test for that!

@@ +5793,5 @@
> +nsContentUtils::HasPluginWithUncontrolledEventDispatch(nsIDocument* aDoc)
> +{
> +#ifdef XP_MACOSX
> +	// We control dispatch to all mac plugins.
> +	return PR_FALSE;

Fix indent.
Comment 14 Chris Pearce (:cpearce) 2011-09-14 15:46:59 PDT
(In reply to Robert O'Callahan (:roc) (Mozilla Corporation) from comment #13)
> Comment on attachment 560100 [details] [diff] [review]
> Patch v2
> 
> Review of attachment 560100 [details] [diff] [review]:
> -----------------------------------------------------------------
> 
> ::: content/base/src/nsContentUtils.cpp
> @@ +5751,5 @@
> > +static void
> > +CheckForWindowedPlugins(nsIContent* aContent, void* aResult)
> > +{
> > +  if (!aContent->IsInDoc()) {
> > +    return;
> 
> I don't think you should do this check. What if (post-bug-90268) a page
> creates a plugin element, doesn't put it in the document, goes full-screen,
> then adds it to the document? I think you end up with a windowed plugin in
> the full-screen document able to receive key events. Better add a test for
> that!

CreateWidget is called every time we add a plugin to a document, so the check in CreateWidget will cause us to exit full-screen in the above case.

I already test this case; in the non-mac case I load a windowed plugin in the document, remove it from document, go full-screen, then re-add it and verify we exited full-screen. 

I'm not testing that adding a windowed plugin which has never been added to a document before and which was created before going full-screen causes us to exit full-screen mode, I can add a test case for that.
Comment 15 Robert O'Callahan (:roc) (Exited; email my personal email if necessary) 2011-09-15 23:36:54 PDT
(In reply to Chris Pearce (:cpearce) (Mozilla Corporation) from comment #14)
> CreateWidget is called every time we add a plugin to a document,

I don't think that's true, post-bug90268.
Comment 16 Chris Pearce (:cpearce) 2011-09-19 15:56:17 PDT
Created attachment 561053 [details] [diff] [review]
Patch v3

* Add a check in nsHTMLSharedObjectElement::BindToTree() rather removing the IsInDoc() check suggested in comment 13, as we can't rely on plugin containers being GC'd before the full-screen request comes in as discussed.
* Also added extra test as I described in comment 14.
Comment 17 Jesse Ruderman 2011-10-19 09:21:13 PDT
How often will this restriction kick in? (Is it only for plugins in the same tab that's going full-screen? Which popular plugins are 'windowed' nowadays?)
Comment 18 Benjamin Smedberg [:bsmedberg] 2011-10-19 09:41:00 PDT
It is only the same tab. Most of the popular plugins can be windowed, including Flash (unless it has wmode="transparent" or wmode="opaque") and silverlight and Acrobat.
Comment 19 Chris Pearce (:cpearce) 2011-10-26 19:14:05 PDT
Created attachment 569886 [details] [diff] [review]
Patch v4 - not based on bug 90268

It looks like this patch pretty much works as-is when rebased without bug 90268. I had to change the test to ensure it waits for the windowed plugin in the test's subdocument to load before starting, but other than that, this patch is pretty much the same.

Re-requesting review just in case the approach I use here isn't supposed to work without 90268.

Looks greenish on Try: https://tbpl.mozilla.org/?tree=Try&rev=55a7472f6e62
Comment 21 Marco Bonardo [::mak] 2011-10-27 01:57:48 PDT
https://hg.mozilla.org/mozilla-central/rev/2e375d0cf797

Note You need to log in before you can comment on or make changes to this bug.