1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/test/tools/javap/T6622260.java Tue Jun 03 13:26:47 2008 -0700 1.3 @@ -0,0 +1,197 @@ 1.4 +/* 1.5 + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 1.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 1.24 + * have any questions. 1.25 + */ 1.26 + 1.27 +/* 1.28 + * @test 1.29 + * @bug 6622260 1.30 + * @summary javap prints negative bytes incorrectly in hex 1.31 + */ 1.32 + 1.33 +import java.io.*; 1.34 + 1.35 +public class T6622260 { 1.36 + public static void main(String[] args) throws Exception { 1.37 + new T6622260().run(); 1.38 + } 1.39 + 1.40 + public void run() throws IOException { 1.41 + File javaFile = writeTestFile(); 1.42 + File classFile = compileTestFile(javaFile); 1.43 + modifyClassFile(classFile); 1.44 + String output = javap(classFile); 1.45 + verify(output); 1.46 + } 1.47 + 1.48 + File writeTestFile() throws IOException { 1.49 + File f = new File("Test.java"); 1.50 + PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f))); 1.51 + out.println("@Deprecated class Test { int f; void m() { } }"); 1.52 + out.close(); 1.53 + return f; 1.54 + } 1.55 + 1.56 + File compileTestFile(File f) { 1.57 + int rc = com.sun.tools.javac.Main.compile(new String[] { f.getPath() }); 1.58 + if (rc != 0) 1.59 + throw new Error("compilation failed. rc=" + rc); 1.60 + String path = f.getPath(); 1.61 + return new File(path.substring(0, path.length() - 5) + ".class"); 1.62 + } 1.63 + 1.64 + void modifyClassFile(File f) throws IOException { 1.65 + String newAttributeName = "NonstandardAttribute"; 1.66 + byte[] newAttributeData = { 0, 1, 2, 127, (byte)128, (byte)129, (byte)254, (byte)255 }; 1.67 + 1.68 + DataInputStream in = new DataInputStream(new FileInputStream(f)); 1.69 + byte[] data = new byte[(int) f.length()]; 1.70 + in.readFully(data); 1.71 + in.close(); 1.72 + 1.73 + in = new DataInputStream(new ByteArrayInputStream(data)); 1.74 + in.skipBytes(4); // magic 1.75 + in.skipBytes(2); // minor 1.76 + in.skipBytes(2); // minor 1.77 + 1.78 + int constantPoolPos = data.length - in.available(); 1.79 + int constant_pool_count = skipConstantPool(in); 1.80 + 1.81 + int flagsPos = data.length - in.available(); 1.82 + in.skipBytes(2); // access_flags 1.83 + in.skipBytes(2); // this_class 1.84 + in.skipBytes(2); // super_class 1.85 + 1.86 + int interfaces_count = in.readUnsignedShort(); 1.87 + in.skipBytes(interfaces_count * 2); 1.88 + 1.89 + int field_count = in.readUnsignedShort(); 1.90 + for (int i = 0; i < field_count; i++) { 1.91 + in.skipBytes(6); // access_flags, name_index, descriptor_index 1.92 + skipAttributes(in); 1.93 + } 1.94 + 1.95 + int method_count = in.readUnsignedShort(); 1.96 + for (int i = 0; i < method_count; i++) { 1.97 + in.skipBytes(6); // access_flags, name_index, descriptor_index 1.98 + skipAttributes(in); 1.99 + } 1.100 + 1.101 + int classAttributesPos = data.length - in.available(); 1.102 + int attributes_count = in.readUnsignedShort(); 1.103 + 1.104 + f.renameTo(new File(f.getPath() + ".BAK")); 1.105 + DataOutputStream out = new DataOutputStream(new FileOutputStream(f)); 1.106 + 1.107 + // copy head 1.108 + out.write(data, 0, constantPoolPos); 1.109 + 1.110 + // copy constant pool, adding in name of new attribute 1.111 + out.writeShort(constant_pool_count + 1); 1.112 + out.write(data, constantPoolPos + 2, flagsPos - constantPoolPos - 2); 1.113 + out.write(1); // CONSTANT_Utf8 1.114 + out.writeUTF(newAttributeName); 1.115 + 1.116 + // copy flags, class, superclass, interfaces, fields and methods 1.117 + out.write(data, flagsPos, classAttributesPos - flagsPos); 1.118 + 1.119 + // copy class attributes, adding in new attribute 1.120 + out.writeShort(attributes_count + 1); 1.121 + out.write(data, classAttributesPos + 2, data.length - classAttributesPos - 2); 1.122 + out.writeShort(constant_pool_count); // index of new attribute name 1.123 + out.writeInt(newAttributeData.length); 1.124 + out.write(newAttributeData); 1.125 + out.close(); 1.126 + } 1.127 + 1.128 + int skipConstantPool(DataInputStream in) throws IOException { 1.129 + int constant_pool_count = in.readUnsignedShort(); 1.130 + for (int i = 1; i < constant_pool_count; i++) { 1.131 + int tag = in.readUnsignedByte(); 1.132 + switch (tag) { 1.133 + case 1: // CONSTANT_Utf8 1.134 + int length = in.readUnsignedShort(); 1.135 + in.skipBytes(length); // bytes 1.136 + break; 1.137 + 1.138 + case 3: // CONSTANT_Integer 1.139 + case 4: // CONSTANT_Float 1.140 + in.skipBytes(4); // bytes 1.141 + break; 1.142 + 1.143 + case 5: // CONSTANT_Long 1.144 + case 6: // CONSTANT_Double 1.145 + in.skipBytes(8); // high_bytes, low_bytes 1.146 + break; 1.147 + 1.148 + case 7: // CONSTANT_Class 1.149 + in.skipBytes(2); // name_index 1.150 + break; 1.151 + 1.152 + case 8: // CONSTANT_String 1.153 + in.skipBytes(2); // string_index 1.154 + break; 1.155 + 1.156 + case 9: // CONSTANT_FieldRef 1.157 + case 10: // CONSTANT_Methodref 1.158 + case 11: // CONSTANT_InterfaceMethodref 1.159 + in.skipBytes(4); // class_index, name_and_type_index 1.160 + break; 1.161 + 1.162 + case 12: // CONSTANT_NameAndType 1.163 + in.skipBytes(4); // name_index, descriptor_index 1.164 + break; 1.165 + 1.166 + default: 1.167 + throw new Error("constant pool tag: " + tag); 1.168 + } 1.169 + } 1.170 + return constant_pool_count; 1.171 + } 1.172 + 1.173 + int skipAttributes(DataInputStream in) throws IOException { 1.174 + int attributes_count = in.readUnsignedShort(); 1.175 + for (int i = 0; i < attributes_count; i++) { 1.176 + in.skipBytes(2); // attribute_name_index; 1.177 + int length = in.readInt(); 1.178 + in.skipBytes(length); // info 1.179 + } 1.180 + return attributes_count; 1.181 + } 1.182 + 1.183 + String javap(File f) { 1.184 + StringWriter sw = new StringWriter(); 1.185 + PrintWriter out = new PrintWriter(sw); 1.186 + int rc = com.sun.tools.javap.Main.run(new String[] { "-v", f.getPath() }, out); 1.187 + if (rc != 0) 1.188 + throw new Error("javap failed. rc=" + rc); 1.189 + out.close(); 1.190 + return sw.toString(); 1.191 + } 1.192 + 1.193 + void verify(String output) { 1.194 + System.out.println(output); 1.195 + if (output.indexOf("-") >= 0) 1.196 + throw new Error("- found in output"); 1.197 + if (output.indexOf("FFFFFF") >= 0) 1.198 + throw new Error("FFFFFF found in output"); 1.199 + } 1.200 +}