6227454: package.html and overview.html may not be read fully
authorjjg
Fri, 04 Mar 2011 19:56:02 -0800
changeset 8632 af2a1f02c8ac
parent 8631 664f84942e74
child 8633 41311e88ffb7
6227454: package.html and overview.html may not be read fully Reviewed-by: bpatel
langtools/src/share/classes/com/sun/tools/javadoc/DocImpl.java
langtools/src/share/classes/com/sun/tools/javadoc/resources/javadoc.properties
langtools/test/tools/javadoc/6227454/Test.java
--- a/langtools/src/share/classes/com/sun/tools/javadoc/DocImpl.java	Fri Mar 04 19:53:03 2011 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/DocImpl.java	Fri Mar 04 19:56:02 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, 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
@@ -25,6 +25,7 @@
 
 package com.sun.tools.javadoc;
 
+import java.io.DataInputStream;
 import java.io.InputStream;
 import java.io.IOException;
 import java.text.CollationKey;
@@ -33,6 +34,8 @@
 import com.sun.javadoc.*;
 
 import com.sun.tools.javac.util.Position;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  * abstract base class of all Doc classes.  Doc item's are representations
@@ -166,51 +169,28 @@
      * Utility for subclasses which read HTML documentation files.
      */
     String readHTMLDocumentation(InputStream input, FileObject filename) throws IOException {
-        int filesize = input.available();
-        byte[] filecontents = new byte[filesize];
-        input.read(filecontents, 0, filesize);
-        input.close();
+        byte[] filecontents = new byte[input.available()];
+        try {
+            DataInputStream dataIn = new DataInputStream(input);
+            dataIn.readFully(filecontents);
+        } finally {
+            input.close();
+        }
         String encoding = env.getEncoding();
         String rawDoc = (encoding!=null)
             ? new String(filecontents, encoding)
             : new String(filecontents);
-        String upper = null;
-        int bodyIdx = rawDoc.indexOf("<body");
-        if (bodyIdx == -1) {
-            bodyIdx = rawDoc.indexOf("<BODY");
-            if (bodyIdx == -1) {
-                upper = rawDoc.toUpperCase();
-                bodyIdx = upper.indexOf("<BODY");
-                if (bodyIdx == -1) {
-                    env.error(SourcePositionImpl.make(filename, Position.NOPOS, null),
-                                       "javadoc.Body_missing_from_html_file");
-                    return "";
-                }
-            }
-        }
-        bodyIdx = rawDoc.indexOf('>', bodyIdx);
-        if (bodyIdx == -1) {
-            env.error(SourcePositionImpl.make(filename, Position.NOPOS, null),
-                               "javadoc.Body_missing_from_html_file");
+        Pattern bodyPat = Pattern.compile("(?is).*<body\\b[^>]*>(.*)</body\\b.*");
+        Matcher m = bodyPat.matcher(rawDoc);
+        if (m.matches()) {
+            return m.group(1);
+        } else {
+            String key = rawDoc.matches("(?is).*<body\\b.*")
+                    ? "javadoc.End_body_missing_from_html_file"
+                    : "javadoc.Body_missing_from_html_file";
+            env.error(SourcePositionImpl.make(filename, Position.NOPOS, null), key);
             return "";
         }
-        ++bodyIdx;
-        int endIdx = rawDoc.indexOf("</body", bodyIdx);
-        if (endIdx == -1) {
-            endIdx = rawDoc.indexOf("</BODY", bodyIdx);
-            if (endIdx == -1) {
-                if (upper == null) {
-                    upper = rawDoc.toUpperCase();
-                }
-                endIdx = upper.indexOf("</BODY", bodyIdx);
-                if (endIdx == -1) {
-                    env.error(SourcePositionImpl.make(filename, Position.NOPOS, null),
-                                       "javadoc.End_body_missing_from_html_file");
-                    return "";
-                }
-            }
-        }
-        return rawDoc.substring(bodyIdx, endIdx);
     }
 
     /**
@@ -256,6 +236,7 @@
     /**
      * Returns a string representation of this Doc item.
      */
+    @Override
     public String toString() {
         return qualifiedName();
     }
--- a/langtools/src/share/classes/com/sun/tools/javadoc/resources/javadoc.properties	Fri Mar 04 19:53:03 2011 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/resources/javadoc.properties	Fri Mar 04 19:56:02 2011 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1997, 2011, 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
@@ -104,7 +104,7 @@
 tag.End_delimiter_missing_for_possible_SeeTag=End Delimiter } missing for possible See Tag in comment string: "{0}"
 tag.Improper_Use_Of_Link_Tag=Missing closing ''}'' character for inline tag: "{0}"
 javadoc.File_Read_Error=Error while reading file {0}
-javadoc.Body_missing_from_html_file=Body tag missing from HTML
+javadoc.Body_missing_from_html_file=Body tag missing from HTML file
 javadoc.End_body_missing_from_html_file=Close body tag missing from HTML file
 javadoc.Multiple_package_comments=Multiple sources of package comments found for package "{0}"
 javadoc.class_not_found=Class {0} not found.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javadoc/6227454/Test.java	Fri Mar 04 19:56:02 2011 -0800
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2011, 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 6227454
+ * @summary package.html and overview.html may not be read fully
+ */
+
+import java.io.*;
+
+import com.sun.javadoc.Doclet;
+import com.sun.javadoc.RootDoc;
+
+public class Test extends Doclet {
+    public static void main(String... args) throws Exception {
+        new Test().run();
+    }
+
+    void run() throws Exception {
+        test("<html><body>ABC      XYZ</body></html>");
+        test("<html><body>ABC      XYZ</BODY></html>");
+        test("<html><BODY>ABC      XYZ</body></html>");
+        test("<html><BODY>ABC      XYZ</BODY></html>");
+        test("<html><BoDy>ABC      XYZ</bOdY></html>");
+        test("<html>      ABC      XYZ</bOdY></html>", "Body tag missing from HTML");
+        test("<html><body>ABC      XYZ       </html>", "Close body tag missing from HTML");
+        test("<html>      ABC      XYZ       </html>", "Body tag missing from HTML");
+        test("<html><body>ABC" + bigText(8192, 40) + "XYZ</body></html>");
+
+        if (errors > 0)
+            throw new Exception(errors + " errors occurred");
+    }
+
+    void test(String text) throws IOException {
+        test(text, null);
+    }
+
+    void test(String text, String expectError) throws IOException {
+        testNum++;
+        System.err.println("test " + testNum);
+        File file = writeFile("overview" + testNum + ".html", text);
+        String thisClassName = Test.class.getName();
+        File testSrc = new File(System.getProperty("test.src"));
+        String[] args = {
+            "-bootclasspath",
+                System.getProperty("java.class.path")
+                + File.pathSeparator
+                + System.getProperty("sun.boot.class.path"),
+            "-classpath", ".",
+            "-package",
+            "-overview", file.getPath(),
+            new File(testSrc, thisClassName + ".java").getPath()
+        };
+
+        StringWriter sw = new StringWriter();
+        PrintWriter pw = new PrintWriter(sw);
+        int rc = com.sun.tools.javadoc.Main.execute(
+                "javadoc",
+                pw, pw, pw,
+                thisClassName,
+                args);
+        pw.close();
+        String out = sw.toString();
+        if (!out.isEmpty())
+            System.err.println(out);
+        System.err.println("javadoc exit: rc=" + rc);
+
+        if (expectError == null) {
+            if (rc != 0)
+                error("unexpected exit from javadoc; rc:" + rc);
+        } else {
+            if (!out.contains(expectError))
+                error("expected error text not found: " + expectError);
+        }
+    }
+
+    String bigText(int lines, int lineLength) {
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < lineLength; i++)
+            sb.append(String.valueOf(i % 10));
+        sb.append("\n");
+        String line = sb.toString();
+        sb.setLength(0);
+        for (int i = 0; i < lines; i++)
+            sb.append(line);
+        return sb.toString();
+    }
+
+    File writeFile(String path, String body) throws IOException {
+        File f = new File(path);
+        FileWriter out = new FileWriter(f);
+        try {
+            out.write(body);
+        } finally {
+            out.close();
+        }
+        return f;
+    }
+
+    void error(String msg) {
+        System.err.println("Error: " + msg);
+        errors++;
+    }
+
+    int testNum;
+    int errors;
+
+    public static boolean start(RootDoc root) {
+        String text = root.commentText();
+        if (text.length() < 64)
+            System.err.println("text: '" + text + "'");
+        else
+            System.err.println("text: '"
+                    + text.substring(0, 20)
+                    + "..."
+                    + text.substring(text.length() - 20)
+                    + "'");
+        return text.startsWith("ABC") && text.endsWith("XYZ");
+    }
+}