2010-05-26 Adam Barth <abarth@webkit.org>
authorabarth@webkit.org <abarth@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 26 May 2010 21:51:01 +0000 (21:51 +0000)
committerabarth@webkit.org <abarth@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 26 May 2010 21:51:01 +0000 (21:51 +0000)
        Reviewed by Eric Seidel.

        Make HTML5 lexer not ASSERT when resuming partial parses
        https://bugs.webkit.org/show_bug.cgi?id=39755

        Add a test suite for partial parsing.  This test runs all our parsing
        test cases, but stops and starts the parser at every character in the
        parse stream to make sure we resume parsing properly.  Currently, a
        bunch of the test cases are commented out, but I'll comment them back
        in as I get them running.

        * html5lib/webkit-resumer-expected-html5.txt: Added.
        * html5lib/webkit-resumer-expected.txt: Added.
        * html5lib/webkit-resumer.html: Added.
2010-05-26  Adam Barth  <abarth@webkit.org>

        Reviewed by Eric Seidel.

        Make HTML5 lexer not ASSERT when resuming partial parses
        https://bugs.webkit.org/show_bug.cgi?id=39755

        I'm working through a variation of the webkit-runner.html test suite
        that stops the parser at every character to make sure we can resume
        parsing correctly.  This patch fixes some errors caught by ASSERTs,
        which prevent the basic tests from running to completion.  There's a
        bunch more work to do, however.

        Test: html5lib/webkit-resumer.html

        * html/HTML5Lexer.cpp:
        (WebCore::HTMLNames::isEndTagBufferingState):
        (WebCore::HTML5Lexer::nextToken):
        (WebCore::HTML5Lexer::addToPossibleEndTag):
        * html/HTML5Lexer.h:
        * html/HTML5Tokenizer.cpp:
        (WebCore::HTML5Tokenizer::write):
        * html/HTML5Tokenizer.h:
2010-05-26  Adam Barth  <abarth@webkit.org>

        Reviewed by Eric Seidel.

        Make HTML5 lexer not ASSERT when resuming partial parses
        https://bugs.webkit.org/show_bug.cgi?id=39755

        Add webkit-resumer.html to the HTML5 parser test suite.

        * Scripts/test-html5-parser:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@60253 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/html5lib/webkit-resumer-expected-html5.txt [new file with mode: 0644]
LayoutTests/html5lib/webkit-resumer-expected.txt [new file with mode: 0644]
LayoutTests/html5lib/webkit-resumer.html [new file with mode: 0644]
WebCore/ChangeLog
WebCore/html/HTML5Lexer.cpp
WebCore/html/HTML5Lexer.h
WebCore/html/HTML5Tokenizer.cpp
WebCore/html/HTML5Tokenizer.h
WebKitTools/ChangeLog
WebKitTools/Scripts/test-html5-parser

index 10db067..2e919c5 100644 (file)
@@ -1,3 +1,20 @@
+2010-05-26  Adam Barth  <abarth@webkit.org>
+
+        Reviewed by Eric Seidel.
+
+        Make HTML5 lexer not ASSERT when resuming partial parses
+        https://bugs.webkit.org/show_bug.cgi?id=39755
+
+        Add a test suite for partial parsing.  This test runs all our parsing
+        test cases, but stops and starts the parser at every character in the
+        parse stream to make sure we resume parsing properly.  Currently, a
+        bunch of the test cases are commented out, but I'll comment them back
+        in as I get them running.
+
+        * html5lib/webkit-resumer-expected-html5.txt: Added.
+        * html5lib/webkit-resumer-expected.txt: Added.
+        * html5lib/webkit-resumer.html: Added.
+
 2010-05-26  Alexey Proskuryakov  <ap@apple.com>
 
         Make the test pass on chromium by weakening expectations. It's probably a chromium bug, but
diff --git a/LayoutTests/html5lib/webkit-resumer-expected-html5.txt b/LayoutTests/html5lib/webkit-resumer-expected-html5.txt
new file mode 100644 (file)
index 0000000..c5ed9ad
--- /dev/null
@@ -0,0 +1,243 @@
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: PASS
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 2: FOO<span>BAR</span>BAZ
+Content-Type: text/plain
+resources/webkit01.dat:
+1.1
+2.2
+3.3
+19.6
+20.7
+21.8
+35.6
+36.7
+37.8
+38.9
+55.26
+56.27
+57.28
+58.29
+59.30
+60.31
+61.32
+62.33
+63.34
+64.35
+65.36
+66.37
+67.38
+68.39
+69.40
+70.41
+71.42
+72.43
+73.44
+74.45
+75.46
+92.63
+93.64
+115.16
+116.17
+117.18
+118.19
+130.6
+131.7
+132.8
+133.9
+150.26
+151.27
+152.28
+153.29
+154.30
+155.31
+156.32
+157.33
+158.34
+159.35
+160.36
+161.37
+162.38
+163.39
+164.40
+165.41
+166.42
+167.43
+168.44
+169.45
+170.46
+171.47
+172.48
+173.49
+174.50
+175.51
+176.52
+177.53
+178.54
+179.55
+180.56
+181.57
+182.58
+183.59
+184.60
+185.61
+186.62
+187.63
+188.64
+205.81
+206.82
+#EOF
diff --git a/LayoutTests/html5lib/webkit-resumer-expected.txt b/LayoutTests/html5lib/webkit-resumer-expected.txt
new file mode 100644 (file)
index 0000000..c6c31a0
--- /dev/null
@@ -0,0 +1,159 @@
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: PASS
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+CONSOLE MESSAGE: line 3: FOO<span>BAR</span>BAZ
+resources/webkit01.dat: PASS
diff --git a/LayoutTests/html5lib/webkit-resumer.html b/LayoutTests/html5lib/webkit-resumer.html
new file mode 100644 (file)
index 0000000..2d3a017
--- /dev/null
@@ -0,0 +1,370 @@
+<title>html5lib test runner</title>
+<script>
+// Copyright (c) 2008 Geoffrey Sneddon
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+// 
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+</script>
+<script>
+String.prototype.toAsciiLowerCase = function () {
+  var output = "";
+  for (var i = 0, len = this.length; i < len; ++i) {
+    if (this.charCodeAt(i) >= 0x41 && this.charCodeAt(i) <= 0x5A) {
+      output += String.fromCharCode(this.charCodeAt(i) + 0x20)
+    } else {
+      output += this.charAt(i);
+    }
+  }
+  return output;
+}
+
+function indent(ancestors) {
+  var str = "";
+  if (ancestors > 0) {
+    while (ancestors--)
+      str += "  ";
+  }
+  return str;
+}
+
+function dom2string(node, ancestors) {
+  var str = "";
+  if (typeof ancestors == "undefined")
+    var ancestors = 0;
+  if (!node.firstChild)
+    return "| ";
+  var parent = node;
+  var current = node.firstChild;
+  var next = null;
+  var misnested = null;
+  for (;;) {
+    str += "\n| " + indent(ancestors);
+    switch (current.nodeType) {
+      case 10:
+        str += '<!DOCTYPE ' + current.nodeName + '>';
+        break;
+      case 8:
+        try {
+          str += '<!-- ' + current.nodeValue + ' -->';
+        } catch (e) {
+          str += '<!--  -->';
+        }
+        if (parent != current.parentNode) {
+          return str += ' (misnested... aborting)';
+        }
+        break;
+      case 7:
+        str += '<?' + current.nodeName + current.nodeValue + '>';
+        break;
+      case 4:
+        str += '<![CDATA[ ' + current.nodeValue + ' ]]>';
+        break;
+      case 3:
+        str += '"' + current.nodeValue + '"';
+        if (parent != current.parentNode) {
+          return str += ' (misnested... aborting)';
+        }
+        break;
+      case 1:
+        str += "<";
+        switch (current.namespaceURI) {
+          case "http://www.w3.org/2000/svg":
+            str += "svg ";
+            break;
+          case "http://www.w3.org/1998/Math/MathML":
+            str += "math ";
+            break;
+        }
+        if (current.localName && current.namespaceURI && current.namespaceURI != null) {
+          str += current.localName;
+        } else {
+          str += current.nodeName.toAsciiLowerCase();
+        }
+        str += '>';
+        if (parent != current.parentNode) {
+          return str += ' (misnested... aborting)';
+        } else {
+          if (current.attributes) {
+            var attrNames = [];
+            var attrPos = {};
+            for (var j = 0; j < current.attributes.length; j += 1) {
+              if (current.attributes[j].specified) {
+                var name = "";
+                switch (current.attributes[j].namespaceURI) {
+                  case "http://www.w3.org/XML/1998/namespace":
+                    name += "xml ";
+                    break;
+                  case "http://www.w3.org/2000/xmlns/":
+                    name += "xmlns ";
+                    break;
+                  case "http://www.w3.org/1999/xlink":
+                    name += "xlink ";
+                    break;
+                }
+                if (current.attributes[j].localName) {
+                  name += current.attributes[j].localName;
+                } else {
+                  name += current.attributes[j].nodeName;
+                }
+                attrNames.push(name);
+                attrPos[name] = j;
+              }
+            }
+            if (attrNames.length > 0) {
+              attrNames.sort();
+              for (var j = 0; j < attrNames.length; j += 1) {
+                str += "\n| " + indent(1 + ancestors) + attrNames[j];
+                str += '="' + current.attributes[attrPos[attrNames[j]]].nodeValue + '"';
+              }
+            }
+          }
+          if (next = current.firstChild) {
+            parent = current;
+            current = next;
+            ancestors++;
+            continue;
+          }
+        }
+        break;
+    }
+    for (;;) {
+      if (next = current.nextSibling) {
+        current = next;
+        break;
+      }
+      current = current.parentNode;
+      parent = parent.parentNode;
+      ancestors--;
+      if (current == node) {
+        return str.substring(1);
+      }
+    }
+  }
+}
+</script>
+<script>
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+</script>
+<style>
+.overview:hover {
+background: #ccc;
+}
+iframe {
+display: none;
+}
+</style>
+<p>Script did not run</p>
+<iframe></iframe>
+<script>
+var test_files = [
+        // 'resources/tests1.dat',
+        // 'resources/tests2.dat',
+        // 'resources/tests3.dat',
+        // 'resources/tests4.dat',
+        // 'resources/tests5.dat',
+        // 'resources/tests6.dat',
+        // 'resources/tests7.dat',
+        // 'resources/tests8.dat',
+        // 'resources/tests9.dat',
+        // 'resources/tests10.dat',
+        // 'resources/tests11.dat',
+        // 'resources/tests12.dat',
+        // 'resources/tests14.dat',
+        // 'resources/tests15.dat',
+        // 'resources/tests16.dat',
+        'resources/webkit01.dat',
+        // 'resources/doctype01.dat',
+        // 'resources/scriptdata01.dat',
+        // 'resources/entities01.dat',
+        // 'resources/comments01.dat'
+    ],
+    tests = [],
+    iframe = document.getElementsByTagName("iframe")[0],
+    stat = document.getElementsByTagName("p")[0].firstChild,
+    file = "",
+    test_number = 1,
+    subtest_number = 0,
+    fail_list = [],
+    log = "";
+
+iframe.contentWindow.document.open()
+iframe.contentWindow.document.write("Test");
+iframe.contentWindow.document.close();
+var write = iframe.contentWindow.document.lastChild.lastChild.lastChild !== null;
+var ignoreTitle = iframe.contentWindow.document.getElementsByTagName("title")[0] !== undefined;
+
+window.onload = function()
+{
+    stat.data = "Running";
+    run();
+}
+
+function run()
+{
+    var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
+    if (file = test_files.shift())
+    {
+        stat.data = "Retriving " + file;
+        test_number = 1;
+        fail_list = [];
+        log = "";
+        xhr.open("GET", file);
+        xhr.onreadystatechange = function()
+        {
+            if (xhr.readyState === 4)
+            {
+                tests = xhr.responseText.split(/(?:^|\n\n)#data\n/);
+                tests.shift();
+                test();
+            }
+        }
+        xhr.send(null);
+    }
+}
+
+function test()
+{
+    var input, errorsStart, fragmentStart, contextElement, domStart, dom;
+    if (data = tests.shift())
+    {
+        subtest_number = 0;
+        stat.data = "Running test " + test_number + " of " + (test_number + tests.length) + " in " + file;
+        errorsStart = data.indexOf("\n#errors\n");
+        if (errorsStart !== -1)
+        {
+            input = data.substring(0, errorsStart);
+            fragmentStart = data.indexOf("\n#document-fragment\n")
+            domStart = data.indexOf("\n#document\n")
+            if (fragmentStart !== -1)
+            {
+                contextElement = data.substring(fragmentStart + 20, domStart);
+            }
+            if (domStart !== -1)
+            {
+                dom = data.substring(domStart + 11);
+                if (dom.substring(dom.length - 1) === "\n")
+                {
+                    dom = dom.substring(0, dom.length - 1);
+                }
+                run_test(input, contextElement, dom);
+                return;
+            }
+        }
+        alert("Invalid test: " + data);
+        test();
+        return;
+    }
+    else
+    {
+        stat.data = "Finished running " + file;
+        var overview = document.createElement("p");
+        if (fail_list.length)
+        {
+            overview.innerHTML = file + ":<br>" + fail_list.join("<br>");
+            overview.className = "overview";
+            overview.title = "Click for more details";
+            overview.onclick = function()
+            {
+                this.nextSibling.style.display = this.nextSibling.style.display == "none" ? "block" : "none";
+            }
+            var detail = document.createElement("pre");
+            detail.appendChild(document.createTextNode(log.substring(2)));
+            detail.style.display = "none";
+            document.body.appendChild(overview);
+            document.body.appendChild(detail);
+        }
+        else
+        {
+            overview.innerHTML = file + ": PASS";
+            document.body.appendChild(overview);
+        }
+        stat.data = "";
+        run();
+    }
+}
+
+function run_test(input, contextElement, expected)
+{
+    while (++subtest_number < input.length) {
+        lower_input = input.substring(0, subtest_number);
+        upper_input = input.substring(subtest_number, input.length);
+        if (contextElement)
+        {
+            var element = document.createElement(contextElement);
+            try
+            {
+                element.innerHTML = input;
+            }
+            catch(e) {}
+            process_result(input, element, expected);
+        }
+        else if (write)
+        {
+            iframe.contentWindow.document.open();
+            try
+            {
+                iframe.contentWindow.document.write(lower_input);
+                iframe.contentWindow.document.write(upper_input);
+            }
+            catch(e) {}
+            iframe.contentWindow.document.close();
+            if (ignoreTitle)
+            {
+                var title = iframe.contentWindow.document.getElementsByTagName("title")[0];
+                if (!title.innerHTML)
+                {
+                    title.parentElement.removeChild(title);
+                }
+            }
+            process_result(input, iframe.contentWindow.document, expected);
+        }
+        else
+        {
+            iframe.onload = function()
+            {
+                if (ignoreTitle)
+                {
+                    var title = iframe.contentWindow.document.getElementsByTagName("title")[0];
+                    if (!title.innerHTML)
+                    {
+                        title.parentElement.removeChild(title);
+                    }
+                }
+                process_result(input, iframe.contentWindow.document, expected, true);
+            }
+            iframe.src = "data:text/html," + encodeURIComponent(input);
+            break;
+        }
+    }
+    test();
+}
+
+function process_result(input, result, expected, async)
+{
+    result = dom2string(result);
+    if (result !== expected)
+    {
+        fail_list.push(test_number + "." + subtest_number);
+        log += "\n\nTest " + (test_number) + " of " + (test_number + tests.length) + " in " + file + " failed. Input:\n" + input + "\nGot:\n" + result + "\nExpected:\n" + expected;
+    }
+    test_number++;
+    if (async)
+        test();
+}
+</script>
index c1f0e28..1051605 100644 (file)
@@ -1,3 +1,27 @@
+2010-05-26  Adam Barth  <abarth@webkit.org>
+
+        Reviewed by Eric Seidel.
+
+        Make HTML5 lexer not ASSERT when resuming partial parses
+        https://bugs.webkit.org/show_bug.cgi?id=39755
+
+        I'm working through a variation of the webkit-runner.html test suite
+        that stops the parser at every character to make sure we can resume
+        parsing correctly.  This patch fixes some errors caught by ASSERTs,
+        which prevent the basic tests from running to completion.  There's a
+        bunch more work to do, however.
+
+        Test: html5lib/webkit-resumer.html
+
+        * html/HTML5Lexer.cpp:
+        (WebCore::HTMLNames::isEndTagBufferingState):
+        (WebCore::HTML5Lexer::nextToken):
+        (WebCore::HTML5Lexer::addToPossibleEndTag):
+        * html/HTML5Lexer.h:
+        * html/HTML5Tokenizer.cpp:
+        (WebCore::HTML5Tokenizer::write):
+        * html/HTML5Tokenizer.h:
+
 2010-05-26  Alexey Proskuryakov  <ap@apple.com>
 
         Mac 32 bit build fix.
index e1ae8c9..6d45902 100644 (file)
@@ -111,6 +111,18 @@ void unconsumeCharacters(SegmentedString& source, const Vector<UChar, 10>& consu
         source.prepend(SegmentedString(String(consumedCharacters.data(), consumedCharacters.size())));
 }
 
+inline bool isEndTagBufferingState(HTML5Lexer::State state)
+{
+    return state == HTML5Lexer::RCDATAEndTagOpenState
+        || state == HTML5Lexer::RCDATAEndTagNameState
+        || state == HTML5Lexer::RAWTEXTEndTagOpenState
+        || state == HTML5Lexer::RAWTEXTEndTagNameState
+        || state == HTML5Lexer::ScriptDataEndTagOpenState
+        || state == HTML5Lexer::ScriptDataEndTagNameState
+        || state == HTML5Lexer::ScriptDataEscapedEndTagOpenState
+        || state == HTML5Lexer::ScriptDataEscapedEndTagNameState;
+}
+
 }
 
 HTML5Lexer::HTML5Lexer()
@@ -280,7 +292,7 @@ bool HTML5Lexer::nextToken(SegmentedString& source, HTML5Token& token)
     ASSERT(!m_token || m_token == &token || token.type() == HTML5Token::Uninitialized);
     m_token = &token;
 
-    if (!m_bufferedEndTagName.isEmpty()) {
+    if (!m_bufferedEndTagName.isEmpty() && !isEndTagBufferingState(m_state)) {
         // FIXME: This should call flushBufferedEndTag().
         // We started an end tag during our last iteration.
         m_token->beginEndTag(m_bufferedEndTagName);
@@ -424,11 +436,11 @@ bool HTML5Lexer::nextToken(SegmentedString& source, HTML5Token& token)
         case RCDATAEndTagOpenState: {
             if (cc >= 'A' && cc <= 'Z') {
                 m_temporaryBuffer.append(cc);
-                m_bufferedEndTagName.append(toLowerCase(cc));
+                addToPossibleEndTag(toLowerCase(cc));
                 m_state = RCDATAEndTagNameState;
             } else if (cc >= 'a' && cc <= 'z') {
                 m_temporaryBuffer.append(cc);
-                m_bufferedEndTagName.append(cc);
+                addToPossibleEndTag(cc);
                 m_state = RCDATAEndTagNameState;
             } else {
                 emitCharacter('<');
@@ -441,10 +453,10 @@ bool HTML5Lexer::nextToken(SegmentedString& source, HTML5Token& token)
         case RCDATAEndTagNameState: {
             if (cc >= 'A' && cc <= 'Z') {
                 m_temporaryBuffer.append(cc);
-                m_bufferedEndTagName.append(toLowerCase(cc));
+                addToPossibleEndTag(toLowerCase(cc));
             } else if (cc >= 'a' && cc <= 'z') {
                 m_temporaryBuffer.append(cc);
-                m_bufferedEndTagName.append(cc);
+                addToPossibleEndTag(cc);
             } else {
                 if (cc == '\x09' || cc == '\x0A' || cc == '\x0C' || cc == ' ') {
                     if (isAppropriateEndTag()) {
@@ -489,11 +501,11 @@ bool HTML5Lexer::nextToken(SegmentedString& source, HTML5Token& token)
         case RAWTEXTEndTagOpenState: {
             if (cc >= 'A' && cc <= 'Z') {
                 m_temporaryBuffer.append(cc);
-                m_bufferedEndTagName.append(toLowerCase(cc));
+                addToPossibleEndTag(toLowerCase(cc));
                 m_state = RAWTEXTEndTagNameState;
             } else if (cc >= 'a' && cc <= 'z') {
                 m_temporaryBuffer.append(cc);
-                m_bufferedEndTagName.append(cc);
+                addToPossibleEndTag(cc);
                 m_state = RAWTEXTEndTagNameState;
             } else {
                 emitCharacter('<');
@@ -506,10 +518,10 @@ bool HTML5Lexer::nextToken(SegmentedString& source, HTML5Token& token)
         case RAWTEXTEndTagNameState: {
             if (cc >= 'A' && cc <= 'Z') {
                 m_temporaryBuffer.append(cc);
-                m_bufferedEndTagName.append(toLowerCase(cc));
+                addToPossibleEndTag(toLowerCase(cc));
             } else if (cc >= 'a' && cc <= 'z') {
                 m_temporaryBuffer.append(cc);
-                m_bufferedEndTagName.append(cc);
+                addToPossibleEndTag(cc);
             } else {
                 if (cc == '\x09' || cc == '\x0A' || cc == '\x0C' || cc == ' ') {
                     if (isAppropriateEndTag()) {
@@ -558,11 +570,11 @@ bool HTML5Lexer::nextToken(SegmentedString& source, HTML5Token& token)
         case ScriptDataEndTagOpenState: {
             if (cc >= 'A' && cc <= 'Z') {
                 m_temporaryBuffer.append(cc);
-                m_bufferedEndTagName.append(toLowerCase(cc));
+                addToPossibleEndTag(toLowerCase(cc));
                 m_state = ScriptDataEndTagNameState;
             } else if (cc >= 'a' && cc <= 'z') {
                 m_temporaryBuffer.append(cc);
-                m_bufferedEndTagName.append(cc);
+                addToPossibleEndTag(cc);
                 m_state = ScriptDataEndTagNameState;
             } else {
                 emitCharacter('<');
@@ -575,10 +587,10 @@ bool HTML5Lexer::nextToken(SegmentedString& source, HTML5Token& token)
         case ScriptDataEndTagNameState: {
             if (cc >= 'A' && cc <= 'Z') {
                 m_temporaryBuffer.append(cc);
-                m_bufferedEndTagName.append(toLowerCase(cc));
+                addToPossibleEndTag(toLowerCase(cc));
             } else if (cc >= 'a' && cc <= 'z') {
                 m_temporaryBuffer.append(cc);
-                m_bufferedEndTagName.append(cc);
+                addToPossibleEndTag(cc);
             } else {
                 if (cc == '\x09' || cc == '\x0A' || cc == '\x0C' || cc == ' ') {
                     if (isAppropriateEndTag()) {
@@ -694,11 +706,11 @@ bool HTML5Lexer::nextToken(SegmentedString& source, HTML5Token& token)
         case ScriptDataEscapedEndTagOpenState: {
             if (cc >= 'A' && cc <= 'Z') {
                 m_temporaryBuffer.append(cc);
-                m_bufferedEndTagName.append(toLowerCase(cc));
+                addToPossibleEndTag(toLowerCase(cc));
                 m_state = ScriptDataEscapedEndTagNameState;
             } else if (cc >= 'a' && cc <= 'z') {
                 m_temporaryBuffer.append(cc);
-                m_bufferedEndTagName.append(cc);
+                addToPossibleEndTag(cc);
                 m_state = ScriptDataEscapedEndTagNameState;
             } else {
                 emitCharacter('<');
@@ -711,10 +723,10 @@ bool HTML5Lexer::nextToken(SegmentedString& source, HTML5Token& token)
         case ScriptDataEscapedEndTagNameState: {
             if (cc >= 'A' && cc <= 'Z') {
                 m_temporaryBuffer.append(cc);
-                m_bufferedEndTagName.append(toLowerCase(cc));
+                addToPossibleEndTag(toLowerCase(cc));
             } else if (cc >= 'a' && cc <= 'z') {
                 m_temporaryBuffer.append(cc);
-                m_bufferedEndTagName.append(cc);
+                addToPossibleEndTag(cc);
             } else {
                 if (cc == '\x09' || cc == '\x0A' || cc == '\x0C' || cc == ' ') {
                     if (isAppropriateEndTag()) {
@@ -1459,6 +1471,12 @@ inline bool HTML5Lexer::temporaryBufferIs(const String& expectedString)
     return vectorEqualsString(m_temporaryBuffer, expectedString);
 }
 
+inline void HTML5Lexer::addToPossibleEndTag(UChar cc)
+{
+    ASSERT(isEndTagBufferingState(m_state));
+    m_bufferedEndTagName.append(cc);
+}
+
 inline bool HTML5Lexer::isAppropriateEndTag()
 {
     return vectorEqualsString(m_bufferedEndTagName, m_appropriateEndTagName);
index 4005f90..4224873 100644 (file)
@@ -130,8 +130,12 @@ namespace WebCore {
         UChar consumeEntity(SegmentedString&, bool& notEnoughCharacters);
 
         inline bool temporaryBufferIs(const String&);
-        inline bool isAppropriateEndTag();
 
+        // Sometimes we speculatively consume input characters and we don't
+        // know whether they represent end tags or RCDATA, etc.  These
+        // functions help manage these state.
+        inline void addToPossibleEndTag(UChar cc);
+        inline bool isAppropriateEndTag();
         inline void maybeFlushBufferedEndTag();
         inline void flushBufferedEndTag();
 
index 0b3ba04..f1a9a25 100644 (file)
@@ -27,7 +27,6 @@
 #include "HTML5Tokenizer.h"
 
 #include "HTML5Lexer.h"
-#include "HTML5Token.h"
 #include "HTML5TreeBuilder.h"
 #include "Node.h"
 #include "NotImplemented.h"
@@ -53,11 +52,9 @@ void HTML5Tokenizer::begin()
 void HTML5Tokenizer::write(const SegmentedString& source, bool)
 {
     m_source.append(source);
-
-    HTML5Token token;
-    while (m_lexer->nextToken(m_source, token)) {
-        m_treeBuilder->constructTreeFromToken(token);
-        token.clear();
+    while (m_lexer->nextToken(m_source, m_token)) {
+        m_treeBuilder->constructTreeFromToken(m_token);
+        m_token.clear();
     }
 }
 
index 7d503aa..b390a5b 100644 (file)
@@ -27,6 +27,7 @@
 #define HTML5Tokenizer_h
 
 #include "CachedResourceClient.h"
+#include "HTML5Token.h"
 #include "SegmentedString.h"
 #include "Tokenizer.h"
 #include <wtf/OwnPtr.h>
@@ -58,6 +59,9 @@ public:
 private:
     SegmentedString m_source;
 
+    // We hold m_token here because it might be partially complete.
+    HTML5Token m_token;
+
     OwnPtr<HTML5Lexer> m_lexer;
     OwnPtr<HTML5TreeBuilder> m_treeBuilder;
 };
index dcf21aa..cfe68cd 100644 (file)
@@ -1,3 +1,14 @@
+2010-05-26  Adam Barth  <abarth@webkit.org>
+
+        Reviewed by Eric Seidel.
+
+        Make HTML5 lexer not ASSERT when resuming partial parses
+        https://bugs.webkit.org/show_bug.cgi?id=39755
+
+        Add webkit-resumer.html to the HTML5 parser test suite.
+
+        * Scripts/test-html5-parser:
+
 2010-05-24  Tony Chang  <tony@chromium.org>
 
         Reviewed by Kent Tamura.
index 189bd91..9dc8bad 100755 (executable)
@@ -60,6 +60,7 @@ system("WebKitTools/Scripts/build-dumprendertree", @args) == 0 or die "Failed to
 
 my @tests = (
     "html5lib/webkit-runner",
+    "html5lib/webkit-resumer",
 );
 
 foreach my $test (@tests) {