Commit 93c09799 authored by Hiroshige Hayashizaki's avatar Hiroshige Hayashizaki Committed by Commit Bot

Do not create Script if an error occurred

As a preparation for
https://chromium-review.googlesource.com/1179488,
this CL stops creating ClassicScript when ErrorOccurred() is true.

Instead of setting |error_occurred| bool, this CL makes
PendingScript::GetSource() return nullptr if an error occurred.
This is consistent with the spec:

- GetSource() corresponds to "the script's script".
- GetSource() == nullptr (previously |error_occurred| == true)
  corresponds to "the script's script is null".

Bug: 875153, 686281
Change-Id: I08d891ce2207894b4a8f8a2d1171f9912c79b8ce
Reviewed-on: https://chromium-review.googlesource.com/1179557Reviewed-by: default avatarYutaka Hirano <yhirano@chromium.org>
Reviewed-by: default avatarKouhei Ueno <kouhei@chromium.org>
Commit-Queue: Hiroshige Hayashizaki <hiroshige@chromium.org>
Cr-Commit-Position: refs/heads/master@{#584371}
parent bf843690
...@@ -75,6 +75,12 @@ class ScriptStreamingTest : public testing::Test { ...@@ -75,6 +75,12 @@ class ScriptStreamingTest : public testing::Test {
return pending_script_.Get(); return pending_script_.Get();
} }
ScriptSourceCode GetScriptSourceCode() const {
ClassicScript* classic_script = GetPendingScript()->GetSource(NullURL());
DCHECK(classic_script);
return classic_script->GetScriptSourceCode();
}
Settings* GetSettings() const { Settings* GetSettings() const {
return &dummy_page_holder_->GetPage().GetSettings(); return &dummy_page_holder_->GetPage().GetSettings();
} }
...@@ -165,11 +171,7 @@ TEST_F(ScriptStreamingTest, CompilingStreamedScript) { ...@@ -165,11 +171,7 @@ TEST_F(ScriptStreamingTest, CompilingStreamedScript) {
// has completed its tasks. // has completed its tasks.
ProcessTasksUntilStreamingComplete(); ProcessTasksUntilStreamingComplete();
EXPECT_TRUE(client->Finished()); EXPECT_TRUE(client->Finished());
bool error_occurred = false; ScriptSourceCode source_code = GetScriptSourceCode();
ScriptSourceCode source_code = GetPendingScript()
->GetSource(NullURL(), error_occurred)
->GetScriptSourceCode();
EXPECT_FALSE(error_occurred);
EXPECT_TRUE(source_code.Streamer()); EXPECT_TRUE(source_code.Streamer());
v8::TryCatch try_catch(scope.GetIsolate()); v8::TryCatch try_catch(scope.GetIsolate());
v8::Local<v8::Script> script; v8::Local<v8::Script> script;
...@@ -212,11 +214,7 @@ TEST_F(ScriptStreamingTest, CompilingStreamedScriptWithParseError) { ...@@ -212,11 +214,7 @@ TEST_F(ScriptStreamingTest, CompilingStreamedScriptWithParseError) {
Finish(); Finish();
EXPECT_TRUE(client->Finished()); EXPECT_TRUE(client->Finished());
bool error_occurred = false; ScriptSourceCode source_code = GetScriptSourceCode();
ScriptSourceCode source_code = GetPendingScript()
->GetSource(NullURL(), error_occurred)
->GetScriptSourceCode();
EXPECT_FALSE(error_occurred);
EXPECT_TRUE(source_code.Streamer()); EXPECT_TRUE(source_code.Streamer());
v8::TryCatch try_catch(scope.GetIsolate()); v8::TryCatch try_catch(scope.GetIsolate());
v8::Local<v8::Script> script; v8::Local<v8::Script> script;
...@@ -288,11 +286,7 @@ TEST_F(ScriptStreamingTest, SuppressingStreaming) { ...@@ -288,11 +286,7 @@ TEST_F(ScriptStreamingTest, SuppressingStreaming) {
ProcessTasksUntilStreamingComplete(); ProcessTasksUntilStreamingComplete();
EXPECT_TRUE(client->Finished()); EXPECT_TRUE(client->Finished());
bool error_occurred = false; ScriptSourceCode source_code = GetScriptSourceCode();
ScriptSourceCode source_code = GetPendingScript()
->GetSource(NullURL(), error_occurred)
->GetScriptSourceCode();
EXPECT_FALSE(error_occurred);
// ScriptSourceCode doesn't refer to the streamer, since we have suppressed // ScriptSourceCode doesn't refer to the streamer, since we have suppressed
// the streaming and resumed the non-streaming code path for script // the streaming and resumed the non-streaming code path for script
// compilation. // compilation.
...@@ -318,11 +312,7 @@ TEST_F(ScriptStreamingTest, EmptyScripts) { ...@@ -318,11 +312,7 @@ TEST_F(ScriptStreamingTest, EmptyScripts) {
// through a background thread. // through a background thread.
EXPECT_TRUE(client->Finished()); EXPECT_TRUE(client->Finished());
bool error_occurred = false; ScriptSourceCode source_code = GetScriptSourceCode();
ScriptSourceCode source_code = GetPendingScript()
->GetSource(NullURL(), error_occurred)
->GetScriptSourceCode();
EXPECT_FALSE(error_occurred);
EXPECT_FALSE(source_code.Streamer()); EXPECT_FALSE(source_code.Streamer());
} }
...@@ -347,11 +337,7 @@ TEST_F(ScriptStreamingTest, SmallScripts) { ...@@ -347,11 +337,7 @@ TEST_F(ScriptStreamingTest, SmallScripts) {
// through a background thread. // through a background thread.
EXPECT_TRUE(client->Finished()); EXPECT_TRUE(client->Finished());
bool error_occurred = false; ScriptSourceCode source_code = GetScriptSourceCode();
ScriptSourceCode source_code = GetPendingScript()
->GetSource(NullURL(), error_occurred)
->GetScriptSourceCode();
EXPECT_FALSE(error_occurred);
EXPECT_FALSE(source_code.Streamer()); EXPECT_FALSE(source_code.Streamer());
} }
...@@ -379,11 +365,7 @@ TEST_F(ScriptStreamingTest, ScriptsWithSmallFirstChunk) { ...@@ -379,11 +365,7 @@ TEST_F(ScriptStreamingTest, ScriptsWithSmallFirstChunk) {
ProcessTasksUntilStreamingComplete(); ProcessTasksUntilStreamingComplete();
EXPECT_TRUE(client->Finished()); EXPECT_TRUE(client->Finished());
bool error_occurred = false; ScriptSourceCode source_code = GetScriptSourceCode();
ScriptSourceCode source_code = GetPendingScript()
->GetSource(NullURL(), error_occurred)
->GetScriptSourceCode();
EXPECT_FALSE(error_occurred);
EXPECT_TRUE(source_code.Streamer()); EXPECT_TRUE(source_code.Streamer());
v8::TryCatch try_catch(scope.GetIsolate()); v8::TryCatch try_catch(scope.GetIsolate());
v8::Local<v8::Script> script; v8::Local<v8::Script> script;
...@@ -423,11 +405,7 @@ TEST_F(ScriptStreamingTest, EncodingChanges) { ...@@ -423,11 +405,7 @@ TEST_F(ScriptStreamingTest, EncodingChanges) {
ProcessTasksUntilStreamingComplete(); ProcessTasksUntilStreamingComplete();
EXPECT_TRUE(client->Finished()); EXPECT_TRUE(client->Finished());
bool error_occurred = false; ScriptSourceCode source_code = GetScriptSourceCode();
ScriptSourceCode source_code = GetPendingScript()
->GetSource(NullURL(), error_occurred)
->GetScriptSourceCode();
EXPECT_FALSE(error_occurred);
EXPECT_TRUE(source_code.Streamer()); EXPECT_TRUE(source_code.Streamer());
v8::TryCatch try_catch(scope.GetIsolate()); v8::TryCatch try_catch(scope.GetIsolate());
v8::Local<v8::Script> script; v8::Local<v8::Script> script;
...@@ -468,11 +446,7 @@ TEST_F(ScriptStreamingTest, EncodingFromBOM) { ...@@ -468,11 +446,7 @@ TEST_F(ScriptStreamingTest, EncodingFromBOM) {
Finish(); Finish();
ProcessTasksUntilStreamingComplete(); ProcessTasksUntilStreamingComplete();
EXPECT_TRUE(client->Finished()); EXPECT_TRUE(client->Finished());
bool error_occurred = false; ScriptSourceCode source_code = GetScriptSourceCode();
ScriptSourceCode source_code = GetPendingScript()
->GetSource(NullURL(), error_occurred)
->GetScriptSourceCode();
EXPECT_FALSE(error_occurred);
EXPECT_TRUE(source_code.Streamer()); EXPECT_TRUE(source_code.Streamer());
v8::TryCatch try_catch(scope.GetIsolate()); v8::TryCatch try_catch(scope.GetIsolate());
v8::Local<v8::Script> script; v8::Local<v8::Script> script;
......
...@@ -331,12 +331,13 @@ static SingleCachedMetadataHandler* GetInlineCacheHandler(const String& source, ...@@ -331,12 +331,13 @@ static SingleCachedMetadataHandler* GetInlineCacheHandler(const String& source,
return document_cache_handler->HandlerForSource(source); return document_cache_handler->HandlerForSource(source);
} }
ClassicScript* ClassicPendingScript::GetSource(const KURL& document_url, ClassicScript* ClassicPendingScript::GetSource(const KURL& document_url) const {
bool& error_occurred) const {
CheckState(); CheckState();
DCHECK(IsReady()); DCHECK(IsReady());
error_occurred = ErrorOccurred(); if (ErrorOccurred())
return nullptr;
if (!is_external_) { if (!is_external_) {
SingleCachedMetadataHandler* cache_handler = nullptr; SingleCachedMetadataHandler* cache_handler = nullptr;
// We only create an inline cache handler for html-embedded scripts, not // We only create an inline cache handler for html-embedded scripts, not
...@@ -370,7 +371,7 @@ ClassicScript* ClassicPendingScript::GetSource(const KURL& document_url, ...@@ -370,7 +371,7 @@ ClassicScript* ClassicPendingScript::GetSource(const KURL& document_url,
if (!AllowedByNosniff::MimeTypeAsScript( if (!AllowedByNosniff::MimeTypeAsScript(
GetElement()->GetDocument().ContextDocument(), GetElement()->GetDocument().ContextDocument(),
resource->GetResponse())) { resource->GetResponse())) {
error_occurred = true; return nullptr;
} }
// Check if we can use the script streamer. // Check if we can use the script streamer.
......
...@@ -59,8 +59,7 @@ class CORE_EXPORT ClassicPendingScript final : public PendingScript, ...@@ -59,8 +59,7 @@ class CORE_EXPORT ClassicPendingScript final : public PendingScript,
return blink::ScriptType::kClassic; return blink::ScriptType::kClassic;
} }
ClassicScript* GetSource(const KURL& document_url, ClassicScript* GetSource(const KURL& document_url) const override;
bool& error_occurred) const override;
bool IsReady() const override; bool IsReady() const override;
bool IsExternal() const override { return is_external_; } bool IsExternal() const override { return is_external_; }
bool ErrorOccurred() const override; bool ErrorOccurred() const override;
......
...@@ -65,10 +65,12 @@ void ModulePendingScript::NotifyModuleTreeLoadFinished() { ...@@ -65,10 +65,12 @@ void ModulePendingScript::NotifyModuleTreeLoadFinished() {
PendingScriptFinished(); PendingScriptFinished();
} }
Script* ModulePendingScript::GetSource(const KURL& document_url, Script* ModulePendingScript::GetSource(const KURL& document_url) const {
bool& error_occurred) const {
CHECK(IsReady()); CHECK(IsReady());
error_occurred = ErrorOccurred(); if (ErrorOccurred())
return nullptr;
DCHECK(GetModuleScript());
return GetModuleScript(); return GetModuleScript();
} }
......
...@@ -72,8 +72,7 @@ class CORE_EXPORT ModulePendingScript : public PendingScript { ...@@ -72,8 +72,7 @@ class CORE_EXPORT ModulePendingScript : public PendingScript {
// PendingScript // PendingScript
ScriptType GetScriptType() const override { return ScriptType::kModule; } ScriptType GetScriptType() const override { return ScriptType::kModule; }
Script* GetSource(const KURL& document_url, Script* GetSource(const KURL& document_url) const override;
bool& error_occurred) const override;
bool IsReady() const override { return ready_; } bool IsReady() const override { return ready_; }
bool IsExternal() const override { return is_external_; } bool IsExternal() const override { return is_external_; }
bool ErrorOccurred() const override; bool ErrorOccurred() const override;
......
...@@ -146,10 +146,9 @@ void PendingScript::ExecuteScriptBlock(const KURL& document_url) { ...@@ -146,10 +146,9 @@ void PendingScript::ExecuteScriptBlock(const KURL& document_url) {
return; return;
} }
bool error_occurred = false; Script* script = GetSource(document_url);
Script* script = GetSource(document_url, error_occurred);
if (!error_occurred && !IsExternal()) { if (script && !IsExternal()) {
bool should_bypass_main_world_csp = bool should_bypass_main_world_csp =
frame->GetScriptController().ShouldBypassMainWorldCSP(); frame->GetScriptController().ShouldBypassMainWorldCSP();
...@@ -160,7 +159,7 @@ void PendingScript::ExecuteScriptBlock(const KURL& document_url) { ...@@ -160,7 +159,7 @@ void PendingScript::ExecuteScriptBlock(const KURL& document_url) {
ContentSecurityPolicy::InlineType::kBlock)) { ContentSecurityPolicy::InlineType::kBlock)) {
// Consider as if "the script's script is null" retrospectively, // Consider as if "the script's script is null" retrospectively,
// if the CSP check fails, which is considered as load failure. // if the CSP check fails, which is considered as load failure.
error_occurred = true; script = nullptr;
} }
} }
...@@ -175,15 +174,13 @@ void PendingScript::ExecuteScriptBlock(const KURL& document_url) { ...@@ -175,15 +174,13 @@ void PendingScript::ExecuteScriptBlock(const KURL& document_url) {
// ExecuteScriptBlockInternal() is split just in order to prevent accidential // ExecuteScriptBlockInternal() is split just in order to prevent accidential
// access to |this| after Dispose(). // access to |this| after Dispose().
ExecuteScriptBlockInternal(script, error_occurred, element, was_canceled, ExecuteScriptBlockInternal(
is_external, created_during_document_write, script, element, was_canceled, is_external, created_during_document_write,
parser_blocking_load_start_time, parser_blocking_load_start_time, is_controlled_by_script_runner);
is_controlled_by_script_runner);
} }
void PendingScript::ExecuteScriptBlockInternal( void PendingScript::ExecuteScriptBlockInternal(
Script* script, Script* script,
bool error_occurred,
ScriptElementBase* element, ScriptElementBase* element,
bool was_canceled, bool was_canceled,
bool is_external, bool is_external,
...@@ -195,7 +192,7 @@ void PendingScript::ExecuteScriptBlockInternal( ...@@ -195,7 +192,7 @@ void PendingScript::ExecuteScriptBlockInternal(
// <spec step="2">If the script's script is null, fire an event named error at // <spec step="2">If the script's script is null, fire an event named error at
// the element, and return.</spec> // the element, and return.</spec>
if (error_occurred) { if (!script) {
element->DispatchErrorEvent(); element->DispatchErrorEvent();
return; return;
} }
......
...@@ -87,8 +87,8 @@ class CORE_EXPORT PendingScript ...@@ -87,8 +87,8 @@ class CORE_EXPORT PendingScript
virtual void Trace(blink::Visitor*); virtual void Trace(blink::Visitor*);
const char* NameInHeapSnapshot() const override { return "PendingScript"; } const char* NameInHeapSnapshot() const override { return "PendingScript"; }
virtual Script* GetSource(const KURL& document_url, // Returns nullptr when "script's script is null", i.e. an error occurred.
bool& error_occurred) const = 0; virtual Script* GetSource(const KURL& document_url) const = 0;
// https://html.spec.whatwg.org/multipage/scripting.html#the-script-is-ready // https://html.spec.whatwg.org/multipage/scripting.html#the-script-is-ready
virtual bool IsReady() const = 0; virtual bool IsReady() const = 0;
...@@ -150,7 +150,6 @@ class CORE_EXPORT PendingScript ...@@ -150,7 +150,6 @@ class CORE_EXPORT PendingScript
private: private:
static void ExecuteScriptBlockInternal( static void ExecuteScriptBlockInternal(
Script*, Script*,
bool error_occurred,
ScriptElementBase*, ScriptElementBase*,
bool was_canceled, bool was_canceled,
bool is_external, bool is_external,
......
...@@ -37,7 +37,7 @@ class MockPendingScript : public PendingScript { ...@@ -37,7 +37,7 @@ class MockPendingScript : public PendingScript {
MOCK_CONST_METHOD0(GetScriptType, ScriptType()); MOCK_CONST_METHOD0(GetScriptType, ScriptType());
MOCK_CONST_METHOD1(CheckMIMETypeBeforeRunScript, bool(Document*)); MOCK_CONST_METHOD1(CheckMIMETypeBeforeRunScript, bool(Document*));
MOCK_CONST_METHOD2(GetSource, Script*(const KURL&, bool&)); MOCK_CONST_METHOD1(GetSource, Script*(const KURL&));
MOCK_CONST_METHOD0(IsExternal, bool()); MOCK_CONST_METHOD0(IsExternal, bool());
MOCK_CONST_METHOD0(ErrorOccurred, bool()); MOCK_CONST_METHOD0(ErrorOccurred, bool());
MOCK_CONST_METHOD0(WasCanceled, bool()); MOCK_CONST_METHOD0(WasCanceled, bool());
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment