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