- Revision
- 143415
- Author
- to...@chromium.org
- Date
- 2013-02-19 17:20:48 -0800 (Tue, 19 Feb 2013)
Log Message
Fix crash in preloading scanning base tags with no href attribute for background parser
https://bugs.webkit.org/show_bug.cgi?id=110276
Reviewed by Eric Seidel.
Previously a <base> tag without an href attribute (like the one in fast/dom/HTMLAnchorElement/set-href-attribute-rebase.html)
would crash the background parser's preload scanner.
To fix that, we only call stripLeadingAndTrailingHTMLSpaces() if the href attribute is non-null. This matches the main thread parser.
Along with this, I decided to templatize updatePredictedBaseURL() so that the main and background parser can share the same impl.
This required making CompactHTMLToken and HTMLToken a little more similar:
1. Give HTMLToken a getAttributeItem() method.
2. Move CompactAttribute to CompactHTMLToken::Attribute and make it a struct.
No new tests because covered by existing tests.
* html/parser/AtomicHTMLToken.h:
(WebCore::AtomicHTMLToken::AtomicHTMLToken):
* html/parser/CompactHTMLToken.cpp:
(SameSizeAsCompactHTMLToken):
(WebCore::CompactHTMLToken::CompactHTMLToken):
(WebCore::CompactHTMLToken::getAttributeItem):
(WebCore::CompactHTMLToken::isSafeToSendToAnotherThread):
* html/parser/CompactHTMLToken.h:
(WebCore::CompactHTMLToken::Attribute::Attribute):
(Attribute):
(WebCore::CompactHTMLToken::attributes):
(CompactHTMLToken):
(WebCore::CompactHTMLToken::publicIdentifier):
(WebCore::CompactHTMLToken::systemIdentifier):
* html/parser/HTMLParserIdioms.h:
(WebCore):
(WebCore::stripLeadingAndTrailingHTMLSpaces):
* html/parser/HTMLPreloadScanner.cpp:
(WebCore::TokenPreloadScanner::StartTagScanner::processAttributes):
(WebCore):
(WebCore::TokenPreloadScanner::updatePredictedBaseURL):
* html/parser/HTMLPreloadScanner.h:
* html/parser/HTMLToken.h:
(WebCore::HTMLToken::getAttributeItem):
(HTMLToken):
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (143414 => 143415)
--- trunk/Source/WebCore/ChangeLog 2013-02-20 01:18:24 UTC (rev 143414)
+++ trunk/Source/WebCore/ChangeLog 2013-02-20 01:20:48 UTC (rev 143415)
@@ -1,3 +1,49 @@
+2013-02-19 Tony Gentilcore <to...@chromium.org>
+
+ Fix crash in preloading scanning base tags with no href attribute for background parser
+ https://bugs.webkit.org/show_bug.cgi?id=110276
+
+ Reviewed by Eric Seidel.
+
+ Previously a <base> tag without an href attribute (like the one in fast/dom/HTMLAnchorElement/set-href-attribute-rebase.html)
+ would crash the background parser's preload scanner.
+
+ To fix that, we only call stripLeadingAndTrailingHTMLSpaces() if the href attribute is non-null. This matches the main thread parser.
+
+ Along with this, I decided to templatize updatePredictedBaseURL() so that the main and background parser can share the same impl.
+
+ This required making CompactHTMLToken and HTMLToken a little more similar:
+ 1. Give HTMLToken a getAttributeItem() method.
+ 2. Move CompactAttribute to CompactHTMLToken::Attribute and make it a struct.
+
+ No new tests because covered by existing tests.
+
+ * html/parser/AtomicHTMLToken.h:
+ (WebCore::AtomicHTMLToken::AtomicHTMLToken):
+ * html/parser/CompactHTMLToken.cpp:
+ (SameSizeAsCompactHTMLToken):
+ (WebCore::CompactHTMLToken::CompactHTMLToken):
+ (WebCore::CompactHTMLToken::getAttributeItem):
+ (WebCore::CompactHTMLToken::isSafeToSendToAnotherThread):
+ * html/parser/CompactHTMLToken.h:
+ (WebCore::CompactHTMLToken::Attribute::Attribute):
+ (Attribute):
+ (WebCore::CompactHTMLToken::attributes):
+ (CompactHTMLToken):
+ (WebCore::CompactHTMLToken::publicIdentifier):
+ (WebCore::CompactHTMLToken::systemIdentifier):
+ * html/parser/HTMLParserIdioms.h:
+ (WebCore):
+ (WebCore::stripLeadingAndTrailingHTMLSpaces):
+ * html/parser/HTMLPreloadScanner.cpp:
+ (WebCore::TokenPreloadScanner::StartTagScanner::processAttributes):
+ (WebCore):
+ (WebCore::TokenPreloadScanner::updatePredictedBaseURL):
+ * html/parser/HTMLPreloadScanner.h:
+ * html/parser/HTMLToken.h:
+ (WebCore::HTMLToken::getAttributeItem):
+ (HTMLToken):
+
2013-02-19 Mark Lam <mark....@apple.com>
Introducing AbstractSQLTransaction and AbstractSQLTransactionBackend.
Modified: trunk/Source/WebCore/html/parser/AtomicHTMLToken.h (143414 => 143415)
--- trunk/Source/WebCore/html/parser/AtomicHTMLToken.h 2013-02-20 01:18:24 UTC (rev 143414)
+++ trunk/Source/WebCore/html/parser/AtomicHTMLToken.h 2013-02-20 01:20:48 UTC (rev 143415)
@@ -201,8 +201,8 @@
break;
case HTMLToken::StartTag:
m_attributes.reserveInitialCapacity(token.attributes().size());
- for (Vector<CompactAttribute>::const_iterator it = token.attributes().begin(); it != token.attributes().end(); ++it)
- m_attributes.append(Attribute(QualifiedName(nullAtom, it->name(), nullAtom), it->value()));
+ for (Vector<CompactHTMLToken::Attribute>::const_iterator it = token.attributes().begin(); it != token.attributes().end(); ++it)
+ m_attributes.append(Attribute(QualifiedName(nullAtom, it->name, nullAtom), it->value));
// Fall through!
case HTMLToken::EndTag:
m_selfClosing = token.selfClosing();
Modified: trunk/Source/WebCore/html/parser/CompactHTMLToken.cpp (143414 => 143415)
--- trunk/Source/WebCore/html/parser/CompactHTMLToken.cpp 2013-02-20 01:18:24 UTC (rev 143414)
+++ trunk/Source/WebCore/html/parser/CompactHTMLToken.cpp 2013-02-20 01:20:48 UTC (rev 143415)
@@ -39,7 +39,7 @@
struct SameSizeAsCompactHTMLToken {
unsigned bitfields;
String name;
- Vector<CompactAttribute> vector;
+ Vector<Attribute> vector;
TextPosition textPosition;
OwnPtr<XSSInfo> xssInfo;
};
@@ -60,7 +60,7 @@
m_data = String(token->name());
// There is only 1 DOCTYPE token per document, so to avoid increasing the
// size of CompactHTMLToken, we just use the m_attributes vector.
- m_attributes.append(CompactAttribute(String(token->publicIdentifier()), String(token->systemIdentifier())));
+ m_attributes.append(Attribute(String(token->publicIdentifier()), String(token->systemIdentifier())));
m_doctypeForcesQuirks = token->forceQuirks();
break;
}
@@ -70,7 +70,7 @@
m_attributes.reserveInitialCapacity(token->attributes().size());
// FIXME: Attribute names and values should be 8bit when possible.
for (Vector<HTMLToken::Attribute>::const_iterator it = token->attributes().begin(); it != token->attributes().end(); ++it)
- m_attributes.append(CompactAttribute(String(it->name), String(it->value)));
+ m_attributes.append(Attribute(String(it->name), String(it->value)));
// Fall through!
case HTMLToken::EndTag:
m_selfClosing = token->selfClosing();
@@ -102,10 +102,10 @@
m_xssInfo = adoptPtr(new XSSInfo(*other.m_xssInfo));
}
-const CompactAttribute* CompactHTMLToken::getAttributeItem(const QualifiedName& name) const
+const CompactHTMLToken::Attribute* CompactHTMLToken::getAttributeItem(const QualifiedName& name) const
{
for (unsigned i = 0; i < m_attributes.size(); ++i) {
- if (threadSafeMatch(m_attributes.at(i).name(), name))
+ if (threadSafeMatch(m_attributes.at(i).name, name))
return &m_attributes.at(i);
}
return 0;
@@ -113,10 +113,10 @@
bool CompactHTMLToken::isSafeToSendToAnotherThread() const
{
- for (Vector<CompactAttribute>::const_iterator it = m_attributes.begin(); it != m_attributes.end(); ++it) {
- if (!it->name().isSafeToSendToAnotherThread())
+ for (Vector<Attribute>::const_iterator it = m_attributes.begin(); it != m_attributes.end(); ++it) {
+ if (!it->name.isSafeToSendToAnotherThread())
return false;
- if (!it->value().isSafeToSendToAnotherThread())
+ if (!it->value.isSafeToSendToAnotherThread())
return false;
}
if (m_xssInfo && !m_xssInfo->isSafeToSendToAnotherThread())
Modified: trunk/Source/WebCore/html/parser/CompactHTMLToken.h (143414 => 143415)
--- trunk/Source/WebCore/html/parser/CompactHTMLToken.h 2013-02-20 01:18:24 UTC (rev 143414)
+++ trunk/Source/WebCore/html/parser/CompactHTMLToken.h 2013-02-20 01:20:48 UTC (rev 143415)
@@ -42,24 +42,19 @@
class QualifiedName;
class XSSInfo;
-class CompactAttribute {
+class CompactHTMLToken {
public:
- CompactAttribute(const String& name, const String& value)
- : m_name(name)
- , m_value(value)
- {
- }
+ struct Attribute {
+ Attribute(const String& name, const String& value)
+ : name(name)
+ , value(value)
+ {
+ }
- const String& name() const { return m_name; }
- const String& value() const { return m_value; }
+ String name;
+ String value;
+ };
-private:
- String m_name;
- String m_value;
-};
-
-class CompactHTMLToken {
-public:
CompactHTMLToken(const HTMLToken*, const TextPosition&);
CompactHTMLToken(const CompactHTMLToken&);
@@ -69,14 +64,14 @@
const String& data() const { return m_data; }
bool selfClosing() const { return m_selfClosing; }
bool isAll8BitData() const { return m_isAll8BitData; }
- const Vector<CompactAttribute>& attributes() const { return m_attributes; }
- const CompactAttribute* getAttributeItem(const QualifiedName&) const;
+ const Vector<Attribute>& attributes() const { return m_attributes; }
+ const Attribute* getAttributeItem(const QualifiedName&) const;
const TextPosition& textPosition() const { return m_textPosition; }
// There is only 1 DOCTYPE token per document, so to avoid increasing the
// size of CompactHTMLToken, we just use the m_attributes vector.
- const String& publicIdentifier() const { return m_attributes[0].name(); }
- const String& systemIdentifier() const { return m_attributes[0].value(); }
+ const String& publicIdentifier() const { return m_attributes[0].name; }
+ const String& systemIdentifier() const { return m_attributes[0].value; }
bool doctypeForcesQuirks() const { return m_doctypeForcesQuirks; }
XSSInfo* xssInfo() const;
void setXSSInfo(PassOwnPtr<XSSInfo>);
@@ -88,7 +83,7 @@
unsigned m_doctypeForcesQuirks: 1;
String m_data; // "name", "characters", or "data" depending on m_type
- Vector<CompactAttribute> m_attributes;
+ Vector<Attribute> m_attributes;
TextPosition m_textPosition;
OwnPtr<XSSInfo> m_xssInfo;
};
Modified: trunk/Source/WebCore/html/parser/HTMLParserIdioms.h (143414 => 143415)
--- trunk/Source/WebCore/html/parser/HTMLParserIdioms.h 2013-02-20 01:18:24 UTC (rev 143414)
+++ trunk/Source/WebCore/html/parser/HTMLParserIdioms.h 2013-02-20 01:20:48 UTC (rev 143415)
@@ -26,6 +26,7 @@
#define HTMLParserIdioms_h
#include <wtf/Forward.h>
+#include <wtf/text/WTFString.h>
#include <wtf/unicode/Unicode.h>
namespace WebCore {
@@ -40,6 +41,11 @@
// Strip leading and trailing whitespace as defined by the HTML specification.
String stripLeadingAndTrailingHTMLSpaces(const String&);
+template<size_t inlineCapacity>
+String stripLeadingAndTrailingHTMLSpaces(const Vector<UChar, inlineCapacity>& vector)
+{
+ return stripLeadingAndTrailingHTMLSpaces(StringImpl::create8BitIfPossible(vector));
+}
// An implementation of the HTML specification's algorithm to convert a number to a string for number and range types.
String serializeForNumberType(const Decimal&);
Modified: trunk/Source/WebCore/html/parser/HTMLPreloadScanner.cpp (143414 => 143415)
--- trunk/Source/WebCore/html/parser/HTMLPreloadScanner.cpp 2013-02-20 01:18:24 UTC (rev 143414)
+++ trunk/Source/WebCore/html/parser/HTMLPreloadScanner.cpp 2013-02-20 01:20:48 UTC (rev 143415)
@@ -127,12 +127,12 @@
}
#if ENABLE(THREADED_HTML_PARSER)
- void processAttributes(const Vector<CompactAttribute>& attributes)
+ void processAttributes(const Vector<CompactHTMLToken::Attribute>& attributes)
{
if (m_tagId >= UnknownTagId)
return;
- for (Vector<CompactAttribute>::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter)
- processAttribute(iter->name(), iter->value());
+ for (Vector<CompactHTMLToken::Attribute>::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter)
+ processAttribute(iter->name, iter->value);
}
#endif
@@ -337,27 +337,14 @@
}
}
-void TokenPreloadScanner::updatePredictedBaseURL(const HTMLToken& token)
+template<typename Token>
+void TokenPreloadScanner::updatePredictedBaseURL(const Token& token)
{
ASSERT(m_predictedBaseElementURL.isEmpty());
- for (HTMLToken::AttributeList::const_iterator iter = token.attributes().begin(); iter != token.attributes().end(); ++iter) {
- AtomicString attributeName(iter->name);
- if (attributeName == hrefAttr) {
- String hrefValue = StringImpl::create8BitIfPossible(iter->value);
- m_predictedBaseElementURL = KURL(m_documentURL, stripLeadingAndTrailingHTMLSpaces(hrefValue));
- break;
- }
- }
+ if (const typename Token::Attribute* hrefAttribute = token.getAttributeItem(hrefAttr))
+ m_predictedBaseElementURL = KURL(m_documentURL, stripLeadingAndTrailingHTMLSpaces(hrefAttribute->value)).copy();
}
-#if ENABLE(THREADED_HTML_PARSER)
-void TokenPreloadScanner::updatePredictedBaseURL(const CompactHTMLToken& token)
-{
- ASSERT(m_predictedBaseElementURL.isEmpty());
- m_predictedBaseElementURL = KURL(m_documentURL, stripLeadingAndTrailingHTMLSpaces(token.getAttributeItem(hrefAttr)->value())).copy();
-}
-#endif
-
HTMLPreloadScanner::HTMLPreloadScanner(const HTMLParserOptions& options, const KURL& documentURL)
: m_scanner(documentURL)
, m_tokenizer(HTMLTokenizer::create(options))
Modified: trunk/Source/WebCore/html/parser/HTMLPreloadScanner.h (143414 => 143415)
--- trunk/Source/WebCore/html/parser/HTMLPreloadScanner.h 2013-02-20 01:18:24 UTC (rev 143414)
+++ trunk/Source/WebCore/html/parser/HTMLPreloadScanner.h 2013-02-20 01:20:48 UTC (rev 143415)
@@ -82,10 +82,8 @@
static String initiatorFor(TagId);
- void updatePredictedBaseURL(const HTMLToken&);
-#if ENABLE(THREADED_HTML_PARSER)
- void updatePredictedBaseURL(const CompactHTMLToken&);
-#endif
+ template<typename Token>
+ void updatePredictedBaseURL(const Token&);
CSSPreloadScanner m_cssScanner;
KURL m_documentURL;
Modified: trunk/Source/WebCore/html/parser/HTMLToken.h (143414 => 143415)
--- trunk/Source/WebCore/html/parser/HTMLToken.h 2013-02-20 01:18:24 UTC (rev 143414)
+++ trunk/Source/WebCore/html/parser/HTMLToken.h 2013-02-20 01:20:48 UTC (rev 143415)
@@ -358,6 +358,15 @@
return m_attributes;
}
+ const Attribute* getAttributeItem(const QualifiedName& name) const
+ {
+ for (unsigned i = 0; i < m_attributes.size(); ++i) {
+ if (AtomicString(m_attributes.at(i).name) == name.localName())
+ return &m_attributes.at(i);
+ }
+ return 0;
+ }
+
// Used by the XSSAuditor to nuke XSS-laden attributes.
void eraseValueOfAttribute(size_t i)
{