| 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.");
|
|
|