summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal Klocek <michal.klocek@qt.io>2018-03-16 05:33:23 +0000
committerMichal Klocek <michal.klocek@qt.io>2018-09-10 09:14:35 +0000
commitaeeeb134caa1e4789f690f99ee26751715867186 (patch)
tree57beaa819ee75960ec1c7098e73dfc0c103d09e1
parenta545641e1311a1068a75a0a3e0eca2cc27f59b75 (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.cpp70
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilderSimulator.h2
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; }