Bug 45344

Summary: Null deref in InlineBox::height()
Product: WebKit Reporter: Cris Neckar <cdn>
Component: Layout and RenderingAssignee: Nobody <webkit-unassigned>
Status: RESOLVED FIXED    
Severity: Normal CC: cdn, eric, jamesr, mitz, rniwa
Priority: P2 Keywords: InRadar
Version: 528+ (Nightly build)   
Hardware: All   
OS: OS X 10.6   
Attachments:
Description Flags
repro
none
Patch
none
Patch
eric: review-
Set the pseudo style bit on the RenderStyle which is going to supply the first-line style sullivan: review+

Description Cris Neckar 2010-09-07 17:32:51 PDT
Created attachment 66801 [details]
repro

When firstline is true the renderers style() method may return null and then be derefed. 

I hav been hitting this a lot with a fuzzer I am working on and will submit a patch shortly.

the attached repro will trigger this.
Comment 1 Cris Neckar 2010-09-07 18:04:09 PDT
Created attachment 66812 [details]
Patch
Comment 2 Cris Neckar 2010-09-07 18:06:06 PDT
+jamesr

James can you review this when you get a chance. Thanks!
Comment 3 James Robinson 2010-09-07 18:26:29 PDT
Comment on attachment 66812 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=66812&action=prettypatch

> WebCore/rendering/InlineBox.cpp:99
> +    if (!renderer()->style(m_firstLine))
> +        return 0;
>      if (renderer()->isText())
>          return m_isText ? renderer()->style(m_firstLine)->font().height() : 0;
>      if (renderer()->isBox() && parent())
There's one very slight behavior change here - if renderer()->isBox() && parent() == true, old code wouldn't call renderer()->style(m_firstLine) at all whereas this patch will.  Can you reoranize this so that's still true?  I think moving the isBox() && ... branch above the NULL check will suffice.
Comment 4 Cris Neckar 2010-09-08 11:10:24 PDT
Created attachment 66917 [details]
Patch
Comment 5 Cris Neckar 2010-09-08 11:11:30 PDT
Good catch. Thank you!
Comment 6 Eric Seidel (no email) 2010-09-15 00:01:36 PDT
Comment on attachment 66917 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=66917&action=prettypatch

> WebCore/rendering/InlineBox.cpp:-97
> +    if (!renderer()->style(m_firstLine))
> +        return 0;
>      if (renderer()->isText())
>          return m_isText ? renderer()->style(m_firstLine)->font().height() : 0;
> -    if (renderer()->isBox() && parent())
I believe style(m_firstLine) is non-trivial.  Shouldn't we cache it in a local variable?

    RenderStyle* firstLineStyle() const { return document()->usesFirstLineRules() ? firstLineStyleSlowCase() : style(); }
    RenderStyle* style(bool firstLine) const { return firstLine ? firstLineStyle() : style(); }
Comment 7 mitz 2010-09-15 00:14:22 PDT
Does this still happen with the fix for bug 45574 (r67255 or later)? style() should never return null and if it is, then that should be fixed, not papered over.
Comment 8 Ryosuke Niwa 2010-09-24 11:32:51 PDT
The repro now causes a crash at the line 96 of InlineBox.cpp:

    if (renderer()->isText())
        return m_isText ? renderer()->style(m_firstLine)->font().height() : 0;

font() is 0 and crashes inside RefPtr.
Comment 9 mitz 2010-09-24 11:52:40 PDT
(In reply to comment #8)
> The repro now causes a crash at the line 96 of InlineBox.cpp:
> 
>     if (renderer()->isText())
>         return m_isText ? renderer()->style(m_firstLine)->font().height() : 0;
> 
> font() is 0 and crashes inside RefPtr.

Seems like style(true) is still null.
Comment 10 mitz 2010-09-24 12:10:16 PDT
I think the issue is that RenderObject::firstLineStyleSlowCase() calls setHasPseudoStyle() on the wrong RenderStyle, namely the RenderText’s instead of its parent’s.
Comment 11 mitz 2010-09-25 00:12:12 PDT
<rdar://problem/8478160>
Comment 12 mitz 2010-09-25 00:22:03 PDT
Created attachment 68814 [details]
Set the pseudo style bit on the RenderStyle which is going to supply the first-line style
Comment 13 mitz 2010-09-25 10:34:37 PDT
Fixed in <http://trac.webkit.org/projects/webkit/changeset/68335>.