1 /* 2 * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 8234687 27 * @summary change javap reporting on unknown attributes 28 * @modules jdk.jdeps/com.sun.tools.javap 29 * @run main BadAttributeName 30 */ 31 32 33 import java.io.*; 34 import java.nio.file.*; 35 36 public class BadAttributeName { 37 38 public static String source = "public class Test {\n" + 39 " public static void main(String[] args) {}\n" + 40 "}"; 41 main(String[] args)42 public static void main(String[] args) throws Exception { 43 final File srcFile = new File("Test.java"); 44 Files.writeString(Path.of("Test.java"), source); 45 46 final String[] javacOpts = {"Test.java"}; 47 48 if (com.sun.tools.javac.Main.compile(javacOpts) != 0) { 49 throw new Exception("Can't compile embedded test."); 50 } 51 52 RandomAccessFile raf = new RandomAccessFile("Test.class", "rw"); 53 String sourceFile = "SourceFile"; 54 long namePos = getConstantPoolUTF8Pos(raf, sourceFile); 55 if (namePos < 0) { 56 throw new Exception("The class file contains no SourceFile attribute."); 57 } 58 59 raf.seek(namePos); // Jump to the SourceFile name 60 // Create a "custom" attribute by reusing/renaming an unimportant existing one 61 String customAttr = "CustomAttribute".substring(0, sourceFile.length()); 62 raf.writeUTF(customAttr); 63 raf.close(); 64 65 String[] opts = { "-v", "Test.class" }; 66 StringWriter sw = new StringWriter(); 67 PrintWriter pout = new PrintWriter(sw); 68 69 com.sun.tools.javap.Main.run(opts, pout); 70 pout.flush(); 71 72 String expect = customAttr + ": length = 0x2 (unknown attribute)"; 73 if (sw.toString().indexOf(expect) == -1) { 74 sw.toString().lines().forEach(System.out::println); 75 throw new Exception("expected text not found: " + expect); 76 } 77 } 78 getConstantPoolUTF8Pos(RandomAccessFile cfile, String name)79 private static long getConstantPoolUTF8Pos(RandomAccessFile cfile, String name) throws Exception { 80 cfile.seek(0); 81 int v1, v2; 82 v1 = cfile.readInt(); 83 // System.out.println("Magic: " + String.format("%X", v1)); 84 85 v1 = cfile.readUnsignedShort(); 86 v2 = cfile.readUnsignedShort(); 87 // System.out.println("Version: " + String.format("%d.%d", v1, v2)); 88 89 v1 = cfile.readUnsignedShort(); 90 // System.out.println("CPool size: " + v1); 91 // Exhaust the constant pool 92 for (; v1 > 1; v1--) { 93 // System.out.print("."); 94 byte tag = cfile.readByte(); 95 switch (tag) { 96 case 7 : // Class 97 case 8 : // String 98 // Data is 2 bytes long 99 cfile.skipBytes(2); 100 break; 101 case 3 : // Integer 102 case 4 : // Float 103 case 9 : // FieldRef 104 case 10 : // MethodRef 105 case 11 : // InterfaceMethodRef 106 case 12 : // Name and Type 107 // Data is 4 bytes long 108 cfile.skipBytes(4); 109 break; 110 case 5 : // Long 111 case 6 : // Double 112 // Data is 8 bytes long 113 cfile.skipBytes(8); 114 break; 115 case 1 : // Utf8 116 long fp = cfile.getFilePointer(); 117 String s = cfile.readUTF(); 118 if (s.equals(name)) { 119 return fp; 120 } 121 break; 122 default : 123 throw new Exception("Unexpected tag in CPool: [" + tag + "] at " 124 + Long.toHexString(cfile.getFilePointer())); 125 } 126 } 127 // System.out.println(); 128 129 // Bummer! Name not found! 130 return -1L; 131 } 132 } 133