summaryrefslogtreecommitdiffstats
path: root/WebCore/html
diff options
context:
space:
mode:
authorCary Clark <cary@android.com>2009-06-03 16:01:34 -0400
committerCary Clark <cary@android.com>2009-06-03 16:51:42 -0400
commitdf1815070cfd8d2ed6f7101d1b8d60d037c839e6 (patch)
tree22220c4d20b523f5900f16b5b5c6614e08fc6d43 /WebCore/html
parentd15fb80564c4e30b088ca87fa21a03d67675c662 (diff)
downloadexternal_webkit-df1815070cfd8d2ed6f7101d1b8d60d037c839e6.zip
external_webkit-df1815070cfd8d2ed6f7101d1b8d60d037c839e6.tar.gz
external_webkit-df1815070cfd8d2ed6f7101d1b8d60d037c839e6.tar.bz2
browser security patches
Bug 25420: REGRESSION: XMLHttpRequest allows loading from another origin - fix: http://trac.webkit.org/changeset/42983 Bug 24575: Cross-origin XMLHttpRequest is always allowed - fix: http://trac.webkit.org/projects/webkit/changeset/41667 Bug 21456: UXSS after navigation via directly referencing document - fix: http://trac.webkit.org/changeset/42223 Bug 22655: Stack overflow crash in WebCore::RenderBlock::layout() with deeply nested <div>s - fix: http://trac.webkit.org/projects/webkit/changeset/41938
Diffstat (limited to 'WebCore/html')
-rw-r--r--WebCore/html/HTMLParser.cpp21
-rw-r--r--WebCore/html/HTMLParser.h5
2 files changed, 26 insertions, 0 deletions
diff --git a/WebCore/html/HTMLParser.cpp b/WebCore/html/HTMLParser.cpp
index 0403dad..a719d7d 100644
--- a/WebCore/html/HTMLParser.cpp
+++ b/WebCore/html/HTMLParser.cpp
@@ -61,6 +61,13 @@ using namespace HTMLNames;
static const unsigned cMaxRedundantTagDepth = 20;
static const unsigned cResidualStyleMaxDepth = 200;
+static const int minBlockLevelTagPriority = 3;
+
+// A cap on the number of tags with priority minBlockLevelTagPriority or higher
+// allowed in blockStack. The cap is enforced by adding such new elements as
+// siblings instead of children once it is reached.
+static const size_t cMaxBlockDepth = 4096;
+
struct HTMLStackElem : Noncopyable {
HTMLStackElem(const AtomicString& t, int lvl, Node* n, bool r, HTMLStackElem* nx)
: tagName(t)
@@ -117,6 +124,7 @@ HTMLParser::HTMLParser(HTMLDocument* doc, bool reportErrors)
, current(doc)
, didRefCurrent(false)
, blockStack(0)
+ , m_blocksInStack(0)
, m_hasPElementInScope(NotInScope)
, head(0)
, inBody(false)
@@ -134,6 +142,7 @@ HTMLParser::HTMLParser(DocumentFragment* frag)
, current(frag)
, didRefCurrent(true)
, blockStack(0)
+ , m_blocksInStack(0)
, m_hasPElementInScope(NotInScope)
, head(0)
, inBody(true)
@@ -320,6 +329,11 @@ bool HTMLParser::insertNode(Node* n, bool flat)
if (inStrayTableContent && localName == tableTag)
popBlock(tableTag);
+ if (tagPriority >= minBlockLevelTagPriority) {
+ while (m_blocksInStack >= cMaxBlockDepth)
+ popBlock(blockStack->tagName);
+ }
+
// let's be stupid and just try to insert it.
// this should work if the document is well-formed
Node* newNode = current->addChild(n);
@@ -1306,6 +1320,8 @@ void HTMLParser::reopenResidualStyleTags(HTMLStackElem* elem, Node* malformedTab
void HTMLParser::pushBlock(const AtomicString& tagName, int level)
{
blockStack = new HTMLStackElem(tagName, level, current, didRefCurrent, blockStack);
+ if (level >= minBlockLevelTagPriority)
+ m_blocksInStack++;
didRefCurrent = false;
if (tagName == pTag)
m_hasPElementInScope = InScope;
@@ -1408,6 +1424,10 @@ inline HTMLStackElem* HTMLParser::popOneBlockCommon()
if (current && elem->node != current)
current->finishParsingChildren();
+ if (blockStack->level >= minBlockLevelTagPriority) {
+ ASSERT(m_blocksInStack > 0);
+ m_blocksInStack--;
+ }
blockStack = elem->next;
current = elem->node;
didRefCurrent = elem->didRefNode;
@@ -1482,6 +1502,7 @@ void HTMLParser::freeBlock()
{
while (blockStack)
popOneBlock();
+ ASSERT(!m_blocksInStack);
}
void HTMLParser::createHead()
diff --git a/WebCore/html/HTMLParser.h b/WebCore/html/HTMLParser.h
index 866835f..251b323 100644
--- a/WebCore/html/HTMLParser.h
+++ b/WebCore/html/HTMLParser.h
@@ -159,6 +159,11 @@ private:
HTMLStackElem* blockStack;
+ // The number of tags with priority minBlockLevelTagPriority or higher
+ // currently in m_blockStack. The parser enforces a cap on this value by
+ // adding such new elements as siblings instead of children once it is reached.
+ size_t m_blocksInStack;
+
enum ElementInScopeState { NotInScope, InScope, Unknown };
ElementInScopeState m_hasPElementInScope;