Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(256)

Unified Diff: third_party/WebKit/Source/core/dom/Document.cpp

Issue 2838123002: Count element name validity per DOM versus HTML parsing. (Closed)
Patch Set: Do not need the attribute counting. Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/WebKit/Source/core/dom/Document.h ('k') | third_party/WebKit/Source/core/dom/Document.idl » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/WebKit/Source/core/dom/Document.cpp
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp
index d4bd0cf376965d8b4e64f373815fabe2d2c02093..f9fbe89d35e960b185a52dab6e06e05ab10af148 100644
--- a/third_party/WebKit/Source/core/dom/Document.cpp
+++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -375,6 +375,54 @@ static inline bool IsValidNamePart(UChar32 c) {
return true;
}
+// Tests whether |name| is something the HTML parser would accept as a
+// tag name.
+template <typename CharType>
+static inline bool IsValidElementNamePerHTMLParser(const CharType* characters,
+ unsigned length) {
+ CharType c = characters[0] | 0x20;
+ if (!('a' <= c && c < 'z'))
+ return false;
+
+ for (unsigned i = 1; i < length; ++i) {
+ c = characters[i];
+ if (c == '\t' || c == '\n' || c == '\f' || c == '\r' || c == ' ' ||
+ c == '/' || c == '>')
+ return false;
+ }
+
+ return true;
+}
+
+static bool IsValidElementNamePerHTMLParser(const String& name) {
+ unsigned length = name.length();
+ if (!length)
+ return false;
+
+ if (name.Is8Bit()) {
+ const LChar* characters = name.Characters8();
+ return IsValidElementNamePerHTMLParser(characters, length);
+ }
+ const UChar* characters = name.Characters16();
+ return IsValidElementNamePerHTMLParser(characters, length);
+}
+
+// Tests whether |name| is a valid name per DOM spec. Also checks
+// whether the HTML parser would accept this element name and counts
+// cases of mismatches.
+static bool IsValidElementName(const LocalDOMWindow* window,
+ const String& name) {
+ bool is_valid_dom_name = Document::IsValidName(name);
+ bool is_valid_html_name = IsValidElementNamePerHTMLParser(name);
+ if (UNLIKELY(is_valid_html_name != is_valid_dom_name && window)) {
+ UseCounter::Count(window->GetFrame(),
+ is_valid_dom_name
+ ? UseCounter::kElementNameDOMValidHTMLParserInvalid
+ : UseCounter::kElementNameDOMInvalidHTMLParserValid);
+ }
+ return is_valid_dom_name;
+}
+
static bool AcceptsEditingFocus(const Element& element) {
DCHECK(HasEditableStyle(element));
@@ -694,9 +742,10 @@ AtomicString Document::ConvertLocalName(const AtomicString& name) {
}
// https://dom.spec.whatwg.org/#dom-document-createelement
-Element* Document::createElement(const AtomicString& name,
+Element* Document::createElement(const LocalDOMWindow* window,
+ const AtomicString& name,
ExceptionState& exception_state) {
- if (!IsValidName(name)) {
+ if (!IsValidElementName(window, name)) {
exception_state.ThrowDOMException(
kInvalidCharacterError,
"The tag name provided ('" + name + "') is not a valid name.");
@@ -746,11 +795,12 @@ String GetTypeExtension(Document* document,
}
// https://dom.spec.whatwg.org/#dom-document-createelement
-Element* Document::createElement(const AtomicString& local_name,
+Element* Document::createElement(const LocalDOMWindow* window,
+ const AtomicString& local_name,
const StringOrDictionary& string_or_options,
ExceptionState& exception_state) {
// 1. If localName does not match Name production, throw InvalidCharacterError
- if (!IsValidName(local_name)) {
+ if (!IsValidElementName(window, local_name)) {
exception_state.ThrowDOMException(
kInvalidCharacterError,
"The tag name provided ('" + local_name + "') is not a valid name.");
@@ -806,7 +856,7 @@ Element* Document::createElement(const AtomicString& local_name,
*this,
QualifiedName(g_null_atom, converted_local_name, xhtmlNamespaceURI));
} else {
- element = createElement(local_name, exception_state);
+ element = createElement(window, local_name, exception_state);
if (exception_state.HadException())
return nullptr;
}
@@ -846,7 +896,8 @@ static inline QualifiedName CreateQualifiedName(
return q_name;
}
-Element* Document::createElementNS(const AtomicString& namespace_uri,
+Element* Document::createElementNS(const LocalDOMWindow* window,
+ const AtomicString& namespace_uri,
const AtomicString& qualified_name,
ExceptionState& exception_state) {
QualifiedName q_name(
@@ -860,7 +911,8 @@ Element* Document::createElementNS(const AtomicString& namespace_uri,
}
// https://dom.spec.whatwg.org/#internal-createelementns-steps
-Element* Document::createElementNS(const AtomicString& namespace_uri,
+Element* Document::createElementNS(const LocalDOMWindow* window,
+ const AtomicString& namespace_uri,
const AtomicString& qualified_name,
const StringOrDictionary& string_or_options,
ExceptionState& exception_state) {
@@ -882,7 +934,7 @@ Element* Document::createElementNS(const AtomicString& namespace_uri,
AtomicString(GetTypeExtension(this, string_or_options, exception_state));
const AtomicString& name = should_create_builtin ? is : qualified_name;
- if (!IsValidName(qualified_name)) {
+ if (!IsValidElementName(window, qualified_name)) {
exception_state.ThrowDOMException(
kInvalidCharacterError, "The tag name provided ('" + qualified_name +
"') is not a valid name.");
« no previous file with comments | « third_party/WebKit/Source/core/dom/Document.h ('k') | third_party/WebKit/Source/core/dom/Document.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698