From 0127190dcf7fd0ee27a935cf1f3f5c74b77c0fc9 Mon Sep 17 00:00:00 2001 From: Tim Ledbetter Date: Tue, 23 Jul 2024 13:10:50 +0100 Subject: [PATCH] LibWeb: Perform DOMTokenList token validation in the correct order --- .../Text/expected/DOM/Element-classList.txt | 1 + .../Text/input/DOM/Element-classList.html | 6 ++++++ .../Libraries/LibWeb/DOM/DOMTokenList.cpp | 19 +++++++++++++++++-- Userland/Libraries/LibWeb/DOM/DOMTokenList.h | 2 ++ 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/Tests/LibWeb/Text/expected/DOM/Element-classList.txt b/Tests/LibWeb/Text/expected/DOM/Element-classList.txt index c9b7f958521..de17e2a005a 100644 --- a/Tests/LibWeb/Text/expected/DOM/Element-classList.txt +++ b/Tests/LibWeb/Text/expected/DOM/Element-classList.txt @@ -3,3 +3,4 @@ element.classList after setting classList to "a": "a" element.classList after setting className to "": "" element.classList after setting to className to "a a b c": "a a b c" element.classList after setting to className to " a a b c ": " a a b c " +element.classList.replace(" ", "") throws "SyntaxError" diff --git a/Tests/LibWeb/Text/input/DOM/Element-classList.html b/Tests/LibWeb/Text/input/DOM/Element-classList.html index 72d7f53c265..3f2243d56b9 100644 --- a/Tests/LibWeb/Text/input/DOM/Element-classList.html +++ b/Tests/LibWeb/Text/input/DOM/Element-classList.html @@ -12,6 +12,12 @@ println(`element.classList after setting to className to "a a b c": "${element.classList.toString()}"`); element.className = " a a b c "; println(`element.classList after setting to className to " a a b c ": "${element.classList.toString()}"`); + + try { + element.classList.replace(" ", ""); + } catch (e) { + println(`element.classList.replace(" ", "") throws "${e.name}"`); + } }); diff --git a/Userland/Libraries/LibWeb/DOM/DOMTokenList.cpp b/Userland/Libraries/LibWeb/DOM/DOMTokenList.cpp index dbbd7b57c2e..fa837c9bb71 100644 --- a/Userland/Libraries/LibWeb/DOM/DOMTokenList.cpp +++ b/Userland/Libraries/LibWeb/DOM/DOMTokenList.cpp @@ -192,9 +192,12 @@ WebIDL::ExceptionOr DOMTokenList::toggle(String const& token, Optional DOMTokenList::replace(String const& token, String const& new_token) { // 1. If either token or newToken is the empty string, then throw a "SyntaxError" DOMException. + TRY(validate_token_not_empty(token)); + TRY(validate_token_not_empty(new_token)); + // 2. If either token or newToken contains any ASCII whitespace, then throw an "InvalidCharacterError" DOMException. - TRY(validate_token(token)); - TRY(validate_token(new_token)); + TRY(validate_token_not_whitespace(token)); + TRY(validate_token_not_whitespace(new_token)); // 3. If this’s token set does not contain token, then return false. if (!contains(token)) @@ -264,9 +267,21 @@ void DOMTokenList::set_value(String const& value) } WebIDL::ExceptionOr DOMTokenList::validate_token(StringView token) const +{ + TRY(validate_token_not_empty(token)); + TRY(validate_token_not_whitespace(token)); + return {}; +} + +WebIDL::ExceptionOr DOMTokenList::validate_token_not_empty(StringView token) const { if (token.is_empty()) return WebIDL::SyntaxError::create(realm(), "Non-empty DOM tokens are not allowed"_fly_string); + return {}; +} + +WebIDL::ExceptionOr DOMTokenList::validate_token_not_whitespace(StringView token) const +{ if (any_of(token, Infra::is_ascii_whitespace)) return WebIDL::InvalidCharacterError::create(realm(), "DOM tokens containing ASCII whitespace are not allowed"_fly_string); return {}; diff --git a/Userland/Libraries/LibWeb/DOM/DOMTokenList.h b/Userland/Libraries/LibWeb/DOM/DOMTokenList.h index a496aaa9e2e..441e6e3b56a 100644 --- a/Userland/Libraries/LibWeb/DOM/DOMTokenList.h +++ b/Userland/Libraries/LibWeb/DOM/DOMTokenList.h @@ -51,6 +51,8 @@ private: virtual void visit_edges(Cell::Visitor&) override; WebIDL::ExceptionOr validate_token(StringView token) const; + WebIDL::ExceptionOr validate_token_not_empty(StringView token) const; + WebIDL::ExceptionOr validate_token_not_whitespace(StringView token) const; void run_update_steps(); String serialize_ordered_set() const;