Changeset 144714 in webkit
- Timestamp:
- Mar 4, 2013 8:57:15 PM (11 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r144713 r144714 1 2013-03-04 Adam Barth <abarth@webkit.org> 2 3 Background HTML parser can rewind the tokenizer after end-of-file 4 https://bugs.webkit.org/show_bug.cgi?id=111365 5 6 Reviewed by Eric Seidel. 7 8 * fast/parser/document-write-fighting-eof.html: Added. 9 1 10 2013-03-04 Tim 'mithro' Ansell <mithro@mithis.com> 2 11 -
trunk/Source/WebCore/ChangeLog
r144713 r144714 1 2013-03-04 Adam Barth <abarth@webkit.org> 2 3 Background HTML parser can rewind the tokenizer after end-of-file 4 https://bugs.webkit.org/show_bug.cgi?id=111365 5 6 Reviewed by Eric Seidel. 7 8 Prior to this patch, it was possible to call didFailSpeculation after 9 processing the end-of-file token because checkForSpeculationFailure 10 didn't zero out m_tokenizer in some control paths. 11 12 This patch renames checkForSpeculationFailure to validateSpeculations 13 and ensures that it always takes ownership of the main thread's 14 HTMLTokenizer. 15 16 This patch also adds a number of ASSERTs to make sure the parser state 17 machine stays in the correct configuration (e.g., that we don't have a 18 main thread tokenizer while we're supposed to be tokenizing on the 19 background thread). 20 21 Test: fast/parser/document-write-fighting-eof.html 22 23 * html/parser/BackgroundHTMLInputStream.cpp: 24 (WebCore::BackgroundHTMLInputStream::rewindTo): 25 * html/parser/BackgroundHTMLParser.cpp: 26 (WebCore::BackgroundHTMLParser::append): 27 * html/parser/HTMLDocumentParser.cpp: 28 (WebCore::HTMLDocumentParser::validateSpeculations): 29 (WebCore::HTMLDocumentParser::processParsedChunkFromBackgroundParser): 30 (WebCore::HTMLDocumentParser::pumpPendingSpeculations): 31 (WebCore::HTMLDocumentParser::resumeParsingAfterScriptExecution): 32 * html/parser/HTMLDocumentParser.h: 33 (HTMLDocumentParser): 34 1 35 2013-03-04 Tim 'mithro' Ansell <mithro@mithis.com> 2 36 -
trunk/Source/WebCore/html/parser/BackgroundHTMLInputStream.cpp
r143685 r144714 72 72 m_current.close(); 73 73 74 ASSERT(m_current.isClosed() == isClosed); 75 74 76 m_segments.clear(); 75 77 m_checkpoints.clear(); -
trunk/Source/WebCore/html/parser/BackgroundHTMLParser.cpp
r144407 r144714 147 147 void BackgroundHTMLParser::append(const String& input) 148 148 { 149 ASSERT(!m_input.current().isClosed()); 149 150 m_input.append(input); 150 151 pumpTokenizer(); -
trunk/Source/WebCore/html/parser/HTMLDocumentParser.cpp
r144543 r144714 329 329 } 330 330 331 void HTMLDocumentParser::checkForSpeculationFailure() 332 { 333 if (!m_tokenizer) 334 return; 335 if (!m_currentChunk) 336 return; 331 void HTMLDocumentParser::validateSpeculations() 332 { 333 OwnPtr<HTMLTokenizer> tokenizer = m_tokenizer.release(); 334 OwnPtr<HTMLToken> token = m_token.release(); 335 336 if (!tokenizer) { 337 // There must not have been any changes to the HTMLTokenizer state on 338 // the main thread, which means the speculation buffer is correct. 339 return; 340 } 341 342 if (!m_currentChunk) { 343 // If there is no m_currentChunk, we must have already called didFailSpeculation 344 // for this chunk. 345 // FIXME: In this case, we're losing whatever state has been changed since 346 // we called didFailSpeculation. See https://bugs.webkit.org/show_bug.cgi?id=110546 347 return; 348 } 349 337 350 // Currently we're only smart enough to reuse the speculation buffer if the tokenizer 338 351 // both starts and ends in the DataState. That state is simplest because the HTMLToken … … 340 353 // speculation buffer in other states, but we'd likely need to do something more 341 354 // sophisticated with the HTMLToken. 342 if (m_currentChunk->tokenizerState == HTMLTokenizer::DataState && m_tokenizer->state() == HTMLTokenizer::DataState && m_input.current().isEmpty()) { 343 ASSERT(m_token->isUninitialized()); 344 m_tokenizer.clear(); 345 m_token.clear(); 346 return; 347 } 348 didFailSpeculation(m_token.release(), m_tokenizer.release()); 355 if (m_currentChunk->tokenizerState == HTMLTokenizer::DataState 356 && tokenizer->state() == HTMLTokenizer::DataState 357 && m_input.current().isEmpty()) { 358 ASSERT(token->isUninitialized()); 359 return; 360 } 361 362 didFailSpeculation(token.release(), tokenizer.release()); 349 363 } 350 364 … … 373 387 ASSERT(refCount() >= 2); 374 388 ASSERT(shouldUseThreading()); 389 ASSERT(!m_tokenizer); 390 ASSERT(!m_token); 375 391 376 392 ActiveParserSession session(contextForParsingSession()); … … 386 402 if (XSSInfo* xssInfo = it->xssInfo()) 387 403 m_xssAuditorDelegate.didBlockScript(*xssInfo); 404 388 405 constructTreeFromCompactHTMLToken(*it); 389 406 … … 396 413 // To match main-thread parser behavior (which never checks locationChangePending on the EOF path) 397 414 // we peek to see if this chunk has an EOF and process it anyway. 398 if (tokens->last().type() == HTMLToken::EndOfFile) 415 if (tokens->last().type() == HTMLToken::EndOfFile) { 416 ASSERT(m_speculations.isEmpty()); 399 417 prepareToStopParsing(); 418 } 400 419 break; 401 420 } … … 404 423 ASSERT(it + 1 == tokens->end()); // The </script> is assumed to be the last token of this bunch. 405 424 runScriptsForPausedTreeBuilder(); 425 validateSpeculations(); 406 426 break; 407 427 } … … 409 429 if (it->type() == HTMLToken::EndOfFile) { 410 430 ASSERT(it + 1 == tokens->end()); // The EOF is assumed to be the last token of this bunch. 431 ASSERT(m_speculations.isEmpty()); 411 432 prepareToStopParsing(); 412 433 break; 413 434 } 414 } 415 416 checkForSpeculationFailure(); 435 436 ASSERT(!m_tokenizer); 437 ASSERT(!m_token); 438 } 417 439 } 418 440 … … 424 446 // ASSERT that this object is both attached to the Document and protected. 425 447 ASSERT(refCount() >= 2); 448 // If this assert fails, you need to call validateSpeculations to make sure 449 // m_tokenizer and m_token don't have state that invalidates m_speculations. 450 ASSERT(!m_tokenizer); 451 ASSERT(!m_token); 426 452 427 453 // FIXME: Pass in current input length. … … 847 873 #if ENABLE(THREADED_HTML_PARSER) 848 874 if (m_haveBackgroundParser) { 849 checkForSpeculationFailure(); 850 875 validateSpeculations(); 851 876 // processParsedChunkFromBackgroundParser can cause this parser to be detached from the Document, 852 877 // but we need to ensure it isn't deleted yet. -
trunk/Source/WebCore/html/parser/HTMLDocumentParser.h
r144498 r144714 141 141 void startBackgroundParser(); 142 142 void stopBackgroundParser(); 143 void checkForSpeculationFailure();143 void validateSpeculations(); 144 144 void didFailSpeculation(PassOwnPtr<HTMLToken>, PassOwnPtr<HTMLTokenizer>); 145 145 void processParsedChunkFromBackgroundParser(PassOwnPtr<ParsedChunk>);
Note: See TracChangeset
for help on using the changeset viewer.