Bug 1483972 - Allow videocontrols to initialize without style r=jaws,dholbert!,jaws!

This crash happens because nsVideoFrame didn't know what to do with two
children in the UA Widget Shadow Root.

The two children are both videocontrols, with the first one being the lingering
DOM inserted by first constructor call that throws.

The subsequent appendChild of the same element caused the videocontrols
to be initialized again, since the previous run didn't return a widget
instance to UAWidgetsChild.

The fix here removes the throw statement added in
https://hg.mozilla.org/mozilla-central/rev/dca187f7c72c#l3.15 ,
allowing the constructor to complete.

Without this statement, we will rely on assertion in the test here
https://hg.mozilla.org/mozilla-central/rev/4ddca5eb06c2#l2.18
to fail on slower platforms to ensure the stylesheet is loaded synchronously.

An alternative fix would be to wrap up the contructor in a try catch block
from UAWidgetsChild and make sure the DOM is cleaned up when the constructor
throw. That however will hide the error thrown so I decided to remove the throw
statement instead.

Differential Revision: https://phabricator.services.mozilla.com/D3560

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Timothy Guan-tin Chien 2018-08-17 20:43:46 +00:00
parent a1c5b33558
commit 166aa2d738
4 changed files with 21 additions and 4 deletions

View File

@ -0,0 +1,10 @@
<script>
window.onload=function(){
window.frames[0].document.body.appendChild(a);
var o=window.frames[0].document.getElementById('a');
document.getElementById('b').appendChild(o.parentNode.removeChild(o));
}
</script>
<audio id='a' controls autobuffer='true'></audio>
<time id='b'>
<iframe hidden>

View File

@ -703,3 +703,4 @@ load 1467239.html
load 1472403.html
load 1474768.html
load 1478178.html
load 1483972.html

View File

@ -179,8 +179,11 @@ nsVideoFrame::GetVideoControls()
return mVideoControls;
}
if (mContent->GetShadowRoot()) {
// The video controls <div> is the only child of the UA Widget Shadow Root.
// The video controls <div> is the only child of the UA Widget Shadow Root
// if it is present. It is only lazily inserted into the DOM when
// the controls attribute is set.
MOZ_ASSERT(mContent->GetShadowRoot()->IsUAWidget());
MOZ_ASSERT(1 >= mContent->GetShadowRoot()->GetChildCount());
return mContent->GetShadowRoot()->GetFirstChild();
}
return nullptr;

View File

@ -264,10 +264,13 @@ this.VideoControlsImplPageWidget = class {
}
let preDefinedSize = this.controlBarComputedStyles.getPropertyValue(propertyName);
// This shouldn't happen, but if it does, the throw here turns
// intermittent oranges to perma-orange.
// The stylesheet from <link> might not be loaded if the
// element was inserted into a hidden iframe.
// We can safely return 0 here for now, given that the controls
// will be resized again, by the resizevideocontrols event,
// from nsVideoFrame, when the element is visible.
if (!preDefinedSize) {
throw new Error("Stylesheet not loaded yet? propertyName: " + propertyName);
return 0;
}
return parseInt(preDefinedSize, 10);