diff --git a/Libraries/LibWeb/DOM/Element.cpp b/Libraries/LibWeb/DOM/Element.cpp index 88b64cbd8ee..df493dff885 100644 --- a/Libraries/LibWeb/DOM/Element.cpp +++ b/Libraries/LibWeb/DOM/Element.cpp @@ -4067,4 +4067,9 @@ bool Element::should_indicate_focus() const return false; } +void Element::set_had_duplicate_attribute_during_tokenization(Badge) +{ + m_had_duplicate_attribute_during_tokenization = true; +} + } diff --git a/Libraries/LibWeb/DOM/Element.h b/Libraries/LibWeb/DOM/Element.h index a12400ae8d7..e7315e481f6 100644 --- a/Libraries/LibWeb/DOM/Element.h +++ b/Libraries/LibWeb/DOM/Element.h @@ -516,6 +516,9 @@ public: virtual bool contributes_a_script_blocking_style_sheet() const { return false; } + void set_had_duplicate_attribute_during_tokenization(Badge); + bool had_duplicate_attribute_during_tokenization() const { return m_had_duplicate_attribute_during_tokenization; } + protected: Element(Document&, DOM::QualifiedName); virtual void initialize(JS::Realm&) override; @@ -614,6 +617,13 @@ private: size_t m_sibling_invalidation_distance { 0 }; + // https://w3c.github.io/webappsec-csp/#is-element-nonceable + // AD-HOC: We need to know the element had a duplicate attribute when it was created from the HTML parser. + // However, there currently isn't any specified way to do this, so we store a flag on the token, which is + // then passed down to here. This is used by Content Security Policy to disable the nonce attribute if this + // flag is set. + bool m_had_duplicate_attribute_during_tokenization { false }; + OwnPtr m_counters_set; // https://drafts.csswg.org/css-contain/#proximity-to-the-viewport diff --git a/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp b/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp index 858c58ea02f..a0ebf8719e5 100644 --- a/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp +++ b/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp @@ -816,6 +816,11 @@ GC::Ref HTMLParser::create_element_for(HTMLToken const& token, Opt // 9. Let element be the result of creating an element given document, localName, given namespace, null, is, and willExecuteScript. auto element = create_element(*document, local_name, namespace_, {}, is_value, will_execute_script).release_value_but_fixme_should_propagate_errors(); + // AD-HOC: See AD-HOC comment on Element.m_had_duplicate_attribute_during_tokenization about why this is done. + if (token.had_duplicate_attribute()) { + element->set_had_duplicate_attribute_during_tokenization({}); + } + // AD-HOC: Let elements know which document they were originally parsed for. // This is used for the render-blocking logic. if (local_name == HTML::TagNames::link && namespace_ == Namespace::HTML) { diff --git a/Libraries/LibWeb/HTML/Parser/HTMLToken.cpp b/Libraries/LibWeb/HTML/Parser/HTMLToken.cpp index 75e9d231c36..e796e3f6dde 100644 --- a/Libraries/LibWeb/HTML/Parser/HTMLToken.cpp +++ b/Libraries/LibWeb/HTML/Parser/HTMLToken.cpp @@ -98,6 +98,7 @@ void HTMLToken::normalize_attributes() // This is a duplicate attribute, remove it. tag_attributes.remove(i); --i; + m_had_duplicate_attribute = true; } } } diff --git a/Libraries/LibWeb/HTML/Parser/HTMLToken.h b/Libraries/LibWeb/HTML/Parser/HTMLToken.h index a881c08ae70..2ac4b7394fd 100644 --- a/Libraries/LibWeb/HTML/Parser/HTMLToken.h +++ b/Libraries/LibWeb/HTML/Parser/HTMLToken.h @@ -328,6 +328,7 @@ public: void set_end_position(Badge, Position end_position) { m_end_position = end_position; } void normalize_attributes(); + bool had_duplicate_attribute() const { return m_had_duplicate_attribute; } private: Vector const* tag_attributes() const @@ -355,6 +356,11 @@ private: bool m_tag_self_closing { false }; bool m_tag_self_closing_acknowledged { false }; + // AD-HOC: We need to know if the token had duplicate attributes, as Content Security Policy disables the nonce + // attribute on the element that will be created from such a token. + // https://w3c.github.io/webappsec-csp/#is-element-nonceable + bool m_had_duplicate_attribute { false }; + // Type::StartTag and Type::EndTag (tag name) FlyString m_string_data;