summaryrefslogtreecommitdiffstats
path: root/WebCore/html/HTMLParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/html/HTMLParser.cpp')
-rw-r--r--WebCore/html/HTMLParser.cpp63
1 files changed, 56 insertions, 7 deletions
diff --git a/WebCore/html/HTMLParser.cpp b/WebCore/html/HTMLParser.cpp
index c5839a8..428e8d5 100644
--- a/WebCore/html/HTMLParser.cpp
+++ b/WebCore/html/HTMLParser.cpp
@@ -57,7 +57,9 @@
#include "Page.h"
#include "Settings.h"
#include "Text.h"
+#include "TreeDepthLimit.h"
#include <wtf/StdLibExtras.h>
+#include <wtf/dtoa.h>
namespace WebCore {
@@ -132,6 +134,7 @@ HTMLParser::HTMLParser(HTMLDocument* doc, bool reportErrors)
, m_didRefCurrent(false)
, m_blockStack(0)
, m_blocksInStack(0)
+ , m_treeDepth(0)
, m_hasPElementInScope(NotInScope)
, m_inBody(false)
, m_haveContent(false)
@@ -151,6 +154,7 @@ HTMLParser::HTMLParser(DocumentFragment* frag, FragmentScriptingPermission scrip
, m_didRefCurrent(true)
, m_blockStack(0)
, m_blocksInStack(0)
+ , m_treeDepth(0)
, m_hasPElementInScope(NotInScope)
, m_inBody(true)
, m_haveContent(false)
@@ -181,6 +185,7 @@ void HTMLParser::reset()
freeBlock();
+ m_treeDepth = 0;
m_inBody = false;
m_haveFrameSet = false;
m_haveContent = false;
@@ -213,17 +218,19 @@ inline static int tagPriorityOfNode(Node* n)
return n->isHTMLElement() ? static_cast<HTMLElement*>(n)->tagPriority() : 0;
}
-inline void HTMLParser::limitBlockDepth(int tagPriority)
+inline void HTMLParser::limitDepth(int tagPriority)
{
+ while (m_treeDepth >= maxDOMTreeDepth)
+ popBlock(m_blockStack->tagName);
if (tagPriority >= minBlockLevelTagPriority) {
while (m_blocksInStack >= cMaxBlockDepth)
popBlock(m_blockStack->tagName);
}
}
-inline bool HTMLParser::insertNodeAfterLimitBlockDepth(Node* n, bool flat)
+inline bool HTMLParser::insertNodeAfterLimitDepth(Node* n, bool flat)
{
- limitBlockDepth(tagPriorityOfNode(n));
+ limitDepth(tagPriorityOfNode(n));
return insertNode(n, flat);
}
@@ -265,7 +272,7 @@ PassRefPtr<Node> HTMLParser::parseToken(Token* t)
while (charsLeft) {
// split large blocks of text to nodes of manageable size
n = Text::createWithLengthLimit(m_document, text, charsLeft);
- if (!insertNodeAfterLimitBlockDepth(n.get(), t->selfClosingTag))
+ if (!insertNodeAfterLimitDepth(n.get(), t->selfClosingTag))
return 0;
}
return n;
@@ -296,7 +303,7 @@ PassRefPtr<Node> HTMLParser::parseToken(Token* t)
}
}
- if (!insertNodeAfterLimitBlockDepth(n.get(), t->selfClosingTag)) {
+ if (!insertNodeAfterLimitDepth(n.get(), t->selfClosingTag)) {
// we couldn't insert the node
if (n->isElementNode()) {
@@ -1188,8 +1195,8 @@ void HTMLParser::handleResidualStyleCloseTagAcrossBlocks(HTMLStackElem* elem)
prevElem->node = currElem->node;
prevElem->didRefNode = currElem->didRefNode;
delete currElem;
- }
- else
+ m_treeDepth--;
+ } else
prevElem = currElem;
currElem = nextElem;
}
@@ -1290,6 +1297,7 @@ void HTMLParser::handleResidualStyleCloseTagAcrossBlocks(HTMLStackElem* elem)
prevElem->derefNode();
prevElem->node = elem->node;
prevElem->didRefNode = elem->didRefNode;
+ m_treeDepth--;
if (!finished) {
// Repurpose |elem| to represent |newNode| and insert it at the appropriate position
// in the stack. We do not do this for the innermost block, because in that case the new
@@ -1303,6 +1311,7 @@ void HTMLParser::handleResidualStyleCloseTagAcrossBlocks(HTMLStackElem* elem)
prevMaxElem->node = newNodePtr;
newNodePtr->ref();
prevMaxElem->didRefNode = true;
+ m_treeDepth++;
} else
delete elem;
}
@@ -1399,6 +1408,7 @@ void HTMLParser::pushBlock(const AtomicString& tagName, int level)
m_blockStack = new HTMLStackElem(tagName, level, m_current, m_didRefCurrent, m_blockStack);
if (level >= minBlockLevelTagPriority)
m_blocksInStack++;
+ m_treeDepth++;
m_didRefCurrent = false;
if (tagName == pTag)
m_hasPElementInScope = InScope;
@@ -1508,6 +1518,7 @@ inline HTMLStackElem* HTMLParser::popOneBlockCommon()
ASSERT(m_blocksInStack > 0);
m_blocksInStack--;
}
+ m_treeDepth--;
m_blockStack = elem->next;
m_current = elem->node;
m_didRefCurrent = elem->didRefNode;
@@ -1583,6 +1594,7 @@ void HTMLParser::freeBlock()
while (m_blockStack)
popOneBlock();
ASSERT(!m_blocksInStack);
+ ASSERT(!m_treeDepth);
}
void HTMLParser::createHead()
@@ -1728,4 +1740,41 @@ bool shouldCreateImplicitHead(Document* document)
}
#endif
+
+String serializeForNumberType(double number)
+{
+ // According to HTML5, "the best representation of the number n as a floating
+ // point number" is a string produced by applying ToString() to n.
+ DtoaBuffer buffer;
+ unsigned length;
+ doubleToStringInJavaScriptFormat(number, buffer, &length);
+ return String(buffer, length);
+}
+
+bool parseToDoubleForNumberType(const String& src, double* out)
+{
+ // See HTML5 2.4.4.3 `Real numbers.'
+
+ if (src.isEmpty())
+ return false;
+ // String::toDouble() accepts leading + \t \n \v \f \r and SPACE, which are invalid in HTML5.
+ // So, check the first character.
+ if (src[0] != '-' && (src[0] < '0' || src[0] > '9'))
+ return false;
+
+ bool valid = false;
+ double value = src.toDouble(&valid);
+ if (!valid)
+ return false;
+ // NaN and Infinity are not valid numbers according to the standard.
+ if (!isfinite(value))
+ return false;
+ // -0 -> 0
+ if (!value)
+ value = 0;
+ if (out)
+ *out = value;
+ return true;
+}
+
}