Thu, 06 Mar 2008 10:25:04 -0800
6668802: javac handles diagnostics for last line badly, if line not terminated by newline
Summary: use CharBuffer.limit(), not the length of the backing array
Reviewed-by: mcimadamore
src/share/classes/com/sun/tools/javac/util/Log.java | file | annotate | diff | comparison | revisions | |
test/tools/javac/T6668802.java | file | annotate | diff | comparison | revisions |
1.1 --- a/src/share/classes/com/sun/tools/javac/util/Log.java Thu Mar 06 10:07:25 2008 -0800 1.2 +++ b/src/share/classes/com/sun/tools/javac/util/Log.java Thu Mar 06 10:25:04 2008 -0800 1.3 @@ -203,6 +203,10 @@ 1.4 */ 1.5 private char[] buf = null; 1.6 1.7 + /** The length of useful data in buf 1.8 + */ 1.9 + private int bufLen = 0; 1.10 + 1.11 /** The position in the buffer at which last error was reported 1.12 */ 1.13 private int bp; 1.14 @@ -256,6 +260,7 @@ 1.15 */ 1.16 protected void setBuf(char[] newBuf) { 1.17 buf = newBuf; 1.18 + bufLen = buf.length; 1.19 bp = 0; 1.20 lineStart = 0; 1.21 line = 1; 1.22 @@ -324,7 +329,7 @@ 1.23 return; 1.24 1.25 int lineEnd = lineStart; 1.26 - while (lineEnd < buf.length && buf[lineEnd] != CR && buf[lineEnd] != LF) 1.27 + while (lineEnd < bufLen && buf[lineEnd] != CR && buf[lineEnd] != LF) 1.28 lineEnd++; 1.29 if (lineEnd - lineStart == 0) 1.30 return; 1.31 @@ -336,12 +341,15 @@ 1.32 writer.flush(); 1.33 } 1.34 1.35 - protected static char[] getCharContent(JavaFileObject fileObject) throws IOException { 1.36 + protected void initBuf(JavaFileObject fileObject) throws IOException { 1.37 CharSequence cs = fileObject.getCharContent(true); 1.38 if (cs instanceof CharBuffer) { 1.39 - return JavacFileManager.toArray((CharBuffer)cs); 1.40 + CharBuffer cb = (CharBuffer) cs; 1.41 + buf = JavacFileManager.toArray(cb); 1.42 + bufLen = cb.limit(); 1.43 } else { 1.44 - return cs.toString().toCharArray(); 1.45 + buf = cs.toString().toCharArray(); 1.46 + bufLen = buf.length; 1.47 } 1.48 } 1.49 1.50 @@ -353,7 +361,7 @@ 1.51 return false; 1.52 try { 1.53 if (buf == null) { 1.54 - buf = getCharContent(currentSource()); 1.55 + initBuf(currentSource()); 1.56 lineStart = 0; 1.57 line = 1; 1.58 } else if (lineStart > pos) { // messages don't come in order 1.59 @@ -361,10 +369,10 @@ 1.60 line = 1; 1.61 } 1.62 bp = lineStart; 1.63 - while (bp < buf.length && bp < pos) { 1.64 + while (bp < bufLen && bp < pos) { 1.65 switch (buf[bp++]) { 1.66 case CR: 1.67 - if (bp < buf.length && buf[bp] == LF) bp++; 1.68 + if (bp < bufLen && buf[bp] == LF) bp++; 1.69 line++; 1.70 lineStart = bp; 1.71 break; 1.72 @@ -374,7 +382,7 @@ 1.73 break; 1.74 } 1.75 } 1.76 - return bp <= buf.length; 1.77 + return bp <= bufLen; 1.78 } catch (IOException e) { 1.79 //e.printStackTrace(); 1.80 // FIXME: include e.getLocalizedMessage() in error message 1.81 @@ -704,7 +712,7 @@ 1.82 if (findLine(pos)) { 1.83 int column = 0; 1.84 for (bp = lineStart; bp < pos; bp++) { 1.85 - if (bp >= buf.length) 1.86 + if (bp >= bufLen) 1.87 return 0; 1.88 if (buf[bp] == '\t') 1.89 column = (column / TabInc * TabInc) + TabInc;
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/test/tools/javac/T6668802.java Thu Mar 06 10:25:04 2008 -0800 2.3 @@ -0,0 +1,79 @@ 2.4 +/* 2.5 + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. 2.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.7 + * 2.8 + * This code is free software; you can redistribute it and/or modify it 2.9 + * under the terms of the GNU General Public License version 2 only, as 2.10 + * published by the Free Software Foundation. Sun designates this 2.11 + * particular file as subject to the "Classpath" exception as provided 2.12 + * by Sun in the LICENSE file that accompanied this code. 2.13 + * 2.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 2.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 2.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 2.17 + * version 2 for more details (a copy is included in the LICENSE file that 2.18 + * accompanied this code). 2.19 + * 2.20 + * You should have received a copy of the GNU General Public License version 2.21 + * 2 along with this work; if not, write to the Free Software Foundation, 2.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2.23 + * 2.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 2.25 + * CA 95054 USA or visit www.sun.com if you need additional information or 2.26 + * have any questions. 2.27 + */ 2.28 + 2.29 +/* 2.30 + * @test 2.31 + * @bug 6668802 2.32 + * @summary javac handles diagnostics for last line badly, if line not terminated by newline 2.33 + */ 2.34 + 2.35 +import java.io.*; 2.36 +import java.util.*; 2.37 + 2.38 +public class T6668802 2.39 +{ 2.40 + public static void main(String[] args) throws Exception { 2.41 + new T6668802().run(); 2.42 + } 2.43 + 2.44 + void run() throws Exception { 2.45 + String test = "public class Test {"; 2.46 + File f = writeTestFile("Test.java", test); 2.47 + String[] out = compileBadFile(f); 2.48 + for (String line: out) 2.49 + System.err.println(">>>" + line + "<<<"); 2.50 + if (!out[1].equals(test)) { 2.51 + show("expected", test); 2.52 + show(" actual", out[1]); 2.53 + throw new Error("test failed"); 2.54 + } 2.55 + } 2.56 + 2.57 + File writeTestFile(String path, String contents) throws IOException { 2.58 + File f = new File(path); 2.59 + FileWriter out = new FileWriter(f); 2.60 + out.write(contents); 2.61 + out.close(); 2.62 + return f; 2.63 + } 2.64 + 2.65 + String[] compileBadFile(File file) throws IOException { 2.66 + List<String> options = new ArrayList<String>(); 2.67 + options.add(file.getPath()); 2.68 + System.err.println("compile: " + options); 2.69 + String[] opts = options.toArray(new String[options.size()]); 2.70 + StringWriter sw = new StringWriter(); 2.71 + PrintWriter out = new PrintWriter(sw); 2.72 + int rc = com.sun.tools.javac.Main.compile(opts, out); 2.73 + if (rc == 0) 2.74 + throw new Error("compilation succeeded unexpectedly"); 2.75 + out.close(); 2.76 + return sw.toString().split("[\n\r]+"); 2.77 + } 2.78 + 2.79 + void show(String prefix, String text) { 2.80 + System.err.println(prefix + ": (" + text.length() + ") " + text); 2.81 + } 2.82 +}