Bug 98869 - Assertion failure in RenderObject::drawLineForBoxSide
Summary: Assertion failure in RenderObject::drawLineForBoxSide
Status: RESOLVED CONFIGURATION CHANGED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Layout and Rendering (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Nobody
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-10-09 23:54 PDT by Matt Falkenhagen
Modified: 2024-03-07 14:19 PST (History)
5 users (show)

See Also:


Attachments
minimized testcase (346 bytes, text/html)
2012-10-09 23:54 PDT, Matt Falkenhagen
no flags Details
more minimal testcase (133 bytes, text/html)
2012-11-07 03:33 PST, Matt Falkenhagen
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Matt Falkenhagen 2012-10-09 23:54:05 PDT
Created attachment 167938 [details]
minimized testcase

Assertion failure seen on a recent Chromium Linux build and Mac build (r130854):

ASSERTION FAILED: x2 >= x1
/Users/falken/WebKit/Source/WebCore/rendering/RenderObject.cpp(1026) : void WebCore::RenderObject::drawLineForBoxSide(WebCore::GraphicsContext *, int, int, int, int, WebCore::BoxSide, WebCore::Color, WebCore::EBorderStyle, int, int, bool)
1   0x108d47d10 WebCore::RenderObject::drawLineForBoxSide(WebCore::GraphicsContext*, int, int, int, int, WebCore::BoxSide, WebCore::Color, WebCore::EBorderStyle, int, int, bool)
2   0x108c67d3f WebCore::RenderBoxModelObject::paintOneBorderSide(WebCore::GraphicsContext*, WebCore::RenderStyle const*, WebCore::RoundedRect const&, WebCore::RoundedRect const&, WebCore::IntRect const&, WebCore::BoxSide, WebCore::BoxSide, WebCore::BoxSide, WebCore::BorderEdge const*, WebCore::Path const*, WebCore::BackgroundBleedAvoidance, bool, bool, bool, WebCore::Color const*)
3   0x108c69c5a WebCore::RenderBoxModelObject::paintBorderSides(WebCore::GraphicsContext*, WebCore::RenderStyle const*, WebCore::RoundedRect const&, WebCore::RoundedRect const&, WebCore::BorderEdge const*, unsigned int, WebCore::BackgroundBleedAvoidance, bool, bool, bool, WebCore::Color const*)
4   0x108c6b4b9 WebCore::RenderBoxModelObject::paintBorder(WebCore::PaintInfo const&, WebCore::FractionalLayoutRect const&, WebCore::RenderStyle const*, WebCore::BackgroundBleedAvoidance, bool, bool)
5   0x108c4308b WebCore::RenderBox::paintBoxDecorations(WebCore::PaintInfo&, WebCore::FractionalLayoutPoint const&)
6   0x108bdb6a9 WebCore::RenderBlock::paintObject(WebCore::PaintInfo&, WebCore::FractionalLayoutPoint const&)
7   0x108bd8ca3 WebCore::RenderBlock::paint(WebCore::PaintInfo&, WebCore::FractionalLayoutPoint const&)
8   0x108cded89 WebCore::RenderLayer::paintLayerContents(WebCore::RenderLayer*, WebCore::GraphicsContext*, WebCore::FractionalLayoutRect const&, WebCore::FractionalLayoutSize const&, unsigned int, WebCore::RenderObject*, WebCore::RenderRegion*, WTF::HashMap<WebCore::OverlapTestRequestClient*, WebCore::IntRect, WTF::PtrHash<WebCore::OverlapTestRequestClient*>, WTF::HashTraits<WebCore::OverlapTestRequestClient*>, WTF::HashTraits<WebCore::IntRect> >*, unsigned int)
9   0x108cde0ea WebCore::RenderLayer::paintLayerContentsAndReflection(WebCore::RenderLayer*, WebCore::GraphicsContext*, WebCore::FractionalLayoutRect const&, WebCore::FractionalLayoutSize const&, unsigned int, WebCore::RenderObject*, WebCore::RenderRegion*, WTF::HashMap<WebCore::OverlapTestRequestClient*, WebCore::IntRect, WTF::PtrHash<WebCore::OverlapTestRequestClient*>, WTF::HashTraits<WebCore::OverlapTestRequestClient*>, WTF::HashTraits<WebCore::IntRect> >*, unsigned int)
10  0x108cdd708 WebCore::RenderLayer::paintLayer(WebCore::RenderLayer*, WebCore::GraphicsContext*, WebCore::FractionalLayoutRect const&, WebCore::FractionalLayoutSize const&, unsigned int, WebCore::RenderObject*, WebCore::RenderRegion*, WTF::HashMap<WebCore::OverlapTestRequestClient*, WebCore::IntRect, WTF::PtrHash<WebCore::OverlapTestRequestClient*>, WTF::HashTraits<WebCore::OverlapTestRequestClient*>, WTF::HashTraits<WebCore::IntRect> >*, unsigned int)
11  0x108ce0075 WebCore::RenderLayer::paintList(WTF::Vector<WebCore::RenderLayer*, 0ul>*, WebCore::RenderLayer*, WebCore::GraphicsContext*, WebCore::FractionalLayoutRect const&, unsigned int, WebCore::RenderObject*, WebCore::RenderRegion*, WTF::HashMap<WebCore::OverlapTestRequestClient*, WebCore::IntRect, WTF::PtrHash<WebCore::OverlapTestRequestClient*>, WTF::HashTraits<WebCore::OverlapTestRequestClient*>, WTF::HashTraits<WebCore::IntRect> >*, unsigned int)
12  0x108cdf2cc WebCore::RenderLayer::paintLayerContents(WebCore::RenderLayer*, WebCore::GraphicsContext*, WebCore::FractionalLayoutRect const&, WebCore::FractionalLayoutSize const&, unsigned int, WebCore::RenderObject*, WebCore::RenderRegion*, WTF::HashMap<WebCore::OverlapTestRequestClient*, WebCore::IntRect, WTF::PtrHash<WebCore::OverlapTestRequestClient*>, WTF::HashTraits<WebCore::OverlapTestRequestClient*>, WTF::HashTraits<WebCore::IntRect> >*, unsigned int)
13  0x108cde0ea WebCore::RenderLayer::paintLayerContentsAndReflection(WebCore::RenderLayer*, WebCore::GraphicsContext*, WebCore::FractionalLayoutRect const&, WebCore::FractionalLayoutSize const&, unsigned int, WebCore::RenderObject*, WebCore::RenderRegion*, WTF::HashMap<WebCore::OverlapTestRequestClient*, WebCore::IntRect, WTF::PtrHash<WebCore::OverlapTestRequestClient*>, WTF::HashTraits<WebCore::OverlapTestRequestClient*>, WTF::HashTraits<WebCore::IntRect> >*, unsigned int)
14  0x108cdd708 WebCore::RenderLayer::paintLayer(WebCore::RenderLayer*, WebCore::GraphicsContext*, WebCore::FractionalLayoutRect const&, WebCore::FractionalLayoutSize const&, unsigned int, WebCore::RenderObject*, WebCore::RenderRegion*, WTF::HashMap<WebCore::OverlapTestRequestClient*, WebCore::IntRect, WTF::PtrHash<WebCore::OverlapTestRequestClient*>, WTF::HashTraits<WebCore::OverlapTestRequestClient*>, WTF::HashTraits<WebCore::IntRect> >*, unsigned int)
15  0x108ce0075 WebCore::RenderLayer::paintList(WTF::Vector<WebCore::RenderLayer*, 0ul>*, WebCore::RenderLayer*, WebCore::GraphicsContext*, WebCore::FractionalLayoutRect const&, unsigned int, WebCore::RenderObject*, WebCore::RenderRegion*, WTF::HashMap<WebCore::OverlapTestRequestClient*, WebCore::IntRect, WTF::PtrHash<WebCore::OverlapTestRequestClient*>, WTF::HashTraits<WebCore::OverlapTestRequestClient*>, WTF::HashTraits<WebCore::IntRect> >*, unsigned int)
16  0x108cdf2cc WebCore::RenderLayer::paintLayerContents(WebCore::RenderLayer*, WebCore::GraphicsContext*, WebCore::FractionalLayoutRect const&, WebCore::FractionalLayoutSize const&, unsigned int, WebCore::RenderObject*, WebCore::RenderRegion*, WTF::HashMap<WebCore::OverlapTestRequestClient*, WebCore::IntRect, WTF::PtrHash<WebCore::OverlapTestRequestClient*>, WTF::HashTraits<WebCore::OverlapTestRequestClient*>, WTF::HashTraits<WebCore::IntRect> >*, unsigned int)
17  0x108cfca78 WebCore::RenderLayerBacking::paintIntoLayer(WebCore::RenderLayer*, WebCore::GraphicsContext*, WebCore::IntRect const&, unsigned int, unsigned int, WebCore::RenderObject*)
18  0x108cfcd91 WebCore::RenderLayerBacking::paintContents(WebCore::GraphicsLayer const*, WebCore::GraphicsContext&, unsigned int, WebCore::IntRect const&)
19  0x10816e5e0 WebCore::GraphicsLayer::paintGraphicsLayerContents(WebCore::GraphicsContext&, WebCore::IntRect const&)
20  0x108176d90 WebCore::GraphicsLayerCA::platformCALayerPaintContents(WebCore::GraphicsContext&, WebCore::IntRect const&)
21  0x108176dd7 non-virtual thunk to WebCore::GraphicsLayerCA::platformCALayerPaintContents(WebCore::GraphicsContext&, WebCore::IntRect const&)
22  0x109304437 __drawLayerContents_block_invoke_0
23  0x105ebd9dd WKCALayerEnumerateRectsBeingDrawnWithBlock
24  0x109303cec drawLayerContents(CGContext*, CALayer*, WebCore::PlatformCALayer*)
25  0x10925eccb WebCore::TileCache::drawLayer(WebTileLayer*, CGContext*)
26  0x10931f389 -[WebTileLayer drawInContext:]
27  0x7fff8c1862a2 CABackingStoreUpdate_
28  0x7fff8c184ce2 CA::Layer::display_()
29  0x7fff8c184661 CA::Layer::display_if_needed(CA::Transaction*)
30  0x7fff8c183e7b CA::Layer::layout_and_display_if_needed(CA::Transaction*)
31  0x7fff8c179653 CA::Context::commit_transaction(CA::Transaction*)
Comment 1 Matt Falkenhagen 2012-10-10 01:03:31 PDT
It looks like it's not a recent regression. A build of June 1, 2012 Chromium also fails the assertion.
Comment 2 Matt Falkenhagen 2012-11-07 03:33:05 PST
Created attachment 172751 [details]
more minimal testcase
Comment 3 Matt Falkenhagen 2012-11-07 03:36:28 PST
The problem here is the render box gets a computed width of -1 during layout. Then the rect computed in RenderBox::paintBoxDecorations by calling RenderBox::borderBoxRectFromRegion also gets a width of -1. Ultimately the assert is tripped when x1=0 and x2=-1 is passed to RenderObject::drawLineForBoxSide.

The computed width comes from the "// RULE 5 (Solve for width)" section in RenderBox::computePositionedLogicalWidthUsing. Since left is 1 and right is 0, the solved for width is -1. In more detail:

    const LayoutUnit availableSpace = containerLogicalWidth - (marginLogicalLeftValue + marginLogicalRightValue + bordersPlusPadding);

Here everything is 0 except borderPlusPadding=6, so availableSpace is -6. Then we get to RULE 5, where:

    logicalLeftValue = valueForLength(logicalLeft, containerLogicalWidth, renderView);
    computedValues.m_extent = availableSpace - (logicalLeftValue + valueForLength(logicalRight, containerLogicalWidth, renderView));

Here logicalLeft=1 and logicalRight=0, so m_extent is -7. Later in computePositionedLogicalWidth:

    computedValues.m_extent += bordersPlusPadding;

So m_extent is -1, which becomes the logical width of the renderer.

I guess there must be a reason that negative widths aren't clamped to zero during layout. If so, the question is how to avoid painting a border with negative dimensions. We could maybe do an early return in RenderBox::paintBoxDecorations when the paintRect has negative dimensions. Or since drawLineForBoxSide already has a check:

    if (!thickness || !length)

We could extend it to check for negatives. But oddly code in that function seems to expect negative dimensions as valid (there is a thickness > 0 check later and only for the SOLID case is there an assert for non-negative).

Or maybe we want to paint the border after all and can just remove the assert. In this test case, Firefox seems to paint a little 6 pixel block as the border.
Comment 4 Ahmad Saleem 2024-03-07 14:19:28 PST
I am unable to reproduce 'Assert Failure' on Debug Build (275804@main) using attached test case.

Marking this as 'RESOLVED CONFIGURATION CHANGED'.