2010-07-29 Simon Fraser <simon.fraser@apple.com>

        Reviewed by Pavel Feldman.

        Crash when computing pseudo-style of a vanished scrollbar in inspector
        https://bugs.webkit.org/show_bug.cgi?id=42561

        When a styled overflow:scroll scrollbar gets destroyed, we need to clear out the m_owner pointer,
        otherwise the event handling code (which keeps the Scrollbar alive) later causes the scrollbar
        to try to use m_owner to get pseudo style.

        Test: scrollbars/overflow-custom-scrollbar-crash.html

        * rendering/RenderLayer.cpp:
        (WebCore::RenderLayer::destroyScrollbar): If this is a custom scrollbar, clear the owning renderer.
        * rendering/RenderScrollbar.cpp:
        (WebCore::RenderScrollbar::getScrollbarPseudoStyle): Bail if m_owner is 0.
        * rendering/RenderScrollbar.h:
        (WebCore::RenderScrollbar::clearOwningRenderer): New method.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@64289 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 79ca94b3
2010-07-29 Simon Fraser <simon.fraser@apple.com>
Reviewed by Pavel Feldman.
Crash when computing pseudo-style of a vanished scrollbar in inspector
https://bugs.webkit.org/show_bug.cgi?id=42561
Test that destroys a styled overflow:scroll scrollbar inside an event handler.
* scrollbars/overflow-custom-scrollbar-crash-expected.txt: Added.
* scrollbars/overflow-custom-scrollbar-crash.html: Added.
2010-07-29 Jeremy Orlow <jorlow@chromium.org> 2010-07-29 Jeremy Orlow <jorlow@chromium.org>
Reviewed by Dimitri Glazkov. Reviewed by Dimitri Glazkov.
<head>
<style>
body {
margin: 0;
}
::-webkit-scrollbar {
width: 20px;
height: 20px;
}
/* Horizontal Scrollbar Styles */
::-webkit-scrollbar:horizontal {
-webkit-border-image: url(resources/horizontal-button.png) 0 2 0 2;
border-color: transparent;
border-width: 0 2px;
background-image: url(resources/horizontal-button-background.png);
background-repeat: repeat-x;
}
::-webkit-scrollbar-thumb:horizontal {
-webkit-border-image: url(resources/horizontal-thumb.png) 0 20 0 20;
border-color: transparent;
border-width: 0 20px;
min-width: 20px;
}
::-webkit-scrollbar-track-piece:horizontal:decrement {
-webkit-border-image: url(resources/horizontal-track.png) 0 20 0 20;
border-color: transparent;
border-width: 0 0 0 20px;
}
::-webkit-scrollbar-track-piece:horizontal:increment {
-webkit-border-image: url(resources/horizontal-track.png) 0 20 0 20;
border-color: transparent;
border-width: 0 20px 0 0;
}
::-webkit-scrollbar-button:horizontal {
width: 20px;
-webkit-border-image: url(resources/horizontal-button.png) 0 2 0 2;
border-color: transparent;
border-width: 0 2px;
}
::-webkit-scrollbar-button:horizontal:decrement {
background-image: url(resources/horizontal-decrement-arrow.png), url(resources/horizontal-button-background.png);
background-repeat: no-repeat, repeat-x;
background-position: 2px 3px, 0 0;
}
::-webkit-scrollbar-button:horizontal:increment {
background-image: url(resources/horizontal-increment-arrow.png), url(resources/horizontal-button-background.png);
background-repeat: no-repeat, repeat-x;
background-position: 7px 3px, 0 0;
}
.container {
position: absolute;
height: 100px;
width: 100px;
background-color: silver;
}
.scroller {
position: absolute;
top: 50px;
left: 0;
width: 300px;
height: 50px;
-webkit-box-sizing: border-box;
border: 1px solid black;
overflow-x: scroll;
}
.inner {
width: 400px;
}
</style>
<script>
function showScroller()
{
var scroller = document.createElement('div');
scroller.className = 'scroller';
var contents = document.createElement('div')
contents.className = 'inner';
contents.appendChild(document.createTextNode('inner'));
scroller.appendChild(contents);
document.getElementById('container').appendChild(scroller);
}
function hideScroller()
{
var scroller = document.getElementById('container').querySelectorAll('.scroller')[0];
scroller.parentNode.removeChild(scroller);
}
function doTest() {
if (window.layoutTestController)
layoutTestController.dumpAsText();
if (window.eventSender) {
eventSender.dragMode = false;
eventSender.mouseMoveTo(50, 40);
eventSender.mouseMoveTo(50, 55);
eventSender.mouseMoveTo(50, 90);
eventSender.mouseDown();
eventSender.mouseUp();
eventSender.mouseMoveTo(50, 120);
}
}
window.addEventListener('load', doTest, false);
</script>
</head>
<body>
<div id="container" class="container" onmouseover="showScroller()" onmouseout="hideScroller()">
</div>
<p>This test should not crash</p>
</body>
\ No newline at end of file
2010-07-29 Simon Fraser <simon.fraser@apple.com>
Reviewed by Pavel Feldman.
Crash when computing pseudo-style of a vanished scrollbar in inspector
https://bugs.webkit.org/show_bug.cgi?id=42561
When a styled overflow:scroll scrollbar gets destroyed, we need to clear out the m_owner pointer,
otherwise the event handling code (which keeps the Scrollbar alive) later causes the scrollbar
to try to use m_owner to get pseudo style.
Test: scrollbars/overflow-custom-scrollbar-crash.html
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::destroyScrollbar): If this is a custom scrollbar, clear the owning renderer.
* rendering/RenderScrollbar.cpp:
(WebCore::RenderScrollbar::getScrollbarPseudoStyle): Bail if m_owner is 0.
* rendering/RenderScrollbar.h:
(WebCore::RenderScrollbar::clearOwningRenderer): New method.
2010-07-29 Nikolas Zimmermann <nzimmermann@rim.com> 2010-07-29 Nikolas Zimmermann <nzimmermann@rim.com>
Not reviewed. Fix release builds, by removing unused variables, that only served for ASSERTs that are no longer needed. Not reviewed. Fix release builds, by removing unused variables, that only served for ASSERTs that are no longer needed.
...@@ -1790,6 +1790,9 @@ void RenderLayer::destroyScrollbar(ScrollbarOrientation orientation) ...@@ -1790,6 +1790,9 @@ void RenderLayer::destroyScrollbar(ScrollbarOrientation orientation)
{ {
RefPtr<Scrollbar>& scrollbar = orientation == HorizontalScrollbar ? m_hBar : m_vBar; RefPtr<Scrollbar>& scrollbar = orientation == HorizontalScrollbar ? m_hBar : m_vBar;
if (scrollbar) { if (scrollbar) {
if (scrollbar->isCustomScrollbar())
static_cast<RenderScrollbar*>(scrollbar.get())->clearOwningRenderer();
scrollbar->removeFromParent(); scrollbar->removeFromParent();
scrollbar->setClient(0); scrollbar->setClient(0);
scrollbar = 0; scrollbar = 0;
......
...@@ -130,6 +130,9 @@ ScrollbarPart RenderScrollbar::partForStyleResolve() ...@@ -130,6 +130,9 @@ ScrollbarPart RenderScrollbar::partForStyleResolve()
PassRefPtr<RenderStyle> RenderScrollbar::getScrollbarPseudoStyle(ScrollbarPart partType, PseudoId pseudoId) PassRefPtr<RenderStyle> RenderScrollbar::getScrollbarPseudoStyle(ScrollbarPart partType, PseudoId pseudoId)
{ {
if (!m_owner)
return 0;
s_styleResolvePart = partType; s_styleResolvePart = partType;
s_styleResolveScrollbar = this; s_styleResolveScrollbar = this;
RefPtr<RenderStyle> result = m_owner->getUncachedPseudoStyle(pseudoId, m_owner->style()); RefPtr<RenderStyle> result = m_owner->getUncachedPseudoStyle(pseudoId, m_owner->style());
......
...@@ -49,6 +49,7 @@ public: ...@@ -49,6 +49,7 @@ public:
static RenderScrollbar* scrollbarForStyleResolve(); static RenderScrollbar* scrollbarForStyleResolve();
RenderBox* owningRenderer() const { return m_owner; } RenderBox* owningRenderer() const { return m_owner; }
void clearOwningRenderer() { m_owner = 0; }
void paintPart(GraphicsContext*, ScrollbarPart, const IntRect&); void paintPart(GraphicsContext*, ScrollbarPart, const IntRect&);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment