Bug 56642 - Null pointer crash in StyleChange::init inside an empty document
Summary: Null pointer crash in StyleChange::init inside an empty document
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: HTML Editing (show other bugs)
Version: 528+ (Nightly build)
Hardware: PC Windows Vista
: P1 Normal
Assignee: Nobody
URL:
Keywords:
Depends on: 56771
Blocks:
  Show dependency treegraph
 
Reported: 2011-03-18 06:01 PDT by Berend-Jan Wever
Modified: 2011-04-03 08:27 PDT (History)
6 users (show)

See Also:


Attachments
fixes the crash (3.28 KB, patch)
2011-03-18 15:48 PDT, Ryosuke Niwa
no flags Details | Formatted Diff | Diff
work in progress; hits an assertion (4.97 KB, patch)
2011-03-18 16:36 PDT, Ryosuke Niwa
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Berend-Jan Wever 2011-03-18 06:01:25 PDT
Chromium: http://code.google.com/p/chromium/issues/detail?id=76672

Repro:
<body onload="go()"></body>
<script>
  function go() {
    var oSelection=window.getSelection();
    document.designMode="on";
    document.open();
    oSelection.addRange(document.createRange());
    document.execCommand("justifyleft");
  }
</script>

id:             chrome.dll!WebCore::CSSStyleDeclaration::diff ReadAV@NULL (1933558aaf23e4d9cc2ec3bc22fad247)
description:    Attempt to read from unallocated NULL pointer in chrome.dll!WebCore::CSSStyleDeclaration::diff
stack:          chrome.dll!WebCore::CSSStyleDeclaration::diff
                chrome.dll!WebCore::getPropertiesNotIn
                chrome.dll!WebCore::StyleChange::init
                chrome.dll!WebCore::ApplyStyleCommand::applyBlockStyle
                chrome.dll!WebCore::ApplyStyleCommand::doApply
                chrome.dll!WebCore::EditCommand::apply
                chrome.dll!WebCore::applyCommand
                chrome.dll!WebCore::Editor::applyParagraphStyle
                chrome.dll!WebCore::executeApplyParagraphStyle
                chrome.dll!WebCore::executeJustifyLeft
                chrome.dll!WebCore::Editor::Command::execute
                chrome.dll!WebCore::Document::execCommand
                chrome.dll!WebCore::DocumentInternal::execCommandCallback
                chrome.dll!v8::internal::HandleApiCallHelper<...>
                chrome.dll!v8::internal::Builtin_HandleApiCall
                chrome.dll!v8::internal::Invoke
                chrome.dll!v8::internal::Execution::Call
                ...
Comment 1 Berend-Jan Wever 2011-03-18 07:12:56 PDT
The problem is that the selection contains only the HTMLDocument when this code is executed:

\source\webcore\editing\applystylecommand.cpp:
void StyleChange::init(EditingStyle* style, const Position& position)
{
    Document* document = position.anchorNode() ? position.anchorNode()->document() : 0;
    if (!style || !style->style() || !document || !document->frame())
        return;

    RefPtr<CSSComputedStyleDeclaration> computedStyle = position.computedStyle();
<snip>

This calls the following code:

\source\webcore\dom\Position.cpp:
PassRefPtr<CSSComputedStyleDeclaration> Position::computedStyle() const
{
    Element* elem = element();
    if (!elem)
        return 0;
    return WebCore::computedStyle(elem);
}

Where "element()" is the following code in the same file:

Element* Position::element() const
{
    Node* n = anchorNode();
    while (n && !n->isElementNode())
        n = n->parentNode();
    return static_cast<Element*>(n);
}

a HTMLDocument is not an ElementNode, so this returns 0, and "Position::computedStyle" returns 0 as well. "StyleChange::init" does not expect this.
Comment 2 Ryosuke Niwa 2011-03-18 15:48:58 PDT
Created attachment 86232 [details]
fixes the crash
Comment 3 Ryosuke Niwa 2011-03-18 16:01:42 PDT
Comment on attachment 86232 [details]
fixes the crash

Thanks for the review, Darin.  But I realized that my fix doesn't allow styles to be applied properly.  So I'm deprecating this patch and uploading new one that actually fixes the feature and after which JustifyRight is applied properly.
Comment 4 Ryosuke Niwa 2011-03-18 16:34:02 PDT
I'm now running into the assertion in:

void Document::setCompatibilityMode(CompatibilityMode mode)
{
    if (m_compatibilityModeLocked || mode == m_compatibilityMode)
        return;
    ASSERT(!documentElement() && !m_styleSheets->length());
    bool wasInQuirksMode = inQuirksMode();
    m_compatibilityMode = mode;
    if (inQuirksMode() != wasInQuirksMode) {
        // All user stylesheets have to reparse using the different mode.
        clearPageUserSheet();
        clearPageGroupUserSheets();
    }
}

Maybe we shouldn't even let execCommand run when there's no body element.
Comment 5 Ryosuke Niwa 2011-03-18 16:34:23 PDT
The assertion was added in http://trac.webkit.org/changeset/66247.
Comment 6 Ryosuke Niwa 2011-03-18 16:36:02 PDT
Created attachment 86241 [details]
work in progress; hits an assertion
Comment 7 Ryosuke Niwa 2011-04-03 08:27:42 PDT
Fixed in http://trac.webkit.org/changeset/82791.