diff options
Diffstat (limited to 'WebCore/html/HTMLParser.cpp')
-rw-r--r-- | WebCore/html/HTMLParser.cpp | 63 |
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; +} + } |