From 83c69fa62e8e5df219975a2ab70d56ee4eb38972 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sat, 17 Sep 2022 17:44:11 +0200 Subject: [PATCH] LibWeb: Handle JavaScript source code with non-UTF-8 encoding When fetching scripts in HTMLScriptElement's "prepare a script" algorithm, we now re-encode the script sources to UTF-8. --- .../LibWeb/HTML/HTMLScriptElement.cpp | 50 +++++++++++-------- .../Libraries/LibWeb/HTML/HTMLScriptElement.h | 9 +++- 2 files changed, 37 insertions(+), 22 deletions(-) diff --git a/Userland/Libraries/LibWeb/HTML/HTMLScriptElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLScriptElement.cpp index 6635370d69..3e5f5e8237 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLScriptElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLScriptElement.cpp @@ -295,26 +295,8 @@ void HTMLScriptElement::prepare_script() if (parser_document) begin_delaying_document_load_event(*parser_document); - ResourceLoader::the().load( - request, - [this, url](auto data, auto&, auto) { - if (data.is_null()) { - dbgln("HTMLScriptElement: Failed to load {}", url); - return; - } - - // FIXME: This is all ad-hoc and needs work. - auto script = ClassicScript::create(url.to_string(), data, document().relevant_settings_object(), AK::URL()); - - // When the chosen algorithm asynchronously completes, set the script's script to the result. At that time, the script is ready. - m_script = script; - script_became_ready(); - }, - [this](auto&, auto) { - m_failed_to_load = true; - dbgln("HONK! Failed to load script, but ready nonetheless."); - script_became_ready(); - }); + auto resource = ResourceLoader::the().load_resource(Resource::Type::Generic, request); + set_resource(resource); } else if (m_script_type == ScriptType::Module) { // FIXME: -> "module" // Fetch an external module script graph given url, settings object, and options. @@ -439,6 +421,34 @@ void HTMLScriptElement::prepare_script() } } +void HTMLScriptElement::resource_did_load() +{ + // FIXME: This is all ad-hoc and needs work. + + auto data = resource()->encoded_data(); + + // If the resource has an explicit encoding (i.e from a HTTP Content-Type header) + // we have to re-encode it to UTF-8. + if (resource()->has_encoding()) { + if (auto* codec = TextCodec::decoder_for(resource()->encoding().value())) { + data = codec->to_utf8(data).to_byte_buffer(); + } + } + + auto script = ClassicScript::create(resource()->url().to_string(), data, document().relevant_settings_object(), AK::URL()); + + // When the chosen algorithm asynchronously completes, set the script's script to the result. At that time, the script is ready. + m_script = script; + script_became_ready(); +} + +void HTMLScriptElement::resource_did_fail() +{ + m_failed_to_load = true; + dbgln("HONK! Failed to load script, but ready nonetheless."); + script_became_ready(); +} + void HTMLScriptElement::script_became_ready() { m_script_ready = true; diff --git a/Userland/Libraries/LibWeb/HTML/HTMLScriptElement.h b/Userland/Libraries/LibWeb/HTML/HTMLScriptElement.h index 0e5acf30a4..e52f339116 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLScriptElement.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLScriptElement.h @@ -13,7 +13,9 @@ namespace Web::HTML { -class HTMLScriptElement final : public HTMLElement { +class HTMLScriptElement final + : public HTMLElement + , public ResourceClient { WEB_PLATFORM_OBJECT(HTMLScriptElement, HTMLElement); public: @@ -49,9 +51,12 @@ public: void set_source_line_number(Badge, size_t source_line_number) { m_source_line_number = source_line_number; } -private: +public: HTMLScriptElement(DOM::Document&, DOM::QualifiedName); + virtual void resource_did_load() override; + virtual void resource_did_fail() override; + virtual void visit_edges(Cell::Visitor&) override; void prepare_script();