Title: [89453] trunk
Revision
89453
Author
[email protected]
Date
2011-06-22 11:26:03 -0700 (Wed, 22 Jun 2011)

Log Message

2011-06-22  Sam Weinig  <[email protected]>

        Reviewed by Adam Barth.

        HTML parser should limit element depth of produced tree
        https://bugs.webkit.org/show_bug.cgi?id=63082

        Test by:
            fast/parser/block-nesting-cap.html
            fast/parser/element-nesting-cap.html

        * html/parser/HTMLConstructionSite.cpp:
        (WebCore::HTMLConstructionSite::attach):
        (WebCore::HTMLConstructionSite::HTMLConstructionSite):
        * html/parser/HTMLConstructionSite.h:
        Limit the DOM tree depth by turning attempts to add a child passed a certain
        threshold (configurable by Settings::maximumDOMTreeDepth) into a sibling.

        * html/parser/HTMLDocumentParser.cpp:
        (WebCore::HTMLDocumentParser::HTMLDocumentParser):
        (WebCore::HTMLDocumentParser::maximumDOMTreeDepth):
        * html/parser/HTMLDocumentParser.h:
        Pass the maximumDOMTreeDepth to the TreeBuilder.

        * html/parser/HTMLElementStack.cpp:
        (WebCore::HTMLElementStack::HTMLElementStack):
        (WebCore::HTMLElementStack::popAll):
        (WebCore::HTMLElementStack::insertAbove):
        (WebCore::HTMLElementStack::pushCommon):
        (WebCore::HTMLElementStack::popCommon):
        (WebCore::HTMLElementStack::removeNonTopCommon):
        * html/parser/HTMLElementStack.h:
        (WebCore::HTMLElementStack::size):
        Keep track of the size of the element stack.

        * html/parser/HTMLTreeBuilder.cpp:
        (WebCore::HTMLTreeBuilder::HTMLTreeBuilder):
        * html/parser/HTMLTreeBuilder.h:
        (WebCore::HTMLTreeBuilder::create):
        Pass the maximumDOMTreeDepth to the construction site.

        * page/Settings.cpp:
        (WebCore::Settings::Settings):
        * page/Settings.h:
        (WebCore::Settings::setMaximumHTMLParserDOMTreeDepth):
        (WebCore::Settings::maximumHTMLParserDOMTreeDepth):
        Add a setting to control the maximum DOM tree depth that the parser will produce.
2011-06-22  Sam Weinig  <[email protected]>

        Reviewed by Adam Barth.

        HTML parser should limit element depth of produced tree
        https://bugs.webkit.org/show_bug.cgi?id=63082

        * fast/parser/block-nesting-cap-expected.txt:
        * fast/parser/element-nesting-cap-expected.txt:
        Update expectations for new parser depth limit.

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (89452 => 89453)


--- trunk/LayoutTests/ChangeLog	2011-06-22 18:12:43 UTC (rev 89452)
+++ trunk/LayoutTests/ChangeLog	2011-06-22 18:26:03 UTC (rev 89453)
@@ -1,3 +1,14 @@
+2011-06-22  Sam Weinig  <[email protected]>
+
+        Reviewed by Adam Barth.
+
+        HTML parser should limit element depth of produced tree
+        https://bugs.webkit.org/show_bug.cgi?id=63082
+
+        * fast/parser/block-nesting-cap-expected.txt:
+        * fast/parser/element-nesting-cap-expected.txt:
+        Update expectations for new parser depth limit.
+
 2011-06-22  Adam Barth  <[email protected]>
 
         Rollout 88332.

Modified: trunk/LayoutTests/fast/parser/block-nesting-cap-expected.txt (89452 => 89453)


--- trunk/LayoutTests/fast/parser/block-nesting-cap-expected.txt	2011-06-22 18:12:43 UTC (rev 89452)
+++ trunk/LayoutTests/fast/parser/block-nesting-cap-expected.txt	2011-06-22 18:26:03 UTC (rev 89453)
@@ -3,9 +3,9 @@
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-FAIL d4096.parentNode === d4094 should be true. Was false.
+PASS d4096.parentNode === d4094 is true
 PASS d4095.parentNode === d4094 is true
-FAIL d4096.previousSibling === d4095 should be true. Was false.
+PASS d4096.previousSibling === d4095 is true
 PASS successfullyParsed is true
 
 TEST COMPLETE

Modified: trunk/LayoutTests/fast/parser/element-nesting-cap-expected.txt (89452 => 89453)


--- trunk/LayoutTests/fast/parser/element-nesting-cap-expected.txt	2011-06-22 18:12:43 UTC (rev 89452)
+++ trunk/LayoutTests/fast/parser/element-nesting-cap-expected.txt	2011-06-22 18:26:03 UTC (rev 89453)
@@ -4,8 +4,8 @@
 
 
 FAIL s3.parentNode === s1 should be true. Was false.
-PASS s2.parentNode === s1 is true
-FAIL s3.previousSibling === s2 should be true. Was false.
+FAIL s2.parentNode === s1 should be true. Was false.
+PASS s3.previousSibling === s2 is true
 PASS successfullyParsed is true
 
 TEST COMPLETE

Modified: trunk/Source/WebCore/ChangeLog (89452 => 89453)


--- trunk/Source/WebCore/ChangeLog	2011-06-22 18:12:43 UTC (rev 89452)
+++ trunk/Source/WebCore/ChangeLog	2011-06-22 18:26:03 UTC (rev 89453)
@@ -1,3 +1,51 @@
+2011-06-22  Sam Weinig  <[email protected]>
+
+        Reviewed by Adam Barth.
+
+        HTML parser should limit element depth of produced tree
+        https://bugs.webkit.org/show_bug.cgi?id=63082
+
+        Test by:
+            fast/parser/block-nesting-cap.html
+            fast/parser/element-nesting-cap.html
+
+        * html/parser/HTMLConstructionSite.cpp:
+        (WebCore::HTMLConstructionSite::attach):
+        (WebCore::HTMLConstructionSite::HTMLConstructionSite):
+        * html/parser/HTMLConstructionSite.h:
+        Limit the DOM tree depth by turning attempts to add a child passed a certain
+        threshold (configurable by Settings::maximumDOMTreeDepth) into a sibling.
+
+        * html/parser/HTMLDocumentParser.cpp:
+        (WebCore::HTMLDocumentParser::HTMLDocumentParser):
+        (WebCore::HTMLDocumentParser::maximumDOMTreeDepth):
+        * html/parser/HTMLDocumentParser.h:
+        Pass the maximumDOMTreeDepth to the TreeBuilder.
+
+        * html/parser/HTMLElementStack.cpp:
+        (WebCore::HTMLElementStack::HTMLElementStack):
+        (WebCore::HTMLElementStack::popAll):
+        (WebCore::HTMLElementStack::insertAbove):
+        (WebCore::HTMLElementStack::pushCommon):
+        (WebCore::HTMLElementStack::popCommon):
+        (WebCore::HTMLElementStack::removeNonTopCommon):
+        * html/parser/HTMLElementStack.h:
+        (WebCore::HTMLElementStack::size):
+        Keep track of the size of the element stack.
+
+        * html/parser/HTMLTreeBuilder.cpp:
+        (WebCore::HTMLTreeBuilder::HTMLTreeBuilder):
+        * html/parser/HTMLTreeBuilder.h:
+        (WebCore::HTMLTreeBuilder::create):
+        Pass the maximumDOMTreeDepth to the construction site.
+
+        * page/Settings.cpp:
+        (WebCore::Settings::Settings):
+        * page/Settings.h:
+        (WebCore::Settings::setMaximumHTMLParserDOMTreeDepth):
+        (WebCore::Settings::maximumHTMLParserDOMTreeDepth):
+        Add a setting to control the maximum DOM tree depth that the parser will produce.
+
 2011-06-22  Adam Barth  <[email protected]>
 
         Rollout 88332.  As discussed on webkit-dev, we'd like to iterate on

Modified: trunk/Source/WebCore/html/parser/HTMLConstructionSite.cpp (89452 => 89453)


--- trunk/Source/WebCore/html/parser/HTMLConstructionSite.cpp	2011-06-22 18:12:43 UTC (rev 89452)
+++ trunk/Source/WebCore/html/parser/HTMLConstructionSite.cpp	2011-06-22 18:26:03 UTC (rev 89453)
@@ -96,6 +96,10 @@
         return child.release();
     }
 
+    // Add as a sibling of the parent if we have reached the maximum depth allowed.
+    if (m_openElements.stackDepth() > m_maximumDOMTreeDepth)
+        parent = parent->parentNode();
+
     parent->parserAddChild(child);
 
     // An event handler (DOM Mutation, beforeload, et al.) could have removed
@@ -126,21 +130,23 @@
         child->attach();
 }
 
-HTMLConstructionSite::HTMLConstructionSite(Document* document)
+HTMLConstructionSite::HTMLConstructionSite(Document* document, unsigned maximumDOMTreeDepth)
     : m_document(document)
     , m_attachmentRoot(document)
     , m_fragmentScriptingPermission(FragmentScriptingAllowed)
     , m_isParsingFragment(false)
     , m_redirectAttachToFosterParent(false)
+    , m_maximumDOMTreeDepth(maximumDOMTreeDepth)
 {
 }
 
-HTMLConstructionSite::HTMLConstructionSite(DocumentFragment* fragment, FragmentScriptingPermission scriptingPermission)
+HTMLConstructionSite::HTMLConstructionSite(DocumentFragment* fragment, FragmentScriptingPermission scriptingPermission, unsigned maximumDOMTreeDepth)
     : m_document(fragment->document())
     , m_attachmentRoot(fragment)
     , m_fragmentScriptingPermission(scriptingPermission)
     , m_isParsingFragment(true)
     , m_redirectAttachToFosterParent(false)
+    , m_maximumDOMTreeDepth(maximumDOMTreeDepth)
 {
 }
 

Modified: trunk/Source/WebCore/html/parser/HTMLConstructionSite.h (89452 => 89453)


--- trunk/Source/WebCore/html/parser/HTMLConstructionSite.h	2011-06-22 18:12:43 UTC (rev 89452)
+++ trunk/Source/WebCore/html/parser/HTMLConstructionSite.h	2011-06-22 18:26:03 UTC (rev 89453)
@@ -44,8 +44,8 @@
 class HTMLConstructionSite {
     WTF_MAKE_NONCOPYABLE(HTMLConstructionSite);
 public:
-    HTMLConstructionSite(Document*);
-    HTMLConstructionSite(DocumentFragment*, FragmentScriptingPermission);
+    HTMLConstructionSite(Document*, unsigned maximumDOMTreeDepth);
+    HTMLConstructionSite(DocumentFragment*, FragmentScriptingPermission, unsigned maximumDOMTreeDepth);
     ~HTMLConstructionSite();
 
     void detach();
@@ -152,6 +152,8 @@
     // "whenever a node would be inserted into the current node, it must instead
     // be foster parented."  This flag tracks whether we're in that state.
     bool m_redirectAttachToFosterParent;
+
+    unsigned m_maximumDOMTreeDepth;
 };
 
 }

Modified: trunk/Source/WebCore/html/parser/HTMLDocumentParser.cpp (89452 => 89453)


--- trunk/Source/WebCore/html/parser/HTMLDocumentParser.cpp	2011-06-22 18:12:43 UTC (rev 89452)
+++ trunk/Source/WebCore/html/parser/HTMLDocumentParser.cpp	2011-06-22 18:26:03 UTC (rev 89453)
@@ -78,7 +78,7 @@
     : ScriptableDocumentParser(document)
     , m_tokenizer(HTMLTokenizer::create(usePreHTML5ParserQuirks(document)))
     , m_scriptRunner(HTMLScriptRunner::create(document, this))
-    , m_treeBuilder(HTMLTreeBuilder::create(this, document, reportErrors, usePreHTML5ParserQuirks(document)))
+    , m_treeBuilder(HTMLTreeBuilder::create(this, document, reportErrors, usePreHTML5ParserQuirks(document), maximumDOMTreeDepth(document)))
     , m_parserScheduler(HTMLParserScheduler::create(this))
     , m_xssAuditor(this)
     , m_endWasDelayed(false)
@@ -91,7 +91,7 @@
 HTMLDocumentParser::HTMLDocumentParser(DocumentFragment* fragment, Element* contextElement, FragmentScriptingPermission scriptingPermission)
     : ScriptableDocumentParser(fragment->document())
     , m_tokenizer(HTMLTokenizer::create(usePreHTML5ParserQuirks(fragment->document())))
-    , m_treeBuilder(HTMLTreeBuilder::create(this, fragment, contextElement, scriptingPermission, usePreHTML5ParserQuirks(fragment->document())))
+    , m_treeBuilder(HTMLTreeBuilder::create(this, fragment, contextElement, scriptingPermission, usePreHTML5ParserQuirks(fragment->document()), maximumDOMTreeDepth(fragment->document())))
     , m_xssAuditor(this)
     , m_endWasDelayed(false)
     , m_pumpSessionNestingLevel(0)
@@ -569,6 +569,12 @@
     return document->settings() && document->settings()->usePreHTML5ParserQuirks();
 }
 
+unsigned HTMLDocumentParser::maximumDOMTreeDepth(Document* document)
+{
+    ASSERT(document);
+    return document->settings() ? document->settings()->maximumHTMLParserDOMTreeDepth() : Settings::defaultMaximumHTMLParserDOMTreeDepth;
+}
+
 void HTMLDocumentParser::suspendScheduledTasks()
 {
     if (m_parserScheduler)

Modified: trunk/Source/WebCore/html/parser/HTMLDocumentParser.h (89452 => 89453)


--- trunk/Source/WebCore/html/parser/HTMLDocumentParser.h	2011-06-22 18:12:43 UTC (rev 89452)
+++ trunk/Source/WebCore/html/parser/HTMLDocumentParser.h	2011-06-22 18:26:03 UTC (rev 89453)
@@ -73,6 +73,7 @@
     static void parseDocumentFragment(const String&, DocumentFragment*, Element* contextElement, FragmentScriptingPermission = FragmentScriptingAllowed);
     
     static bool usePreHTML5ParserQuirks(Document*);
+    static unsigned maximumDOMTreeDepth(Document*);
 
     HTMLTokenizer* tokenizer() const { return m_tokenizer.get(); }
     String sourceForToken(const HTMLToken&);

Modified: trunk/Source/WebCore/html/parser/HTMLElementStack.cpp (89452 => 89453)


--- trunk/Source/WebCore/html/parser/HTMLElementStack.cpp	2011-06-22 18:12:43 UTC (rev 89452)
+++ trunk/Source/WebCore/html/parser/HTMLElementStack.cpp	2011-06-22 18:26:03 UTC (rev 89453)
@@ -164,6 +164,7 @@
     : m_rootNode(0)
     , m_headElement(0)
     , m_bodyElement(0)
+    , m_stackDepth(0)
 {
 }
 
@@ -207,6 +208,7 @@
     m_rootNode = 0;
     m_headElement = 0;
     m_bodyElement = 0;
+    m_stackDepth = 0;
     while (m_top) {
         topNode()->finishParsingChildren();
         m_top = m_top->releaseNext();
@@ -343,6 +345,7 @@
         if (recordAbove->next() != recordBelow)
             continue;
 
+        m_stackDepth++;
         recordAbove->setNext(adoptPtr(new ElementRecord(element, recordAbove->releaseNext())));
         recordAbove->next()->element()->beginParsingChildren();
         return;
@@ -553,6 +556,8 @@
 void HTMLElementStack::pushCommon(PassRefPtr<ContainerNode> node)
 {
     ASSERT(m_rootNode);
+
+    m_stackDepth++;
     m_top = adoptPtr(new ElementRecord(node, m_top.release()));
     topNode()->beginParsingChildren();
 }
@@ -564,6 +569,8 @@
     ASSERT(!top()->hasTagName(HTMLNames::bodyTag) || !m_bodyElement);
     top()->finishParsingChildren();
     m_top = m_top->releaseNext();
+
+    m_stackDepth--;
 }
 
 void HTMLElementStack::removeNonTopCommon(Element* element)
@@ -577,6 +584,7 @@
             // when the children aren't actually finished?
             element->finishParsingChildren();
             pos->setNext(pos->next()->releaseNext());
+            m_stackDepth--;
             return;
         }
     }

Modified: trunk/Source/WebCore/html/parser/HTMLElementStack.h (89452 => 89453)


--- trunk/Source/WebCore/html/parser/HTMLElementStack.h	2011-06-22 18:12:43 UTC (rev 89452)
+++ trunk/Source/WebCore/html/parser/HTMLElementStack.h	2011-06-22 18:26:03 UTC (rev 89453)
@@ -75,6 +75,8 @@
         OwnPtr<ElementRecord> m_next;
     };
 
+    unsigned stackDepth() const { return m_stackDepth; }
+
     // Inlining this function is a (small) performance win on the parsing
     // benchmark.
     Element* top() const
@@ -167,6 +169,7 @@
     ContainerNode* m_rootNode;
     Element* m_headElement;
     Element* m_bodyElement;
+    unsigned m_stackDepth;
 };
     
 inline bool isInHTMLNamespace(Node* node)

Modified: trunk/Source/WebCore/html/parser/HTMLTreeBuilder.cpp (89452 => 89453)


--- trunk/Source/WebCore/html/parser/HTMLTreeBuilder.cpp	2011-06-22 18:12:43 UTC (rev 89452)
+++ trunk/Source/WebCore/html/parser/HTMLTreeBuilder.cpp	2011-06-22 18:26:03 UTC (rev 89453)
@@ -341,10 +341,10 @@
 };
 
 
-HTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser* parser, HTMLDocument* document, bool reportErrors, bool usePreHTML5ParserQuirks)
+HTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser* parser, HTMLDocument* document, bool reportErrors, bool usePreHTML5ParserQuirks, unsigned maximumDOMTreeDepth)
     : m_framesetOk(true)
     , m_document(document)
-    , m_tree(document)
+    , m_tree(document, maximumDOMTreeDepth)
     , m_reportErrors(reportErrors)
     , m_isPaused(false)
     , m_insertionMode(InitialMode)
@@ -359,11 +359,11 @@
 
 // FIXME: Member variables should be grouped into self-initializing structs to
 // minimize code duplication between these constructors.
-HTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser* parser, DocumentFragment* fragment, Element* contextElement, FragmentScriptingPermission scriptingPermission, bool usePreHTML5ParserQuirks)
+HTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser* parser, DocumentFragment* fragment, Element* contextElement, FragmentScriptingPermission scriptingPermission, bool usePreHTML5ParserQuirks, unsigned maximumDOMTreeDepth)
     : m_framesetOk(true)
     , m_fragmentContext(fragment, contextElement, scriptingPermission)
     , m_document(fragment->document())
-    , m_tree(fragment, scriptingPermission)
+    , m_tree(fragment, scriptingPermission, maximumDOMTreeDepth)
     , m_reportErrors(false) // FIXME: Why not report errors in fragments?
     , m_isPaused(false)
     , m_insertionMode(InitialMode)

Modified: trunk/Source/WebCore/html/parser/HTMLTreeBuilder.h (89452 => 89453)


--- trunk/Source/WebCore/html/parser/HTMLTreeBuilder.h	2011-06-22 18:12:43 UTC (rev 89452)
+++ trunk/Source/WebCore/html/parser/HTMLTreeBuilder.h	2011-06-22 18:26:03 UTC (rev 89453)
@@ -55,13 +55,13 @@
 class HTMLTreeBuilder {
     WTF_MAKE_NONCOPYABLE(HTMLTreeBuilder); WTF_MAKE_FAST_ALLOCATED;
 public:
-    static PassOwnPtr<HTMLTreeBuilder> create(HTMLDocumentParser* parser, HTMLDocument* document, bool reportErrors, bool usePreHTML5ParserQuirks)
+    static PassOwnPtr<HTMLTreeBuilder> create(HTMLDocumentParser* parser, HTMLDocument* document, bool reportErrors, bool usePreHTML5ParserQuirks, unsigned maximumDOMTreeDepth)
     {
-        return adoptPtr(new HTMLTreeBuilder(parser, document, reportErrors, usePreHTML5ParserQuirks));
+        return adoptPtr(new HTMLTreeBuilder(parser, document, reportErrors, usePreHTML5ParserQuirks, maximumDOMTreeDepth));
     }
-    static PassOwnPtr<HTMLTreeBuilder> create(HTMLDocumentParser* parser, DocumentFragment* fragment, Element* contextElement, FragmentScriptingPermission scriptingPermission, bool usePreHTML5ParserQuirks)
+    static PassOwnPtr<HTMLTreeBuilder> create(HTMLDocumentParser* parser, DocumentFragment* fragment, Element* contextElement, FragmentScriptingPermission scriptingPermission, bool usePreHTML5ParserQuirks, unsigned maximumDOMTreeDepth)
     {
-        return adoptPtr(new HTMLTreeBuilder(parser, fragment, contextElement, scriptingPermission, usePreHTML5ParserQuirks));
+        return adoptPtr(new HTMLTreeBuilder(parser, fragment, contextElement, scriptingPermission, usePreHTML5ParserQuirks, maximumDOMTreeDepth));
     }
     ~HTMLTreeBuilder();
 
@@ -116,8 +116,8 @@
         AfterAfterFramesetMode,
     };
 
-    HTMLTreeBuilder(HTMLDocumentParser* parser, HTMLDocument*, bool reportErrors, bool usePreHTML5ParserQuirks);
-    HTMLTreeBuilder(HTMLDocumentParser* parser, DocumentFragment*, Element* contextElement, FragmentScriptingPermission, bool usePreHTML5ParserQuirks);
+    HTMLTreeBuilder(HTMLDocumentParser*, HTMLDocument*, bool reportErrors, bool usePreHTML5ParserQuirks, unsigned maximumDOMTreeDepth);
+    HTMLTreeBuilder(HTMLDocumentParser*, DocumentFragment*, Element* contextElement, FragmentScriptingPermission, bool usePreHTML5ParserQuirks, unsigned maximumDOMTreeDepth);
 
     void processToken(AtomicHTMLToken&);
 

Modified: trunk/Source/WebCore/page/Settings.cpp (89452 => 89453)


--- trunk/Source/WebCore/page/Settings.cpp	2011-06-22 18:12:43 UTC (rev 89452)
+++ trunk/Source/WebCore/page/Settings.cpp	2011-06-22 18:26:03 UTC (rev 89453)
@@ -100,6 +100,7 @@
 #endif
     , m_pluginAllowedRunTime(numeric_limits<unsigned>::max())
     , m_editingBehaviorType(editingBehaviorTypeForPlatform())
+    , m_maximumHTMLParserDOMTreeDepth(defaultMaximumHTMLParserDOMTreeDepth)
     , m_isSpatialNavigationEnabled(false)
     , m_isJavaEnabled(false)
     , m_loadsImagesAutomatically(false)

Modified: trunk/Source/WebCore/page/Settings.h (89452 => 89453)


--- trunk/Source/WebCore/page/Settings.h	2011-06-22 18:12:43 UTC (rev 89452)
+++ trunk/Source/WebCore/page/Settings.h	2011-06-22 18:26:03 UTC (rev 89453)
@@ -388,6 +388,10 @@
         void setUsePreHTML5ParserQuirks(bool flag) { m_usePreHTML5ParserQuirks = flag; }
         bool usePreHTML5ParserQuirks() const { return m_usePreHTML5ParserQuirks; }
 
+        static const unsigned defaultMaximumHTMLParserDOMTreeDepth = 4096;
+        void setMaximumHTMLParserDOMTreeDepth(unsigned maximumHTMLParserDOMTreeDepth) { m_maximumHTMLParserDOMTreeDepth = maximumHTMLParserDOMTreeDepth; }
+        unsigned maximumHTMLParserDOMTreeDepth() const { return m_maximumHTMLParserDOMTreeDepth; }
+
         void setHyperlinkAuditingEnabled(bool flag) { m_hyperlinkAuditingEnabled = flag; }
         bool hyperlinkAuditingEnabled() const { return m_hyperlinkAuditingEnabled; }
 
@@ -436,6 +440,7 @@
 #endif
         unsigned m_pluginAllowedRunTime;
         unsigned m_editingBehaviorType;
+        unsigned m_maximumHTMLParserDOMTreeDepth;
         bool m_isSpatialNavigationEnabled : 1;
         bool m_isJavaEnabled : 1;
         bool m_loadsImagesAutomatically : 1;
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to