Changeset 60813 in webkit


Ignore:
Timestamp:
Jun 7, 2010 5:57:13 PM (14 years ago)
Author:
eric@webkit.org
Message:

2010-06-07 Eric Seidel <eric@webkit.org>

Reviewed by Adam Barth.

HTML5 Parser hits ASSERT in fast/events/stop-load-in-unload-handler-using-document-write.html
https://bugs.webkit.org/show_bug.cgi?id=40268

Teach HTML5Tokenizer about m_parserStopped.

While tracking down how m_parserStopped was used, I found
several useless implementations of stopParsing() which I removed.

I also found a comment in HTMLTokenizer which still talks about the
"part" (an old class now split into Frame, Page, FrameLoader, etc.)
and an nearly empty FrameLoader::tokenizerProcessedData which I just
inlined into its one caller.

Tests:

fast/events/stop-load-in-unload-handler-using-document-write.html
http/tests/security/xssAuditor/full-block-base-href.html

  • html/HTML5Tokenizer.cpp: (WebCore::HTML5Tokenizer::pumpLexerIfPossible):
    • New method used instead of direct calls to pumpLexer for when callers would like to pump the lexer if possible, but don't want to check if the parser is stopped, etc.

(WebCore::HTML5Tokenizer::pumpLexer):

  • Added an ASSERT that the parser is not stopped.
  • Stop pumping if the parser is stopped.

(WebCore::HTML5Tokenizer::write):

  • Ignore the write if the parser is already stopped.

(WebCore::HTML5Tokenizer::end):
(WebCore::HTML5Tokenizer::attemptToEnd):

  • Move comment back to finish() which was incorrectly moved here.

(WebCore::HTML5Tokenizer::endIfDelayed):
(WebCore::HTML5Tokenizer::finish):

  • Move comment back here from attemptToEnd()

(WebCore::HTML5Tokenizer::resumeParsingAfterScriptExecution):

  • Remove a bogus ASSERT. The lexer will stop when it needs more data, which may not necessarily mean m_source.isEmpty().
  • html/HTML5Tokenizer.h:
    • Add pumpLexerIfPossible().
  • html/HTMLTokenizer.cpp: (WebCore::HTMLTokenizer::stopParsing):
    • Add a FIXME about if we really should call checkCompleted() here.
    • Inline FrameLoader::tokenizerProcessedData() since this was the only caller.
  • loader/FrameLoader.cpp:
    • Remove tokenizerProcessedData()
  • loader/FrameLoader.h:
    • Remove tokenizerProcessedData()
  • loader/MediaDocument.cpp:
    • Remove unneeded Tokenizer::stopParsing() override.
  • loader/PluginDocument.cpp:
    • Remove unneeded Tokenizer::stopParsing() override.
  • loader/SinkDocument.cpp:
    • Remove unneeded Tokenizer::stopParsing() override.
Location:
trunk/WebCore
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r60805 r60813  
     12010-06-07  Eric Seidel  <eric@webkit.org>
     2
     3        Reviewed by Adam Barth.
     4
     5        HTML5 Parser hits ASSERT in fast/events/stop-load-in-unload-handler-using-document-write.html
     6        https://bugs.webkit.org/show_bug.cgi?id=40268
     7
     8        Teach HTML5Tokenizer about m_parserStopped.
     9
     10        While tracking down how m_parserStopped was used, I found
     11        several useless implementations of stopParsing() which I removed.
     12
     13        I also found a comment in HTMLTokenizer which still talks about the
     14        "part" (an old class now split into Frame, Page, FrameLoader, etc.)
     15        and an nearly empty FrameLoader::tokenizerProcessedData which I just
     16        inlined into its one caller.
     17
     18        Tests:
     19         fast/events/stop-load-in-unload-handler-using-document-write.html
     20         http/tests/security/xssAuditor/full-block-base-href.html
     21
     22        * html/HTML5Tokenizer.cpp:
     23        (WebCore::HTML5Tokenizer::pumpLexerIfPossible):
     24         - New method used instead of direct calls to pumpLexer for when
     25           callers would like to pump the lexer if possible, but don't want
     26           to check if the parser is stopped, etc.
     27        (WebCore::HTML5Tokenizer::pumpLexer):
     28         - Added an ASSERT that the parser is not stopped.
     29         - Stop pumping if the parser is stopped.
     30        (WebCore::HTML5Tokenizer::write):
     31         - Ignore the write if the parser is already stopped.
     32        (WebCore::HTML5Tokenizer::end):
     33        (WebCore::HTML5Tokenizer::attemptToEnd):
     34         - Move comment back to finish() which was incorrectly moved here.
     35        (WebCore::HTML5Tokenizer::endIfDelayed):
     36        (WebCore::HTML5Tokenizer::finish):
     37         - Move comment back here from attemptToEnd()
     38        (WebCore::HTML5Tokenizer::resumeParsingAfterScriptExecution):
     39         - Remove a bogus ASSERT.  The lexer will stop when it needs
     40           more data, which may not necessarily mean m_source.isEmpty().
     41        * html/HTML5Tokenizer.h:
     42         - Add pumpLexerIfPossible().
     43        * html/HTMLTokenizer.cpp:
     44        (WebCore::HTMLTokenizer::stopParsing):
     45         - Add a FIXME about if we really should call checkCompleted() here.
     46         - Inline FrameLoader::tokenizerProcessedData() since this was the only caller.
     47        * loader/FrameLoader.cpp:
     48         - Remove tokenizerProcessedData()
     49        * loader/FrameLoader.h:
     50         - Remove tokenizerProcessedData()
     51        * loader/MediaDocument.cpp:
     52         - Remove unneeded Tokenizer::stopParsing() override.
     53        * loader/PluginDocument.cpp:
     54         - Remove unneeded Tokenizer::stopParsing() override.
     55        * loader/SinkDocument.cpp:
     56         - Remove unneeded Tokenizer::stopParsing() override.
     57
    1582010-06-07  Adam Barth  <abarth@webkit.org>
    259
  • trunk/WebCore/html/HTML5Tokenizer.cpp

    r60802 r60813  
    8181}
    8282
     83void HTML5Tokenizer::pumpLexerIfPossible()
     84{
     85    if (m_parserStopped || m_treeBuilder->isPaused())
     86        return;
     87    pumpLexer();
     88}
     89
    8390void HTML5Tokenizer::pumpLexer()
    8491{
     92    ASSERT(!m_parserStopped);
    8593    ASSERT(!m_treeBuilder->isPaused());
    86     while (m_lexer->nextToken(m_source, m_token)) {
     94    while (!m_parserStopped && m_lexer->nextToken(m_source, m_token)) {
    8795        m_treeBuilder->constructTreeFromToken(m_token);
    8896        m_token.clear();
     
    104112void HTML5Tokenizer::write(const SegmentedString& source, bool)
    105113{
     114    if (m_parserStopped)
     115        return;
     116
    106117    NestingLevelIncrementer nestingLevelIncrementer(m_writeNestingLevel);
    107118
    108119    // HTML5Tokenizer::executeScript is responsible for handling saving m_source before re-entry.
    109120    m_source.append(source);
    110     if (!m_treeBuilder->isPaused())
    111         pumpLexer();
    112 
     121    pumpLexerIfPossible();
    113122    endIfDelayed();
    114123}
     
    117126{
    118127    m_source.close();
    119     if (!m_treeBuilder->isPaused())
    120         pumpLexer();
     128    pumpLexerIfPossible();
     129    // Informs the the rest of WebCore that parsing is really finished.
    121130    m_treeBuilder->finished();
    122131}
     
    131140        return;
    132141    }
    133 
     142    end();
     143}
     144
     145void HTML5Tokenizer::endIfDelayed()
     146{
     147    if (!m_endWasDelayed || isWaitingForScripts() || executingScript())
     148        return;
     149
     150    m_endWasDelayed = false;
     151    end();
     152}
     153
     154void HTML5Tokenizer::finish()
     155{
    134156    // We can't call m_source.close() yet as we may have a <script> execution
    135157    // pending which will call document.write().  No more data off the network though.
    136     end();
    137 }
    138 
    139 void HTML5Tokenizer::endIfDelayed()
    140 {
    141     if (!m_endWasDelayed || !m_source.isEmpty() || isWaitingForScripts() || executingScript())
    142         return;
    143 
    144     m_endWasDelayed = false;
    145     end();
    146 }
    147 
    148 void HTML5Tokenizer::finish()
    149 {
     158    // end() calls Document::finishedParsing() once we're actually done parsing.
    150159    attemptToEnd();
    151160}
     
    175184    ASSERT(!m_scriptRunner->inScriptExecution());
    176185    ASSERT(!m_treeBuilder->isPaused());
    177     pumpLexer();
    178     ASSERT(m_treeBuilder->isPaused() || m_source.isEmpty());
     186    pumpLexerIfPossible();
     187
    179188    // The document already finished parsing we were just waiting on scripts when finished() was called.
    180189    endIfDelayed();
  • trunk/WebCore/html/HTML5Tokenizer.h

    r60802 r60813  
    7171private:
    7272    void pumpLexer();
     73    void pumpLexerIfPossible();
    7374    void resumeParsingAfterScriptExecution();
    7475
  • trunk/WebCore/html/HTMLTokenizer.cpp

    r60786 r60813  
    18011801    m_timer.stop();
    18021802
    1803     // The part needs to know that the tokenizer has finished with its data,
     1803    // FIXME: Why is HTMLTokenizer the only Tokenizer which calls checkCompleted?
     1804    // The FrameLoader needs to know that the tokenizer has finished with its data,
    18041805    // regardless of whether it happened naturally or due to manual intervention.
    18051806    if (!m_fragment && m_doc->frame())
    1806         m_doc->frame()->loader()->tokenizerProcessedData();
     1807        m_doc->frame()->loader()->checkCompleted();
    18071808}
    18081809
  • trunk/WebCore/loader/FrameLoader.cpp

    r60688 r60813  
    28702870}
    28712871
    2872 void FrameLoader::tokenizerProcessedData()
    2873 {
    2874     checkCompleted();
    2875 }
    2876 
    28772872void FrameLoader::handledOnloadEvents()
    28782873{
  • trunk/WebCore/loader/FrameLoader.h

    r60688 r60813  
    245245    KURL baseURL() const;
    246246
    247     void tokenizerProcessedData();
    248 
    249247    void handledOnloadEvents();
    250248    String userAgent(const KURL&) const;
  • trunk/WebCore/loader/MediaDocument.cpp

    r57927 r60813  
    5858private:
    5959    virtual void write(const SegmentedString&, bool appendData);
    60     virtual void stopParsing();
    6160    virtual void finish();
    6261    virtual bool isWaitingForScripts() const;
     
    116115    return false;
    117116}
    118    
    119 void MediaTokenizer::stopParsing()
    120 {
    121     Tokenizer::stopParsing();       
    122 }
    123    
     117
    124118void MediaTokenizer::finish()
    125119{
  • trunk/WebCore/loader/PluginDocument.cpp

    r57927 r60813  
    5353private:
    5454    virtual void write(const SegmentedString&, bool appendData);
    55     virtual void stopParsing();
    5655    virtual void finish();
    5756    virtual bool isWaitingForScripts() const;
     
    135134    return false;
    136135}
    137    
    138 void PluginTokenizer::stopParsing()
    139 {
    140     Tokenizer::stopParsing();       
    141 }
    142    
     136
    143137void PluginTokenizer::finish()
    144138{
  • trunk/WebCore/loader/SinkDocument.cpp

    r59719 r60813  
    3737private:
    3838    virtual void write(const SegmentedString&, bool) { ASSERT_NOT_REACHED(); }
    39     virtual void stopParsing();
    4039    virtual void finish();
    4140    virtual bool isWaitingForScripts() const { return false; }
     
    4645    Document* m_document;
    4746};
    48 
    49 void SinkTokenizer::stopParsing()
    50 {
    51     Tokenizer::stopParsing();
    52 }
    5347
    5448void SinkTokenizer::finish()
Note: See TracChangeset for help on using the changeset viewer.