| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2010 Google, Inc. All Rights Reserved. | 2 * Copyright (C) 2010 Google, Inc. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 #include "platform/Histogram.h" | 48 #include "platform/Histogram.h" |
| 49 #include "platform/SharedBuffer.h" | 49 #include "platform/SharedBuffer.h" |
| 50 #include "platform/ThreadSafeFunctional.h" | 50 #include "platform/ThreadSafeFunctional.h" |
| 51 #include "platform/TraceEvent.h" | 51 #include "platform/TraceEvent.h" |
| 52 #include "platform/heap/Handle.h" | 52 #include "platform/heap/Handle.h" |
| 53 #include "public/platform/Platform.h" | 53 #include "public/platform/Platform.h" |
| 54 #include "public/platform/WebFrameScheduler.h" | 54 #include "public/platform/WebFrameScheduler.h" |
| 55 #include "public/platform/WebLoadingBehaviorFlag.h" | 55 #include "public/platform/WebLoadingBehaviorFlag.h" |
| 56 #include "public/platform/WebScheduler.h" | 56 #include "public/platform/WebScheduler.h" |
| 57 #include "public/platform/WebThread.h" | 57 #include "public/platform/WebThread.h" |
| 58 #include "wtf/PtrUtil.h" | |
| 59 #include "wtf/TemporaryChange.h" | 58 #include "wtf/TemporaryChange.h" |
| 60 #include <memory> | |
| 61 | 59 |
| 62 namespace blink { | 60 namespace blink { |
| 63 | 61 |
| 64 using namespace HTMLNames; | 62 using namespace HTMLNames; |
| 65 | 63 |
| 66 // This is a direct transcription of step 4 from: | 64 // This is a direct transcription of step 4 from: |
| 67 // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#frag
ment-case | 65 // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#frag
ment-case |
| 68 static HTMLTokenizer::State tokenizerStateForContextElement(Element* contextElem
ent, bool reportErrors, const HTMLParserOptions& options) | 66 static HTMLTokenizer::State tokenizerStateForContextElement(Element* contextElem
ent, bool reportErrors, const HTMLParserOptions& options) |
| 69 { | 67 { |
| 70 if (!contextElement) | 68 if (!contextElement) |
| (...skipping 13 matching lines...) Expand all Loading... |
| 84 if (contextTag.matches(scriptTag)) | 82 if (contextTag.matches(scriptTag)) |
| 85 return reportErrors ? HTMLTokenizer::ScriptDataState : HTMLTokenizer::PL
AINTEXTState; | 83 return reportErrors ? HTMLTokenizer::ScriptDataState : HTMLTokenizer::PL
AINTEXTState; |
| 86 if (contextTag.matches(plaintextTag)) | 84 if (contextTag.matches(plaintextTag)) |
| 87 return HTMLTokenizer::PLAINTEXTState; | 85 return HTMLTokenizer::PLAINTEXTState; |
| 88 return HTMLTokenizer::DataState; | 86 return HTMLTokenizer::DataState; |
| 89 } | 87 } |
| 90 | 88 |
| 91 HTMLDocumentParser::HTMLDocumentParser(HTMLDocument& document, ParserSynchroniza
tionPolicy syncPolicy) | 89 HTMLDocumentParser::HTMLDocumentParser(HTMLDocument& document, ParserSynchroniza
tionPolicy syncPolicy) |
| 92 : ScriptableDocumentParser(document) | 90 : ScriptableDocumentParser(document) |
| 93 , m_options(&document) | 91 , m_options(&document) |
| 94 , m_token(syncPolicy == ForceSynchronousParsing ? wrapUnique(new HTMLToken)
: nullptr) | 92 , m_token(syncPolicy == ForceSynchronousParsing ? adoptPtr(new HTMLToken) :
nullptr) |
| 95 , m_tokenizer(syncPolicy == ForceSynchronousParsing ? HTMLTokenizer::create(
m_options) : nullptr) | 93 , m_tokenizer(syncPolicy == ForceSynchronousParsing ? HTMLTokenizer::create(
m_options) : nullptr) |
| 96 , m_scriptRunner(HTMLScriptRunner::create(&document, this)) | 94 , m_scriptRunner(HTMLScriptRunner::create(&document, this)) |
| 97 , m_treeBuilder(HTMLTreeBuilder::create(this, &document, getParserContentPol
icy(), m_options)) | 95 , m_treeBuilder(HTMLTreeBuilder::create(this, &document, getParserContentPol
icy(), m_options)) |
| 98 , m_loadingTaskRunner(wrapUnique(document.loadingTaskRunner()->clone())) | 96 , m_loadingTaskRunner(adoptPtr(document.loadingTaskRunner()->clone())) |
| 99 , m_parserScheduler(HTMLParserScheduler::create(this, m_loadingTaskRunner.ge
t())) | 97 , m_parserScheduler(HTMLParserScheduler::create(this, m_loadingTaskRunner.ge
t())) |
| 100 , m_xssAuditorDelegate(&document) | 98 , m_xssAuditorDelegate(&document) |
| 101 , m_weakFactory(this) | 99 , m_weakFactory(this) |
| 102 , m_preloader(HTMLResourcePreloader::create(document)) | 100 , m_preloader(HTMLResourcePreloader::create(document)) |
| 103 , m_parsedChunkQueue(ParsedChunkQueue::create()) | 101 , m_parsedChunkQueue(ParsedChunkQueue::create()) |
| 104 , m_evaluator(DocumentWriteEvaluator::create(document)) | 102 , m_evaluator(DocumentWriteEvaluator::create(document)) |
| 105 , m_shouldUseThreading(syncPolicy == AllowAsynchronousParsing) | 103 , m_shouldUseThreading(syncPolicy == AllowAsynchronousParsing) |
| 106 , m_endWasDelayed(false) | 104 , m_endWasDelayed(false) |
| 107 , m_haveBackgroundParser(false) | 105 , m_haveBackgroundParser(false) |
| 108 , m_tasksWereSuspended(false) | 106 , m_tasksWereSuspended(false) |
| 109 , m_pumpSessionNestingLevel(0) | 107 , m_pumpSessionNestingLevel(0) |
| 110 , m_pumpSpeculationsSessionNestingLevel(0) | 108 , m_pumpSpeculationsSessionNestingLevel(0) |
| 111 , m_isParsingAtLineNumber(false) | 109 , m_isParsingAtLineNumber(false) |
| 112 , m_triedLoadingLinkHeaders(false) | 110 , m_triedLoadingLinkHeaders(false) |
| 113 { | 111 { |
| 114 ASSERT(shouldUseThreading() || (m_token && m_tokenizer)); | 112 ASSERT(shouldUseThreading() || (m_token && m_tokenizer)); |
| 115 } | 113 } |
| 116 | 114 |
| 117 // FIXME: Member variables should be grouped into self-initializing structs to | 115 // FIXME: Member variables should be grouped into self-initializing structs to |
| 118 // minimize code duplication between these constructors. | 116 // minimize code duplication between these constructors. |
| 119 HTMLDocumentParser::HTMLDocumentParser(DocumentFragment* fragment, Element* cont
extElement, ParserContentPolicy parserContentPolicy) | 117 HTMLDocumentParser::HTMLDocumentParser(DocumentFragment* fragment, Element* cont
extElement, ParserContentPolicy parserContentPolicy) |
| 120 : ScriptableDocumentParser(fragment->document(), parserContentPolicy) | 118 : ScriptableDocumentParser(fragment->document(), parserContentPolicy) |
| 121 , m_options(&fragment->document()) | 119 , m_options(&fragment->document()) |
| 122 , m_token(wrapUnique(new HTMLToken)) | 120 , m_token(adoptPtr(new HTMLToken)) |
| 123 , m_tokenizer(HTMLTokenizer::create(m_options)) | 121 , m_tokenizer(HTMLTokenizer::create(m_options)) |
| 124 , m_treeBuilder(HTMLTreeBuilder::create(this, fragment, contextElement, this
->getParserContentPolicy(), m_options)) | 122 , m_treeBuilder(HTMLTreeBuilder::create(this, fragment, contextElement, this
->getParserContentPolicy(), m_options)) |
| 125 , m_loadingTaskRunner(wrapUnique(fragment->document().loadingTaskRunner()->c
lone())) | 123 , m_loadingTaskRunner(adoptPtr(fragment->document().loadingTaskRunner()->clo
ne())) |
| 126 , m_xssAuditorDelegate(&fragment->document()) | 124 , m_xssAuditorDelegate(&fragment->document()) |
| 127 , m_weakFactory(this) | 125 , m_weakFactory(this) |
| 128 , m_shouldUseThreading(false) | 126 , m_shouldUseThreading(false) |
| 129 , m_endWasDelayed(false) | 127 , m_endWasDelayed(false) |
| 130 , m_haveBackgroundParser(false) | 128 , m_haveBackgroundParser(false) |
| 131 , m_tasksWereSuspended(false) | 129 , m_tasksWereSuspended(false) |
| 132 , m_pumpSessionNestingLevel(0) | 130 , m_pumpSessionNestingLevel(0) |
| 133 , m_pumpSpeculationsSessionNestingLevel(0) | 131 , m_pumpSpeculationsSessionNestingLevel(0) |
| 134 { | 132 { |
| 135 bool reportErrors = false; // For now document fragment parsing never report
s errors. | 133 bool reportErrors = false; // For now document fragment parsing never report
s errors. |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 285 return false; | 283 return false; |
| 286 | 284 |
| 287 return true; | 285 return true; |
| 288 } | 286 } |
| 289 | 287 |
| 290 void HTMLDocumentParser::notifyPendingParsedChunks() | 288 void HTMLDocumentParser::notifyPendingParsedChunks() |
| 291 { | 289 { |
| 292 TRACE_EVENT0("blink", "HTMLDocumentParser::notifyPendingParsedChunks"); | 290 TRACE_EVENT0("blink", "HTMLDocumentParser::notifyPendingParsedChunks"); |
| 293 ASSERT(m_parsedChunkQueue); | 291 ASSERT(m_parsedChunkQueue); |
| 294 | 292 |
| 295 Vector<std::unique_ptr<ParsedChunk>> pendingChunks; | 293 Vector<OwnPtr<ParsedChunk>> pendingChunks; |
| 296 m_parsedChunkQueue->takeAll(pendingChunks); | 294 m_parsedChunkQueue->takeAll(pendingChunks); |
| 297 | 295 |
| 298 if (!isParsing()) | 296 if (!isParsing()) |
| 299 return; | 297 return; |
| 300 | 298 |
| 301 // ApplicationCache needs to be initialized before issuing preloads. | 299 // ApplicationCache needs to be initialized before issuing preloads. |
| 302 // We suspend preload until HTMLHTMLElement is inserted and | 300 // We suspend preload until HTMLHTMLElement is inserted and |
| 303 // ApplicationCache is initialized. | 301 // ApplicationCache is initialized. |
| 304 if (!document()->documentElement()) { | 302 if (!document()->documentElement()) { |
| 305 for (auto& chunk : pendingChunks) { | 303 for (auto& chunk : pendingChunks) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 336 else | 334 else |
| 337 m_parserScheduler->scheduleForResume(); | 335 m_parserScheduler->scheduleForResume(); |
| 338 } | 336 } |
| 339 } | 337 } |
| 340 | 338 |
| 341 void HTMLDocumentParser::didReceiveEncodingDataFromBackgroundParser(const Docume
ntEncodingData& data) | 339 void HTMLDocumentParser::didReceiveEncodingDataFromBackgroundParser(const Docume
ntEncodingData& data) |
| 342 { | 340 { |
| 343 document()->setEncodingData(data); | 341 document()->setEncodingData(data); |
| 344 } | 342 } |
| 345 | 343 |
| 346 void HTMLDocumentParser::validateSpeculations(std::unique_ptr<ParsedChunk> chunk
) | 344 void HTMLDocumentParser::validateSpeculations(PassOwnPtr<ParsedChunk> chunk) |
| 347 { | 345 { |
| 348 ASSERT(chunk); | 346 ASSERT(chunk); |
| 349 if (isWaitingForScripts()) { | 347 if (isWaitingForScripts()) { |
| 350 // We're waiting on a network script, just save the chunk, we'll get | 348 // We're waiting on a network script, just save the chunk, we'll get |
| 351 // a second validateSpeculations call after the script completes. | 349 // a second validateSpeculations call after the script completes. |
| 352 // This call should have been made immediately after runScriptsForPaused
TreeBuilder | 350 // This call should have been made immediately after runScriptsForPaused
TreeBuilder |
| 353 // which may have started a network load and left us waiting. | 351 // which may have started a network load and left us waiting. |
| 354 ASSERT(!m_lastChunkBeforeScript); | 352 ASSERT(!m_lastChunkBeforeScript); |
| 355 m_lastChunkBeforeScript = std::move(chunk); | 353 m_lastChunkBeforeScript = std::move(chunk); |
| 356 return; | 354 return; |
| 357 } | 355 } |
| 358 | 356 |
| 359 ASSERT(!m_lastChunkBeforeScript); | 357 ASSERT(!m_lastChunkBeforeScript); |
| 360 std::unique_ptr<HTMLTokenizer> tokenizer = std::move(m_tokenizer); | 358 OwnPtr<HTMLTokenizer> tokenizer = std::move(m_tokenizer); |
| 361 std::unique_ptr<HTMLToken> token = std::move(m_token); | 359 OwnPtr<HTMLToken> token = std::move(m_token); |
| 362 | 360 |
| 363 if (!tokenizer) { | 361 if (!tokenizer) { |
| 364 // There must not have been any changes to the HTMLTokenizer state on | 362 // There must not have been any changes to the HTMLTokenizer state on |
| 365 // the main thread, which means the speculation buffer is correct. | 363 // the main thread, which means the speculation buffer is correct. |
| 366 return; | 364 return; |
| 367 } | 365 } |
| 368 | 366 |
| 369 // Currently we're only smart enough to reuse the speculation buffer if the
tokenizer | 367 // Currently we're only smart enough to reuse the speculation buffer if the
tokenizer |
| 370 // both starts and ends in the DataState. That state is simplest because the
HTMLToken | 368 // both starts and ends in the DataState. That state is simplest because the
HTMLToken |
| 371 // is always in the Uninitialized state. We should consider whether we can r
euse the | 369 // is always in the Uninitialized state. We should consider whether we can r
euse the |
| 372 // speculation buffer in other states, but we'd likely need to do something
more | 370 // speculation buffer in other states, but we'd likely need to do something
more |
| 373 // sophisticated with the HTMLToken. | 371 // sophisticated with the HTMLToken. |
| 374 if (chunk->tokenizerState == HTMLTokenizer::DataState | 372 if (chunk->tokenizerState == HTMLTokenizer::DataState |
| 375 && tokenizer->getState() == HTMLTokenizer::DataState | 373 && tokenizer->getState() == HTMLTokenizer::DataState |
| 376 && m_input.current().isEmpty() | 374 && m_input.current().isEmpty() |
| 377 && chunk->treeBuilderState == HTMLTreeBuilderSimulator::stateFor(m_treeB
uilder.get())) { | 375 && chunk->treeBuilderState == HTMLTreeBuilderSimulator::stateFor(m_treeB
uilder.get())) { |
| 378 ASSERT(token->isUninitialized()); | 376 ASSERT(token->isUninitialized()); |
| 379 return; | 377 return; |
| 380 } | 378 } |
| 381 | 379 |
| 382 discardSpeculationsAndResumeFrom(std::move(chunk), std::move(token), std::mo
ve(tokenizer)); | 380 discardSpeculationsAndResumeFrom(std::move(chunk), std::move(token), std::mo
ve(tokenizer)); |
| 383 } | 381 } |
| 384 | 382 |
| 385 void HTMLDocumentParser::discardSpeculationsAndResumeFrom(std::unique_ptr<Parsed
Chunk> lastChunkBeforeScript, std::unique_ptr<HTMLToken> token, std::unique_ptr<
HTMLTokenizer> tokenizer) | 383 void HTMLDocumentParser::discardSpeculationsAndResumeFrom(PassOwnPtr<ParsedChunk
> lastChunkBeforeScript, PassOwnPtr<HTMLToken> token, PassOwnPtr<HTMLTokenizer>
tokenizer) |
| 386 { | 384 { |
| 387 m_weakFactory.revokeAll(); | 385 m_weakFactory.revokeAll(); |
| 388 m_speculations.clear(); | 386 m_speculations.clear(); |
| 389 | 387 |
| 390 std::unique_ptr<BackgroundHTMLParser::Checkpoint> checkpoint = wrapUnique(ne
w BackgroundHTMLParser::Checkpoint); | 388 OwnPtr<BackgroundHTMLParser::Checkpoint> checkpoint = adoptPtr(new Backgroun
dHTMLParser::Checkpoint); |
| 391 checkpoint->parser = m_weakFactory.createWeakPtr(); | 389 checkpoint->parser = m_weakFactory.createWeakPtr(); |
| 392 checkpoint->token = std::move(token); | 390 checkpoint->token = std::move(token); |
| 393 checkpoint->tokenizer = std::move(tokenizer); | 391 checkpoint->tokenizer = std::move(tokenizer); |
| 394 checkpoint->treeBuilderState = HTMLTreeBuilderSimulator::stateFor(m_treeBuil
der.get()); | 392 checkpoint->treeBuilderState = HTMLTreeBuilderSimulator::stateFor(m_treeBuil
der.get()); |
| 395 checkpoint->inputCheckpoint = lastChunkBeforeScript->inputCheckpoint; | 393 checkpoint->inputCheckpoint = lastChunkBeforeScript->inputCheckpoint; |
| 396 checkpoint->preloadScannerCheckpoint = lastChunkBeforeScript->preloadScanner
Checkpoint; | 394 checkpoint->preloadScannerCheckpoint = lastChunkBeforeScript->preloadScanner
Checkpoint; |
| 397 checkpoint->unparsedInput = m_input.current().toString().isolatedCopy(); | 395 checkpoint->unparsedInput = m_input.current().toString().isolatedCopy(); |
| 398 m_input.current().clear(); // FIXME: This should be passed in instead of cle
ared. | 396 m_input.current().clear(); // FIXME: This should be passed in instead of cle
ared. |
| 399 | 397 |
| 400 ASSERT(checkpoint->unparsedInput.isSafeToSendToAnotherThread()); | 398 ASSERT(checkpoint->unparsedInput.isSafeToSendToAnotherThread()); |
| 401 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParser::r
esumeFrom, m_backgroundParser, passed(std::move(checkpoint)))); | 399 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParser::r
esumeFrom, m_backgroundParser, passed(std::move(checkpoint)))); |
| 402 } | 400 } |
| 403 | 401 |
| 404 size_t HTMLDocumentParser::processParsedChunkFromBackgroundParser(std::unique_pt
r<ParsedChunk> popChunk) | 402 size_t HTMLDocumentParser::processParsedChunkFromBackgroundParser(PassOwnPtr<Par
sedChunk> popChunk) |
| 405 { | 403 { |
| 406 TRACE_EVENT_WITH_FLOW0("blink,loading", "HTMLDocumentParser::processParsedCh
unkFromBackgroundParser", popChunk.get(), TRACE_EVENT_FLAG_FLOW_IN); | 404 TRACE_EVENT_WITH_FLOW0("blink,loading", "HTMLDocumentParser::processParsedCh
unkFromBackgroundParser", popChunk.get(), TRACE_EVENT_FLAG_FLOW_IN); |
| 407 TemporaryChange<bool> hasLineNumber(m_isParsingAtLineNumber, true); | 405 TemporaryChange<bool> hasLineNumber(m_isParsingAtLineNumber, true); |
| 408 | 406 |
| 409 ASSERT_WITH_SECURITY_IMPLICATION(m_pumpSpeculationsSessionNestingLevel == 1)
; | 407 ASSERT_WITH_SECURITY_IMPLICATION(m_pumpSpeculationsSessionNestingLevel == 1)
; |
| 410 ASSERT_WITH_SECURITY_IMPLICATION(!inPumpSession()); | 408 ASSERT_WITH_SECURITY_IMPLICATION(!inPumpSession()); |
| 411 ASSERT(!isParsingFragment()); | 409 ASSERT(!isParsingFragment()); |
| 412 ASSERT(!isWaitingForScripts()); | 410 ASSERT(!isWaitingForScripts()); |
| 413 ASSERT(!isStopped()); | 411 ASSERT(!isStopped()); |
| 414 ASSERT(shouldUseThreading()); | 412 ASSERT(shouldUseThreading()); |
| 415 ASSERT(!m_tokenizer); | 413 ASSERT(!m_tokenizer); |
| 416 ASSERT(!m_token); | 414 ASSERT(!m_token); |
| 417 ASSERT(!m_lastChunkBeforeScript); | 415 ASSERT(!m_lastChunkBeforeScript); |
| 418 | 416 |
| 419 std::unique_ptr<ParsedChunk> chunk(std::move(popChunk)); | 417 OwnPtr<ParsedChunk> chunk(std::move(popChunk)); |
| 420 std::unique_ptr<CompactHTMLTokenStream> tokens = std::move(chunk->tokens); | 418 OwnPtr<CompactHTMLTokenStream> tokens = std::move(chunk->tokens); |
| 421 size_t elementTokenCount = 0; | 419 size_t elementTokenCount = 0; |
| 422 | 420 |
| 423 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParser::s
tartedChunkWithCheckpoint, m_backgroundParser, chunk->inputCheckpoint)); | 421 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParser::s
tartedChunkWithCheckpoint, m_backgroundParser, chunk->inputCheckpoint)); |
| 424 | 422 |
| 425 for (const auto& xssInfo : chunk->xssInfos) { | 423 for (const auto& xssInfo : chunk->xssInfos) { |
| 426 m_textPosition = xssInfo->m_textPosition; | 424 m_textPosition = xssInfo->m_textPosition; |
| 427 m_xssAuditorDelegate.didBlockScript(*xssInfo); | 425 m_xssAuditorDelegate.didBlockScript(*xssInfo); |
| 428 if (isStopped()) | 426 if (isStopped()) |
| 429 break; | 427 break; |
| 430 } | 428 } |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 579 m_sourceTracker.start(m_input.current(), m_tokenizer.get(), token())
; | 577 m_sourceTracker.start(m_input.current(), m_tokenizer.get(), token())
; |
| 580 | 578 |
| 581 if (!m_tokenizer->nextToken(m_input.current(), token())) | 579 if (!m_tokenizer->nextToken(m_input.current(), token())) |
| 582 break; | 580 break; |
| 583 | 581 |
| 584 if (m_xssAuditor.isEnabled()) { | 582 if (m_xssAuditor.isEnabled()) { |
| 585 m_sourceTracker.end(m_input.current(), m_tokenizer.get(), token()); | 583 m_sourceTracker.end(m_input.current(), m_tokenizer.get(), token()); |
| 586 | 584 |
| 587 // We do not XSS filter innerHTML, which means we (intentionally) fa
il | 585 // We do not XSS filter innerHTML, which means we (intentionally) fa
il |
| 588 // http/tests/security/xssAuditor/dom-write-innerHTML.html | 586 // http/tests/security/xssAuditor/dom-write-innerHTML.html |
| 589 if (std::unique_ptr<XSSInfo> xssInfo = m_xssAuditor.filterToken(Filt
erTokenRequest(token(), m_sourceTracker, m_tokenizer->shouldAllowCDATA()))) | 587 if (OwnPtr<XSSInfo> xssInfo = m_xssAuditor.filterToken(FilterTokenRe
quest(token(), m_sourceTracker, m_tokenizer->shouldAllowCDATA()))) |
| 590 m_xssAuditorDelegate.didBlockScript(*xssInfo); | 588 m_xssAuditorDelegate.didBlockScript(*xssInfo); |
| 591 } | 589 } |
| 592 | 590 |
| 593 constructTreeFromHTMLToken(); | 591 constructTreeFromHTMLToken(); |
| 594 ASSERT(isStopped() || token().isUninitialized()); | 592 ASSERT(isStopped() || token().isUninitialized()); |
| 595 } | 593 } |
| 596 | 594 |
| 597 if (isStopped()) | 595 if (isStopped()) |
| 598 return; | 596 return; |
| 599 | 597 |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 668 void HTMLDocumentParser::insert(const SegmentedString& source) | 666 void HTMLDocumentParser::insert(const SegmentedString& source) |
| 669 { | 667 { |
| 670 if (isStopped()) | 668 if (isStopped()) |
| 671 return; | 669 return; |
| 672 | 670 |
| 673 TRACE_EVENT1("blink", "HTMLDocumentParser::insert", "source_length", source.
length()); | 671 TRACE_EVENT1("blink", "HTMLDocumentParser::insert", "source_length", source.
length()); |
| 674 | 672 |
| 675 if (!m_tokenizer) { | 673 if (!m_tokenizer) { |
| 676 ASSERT(!inPumpSession()); | 674 ASSERT(!inPumpSession()); |
| 677 ASSERT(m_haveBackgroundParser || wasCreatedByScript()); | 675 ASSERT(m_haveBackgroundParser || wasCreatedByScript()); |
| 678 m_token = wrapUnique(new HTMLToken); | 676 m_token = adoptPtr(new HTMLToken); |
| 679 m_tokenizer = HTMLTokenizer::create(m_options); | 677 m_tokenizer = HTMLTokenizer::create(m_options); |
| 680 } | 678 } |
| 681 | 679 |
| 682 SegmentedString excludedLineNumberSource(source); | 680 SegmentedString excludedLineNumberSource(source); |
| 683 excludedLineNumberSource.setExcludeLineNumbers(); | 681 excludedLineNumberSource.setExcludeLineNumbers(); |
| 684 m_input.insertAtCurrentInsertionPoint(excludedLineNumberSource); | 682 m_input.insertAtCurrentInsertionPoint(excludedLineNumberSource); |
| 685 pumpTokenizerIfPossible(); | 683 pumpTokenizerIfPossible(); |
| 686 | 684 |
| 687 if (isWaitingForScripts()) { | 685 if (isWaitingForScripts()) { |
| 688 // Check the document.write() output with a separate preload scanner as | 686 // Check the document.write() output with a separate preload scanner as |
| (...skipping 15 matching lines...) Expand all Loading... |
| 704 ASSERT(document()); | 702 ASSERT(document()); |
| 705 m_haveBackgroundParser = true; | 703 m_haveBackgroundParser = true; |
| 706 | 704 |
| 707 // Make sure that a resolver is set up, so that the correct viewport dimensi
ons will be fed to the background parser and preload scanner. | 705 // Make sure that a resolver is set up, so that the correct viewport dimensi
ons will be fed to the background parser and preload scanner. |
| 708 if (document()->loader()) | 706 if (document()->loader()) |
| 709 document()->ensureStyleResolver(); | 707 document()->ensureStyleResolver(); |
| 710 | 708 |
| 711 RefPtr<WeakReference<BackgroundHTMLParser>> reference = WeakReference<Backgr
oundHTMLParser>::createUnbound(); | 709 RefPtr<WeakReference<BackgroundHTMLParser>> reference = WeakReference<Backgr
oundHTMLParser>::createUnbound(); |
| 712 m_backgroundParser = WeakPtr<BackgroundHTMLParser>(reference); | 710 m_backgroundParser = WeakPtr<BackgroundHTMLParser>(reference); |
| 713 | 711 |
| 714 std::unique_ptr<BackgroundHTMLParser::Configuration> config = wrapUnique(new
BackgroundHTMLParser::Configuration); | 712 OwnPtr<BackgroundHTMLParser::Configuration> config = adoptPtr(new Background
HTMLParser::Configuration); |
| 715 config->options = m_options; | 713 config->options = m_options; |
| 716 config->parser = m_weakFactory.createWeakPtr(); | 714 config->parser = m_weakFactory.createWeakPtr(); |
| 717 config->xssAuditor = wrapUnique(new XSSAuditor); | 715 config->xssAuditor = adoptPtr(new XSSAuditor); |
| 718 config->xssAuditor->init(document(), &m_xssAuditorDelegate); | 716 config->xssAuditor->init(document(), &m_xssAuditorDelegate); |
| 719 | 717 |
| 720 config->decoder = takeDecoder(); | 718 config->decoder = takeDecoder(); |
| 721 config->parsedChunkQueue = m_parsedChunkQueue.get(); | 719 config->parsedChunkQueue = m_parsedChunkQueue.get(); |
| 722 if (document()->settings()) { | 720 if (document()->settings()) { |
| 723 if (document()->settings()->backgroundHtmlParserOutstandingTokenLimit()) | 721 if (document()->settings()->backgroundHtmlParserOutstandingTokenLimit()) |
| 724 config->outstandingTokenLimit = document()->settings()->backgroundHt
mlParserOutstandingTokenLimit(); | 722 config->outstandingTokenLimit = document()->settings()->backgroundHt
mlParserOutstandingTokenLimit(); |
| 725 if (document()->settings()->backgroundHtmlParserPendingTokenLimit()) | 723 if (document()->settings()->backgroundHtmlParserPendingTokenLimit()) |
| 726 config->pendingTokenLimit = document()->settings()->backgroundHtmlPa
rserPendingTokenLimit(); | 724 config->pendingTokenLimit = document()->settings()->backgroundHtmlPa
rserPendingTokenLimit(); |
| 727 } | 725 } |
| 728 | 726 |
| 729 ASSERT(config->xssAuditor->isSafeToSendToAnotherThread()); | 727 ASSERT(config->xssAuditor->isSafeToSendToAnotherThread()); |
| 730 HTMLParserThread::shared()->postTask(threadSafeBind( | 728 HTMLParserThread::shared()->postTask(threadSafeBind( |
| 731 &BackgroundHTMLParser::start, | 729 &BackgroundHTMLParser::start, |
| 732 reference.release(), | 730 reference.release(), |
| 733 passed(std::move(config)), | 731 passed(std::move(config)), |
| 734 document()->url(), | 732 document()->url(), |
| 735 passed(CachedDocumentParameters::create(document())), | 733 passed(CachedDocumentParameters::create(document())), |
| 736 MediaValuesCached::MediaValuesCachedData(*document()), | 734 MediaValuesCached::MediaValuesCachedData(*document()), |
| 737 passed(wrapUnique(m_loadingTaskRunner->clone())))); | 735 passed(adoptPtr(m_loadingTaskRunner->clone())))); |
| 738 } | 736 } |
| 739 | 737 |
| 740 void HTMLDocumentParser::stopBackgroundParser() | 738 void HTMLDocumentParser::stopBackgroundParser() |
| 741 { | 739 { |
| 742 ASSERT(shouldUseThreading()); | 740 ASSERT(shouldUseThreading()); |
| 743 ASSERT(m_haveBackgroundParser); | 741 ASSERT(m_haveBackgroundParser); |
| 744 m_haveBackgroundParser = false; | 742 m_haveBackgroundParser = false; |
| 745 | 743 |
| 746 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParser::s
top, m_backgroundParser)); | 744 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParser::s
top, m_backgroundParser)); |
| 747 m_weakFactory.revokeAll(); | 745 m_weakFactory.revokeAll(); |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 853 m_input.closeWithoutMarkingEndOfFile(); | 851 m_input.closeWithoutMarkingEndOfFile(); |
| 854 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParse
r::finish, m_backgroundParser)); | 852 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParse
r::finish, m_backgroundParser)); |
| 855 return; | 853 return; |
| 856 } | 854 } |
| 857 | 855 |
| 858 if (!m_tokenizer) { | 856 if (!m_tokenizer) { |
| 859 ASSERT(!m_token); | 857 ASSERT(!m_token); |
| 860 // We're finishing before receiving any data. Rather than booting up | 858 // We're finishing before receiving any data. Rather than booting up |
| 861 // the background parser just to spin it down, we finish parsing | 859 // the background parser just to spin it down, we finish parsing |
| 862 // synchronously. | 860 // synchronously. |
| 863 m_token = wrapUnique(new HTMLToken); | 861 m_token = adoptPtr(new HTMLToken); |
| 864 m_tokenizer = HTMLTokenizer::create(m_options); | 862 m_tokenizer = HTMLTokenizer::create(m_options); |
| 865 } | 863 } |
| 866 | 864 |
| 867 // We're not going to get any more data off the network, so we tell the | 865 // We're not going to get any more data off the network, so we tell the |
| 868 // input stream we've reached the end of file. finish() can be called more | 866 // input stream we've reached the end of file. finish() can be called more |
| 869 // than once, if the first time does not call end(). | 867 // than once, if the first time does not call end(). |
| 870 if (!m_input.haveSeenEndOfFile()) | 868 if (!m_input.haveSeenEndOfFile()) |
| 871 m_input.markEndOfFile(); | 869 m_input.markEndOfFile(); |
| 872 | 870 |
| 873 attemptToEnd(); | 871 attemptToEnd(); |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1005 | 1003 |
| 1006 void HTMLDocumentParser::appendBytes(const char* data, size_t length) | 1004 void HTMLDocumentParser::appendBytes(const char* data, size_t length) |
| 1007 { | 1005 { |
| 1008 if (!length || isStopped()) | 1006 if (!length || isStopped()) |
| 1009 return; | 1007 return; |
| 1010 | 1008 |
| 1011 if (shouldUseThreading()) { | 1009 if (shouldUseThreading()) { |
| 1012 if (!m_haveBackgroundParser) | 1010 if (!m_haveBackgroundParser) |
| 1013 startBackgroundParser(); | 1011 startBackgroundParser(); |
| 1014 | 1012 |
| 1015 std::unique_ptr<Vector<char>> buffer = wrapUnique(new Vector<char>(lengt
h)); | 1013 OwnPtr<Vector<char>> buffer = adoptPtr(new Vector<char>(length)); |
| 1016 memcpy(buffer->data(), data, length); | 1014 memcpy(buffer->data(), data, length); |
| 1017 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.debug"), "HTMLDocumentPars
er::appendBytes", "size", (unsigned)length); | 1015 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.debug"), "HTMLDocumentPars
er::appendBytes", "size", (unsigned)length); |
| 1018 | 1016 |
| 1019 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParse
r::appendRawBytesFromMainThread, m_backgroundParser, passed(std::move(buffer))))
; | 1017 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParse
r::appendRawBytesFromMainThread, m_backgroundParser, passed(std::move(buffer))))
; |
| 1020 return; | 1018 return; |
| 1021 } | 1019 } |
| 1022 | 1020 |
| 1023 DecodedDataDocumentParser::appendBytes(data, length); | 1021 DecodedDataDocumentParser::appendBytes(data, length); |
| 1024 } | 1022 } |
| 1025 | 1023 |
| 1026 void HTMLDocumentParser::flush() | 1024 void HTMLDocumentParser::flush() |
| 1027 { | 1025 { |
| 1028 // If we've got no decoder, we never received any data. | 1026 // If we've got no decoder, we never received any data. |
| 1029 if (isDetached() || needsDecoder()) | 1027 if (isDetached() || needsDecoder()) |
| 1030 return; | 1028 return; |
| 1031 | 1029 |
| 1032 if (shouldUseThreading()) { | 1030 if (shouldUseThreading()) { |
| 1033 // In some cases, flush() is called without any invocation of | 1031 // In some cases, flush() is called without any invocation of |
| 1034 // appendBytes. Fallback to synchronous parsing in that case. | 1032 // appendBytes. Fallback to synchronous parsing in that case. |
| 1035 if (!m_haveBackgroundParser) { | 1033 if (!m_haveBackgroundParser) { |
| 1036 m_shouldUseThreading = false; | 1034 m_shouldUseThreading = false; |
| 1037 m_token = wrapUnique(new HTMLToken); | 1035 m_token = adoptPtr(new HTMLToken); |
| 1038 m_tokenizer = HTMLTokenizer::create(m_options); | 1036 m_tokenizer = HTMLTokenizer::create(m_options); |
| 1039 DecodedDataDocumentParser::flush(); | 1037 DecodedDataDocumentParser::flush(); |
| 1040 return; | 1038 return; |
| 1041 } | 1039 } |
| 1042 | 1040 |
| 1043 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParse
r::flush, m_backgroundParser)); | 1041 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParse
r::flush, m_backgroundParser)); |
| 1044 } else { | 1042 } else { |
| 1045 DecodedDataDocumentParser::flush(); | 1043 DecodedDataDocumentParser::flush(); |
| 1046 } | 1044 } |
| 1047 } | 1045 } |
| 1048 | 1046 |
| 1049 void HTMLDocumentParser::setDecoder(std::unique_ptr<TextResourceDecoder> decoder
) | 1047 void HTMLDocumentParser::setDecoder(PassOwnPtr<TextResourceDecoder> decoder) |
| 1050 { | 1048 { |
| 1051 ASSERT(decoder); | 1049 ASSERT(decoder); |
| 1052 DecodedDataDocumentParser::setDecoder(std::move(decoder)); | 1050 DecodedDataDocumentParser::setDecoder(std::move(decoder)); |
| 1053 | 1051 |
| 1054 if (m_haveBackgroundParser) | 1052 if (m_haveBackgroundParser) |
| 1055 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParse
r::setDecoder, m_backgroundParser, passed(takeDecoder()))); | 1053 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParse
r::setDecoder, m_backgroundParser, passed(takeDecoder()))); |
| 1056 } | 1054 } |
| 1057 | 1055 |
| 1058 void HTMLDocumentParser::documentElementAvailable() | 1056 void HTMLDocumentParser::documentElementAvailable() |
| 1059 { | 1057 { |
| 1060 TRACE_EVENT0("blink,loader", "HTMLDocumentParser::documentElementAvailable")
; | 1058 TRACE_EVENT0("blink,loader", "HTMLDocumentParser::documentElementAvailable")
; |
| 1061 DCHECK(document()->documentElement()); | 1059 DCHECK(document()->documentElement()); |
| 1062 for (const String& scriptSource : m_queuedDocumentWriteScripts) { | 1060 for (const String& scriptSource : m_queuedDocumentWriteScripts) { |
| 1063 evaluateAndPreloadScriptForDocumentWrite(scriptSource); | 1061 evaluateAndPreloadScriptForDocumentWrite(scriptSource); |
| 1064 } | 1062 } |
| 1065 | 1063 |
| 1066 m_queuedDocumentWriteScripts.clear(); | 1064 m_queuedDocumentWriteScripts.clear(); |
| 1067 if (!m_queuedPreloads.isEmpty()) | 1065 if (!m_queuedPreloads.isEmpty()) |
| 1068 m_preloader->takeAndPreload(m_queuedPreloads); | 1066 m_preloader->takeAndPreload(m_queuedPreloads); |
| 1069 } | 1067 } |
| 1070 | 1068 |
| 1071 std::unique_ptr<HTMLPreloadScanner> HTMLDocumentParser::createPreloadScanner() | 1069 PassOwnPtr<HTMLPreloadScanner> HTMLDocumentParser::createPreloadScanner() |
| 1072 { | 1070 { |
| 1073 return HTMLPreloadScanner::create( | 1071 return HTMLPreloadScanner::create( |
| 1074 m_options, | 1072 m_options, |
| 1075 document()->url(), | 1073 document()->url(), |
| 1076 CachedDocumentParameters::create(document()), | 1074 CachedDocumentParameters::create(document()), |
| 1077 MediaValuesCached::MediaValuesCachedData(*document())); | 1075 MediaValuesCached::MediaValuesCachedData(*document())); |
| 1078 } | 1076 } |
| 1079 | 1077 |
| 1080 void HTMLDocumentParser::evaluateAndPreloadScriptForDocumentWrite(const String&
source) | 1078 void HTMLDocumentParser::evaluateAndPreloadScriptForDocumentWrite(const String&
source) |
| 1081 { | 1079 { |
| 1082 if (!m_evaluator->shouldEvaluate(source)) | 1080 if (!m_evaluator->shouldEvaluate(source)) |
| 1083 return; | 1081 return; |
| 1084 document()->loader()->didObserveLoadingBehavior(WebLoadingBehaviorFlag::WebL
oadingBehaviorDocumentWriteEvaluator); | 1082 document()->loader()->didObserveLoadingBehavior(WebLoadingBehaviorFlag::WebL
oadingBehaviorDocumentWriteEvaluator); |
| 1085 if (!RuntimeEnabledFeatures::documentWriteEvaluatorEnabled()) | 1083 if (!RuntimeEnabledFeatures::documentWriteEvaluatorEnabled()) |
| 1086 return; | 1084 return; |
| 1087 TRACE_EVENT0("blink", "HTMLDocumentParser::evaluateAndPreloadScriptForDocume
ntWrite"); | 1085 TRACE_EVENT0("blink", "HTMLDocumentParser::evaluateAndPreloadScriptForDocume
ntWrite"); |
| 1088 | 1086 |
| 1089 double initializeStartTime = monotonicallyIncreasingTimeMS(); | 1087 double initializeStartTime = monotonicallyIncreasingTimeMS(); |
| 1090 bool neededInitialization = m_evaluator->ensureEvaluationContext(); | 1088 bool neededInitialization = m_evaluator->ensureEvaluationContext(); |
| 1091 double initializationDuration = monotonicallyIncreasingTimeMS() - initialize
StartTime; | 1089 double initializationDuration = monotonicallyIncreasingTimeMS() - initialize
StartTime; |
| 1092 | 1090 |
| 1093 double startTime = monotonicallyIncreasingTimeMS(); | 1091 double startTime = monotonicallyIncreasingTimeMS(); |
| 1094 String writtenSource = m_evaluator->evaluateAndEmitWrittenSource(source); | 1092 String writtenSource = m_evaluator->evaluateAndEmitWrittenSource(source); |
| 1095 double duration = monotonicallyIncreasingTimeMS() - startTime; | 1093 double duration = monotonicallyIncreasingTimeMS() - startTime; |
| 1096 | 1094 |
| 1097 int currentPreloadCount = document()->loader()->fetcher()->countPreloads(); | 1095 int currentPreloadCount = document()->loader()->fetcher()->countPreloads(); |
| 1098 std::unique_ptr<HTMLPreloadScanner> scanner = createPreloadScanner(); | 1096 OwnPtr<HTMLPreloadScanner> scanner = createPreloadScanner(); |
| 1099 scanner->appendToEnd(SegmentedString(writtenSource)); | 1097 scanner->appendToEnd(SegmentedString(writtenSource)); |
| 1100 scanner->scanAndPreload(m_preloader.get(), document()->baseElementURL(), nul
lptr); | 1098 scanner->scanAndPreload(m_preloader.get(), document()->baseElementURL(), nul
lptr); |
| 1101 int numPreloads = document()->loader()->fetcher()->countPreloads() - current
PreloadCount; | 1099 int numPreloads = document()->loader()->fetcher()->countPreloads() - current
PreloadCount; |
| 1102 | 1100 |
| 1103 TRACE_EVENT_INSTANT2("blink", "HTMLDocumentParser::evaluateAndPreloadScriptF
orDocumentWrite.data", TRACE_EVENT_SCOPE_THREAD, "numPreloads", numPreloads, "sc
riptLength", source.length()); | 1101 TRACE_EVENT_INSTANT2("blink", "HTMLDocumentParser::evaluateAndPreloadScriptF
orDocumentWrite.data", TRACE_EVENT_SCOPE_THREAD, "numPreloads", numPreloads, "sc
riptLength", source.length()); |
| 1104 | 1102 |
| 1105 if (neededInitialization) { | 1103 if (neededInitialization) { |
| 1106 DEFINE_STATIC_LOCAL(CustomCountHistogram, initializeHistograms, ("Preloa
dScanner.DocumentWrite.InitializationTime", 1, 10000, 50)); | 1104 DEFINE_STATIC_LOCAL(CustomCountHistogram, initializeHistograms, ("Preloa
dScanner.DocumentWrite.InitializationTime", 1, 10000, 50)); |
| 1107 initializeHistograms.count(initializationDuration); | 1105 initializeHistograms.count(initializationDuration); |
| 1108 } | 1106 } |
| 1109 | 1107 |
| 1110 if (numPreloads) { | 1108 if (numPreloads) { |
| 1111 DEFINE_STATIC_LOCAL(CustomCountHistogram, successHistogram, ("PreloadSca
nner.DocumentWrite.ExecutionTime.Success", 1, 10000, 50)); | 1109 DEFINE_STATIC_LOCAL(CustomCountHistogram, successHistogram, ("PreloadSca
nner.DocumentWrite.ExecutionTime.Success", 1, 10000, 50)); |
| 1112 successHistogram.count(duration); | 1110 successHistogram.count(duration); |
| 1113 } else { | 1111 } else { |
| 1114 DEFINE_STATIC_LOCAL(CustomCountHistogram, failureHistogram, ("PreloadSca
nner.DocumentWrite.ExecutionTime.Failure", 1, 10000, 50)); | 1112 DEFINE_STATIC_LOCAL(CustomCountHistogram, failureHistogram, ("PreloadSca
nner.DocumentWrite.ExecutionTime.Failure", 1, 10000, 50)); |
| 1115 failureHistogram.count(duration); | 1113 failureHistogram.count(duration); |
| 1116 } | 1114 } |
| 1117 | 1115 |
| 1118 } | 1116 } |
| 1119 | 1117 |
| 1120 } // namespace blink | 1118 } // namespace blink |
| OLD | NEW |