Mercurial > hg > release > icedtea7-forest-2.3 > jdk
changeset 5403:fd2ca62fe5e0
7165725: JAVA6 HTML PARSER CANNOT PARSE MULTIPLE SCRIPT TAGS IN A LINE CORRECTLY
Reviewed-by: alexsch
author | rupashka |
---|---|
date | Fri, 15 Jun 2012 12:19:18 +0400 |
parents | 4d114f6ece0b |
children | 9b727b561f58 |
files | src/share/classes/javax/swing/text/html/parser/Parser.java test/javax/swing/text/html/parser/Parser/7165725/bug7165725.java test/javax/swing/text/html/parser/Parser/7165725/false-text-after-script.html test/javax/swing/text/html/parser/Parser/7165725/successive-script-tag.html |
diffstat | 4 files changed, 335 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/javax/swing/text/html/parser/Parser.java Thu Jun 14 14:43:52 2012 +0400 +++ b/src/share/classes/javax/swing/text/html/parser/Parser.java Fri Jun 15 12:19:18 2012 +0400 @@ -1986,8 +1986,6 @@ if (i == SCRIPT_END_TAG.length) { /* '</script>' tag detected */ - /* Here, ch == '>' */ - ch = readCh(); /* Here, ch == the first character after </script> */ return; } else { @@ -2060,6 +2058,8 @@ handleComment(str.toCharArray()); endTag(false); lastBlockStartPos = currentPosition; + + continue; } else { switch (c) { case '<':
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/swing/text/html/parser/Parser/7165725/bug7165725.java Fri Jun 15 12:19:18 2012 +0400 @@ -0,0 +1,305 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + @bug 7165725 + @summary Tests if HTML parser can handle successive script tags in a line + and it does not call false text callback after script tags. + @run main bug7165725 +*/ + +import sun.awt.SunToolkit; + +import java.awt.BorderLayout; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import javax.swing.*; +import javax.swing.text.AbstractDocument.AbstractElement; +import javax.swing.text.AbstractDocument; +import javax.swing.text.Document; +import javax.swing.text.MutableAttributeSet; +import javax.swing.text.html.HTML; +import javax.swing.text.html.HTMLDocument; +import javax.swing.text.html.HTMLEditorKit; +import javax.swing.text.html.parser.ParserDelegator; + +public class bug7165725 extends JFrame { + private static class GoldenElement { + + private String goldenName; + private List<GoldenElement> goldenChildren; + + GoldenElement(String goldenName, GoldenElement... goldenChildren){ + this.goldenName = goldenName; + if (goldenChildren != null) { + this.goldenChildren = Arrays.asList(goldenChildren); + } else { + this.goldenChildren = new ArrayList<>(); + } + } + + // throws RuntimeException if not ok + public void checkStructureEquivalence(AbstractDocument.AbstractElement elem) { + String name = elem.getName(); + if (!goldenName.equals(name)) { + throw new RuntimeException("Bad structure: expected element name is '" + goldenName + "' but the actual name was '" + name + "'."); + } + int goldenChildCount = goldenChildren.size(); + int childCount = elem.getChildCount(); + if (childCount != goldenChildCount) { + System.out.print("D: children: "); + for (int i = 0; i < childCount; i++) { + System.out.print(" " + elem.getElement(i).getName()); + } + System.out.println(""); + System.out.print("D: goldenChildren: "); + for (GoldenElement ge : goldenChildren) { + System.out.print(" " + ge.goldenName); + } + System.out.println(""); + + throw new RuntimeException("Bad structure: expected child count of element '" + goldenName + "' is '" + goldenChildCount + "' but the actual count was '" + childCount + "'."); + } + for (int i = 0; i < childCount; i++) { + AbstractDocument.AbstractElement nextElem = (AbstractDocument.AbstractElement) elem.getElement(i); + GoldenElement goldenElement = goldenChildren.get(i); + goldenElement.checkStructureEquivalence(nextElem); + } + } + } + + private JEditorPane editorPane; + public void execute(final String urlStr, final GoldenElement goldenElement) throws Exception { + System.out.println(); + System.out.println("***** TEST: " + urlStr + " *****"); + System.out.println(); + + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + try { + editorPane = new JEditorPane(); + editorPane.setEditorKit(new HTMLEditorKit() { + public Document createDefaultDocument() { + AbstractDocument doc = + (AbstractDocument) super.createDefaultDocument(); + doc.setAsynchronousLoadPriority(-1); + return doc; + } + }); + editorPane.setPage(new URL(urlStr)); + } catch (IOException ex) { + throw new RuntimeException("Test failed", ex); + } + editorPane.setEditable(false); + JScrollPane scroller = new JScrollPane(); + JViewport vp = scroller.getViewport(); + vp.add(editorPane); + add(scroller, BorderLayout.CENTER); + setDefaultCloseOperation(EXIT_ON_CLOSE); + setSize(400, 400); + setLocationRelativeTo(null); + setVisible(true); + } + }); + + ((SunToolkit) SunToolkit.getDefaultToolkit()).realSync(); + + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + HTMLDocument doc = (HTMLDocument) editorPane.getDocument(); + doc.dump(System.out); + goldenElement.checkStructureEquivalence((AbstractElement) doc.getDefaultRootElement()); + dispose(); + } + }); + + System.out.println(); + System.out.println("*********************************"); + System.out.println(); + } + + public static void main(String[] args) throws Exception { + + String dirURL = getDirURL(); + + System.out.println("dirURL = " + dirURL); + + new bug7165725().execute(dirURL + "successive-script-tag.html", createSuccessiveScriptTags()); + new bug7165725().execute(dirURL + "false-text-after-script.html", createFalseTextAfterScript()); + + checkByCallbackForSuccessiveScript(); + checkByCallbackForFalseTextAfterScript(); + + System.out.println(); + System.out.println(); + System.out.println("Test passed."); + } + + static String getDirURL() { + return "file:///" + + new File(System.getProperty("test.src", ".")).getAbsolutePath() + + File.separator; + } + + static String getParsedContentOneLine(String path) throws Exception { + File f = new File(path); + FileReader fr = new FileReader(f); + ParserDelegator pd = new ParserDelegator(); + SBParserCallback sbcallback = new SBParserCallback(); + pd.parse(fr, sbcallback, true); + fr.close(); + return sbcallback.getStringOneLine(); + } + + static String getParsedContentOneLine(URL url) throws Exception { + return getParsedContentOneLine(url.getPath()); + } + + static void checkByCallbackForSuccessiveScript() throws Exception { + String content = getParsedContentOneLine(new URL(getDirURL() + "successive-script-tag.html")); + if (!content.matches(".*<script .*/js/js1\\.js.*<script .*/js/js2\\.js.*<script .*/js/js3\\.js.*")) + throw new RuntimeException("Failed to lookup script tags/attributes."); + if (!content.matches(".*<style .*stylesheets/base\\.css.*<style .*stylesheets/adv\\.css.*")) + throw new RuntimeException("Failed to lookup style tags."); + } + + static void checkByCallbackForFalseTextAfterScript() throws Exception { + String content = getParsedContentOneLine(new URL(getDirURL() + "false-text-after-script.html")); + final int bodyIdx = content.indexOf("<body "); + if (bodyIdx > 0) { + String sbody = content.substring(bodyIdx); + // There should be no Text(...) in this html + if (sbody.indexOf("Text(") >= 0) + throw new RuntimeException("Unexpected text found."); + } else { + throw new RuntimeException("Failed to find body tag."); + } + } + + private static GoldenElement createSuccessiveScriptTags() { + return new GoldenElement("html", + new GoldenElement("head", + new GoldenElement("p-implied", + new GoldenElement("title"), + new GoldenElement("title"), + new GoldenElement("script"), + new GoldenElement("comment"), + new GoldenElement("script"), + new GoldenElement("script"), + new GoldenElement("comment"), + new GoldenElement("script"), + new GoldenElement("script"), + new GoldenElement("comment"), + new GoldenElement("script"), + new GoldenElement("content"))), + new GoldenElement("body", + new GoldenElement("p-implied", + new GoldenElement("content")))); + } + + private static GoldenElement createFalseTextAfterScript() { + return new GoldenElement("html", + new GoldenElement("head", + new GoldenElement("p-implied", + new GoldenElement("title"), + new GoldenElement("title"), + new GoldenElement("content"))), + new GoldenElement("body", + new GoldenElement("form", + new GoldenElement("p-implied", + new GoldenElement("input"), + new GoldenElement("input"), + new GoldenElement("content"))), + new GoldenElement("p-implied", + new GoldenElement("script"), + new GoldenElement("comment"), + new GoldenElement("script"), + new GoldenElement("script"), + new GoldenElement("comment"), + new GoldenElement("script"), + new GoldenElement("content")))); + } + + static class SBParserCallback extends HTMLEditorKit.ParserCallback + { + private int indentSize = 0; + private ArrayList<String> elist = new ArrayList<>(); + + public String getStringOneLine() { + StringBuilder sb = new StringBuilder(); + for (String s : elist) sb.append(s); + return sb.toString(); + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + for (String s : elist) sb.append(s + "\n"); + return sb.toString(); + } + + protected void indent() { + indentSize += 3; + } + protected void unIndent() { + indentSize -= 3; if (indentSize < 0) indentSize = 0; + } + + protected String pIndent() { + StringBuilder sb = new StringBuilder(); + for(int i = 0; i < indentSize; i++) sb.append(" "); + return sb.toString(); + } + + public void handleText(char[] data, int pos) { + elist.add(pIndent() + "Text(" + data.length + " chars) \"" + new String(data) + "\""); + } + + public void handleComment(char[] data, int pos) { + elist.add(pIndent() + "Comment(" + data.length + " chars)"); + } + + public void handleStartTag(HTML.Tag t, MutableAttributeSet a, int pos) { + elist.add(pIndent() + "Tag start(<" + t.toString() + " " + a + ">, " + + a.getAttributeCount() + " attrs)"); + indent(); + } + + public void handleEndTag(HTML.Tag t, int pos) { + unIndent(); + elist.add(pIndent() + "Tag end(</" + t.toString() + ">)"); + } + + public void handleSimpleTag(HTML.Tag t, MutableAttributeSet a, int pos) { + elist.add(pIndent() + "Tag(<" + t.toString() + ">, " + + a.getAttributeCount() + " attrs)"); + } + + public void handleError(String errorMsg, int pos){ + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/swing/text/html/parser/Parser/7165725/false-text-after-script.html Fri Jun 15 12:19:18 2012 +0400 @@ -0,0 +1,20 @@ +<html> +<head> <title> Testing </title> </head> +<body> +<form> + + <input type="text" name="text1" > + <input type="button" name="button1" value="button" onclick="test1(this.form)"> + +</form> + +<SCRIPT LANGUAGE="JavaScript"> + function test1(form) { + alert(form.text1.value); + } +</SCRIPT> +<SCRIPT> + history.forward(); +</SCRIPT> +</body> +</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/swing/text/html/parser/Parser/7165725/successive-script-tag.html Fri Jun 15 12:19:18 2012 +0400 @@ -0,0 +1,8 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html> +<head><title>my title</title> + <script src="../../js/js1.js" language="JavaScript"></script><script src="../../js/js2.js" language="JavaScript"></script><script src="../../js/js3.js" language="JavaScript"></script><style type="text/css" media="screen">@import "stylesheets/base.css";</style><style type="text/css" media="screen">@import "stylesheets/adv.css";</style> +</head> +<body> +</body> +</html>