LibWeb: Update attribute name validation in Element.setAttribute()

This now follows the latest specification steps.
This commit is contained in:
Tim Ledbetter 2025-06-19 08:47:12 +01:00 committed by Tim Ledbetter
commit ba641d4784
Notes: github-actions[bot] 2025-06-19 10:02:13 +00:00
7 changed files with 67 additions and 7 deletions

View file

@ -211,8 +211,8 @@ GC::Ptr<Attr> Element::get_attribute_node_ns(Optional<FlyString> const& namespac
// https://dom.spec.whatwg.org/#dom-element-setattribute
WebIDL::ExceptionOr<void> Element::set_attribute(FlyString const& name, String const& value)
{
// 1. If qualifiedName does not match the Name production in XML, then throw an "InvalidCharacterError" DOMException.
if (!Document::is_valid_name(name.to_string()))
// 1. If qualifiedName is not a valid attribute local name, then throw an "InvalidCharacterError" DOMException.
if (!is_valid_attribute_local_name(name))
return WebIDL::InvalidCharacterError::create(realm(), "Attribute name must not be empty or contain invalid characters"_string);
// 2. If this is in the HTML namespace and its node document is an HTML document, then set qualifiedName to qualifiedName in ASCII lowercase.

View file

@ -2,3 +2,4 @@ OK: InvalidCharacterError: Attribute name must not be empty or contain invalid c
OK: InvalidCharacterError: Attribute name must not be empty or contain invalid characters
OK: InvalidCharacterError: Attribute name must not be empty or contain invalid characters
OK: InvalidCharacterError: Attribute name must not be empty or contain invalid characters
OK: InvalidCharacterError: Attribute name must not be empty or contain invalid characters

View file

@ -2,8 +2,7 @@ Harness status: OK
Found 67 tests
66 Pass
1 Fail
67 Pass
Pass When qualifiedName does not match the Name production, an INVALID_CHARACTER_ERR exception is to be thrown. (toggleAttribute)
Pass toggleAttribute should lowercase its name argument (upper case attribute)
Pass toggleAttribute should lowercase its name argument (mixed case attribute)
@ -17,7 +16,7 @@ Pass When qualifiedName does not match the Name production, an INVALID_CHARACTER
Pass setAttribute should lowercase its name argument (upper case attribute)
Pass setAttribute should lowercase its name argument (mixed case attribute)
Pass setAttribute should not throw even when qualifiedName starts with 'xmlns'
Fail Basic functionality should be intact.
Pass Basic functionality should be intact.
Pass setAttribute should not change the order of previously set attributes.
Pass setAttribute should set the first attribute with the given name
Pass setAttribute should set the attribute with the given qualified name

View file

@ -0,0 +1,16 @@
Harness status: OK
Found 11 tests
11 Pass
Pass Setting element.dataset['foo'] should also change the value of element.getAttribute('data-foo')
Pass Setting element.dataset['fooBar'] should also change the value of element.getAttribute('data-foo-bar')
Pass Setting element.dataset['-'] should also change the value of element.getAttribute('data--')
Pass Setting element.dataset['Foo'] should also change the value of element.getAttribute('data--foo')
Pass Setting element.dataset['-Foo'] should also change the value of element.getAttribute('data---foo')
Pass Setting element.dataset[''] should also change the value of element.getAttribute('data-')
Pass Setting element.dataset['à'] should also change the value of element.getAttribute('data-à')
Pass Setting element.dataset['-foo'] should throw a SYNTAX_ERR
Pass Setting element.dataset['foo '] should throw an INVALID_CHARACTER_ERR
Pass Setting element.dataset[';foo'] should not throw.
Pass Setting element.dataset['ெfoo'] should also change the value of element.getAttribute('ெfoo')

View file

@ -4,7 +4,7 @@
test(() => {
let threw = false;
try {
document.body.dataset["'\uDBF8"] = "foo";
document.body.dataset["=foo"] = "foo";
} catch {
threw = true;
}

View file

@ -13,7 +13,7 @@
}
invalidNames =
['', '1foo', 'f@oo', 'foo!']
['', '=foo', 'f/oo', 'fo o', 'foo>']
for (let i = 0; i < invalidNames.length; i++) {
testInvalidQualifiedName(invalidNames[i])

View file

@ -0,0 +1,44 @@
<!DOCTYPE html>
<html>
<head>
<title>Dataset - Set</title>
<script src="../../../../resources/testharness.js"></script>
<script src="../../../../resources/testharnessreport.js"></script>
</head>
<body>
<h1>Dataset - Set</h1>
<div id="log"></div>
<script>
function testSet(prop, expected)
{
var d = document.createElement("div");
d.dataset[prop] = "value";
return d.getAttribute(expected) == "value";
}
test(function() { assert_true(testSet('foo', 'data-foo')); },
"Setting element.dataset['foo'] should also change the value of element.getAttribute('data-foo')");
test(function() { assert_true(testSet('fooBar', 'data-foo-bar')); },
"Setting element.dataset['fooBar'] should also change the value of element.getAttribute('data-foo-bar')");
test(function() { assert_true(testSet('-', 'data--')); },
"Setting element.dataset['-'] should also change the value of element.getAttribute('data--')");
test(function() { assert_true(testSet('Foo', 'data--foo')); },
"Setting element.dataset['Foo'] should also change the value of element.getAttribute('data--foo')");
test(function() { assert_true(testSet('-Foo', 'data---foo')); },
"Setting element.dataset['-Foo'] should also change the value of element.getAttribute('data---foo')");
test(function() { assert_true(testSet('', 'data-')); },
"Setting element.dataset[''] should also change the value of element.getAttribute('data-')");
test(function() { assert_true(testSet('\xE0', 'data-\xE0')); },
"Setting element.dataset['\xE0'] should also change the value of element.getAttribute('data-\xE0')");
test(function() { assert_throws_dom('SYNTAX_ERR', function() { testSet('-foo', 'dummy') }); },
"Setting element.dataset['-foo'] should throw a SYNTAX_ERR");
test(function() { assert_throws_dom('INVALID_CHARACTER_ERR', function() { testSet('foo\x20', 'dummy') }); },
"Setting element.dataset['foo\x20'] should throw an INVALID_CHARACTER_ERR");
test(function() { assert_true(testSet('\u037Efoo', 'data-\u037Efoo')); },
"Setting element.dataset['\u037Efoo'] should not throw.");
test(function() { assert_true(testSet('\u0BC6foo', 'data-\u0BC6foo')); },
"Setting element.dataset['\u0BC6foo'] should also change the value of element.getAttribute('\u0BC6foo')");
</script>
</body>
</html>