diff options
author | Michal Klocek <michal.klocek@qt.io> | 2018-03-16 05:33:23 +0000 |
---|---|---|
committer | Michal Klocek <michal.klocek@qt.io> | 2018-09-10 09:14:35 +0000 |
commit | aeeeb134caa1e4789f690f99ee26751715867186 (patch) | |
tree | 57beaa819ee75960ec1c7098e73dfc0c103d09e1 | |
parent | a545641e1311a1068a75a0a3e0eca2cc27f59b75 (diff) |
[Backport] CVE-2018-6145
HTML parser: Fix "HTML integration point" implementation in HTMLTreeBuilderSimulator.
HTMLTreeBuilderSimulator assumed only <foreignObject> as an HTML
integration point. This CL adds <annotation-xml>, <desc>, and SVG
<title>.
Bug: 805924
Reviewed-on: https://chromium-review.googlesource.com/964038
Change-Id: Iadbba35420744be0c5851a99200482e885c3f26a
Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
-rw-r--r-- | chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilderSimulator.cpp | 70 | ||||
-rw-r--r-- | chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilderSimulator.h | 2 |
2 files changed, 61 insertions, 11 deletions
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilderSimulator.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilderSimulator.cpp index 97973d540c5..8b12100302c 100644 --- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilderSimulator.cpp +++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilderSimulator.cpp @@ -74,12 +74,6 @@ static bool tokenExitsForeignContent(const CompactHTMLToken& token) { token.getAttributeItem(sizeAttr))); } -static bool tokenExitsSVG(const CompactHTMLToken& token) { - // FIXME: It's very fragile that we special case foreignObject here to be - // case-insensitive. - return equalIgnoringCase(token.data(), - SVGNames::foreignObjectTag.localName()); -} static bool tokenExitsMath(const CompactHTMLToken& token) { // FIXME: This is copied from HTMLElementStack::isMathMLTextIntegrationPoint @@ -139,10 +133,10 @@ HTMLTreeBuilderSimulator::SimulatedToken HTMLTreeBuilderSimulator::simulate( m_namespaceStack.append(MathML); if (inForeignContent() && tokenExitsForeignContent(token)) m_namespaceStack.pop_back(); - if ((m_namespaceStack.last() == SVG && tokenExitsSVG(token)) || - (m_namespaceStack.last() == MathML && tokenExitsMath(token))) + if (IsHTMLIntegrationPointForStartTag(token) || + (m_namespaceStack.last() == MathML && tokenExitsMath(token))) { m_namespaceStack.append(HTML); - if (!inForeignContent()) { + } else if (!inForeignContent()) { // FIXME: This is just a copy of Tokenizer::updateStateFor which uses // threadSafeMatches. if (threadSafeMatch(tagName, textareaTag) || @@ -190,8 +184,7 @@ HTMLTreeBuilderSimulator::SimulatedToken HTMLTreeBuilderSimulator::simulate( threadSafeMatch(tagName, SVGNames::svgTag)) || (m_namespaceStack.last() == MathML && threadSafeMatch(tagName, MathMLNames::mathTag)) || - (m_namespaceStack.contains(SVG) && m_namespaceStack.last() == HTML && - tokenExitsSVG(token)) || + IsHTMLIntegrationPointForEndTag(token) || (m_namespaceStack.contains(MathML) && m_namespaceStack.last() == HTML && tokenExitsMath(token))) { m_namespaceStack.pop_back(); @@ -211,4 +204,59 @@ HTMLTreeBuilderSimulator::SimulatedToken HTMLTreeBuilderSimulator::simulate( return simulatedToken; } +// https://html.spec.whatwg.org/multipage/parsing.html#html-integration-point +bool HTMLTreeBuilderSimulator::IsHTMLIntegrationPointForStartTag( + const CompactHTMLToken& token) const { + DCHECK(token.type() == HTMLToken::StartTag) << token.type(); + + Namespace tokens_ns = m_namespaceStack.last(); + const String& tag_name = token.data(); + if (tokens_ns == MathML) { + if (!threadSafeMatch(tag_name, MathMLNames::annotation_xmlTag)) + return false; + if (auto* encoding = token.getAttributeItem(MathMLNames::encodingAttr)) { + return equalIgnoringASCIICase(encoding->value(), "text/html") || + equalIgnoringASCIICase(encoding->value(), "application/xhtml+xml"); + } + } else if (tokens_ns == SVG) { + // FIXME: It's very fragile that we special case foreignObject here to be + // case-insensitive. + if (equalIgnoringCase(tag_name, + SVGNames::foreignObjectTag.localName())) + return true; + return threadSafeMatch(tag_name, SVGNames::descTag) || + threadSafeMatch(tag_name, SVGNames::titleTag); + } + return false; +} + +// https://html.spec.whatwg.org/multipage/parsing.html#html-integration-point +bool HTMLTreeBuilderSimulator::IsHTMLIntegrationPointForEndTag( + const CompactHTMLToken& token) const { + if (token.type() != HTMLToken::EndTag) + return false; + + // If it's inside an HTML integration point, the top namespace is + // HTML, and its next namespace is not HTML. + if (m_namespaceStack.last() != HTML) + return false; + if (m_namespaceStack.size() < 2) + return false; + Namespace tokens_ns = m_namespaceStack[m_namespaceStack.size() - 2]; + + const String& tag_name = token.data(); + if (tokens_ns == MathML) + return threadSafeMatch(tag_name, MathMLNames::annotation_xmlTag); + if (tokens_ns == SVG) { + // FIXME: It's very fragile that we special case foreignObject here to be + // case-insensitive. + if (equalIgnoringCase(tag_name, + SVGNames::foreignObjectTag.localName())) + return true; + return threadSafeMatch(tag_name, SVGNames::descTag) || + threadSafeMatch(tag_name, SVGNames::titleTag); + } + return false; +} + } // namespace blink diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilderSimulator.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilderSimulator.h index 41f0f8b5c11..c9a1bc925b8 100644 --- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilderSimulator.h +++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilderSimulator.h @@ -57,6 +57,8 @@ class HTMLTreeBuilderSimulator { private: explicit HTMLTreeBuilderSimulator(HTMLTreeBuilder*); + bool IsHTMLIntegrationPointForStartTag(const CompactHTMLToken&) const; + bool IsHTMLIntegrationPointForEndTag(const CompactHTMLToken&) const; bool inForeignContent() const { return m_namespaceStack.last() != HTML; } |