Skip to content

Commit d472e33

Browse files
Allow more characters in element/attribute names and prefixes
https://bugs.webkit.org/show_bug.cgi?id=241419 Reviewed by NOBODY (OOPS!). Implement relaxed name-validation rules per whatwg/dom#1079, whatwg/html#7991, and whatwg/html#11453. This aligns DOM API name behavior with HTML parser behavior — which has always allowed a wider range of characters in element and attribute names. New validation functions in NameValidation.h/cpp: - isValidElementName(): For createElement — allows [A-Za-z] start followed by any char except null/whitespace/>//, or [:_>=0x80] start with restricted continuation - isValidAttributeName(): For setAttribute/toggleAttribute/createAttribute — no null, whitespace, /, >, or = - isValidNamespacePrefix(): For *NS methods — no null, whitespace, /, or > - isValidDoctypeName(): For createDocumentType — no null, whitespace, or > - isValidXMLName(): Preserves old XML Name production for createProcessingInstruction * Source/WebCore/Headers.cmake: * Source/WebCore/Sources.txt: * Source/WebCore/WebCore.xcodeproj/project.pbxproj: * Source/WebCore/dom/DOMImplementation.cpp: (WebCore::DOMImplementation::createDocumentType): * Source/WebCore/dom/Document.cpp: (WebCore::createHTMLElementWithNameValidation): (WebCore::Document::createElementForBindings): (WebCore::Document::createProcessingInstruction): (WebCore::Document::createElementNS): (WebCore::Document::createAttribute): (WebCore::Document::createAttributeNS): (WebCore::isValidNameStart): Deleted. (WebCore::isValidNamePart): Deleted. (WebCore::isValidHTMLElementName): (WebCore::Document::hasValidNamespaceForElements): Deleted. (WebCore::Document::hasValidNamespaceForAttributes): Deleted. (WebCore::isValidNameNonASCII): Deleted. (WebCore::isValidNameASCII): Deleted. (WebCore::isValidNameASCIIWithoutColon): Deleted. (WebCore::Document::isValidName): Deleted. (WebCore::Document::parseQualifiedName): Deleted. * Source/WebCore/dom/Document.h: * Source/WebCore/dom/Element.cpp: (WebCore::Element::toggleAttribute): (WebCore::Element::setAttribute): (WebCore::Element::setAttributeNS): (WebCore::Element::parseAttributeName): * Source/WebCore/dom/Element.h: * Source/WebCore/dom/NameValidation.cpp: Added. (WebCore::NameValidation::isInvalidAttributeNameCharacter): (WebCore::NameValidation::isInvalidElementNameCharacterAfterAlphaStart): (WebCore::NameValidation::isValidElementNameContinuationCharacter): (WebCore::NameValidation::isInvalidNamespacePrefixCharacter): (WebCore::NameValidation::isInvalidDoctypeNameCharacter): (WebCore::NameValidation::isValidElementName): (WebCore::NameValidation::isValidAttributeName): (WebCore::NameValidation::isValidNamespacePrefix): (WebCore::NameValidation::isValidDoctypeName): (WebCore::NameValidation::isValidASCIIXMLName): (WebCore::NameValidation::isValidXMLNameStart): (WebCore::NameValidation::isValidXMLNamePart): (WebCore::NameValidation::isValidXMLName): (WebCore::NameValidation::parseQualifiedNameToPair): (WebCore::NameValidation::parseQualifiedElementName): (WebCore::NameValidation::parseQualifiedAttributeName): (WebCore::NameValidation::hasValidNamespaceForElements): (WebCore::NameValidation::hasValidNamespaceForAttributes): * Source/WebCore/dom/NameValidation.h: Added. * Source/WebCore/dom/Node.cpp: (WebCore::Node::checkSetPrefix): * Source/WebCore/dom/ProcessingInstruction.cpp: * Source/WebCore/editing/EditorCommand.cpp: (WebCore::executeFormatBlock): * Source/WebCore/svg/animation/SVGSMILElement.cpp: (WebCore::SVGSMILElement::constructAttributeName const): * Source/WebCore/xml/parser/XMLDocumentParserLibxml2.cpp: (WebCore::handleNamespaceAttributes): (WebCore::handleElementAttributes):
1 parent 0cec9ab commit d472e33

File tree

15 files changed

+390
-243
lines changed

15 files changed

+390
-243
lines changed

Source/WebCore/Headers.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1341,6 +1341,7 @@ set(WebCore_PRIVATE_FRAMEWORK_HEADERS
13411341
dom/MouseRelatedEvent.h
13421342
dom/MutationEvent.h
13431343
dom/MutationObserverOptions.h
1344+
dom/NameValidation.h
13441345
dom/NamedNodeMap.h
13451346
dom/NativeNodeFilter.h
13461347
dom/Node.h

Source/WebCore/Sources.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1321,6 +1321,7 @@ dom/MutationObserverInterestGroup.cpp
13211321
dom/MutationObserverRegistration.cpp
13221322
dom/MutationRecord.cpp
13231323
dom/NameNodeList.cpp
1324+
dom/NameValidation.cpp
13241325
dom/NamedNodeMap.cpp
13251326
dom/NativeNodeFilter.cpp
13261327
dom/Node.cpp

Source/WebCore/WebCore.xcodeproj/project.pbxproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4451,6 +4451,7 @@
44514451
A818721B0977D3C0005826D9 /* NodeList.h in Headers */ = {isa = PBXBuildFile; fileRef = A81872100977D3C0005826D9 /* NodeList.h */; settings = {ATTRIBUTES = (Private, ); }; };
44524452
A818721C0977D3C0005826D9 /* ContainerNode.h in Headers */ = {isa = PBXBuildFile; fileRef = A81872110977D3C0005826D9 /* ContainerNode.h */; settings = {ATTRIBUTES = (Private, ); }; };
44534453
A818721E0977D3C0005826D9 /* NameNodeList.h in Headers */ = {isa = PBXBuildFile; fileRef = A81872130977D3C0005826D9 /* NameNodeList.h */; };
4454+
5CC59425C83340698819A8EE /* NameValidation.h in Headers */ = {isa = PBXBuildFile; fileRef = 1043649292C14384B5937F8F /* NameValidation.h */; };
44544455
A81872200977D3C0005826D9 /* ChildNodeList.h in Headers */ = {isa = PBXBuildFile; fileRef = A81872150977D3C0005826D9 /* ChildNodeList.h */; };
44554456
A81872230977D3C0005826D9 /* NamedNodeMap.h in Headers */ = {isa = PBXBuildFile; fileRef = A81872180977D3C0005826D9 /* NamedNodeMap.h */; settings = {ATTRIBUTES = (Private, ); }; };
44564457
A8239E0109B3CF8A00B60641 /* Logging.h in Headers */ = {isa = PBXBuildFile; fileRef = A8239DFF09B3CF8A00B60641 /* Logging.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -17383,6 +17384,8 @@
1738317384
A81872100977D3C0005826D9 /* NodeList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = NodeList.h; sourceTree = "<group>"; };
1738417385
A81872110977D3C0005826D9 /* ContainerNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ContainerNode.h; sourceTree = "<group>"; };
1738517386
A81872130977D3C0005826D9 /* NameNodeList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = NameNodeList.h; sourceTree = "<group>"; };
17387+
A87BC832E99A41359C1D4FA8 /* NameValidation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NameValidation.cpp; sourceTree = "<group>"; };
17388+
1043649292C14384B5937F8F /* NameValidation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NameValidation.h; sourceTree = "<group>"; };
1738617389
A81872140977D3C0005826D9 /* ContainerNode.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ContainerNode.cpp; sourceTree = "<group>"; };
1738717390
A81872150977D3C0005826D9 /* ChildNodeList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ChildNodeList.h; sourceTree = "<group>"; };
1738817391
A81872180977D3C0005826D9 /* NamedNodeMap.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = NamedNodeMap.h; sourceTree = "<group>"; };
@@ -41688,6 +41691,8 @@
4168841691
85ACA9F90A9B631000671E90 /* NamedNodeMap.idl */,
4168941692
A81872190977D3C0005826D9 /* NameNodeList.cpp */,
4169041693
A81872130977D3C0005826D9 /* NameNodeList.h */,
41694+
A87BC832E99A41359C1D4FA8 /* NameValidation.cpp */,
41695+
1043649292C14384B5937F8F /* NameValidation.h */,
4169141696
8306EFF01B8BCE7C0031D032 /* NativeNodeFilter.cpp */,
4169241697
83E959E11B8BC22B004D9385 /* NativeNodeFilter.h */,
4169341698
71FF851822A3F81F005D5959 /* NavigatorMaxTouchPoints.idl */,
@@ -46214,6 +46219,7 @@
4621446219
A81872230977D3C0005826D9 /* NamedNodeMap.h in Headers */,
4621546220
A818721E0977D3C0005826D9 /* NameNodeList.h in Headers */,
4621646221
3227A93128BD744C00BC2697 /* Namespace.h in Headers */,
46222+
5CC59425C83340698819A8EE /* NameValidation.h in Headers */,
4621746223
726D56E3253AE3660002EF90 /* NativeImage.h in Headers */,
4621846224
72854E692B6987B700E0181A /* NativeImageSource.h in Headers */,
4621946225
83B2D1751B8BCD6A00A02E47 /* NativeNodeFilter.h in Headers */,

Source/WebCore/dom/DOMImplementation.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#include "MediaDocument.h"
4545
#include "MediaPlayer.h"
4646
#include "MediaQueryParser.h"
47+
#include "NameValidation.h"
4748
#include "PDFDocument.h"
4849
#include "ParserContentPolicy.h"
4950
#include "PluginData.h"
@@ -78,9 +79,8 @@ DOMImplementation::DOMImplementation(Document& document)
7879

7980
ExceptionOr<Ref<DocumentType>> DOMImplementation::createDocumentType(const AtomString& qualifiedName, const String& publicId, const String& systemId)
8081
{
81-
auto parseResult = Document::parseQualifiedName(qualifiedName);
82-
if (parseResult.hasException())
83-
return parseResult.releaseException();
82+
if (!NameValidation::isValidDoctypeName(qualifiedName))
83+
return Exception { ExceptionCode::InvalidCharacterError, makeString("Invalid doctype name: '"_s, qualifiedName, '\'') };
8484
return DocumentType::create(protect(document()), qualifiedName, publicId, systemId);
8585
}
8686

Source/WebCore/dom/Document.cpp

Lines changed: 11 additions & 192 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@
199199
#include "MouseEventWithHitTestResults.h"
200200
#include "MutationEvent.h"
201201
#include "NameNodeList.h"
202+
#include "NameValidation.h"
202203
#include "Navigation.h"
203204
#include "NavigationActivation.h"
204205
#include "NavigationDisabler.h"
@@ -521,24 +522,6 @@ static void CallbackForContainIntrinsicSize(const Vector<Ref<ResizeObserverEntry
521522
}
522523
}
523524

524-
// https://www.w3.org/TR/xml/#NT-NameStartChar
525-
// NameStartChar ::= ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
526-
static inline bool NODELETE isValidNameStart(char32_t c)
527-
{
528-
return c == ':' || (c >= 'A' && c <= 'Z') || c == '_' || (c >= 'a' && c <= 'z') || (c >= 0x00C0 && c <= 0x00D6)
529-
|| (c >= 0x00D8 && c <= 0x00F6) || (c >= 0x00F8 && c <= 0x02FF) || (c >= 0x0370 && c <= 0x037D) || (c >= 0x037F && c <= 0x1FFF)
530-
|| (c >= 0x200C && c <= 0x200D) || (c >= 0x2070 && c <= 0x218F) || (c >= 0x2C00 && c <= 0x2FeF) || (c >= 0x3001 && c <= 0xD7FF)
531-
|| (c >= 0xF900 && c <= 0xFDCF) || (c >= 0xFDF0 && c <= 0xFFFD) || (c >= 0x10000 && c <= 0xEFFFF);
532-
}
533-
534-
// https://www.w3.org/TR/xml/#NT-NameChar
535-
// NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
536-
static inline bool NODELETE isValidNamePart(char32_t c)
537-
{
538-
return isValidNameStart(c) || c == '-' || c == '.' || (c >= '0' && c <= '9') || c == 0x00B7
539-
|| (c >= 0x0300 && c <= 0x036F) || (c >= 0x203F && c <= 0x2040);
540-
}
541-
542525
static Widget* NODELETE widgetForElement(Element* focusedElement)
543526
{
544527
auto* renderer = focusedElement ? dynamicDowncast<RenderWidget>(focusedElement->renderer()) : nullptr;
@@ -1550,16 +1533,6 @@ static ALWAYS_INLINE Ref<HTMLElement> createUpgradeCandidateElement(Document& do
15501533
return createUpgradeCandidateElement(document, registry, QualifiedName { nullAtom(), localName, xhtmlNamespaceURI });
15511534
}
15521535

1553-
static inline bool NODELETE isValidHTMLElementName(const AtomString& localName)
1554-
{
1555-
return Document::isValidName(localName);
1556-
}
1557-
1558-
static inline bool NODELETE isValidHTMLElementName(const QualifiedName& name)
1559-
{
1560-
return Document::isValidName(name.localName());
1561-
}
1562-
15631536
template<typename NameType>
15641537
static ExceptionOr<Ref<Element>> createHTMLElementWithNameValidation(Document& document, const NameType& name, CustomElementRegistry* registry)
15651538
{
@@ -1575,7 +1548,7 @@ static ExceptionOr<Ref<Element>> createHTMLElementWithNameValidation(Document& d
15751548
return elementInterface->constructElementWithFallback(document, *registry, name);
15761549
}
15771550

1578-
if (!isValidHTMLElementName(name)) [[unlikely]]
1551+
if (!NameValidation::isValidElementName(name)) [[unlikely]]
15791552
return Exception { ExceptionCode::InvalidCharacterError };
15801553

15811554
return Ref<Element> { createUpgradeCandidateElement(document, registry, name) };
@@ -1603,7 +1576,7 @@ ExceptionOr<Ref<Element>> Document::createElementForBindings(const AtomString& n
16031576
if (document->isXHTMLDocument())
16041577
return createHTMLElementWithNameValidation(document, name, registry.get());
16051578

1606-
if (!document->isValidName(name))
1579+
if (!NameValidation::isValidElementName(name))
16071580
return Exception { ExceptionCode::InvalidCharacterError, makeString("Invalid qualified name: '"_s, name, '\'') };
16081581

16091582
return createElement(QualifiedName(nullAtom(), name, nullAtom()), false, registry.get());
@@ -1654,8 +1627,8 @@ ExceptionOr<Ref<CDATASection>> Document::createCDATASection(String&& data)
16541627

16551628
ExceptionOr<Ref<ProcessingInstruction>> Document::createProcessingInstruction(String&& target, String&& data)
16561629
{
1657-
if (!isValidName(target))
1658-
return Exception { ExceptionCode::InvalidCharacterError, makeString("Invalid qualified name: '"_s, target, '\'') };
1630+
if (!NameValidation::isValidXMLName(target))
1631+
return Exception { ExceptionCode::InvalidCharacterError, makeString("Invalid processing instruction target: '"_s, target, '\'') };
16591632

16601633
if (data.contains("?>"_s))
16611634
return Exception { ExceptionCode::InvalidCharacterError };
@@ -1748,28 +1721,6 @@ ExceptionOr<Ref<Node>> Document::adoptNode(Node& source)
17481721
return Ref<Node> { source };
17491722
}
17501723

1751-
bool Document::hasValidNamespaceForElements(const QualifiedName& qName)
1752-
{
1753-
// These checks are from DOM Core Level 2, createElementNS
1754-
// http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-DocCrElNS
1755-
if (!qName.prefix().isEmpty() && qName.namespaceURI().isNull()) // createElementNS(null, "html:div")
1756-
return false;
1757-
if (qName.prefix() == xmlAtom() && qName.namespaceURI() != XMLNames::xmlNamespaceURI) // createElementNS("http://www.example.com", "xml:lang")
1758-
return false;
1759-
1760-
// Required by DOM Level 3 Core and unspecified by DOM Level 2 Core:
1761-
// http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#ID-DocCrElNS
1762-
// createElementNS("http://www.w3.org/2000/xmlns/", "foo:bar"), createElementNS(null, "xmlns:bar"), createElementNS(null, "xmlns")
1763-
if (qName.prefix() == xmlnsAtom() || (qName.prefix().isEmpty() && qName.localName() == xmlnsAtom()))
1764-
return qName.namespaceURI() == XMLNSNames::xmlnsNamespaceURI;
1765-
return qName.namespaceURI() != XMLNSNames::xmlnsNamespaceURI;
1766-
}
1767-
1768-
bool Document::hasValidNamespaceForAttributes(const QualifiedName& qName)
1769-
{
1770-
return hasValidNamespaceForElements(qName);
1771-
}
1772-
17731724
static Ref<HTMLElement> createFallbackHTMLElement(Document& document, CustomElementRegistry* registry, const QualifiedName& name)
17741725
{
17751726
if (registry) {
@@ -2039,11 +1990,11 @@ ExceptionOr<Ref<Element>> Document::createElementNS(const AtomString& namespaceU
20391990
if (opportunisticallyMatchedBuiltinElement) [[likely]]
20401991
return opportunisticallyMatchedBuiltinElement.releaseNonNull();
20411992

2042-
auto parseResult = Document::parseQualifiedName(namespaceURI, qualifiedName);
1993+
auto parseResult = NameValidation::parseQualifiedElementName(namespaceURI, qualifiedName);
20431994
if (parseResult.hasException())
20441995
return parseResult.releaseException();
20451996
QualifiedName parsedName { parseResult.releaseReturnValue() };
2046-
if (!Document::hasValidNamespaceForElements(parsedName))
1997+
if (!NameValidation::hasValidNamespaceForElements(parsedName))
20471998
return Exception { ExceptionCode::NamespaceError };
20481999

20492000
if (parsedName.namespaceURI() == xhtmlNamespaceURI)
@@ -7473,138 +7424,6 @@ void Document::updateCachedCookiesEnabled()
74737424
});
74747425
}
74757426

7476-
static bool NODELETE isValidNameNonASCII(std::span<const Latin1Character> characters)
7477-
{
7478-
if (!isValidNameStart(characters[0]))
7479-
return false;
7480-
7481-
for (size_t i = 1; i < characters.size(); ++i) {
7482-
if (!isValidNamePart(characters[i]))
7483-
return false;
7484-
}
7485-
7486-
return true;
7487-
}
7488-
7489-
static bool NODELETE isValidNameNonASCII(std::span<const char16_t> characters)
7490-
{
7491-
for (size_t i = 0; i < characters.size();) {
7492-
bool first = !i;
7493-
char32_t c;
7494-
U16_NEXT(characters, i, characters.size(), c); // Increments i.
7495-
if (first ? !isValidNameStart(c) : !isValidNamePart(c))
7496-
return false;
7497-
}
7498-
7499-
return true;
7500-
}
7501-
7502-
template<typename CharType>
7503-
static inline bool isValidNameASCII(std::span<const CharType> characters)
7504-
{
7505-
CharType c = characters[0];
7506-
if (!(isASCIIAlpha(c) || c == ':' || c == '_'))
7507-
return false;
7508-
7509-
for (size_t i = 1; i < characters.size(); ++i) {
7510-
c = characters[i];
7511-
if (!(isASCIIAlphanumeric(c) || c == ':' || c == '_' || c == '-' || c == '.'))
7512-
return false;
7513-
}
7514-
7515-
return true;
7516-
}
7517-
7518-
static bool NODELETE isValidNameASCIIWithoutColon(std::span<const Latin1Character> characters)
7519-
{
7520-
auto c = characters.front();
7521-
if (!(isASCIIAlpha(c) || c == '_'))
7522-
return false;
7523-
7524-
for (size_t i = 1; i < characters.size(); ++i) {
7525-
c = characters[i];
7526-
if (!(isASCIIAlphanumeric(c) || c == '_' || c == '-' || c == '.'))
7527-
return false;
7528-
}
7529-
7530-
return true;
7531-
}
7532-
7533-
bool Document::isValidName(const String& name)
7534-
{
7535-
unsigned length = name.length();
7536-
if (!length)
7537-
return false;
7538-
7539-
if (name.is8Bit()) {
7540-
auto characters = name.span8();
7541-
7542-
if (isValidNameASCII(characters))
7543-
return true;
7544-
7545-
return isValidNameNonASCII(characters);
7546-
}
7547-
7548-
auto characters = name.span16();
7549-
7550-
if (isValidNameASCII(characters))
7551-
return true;
7552-
7553-
return isValidNameNonASCII(characters);
7554-
}
7555-
7556-
ExceptionOr<std::pair<AtomString, AtomString>> Document::parseQualifiedName(const AtomString& qualifiedName)
7557-
{
7558-
unsigned length = qualifiedName.length();
7559-
7560-
if (!length)
7561-
return Exception { ExceptionCode::InvalidCharacterError };
7562-
7563-
bool nameStart = true;
7564-
bool sawColon = false;
7565-
unsigned colonPosition = 0;
7566-
7567-
bool isValidLocalName = qualifiedName.is8Bit() && isValidNameASCIIWithoutColon(qualifiedName.span8());
7568-
if (isValidLocalName) [[likely]]
7569-
return std::pair<AtomString, AtomString> { { }, { qualifiedName } };
7570-
7571-
for (unsigned i = 0; i < length; ) {
7572-
char32_t c;
7573-
U16_NEXT(qualifiedName, i, length, c);
7574-
if (c == ':') {
7575-
if (sawColon)
7576-
return Exception { ExceptionCode::InvalidCharacterError, makeString("Unexpected colon in qualified name '"_s, qualifiedName, '\'') };
7577-
nameStart = true;
7578-
sawColon = true;
7579-
colonPosition = i - 1;
7580-
} else if (nameStart) {
7581-
if (!isValidNameStart(c))
7582-
return Exception { ExceptionCode::InvalidCharacterError, makeString("Invalid qualified name start in '"_s, qualifiedName, '\'') };
7583-
nameStart = false;
7584-
} else {
7585-
if (!isValidNamePart(c))
7586-
return Exception { ExceptionCode::InvalidCharacterError, makeString("Invalid qualified name part in '"_s, qualifiedName, '\'') };
7587-
}
7588-
}
7589-
7590-
if (!sawColon)
7591-
return std::pair<AtomString, AtomString> { { }, { qualifiedName } };
7592-
7593-
if (!colonPosition || length - colonPosition <= 1)
7594-
return Exception { ExceptionCode::InvalidCharacterError, makeString("Namespace in qualified name '"_s, qualifiedName, "' is too short"_s) };
7595-
7596-
return std::pair<AtomString, AtomString> { StringView { qualifiedName }.left(colonPosition).toAtomString(), StringView { qualifiedName }.substring(colonPosition + 1).toAtomString() };
7597-
}
7598-
7599-
ExceptionOr<QualifiedName> Document::parseQualifiedName(const AtomString& namespaceURI, const AtomString& qualifiedName)
7600-
{
7601-
auto parseResult = parseQualifiedName(qualifiedName);
7602-
if (parseResult.hasException())
7603-
return parseResult.releaseException();
7604-
auto parsedPieces = parseResult.releaseReturnValue();
7605-
return QualifiedName { parsedPieces.first, parsedPieces.second, namespaceURI };
7606-
}
7607-
76087427
void Document::setDecoder(RefPtr<TextResourceDecoder>&& decoder)
76097428
{
76107429
m_decoder = WTF::move(decoder);
@@ -8170,18 +7989,18 @@ ScriptModuleLoader& Document::ensureModuleLoader()
81707989

81717990
ExceptionOr<Ref<Attr>> Document::createAttribute(const AtomString& localName)
81727991
{
8173-
if (!isValidName(localName))
8174-
return Exception { ExceptionCode::InvalidCharacterError, makeString("Invalid qualified name: '"_s, localName, '\'') };
7992+
if (!NameValidation::isValidAttributeName(localName))
7993+
return Exception { ExceptionCode::InvalidCharacterError, makeString("Invalid attribute name: '"_s, localName, '\'') };
81757994
return Attr::create(*this, QualifiedName { nullAtom(), isHTMLDocument() ? localName.convertToASCIILowercase() : localName, nullAtom() }, emptyAtom());
81767995
}
81777996

81787997
ExceptionOr<Ref<Attr>> Document::createAttributeNS(const AtomString& namespaceURI, const AtomString& qualifiedName, bool shouldIgnoreNamespaceChecks)
81797998
{
8180-
auto parseResult = parseQualifiedName(namespaceURI, qualifiedName);
7999+
auto parseResult = NameValidation::parseQualifiedAttributeName(namespaceURI, qualifiedName);
81818000
if (parseResult.hasException())
81828001
return parseResult.releaseException();
81838002
QualifiedName parsedName { parseResult.releaseReturnValue() };
8184-
if (!shouldIgnoreNamespaceChecks && !hasValidNamespaceForAttributes(parsedName))
8003+
if (!shouldIgnoreNamespaceChecks && !NameValidation::hasValidNamespaceForAttributes(parsedName))
81858004
return Exception { ExceptionCode::NamespaceError };
81868005
return Attr::create(*this, parsedName, emptyAtom());
81878006
}

Source/WebCore/dom/Document.h

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1250,19 +1250,6 @@ class Document
12501250
void setSiteForCookies(const URL& url) { m_siteForCookies = url; }
12511251
bool isSameSiteForCookies(const URL&) const;
12521252

1253-
// The following implements the rule from HTML 4 for what valid names are.
1254-
// To get this right for all the XML cases, we probably have to improve this or move it
1255-
// and make it sensitive to the type of document.
1256-
static bool NODELETE isValidName(const String&);
1257-
1258-
// The following breaks a qualified name into a prefix and a local name.
1259-
// It also does a validity check, and returns an error if the qualified name is invalid.
1260-
static ExceptionOr<std::pair<AtomString, AtomString>> parseQualifiedName(const AtomString& qualifiedName);
1261-
static ExceptionOr<QualifiedName> parseQualifiedName(const AtomString& namespaceURI, const AtomString& qualifiedName);
1262-
1263-
// Checks to make sure prefix and namespace do not conflict (per DOM Core 3)
1264-
static bool hasValidNamespaceForElements(const QualifiedName&);
1265-
static bool hasValidNamespaceForAttributes(const QualifiedName&);
12661253

12671254
// This is the "HTML body element" as defined by CSSOM View spec, the first body child of the
12681255
// document element. See http://dev.w3.org/csswg/cssom-view/#the-html-body-element.

0 commit comments

Comments
 (0)