Bug 21381: Incremental parsing of html causes bogus line numbers in some cases
authoroliver@apple.com <oliver@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 5 Oct 2008 08:28:51 +0000 (08:28 +0000)
committeroliver@apple.com <oliver@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 5 Oct 2008 08:28:51 +0000 (08:28 +0000)
<https://bugs.webkit.org/show_bug.cgi?id=21381>

Reviewed by Tim Hatcher.

If we hit a parsing boundary (end of a packet, etc) in the middle of a
<script> element when we are doing an incremental parse, we exit the
parser, and reenter later when more data is available.  During this
reentry we incorrectly reset the scriptStartLineno to the current line
in the parser, which is now part way through the script element.

The solution is to track whether we are entering or reentering the parsing
of a script element.  We do this simply by 0 checking scriptStartLineno,
and resetting it after we complete parsing of each script element.

Test: http/tests/incremental/pause-in-script-element.pl

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

LayoutTests/ChangeLog
LayoutTests/http/tests/incremental/pause-in-script-element-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/incremental/pause-in-script-element.pl [new file with mode: 0755]
WebCore/ChangeLog
WebCore/html/HTMLTokenizer.cpp

index 4d6fea3..015660e 100644 (file)
@@ -1,3 +1,15 @@
+2008-10-05  Oliver Hunt  <oliver@apple.com>
+
+        Reviewed by Reviewed by Tim Hatcher.
+
+        Bug 21381: Incremental parsing of html causes bogus line numbers in some cases
+        <https://bugs.webkit.org/show_bug.cgi?id=21381>
+
+        Test case for incremental parsing being interrupted midway through a script element.
+
+        * http/tests/incremental/pause-in-script-element-expected.txt: Added.
+        * http/tests/incremental/pause-in-script-element.pl: Added.
+
 2008-10-03  Maciej Stachowiak  <mjs@apple.com>
 
         Reviewed by Cameron Zwarich.
diff --git a/LayoutTests/http/tests/incremental/pause-in-script-element-expected.txt b/LayoutTests/http/tests/incremental/pause-in-script-element-expected.txt
new file mode 100644 (file)
index 0000000..e585662
--- /dev/null
@@ -0,0 +1,5 @@
+Bug 21381: Incremental parsing of html causes bogus line numbers in some cases
+
+This tests that the line numbers associated with a script element are correct, even when parsing is interrupted mid way through the script element
+
+PASS: Got 4006
diff --git a/LayoutTests/http/tests/incremental/pause-in-script-element.pl b/LayoutTests/http/tests/incremental/pause-in-script-element.pl
new file mode 100755 (executable)
index 0000000..2e6b57d
--- /dev/null
@@ -0,0 +1,29 @@
+#!/usr/bin/perl -w
+
+# flush the buffers after each print
+select (STDOUT);
+$| = 1;
+
+print "Content-Type: text/html\n";
+print "Expires: Thu, 01 Dec 2003 16:00:00 GMT\n";
+print "Cache-Control: no-store, no-cache, must-revalidate\n";
+print "Pragma: no-cache\n";
+print "\n";
+
+print "\xef\xbb\xbf<body><p>Bug 21381: Incremental parsing of html causes bogus line numbers in some cases</p>\n";
+print "<p>This tests that the line numbers associated with a script element are correct, even when parsing is ";
+print "interrupted mid way through the script element</p>\n";
+print "<pre id=log></pre>\n";
+print "<script>\n";
+print "if (window.layoutTestController)\n";
+print "    layoutTestController.dumpAsText();\n";
+for ($count=1; $count<4000; $count++) {
+    print "\n";
+}
+print "try { unknownFunction(); } catch(e) { \n";
+print "if (e.line != 4006)\n";
+print "    document.getElementById('log').innerText = 'FAIL: Got ' + e.line + ' expected 4006';\n";
+print "else \n";
+print "    document.getElementById('log').innerText = 'PASS: Got ' + e.line;\n"; 
+print "}\n";
+print "</script>\n";
index 9af8aa1..d5aaf5b 100644 (file)
@@ -1,3 +1,27 @@
+2008-10-04  Oliver Hunt  <oliver@apple.com>
+
+        Reviewed by Tim Hatcher.
+
+        Bug 21381: Incremental parsing of html causes bogus line numbers in some cases
+        <https://bugs.webkit.org/show_bug.cgi?id=21381>
+
+        If we hit a parsing boundary (end of a packet, etc) in the middle of a
+        <script> element when we are doing an incremental parse, we exit the
+        parser, and reenter later when more data is available.  During this
+        reentry we incorrectly reset the scriptStartLineno to the current line
+        in the parser, which is now part way through the script element.
+
+        The solution is to track whether we are entering or reentering the parsing
+        of a script element.  We do this simply by 0 checking scriptStartLineno,
+        and resetting it after we complete parsing of each script element. 
+
+        Test: http/tests/incremental/pause-in-script-element.pl
+
+        * ChangeLog:
+        * html/HTMLTokenizer.cpp:
+        (WebCore::HTMLTokenizer::parseSpecial):
+        (WebCore::HTMLTokenizer::scriptHandler):
+
 2008-10-04  Alp Toker  <alp@nuanti.com>
 
         Reviewed by David Hyatt. Landed by Jan Alonzo.
index 5caaa0d..e20b7b8 100644 (file)
@@ -317,7 +317,7 @@ HTMLTokenizer::State HTMLTokenizer::parseSpecial(SegmentedString &src, State sta
     ASSERT(state.inTextArea() || state.inTitle() || state.inIFrame() || !state.hasEntityState());
     ASSERT(!state.hasTagState());
     ASSERT(state.inXmp() + state.inTextArea() + state.inTitle() + state.inStyle() + state.inScript() + state.inIFrame() == 1 );
-    if (state.inScript())
+    if (state.inScript() && !scriptStartLineno)
         scriptStartLineno = m_lineNumber + 1; // Script line numbers are 1 based.
 
     if (state.inComment()) 
@@ -413,6 +413,10 @@ HTMLTokenizer::State HTMLTokenizer::scriptHandler(State state)
 {
     // We are inside a <script>
     bool doScriptExec = false;
+    int startLine = scriptStartLineno;
+
+    // Reset scriptStartLineno to indicate that we've finished parsing the current script element
+    scriptStartLineno = 0;
 
     // (Bugzilla 3837) Scripts following a frameset element should not execute or, 
     // in the case of extern scripts, even load.
@@ -496,7 +500,7 @@ HTMLTokenizer::State HTMLTokenizer::scriptHandler(State state)
             else
                 prependingSrc = src;
             setSrc(SegmentedString());
-            state = scriptExecution(scriptString, state, String(), scriptStartLineno);
+            state = scriptExecution(scriptString, state, String(), startLine);
         }
     }
 
@@ -522,7 +526,7 @@ HTMLTokenizer::State HTMLTokenizer::scriptHandler(State state)
             write(prependingSrc, false);
             state = m_state;
         }
-    } 
+    }
     
 #if PRELOAD_SCANNER_ENABLED
     if (!pendingScripts.isEmpty() && !m_executingScript) {