Path: blob/master/test/langtools/tools/javap/T6622260.java
41144 views
/*1* Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 662226026* @summary javap prints negative bytes incorrectly in hex27* @modules jdk.jdeps/com.sun.tools.javap28*/2930import java.io.*;3132public class T6622260 {33public static void main(String[] args) throws Exception {34new T6622260().run();35}3637public void run() throws IOException {38File javaFile = writeTestFile();39File classFile = compileTestFile(javaFile);40modifyClassFile(classFile);41String output = javap(classFile);42verify(output);43}4445File writeTestFile() throws IOException {46File f = new File("Test.java");47PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f)));48out.println("@Deprecated class Test { int f; void m() { } }");49out.close();50return f;51}5253File compileTestFile(File f) {54int rc = com.sun.tools.javac.Main.compile(new String[] { f.getPath() });55if (rc != 0)56throw new Error("compilation failed. rc=" + rc);57String path = f.getPath();58return new File(path.substring(0, path.length() - 5) + ".class");59}6061void modifyClassFile(File f) throws IOException {62String newAttributeName = "NonstandardAttribute";63byte[] newAttributeData = { 0, 1, 2, 127, (byte)128, (byte)129, (byte)254, (byte)255 };6465DataInputStream in = new DataInputStream(new FileInputStream(f));66byte[] data = new byte[(int) f.length()];67in.readFully(data);68in.close();6970in = new DataInputStream(new ByteArrayInputStream(data));71in.skipBytes(4); // magic72in.skipBytes(2); // minor73in.skipBytes(2); // minor7475int constantPoolPos = data.length - in.available();76int constant_pool_count = skipConstantPool(in);7778int flagsPos = data.length - in.available();79in.skipBytes(2); // access_flags80in.skipBytes(2); // this_class81in.skipBytes(2); // super_class8283int interfaces_count = in.readUnsignedShort();84in.skipBytes(interfaces_count * 2);8586int field_count = in.readUnsignedShort();87for (int i = 0; i < field_count; i++) {88in.skipBytes(6); // access_flags, name_index, descriptor_index89skipAttributes(in);90}9192int method_count = in.readUnsignedShort();93for (int i = 0; i < method_count; i++) {94in.skipBytes(6); // access_flags, name_index, descriptor_index95skipAttributes(in);96}9798int classAttributesPos = data.length - in.available();99int attributes_count = in.readUnsignedShort();100101f.renameTo(new File(f.getPath() + ".BAK"));102DataOutputStream out = new DataOutputStream(new FileOutputStream(f));103104// copy head105out.write(data, 0, constantPoolPos);106107// copy constant pool, adding in name of new attribute108out.writeShort(constant_pool_count + 1);109out.write(data, constantPoolPos + 2, flagsPos - constantPoolPos - 2);110out.write(1); // CONSTANT_Utf8111out.writeUTF(newAttributeName);112113// copy flags, class, superclass, interfaces, fields and methods114out.write(data, flagsPos, classAttributesPos - flagsPos);115116// copy class attributes, adding in new attribute117out.writeShort(attributes_count + 1);118out.write(data, classAttributesPos + 2, data.length - classAttributesPos - 2);119out.writeShort(constant_pool_count); // index of new attribute name120out.writeInt(newAttributeData.length);121out.write(newAttributeData);122out.close();123}124125int skipConstantPool(DataInputStream in) throws IOException {126int constant_pool_count = in.readUnsignedShort();127for (int i = 1; i < constant_pool_count; i++) {128int tag = in.readUnsignedByte();129switch (tag) {130case 1: // CONSTANT_Utf8131int length = in.readUnsignedShort();132in.skipBytes(length); // bytes133break;134135case 3: // CONSTANT_Integer136case 4: // CONSTANT_Float137in.skipBytes(4); // bytes138break;139140case 5: // CONSTANT_Long141case 6: // CONSTANT_Double142in.skipBytes(8); // high_bytes, low_bytes143break;144145case 7: // CONSTANT_Class146in.skipBytes(2); // name_index147break;148149case 8: // CONSTANT_String150in.skipBytes(2); // string_index151break;152153case 9: // CONSTANT_FieldRef154case 10: // CONSTANT_Methodref155case 11: // CONSTANT_InterfaceMethodref156in.skipBytes(4); // class_index, name_and_type_index157break;158159case 12: // CONSTANT_NameAndType160in.skipBytes(4); // name_index, descriptor_index161break;162163default:164throw new Error("constant pool tag: " + tag);165}166}167return constant_pool_count;168}169170int skipAttributes(DataInputStream in) throws IOException {171int attributes_count = in.readUnsignedShort();172for (int i = 0; i < attributes_count; i++) {173in.skipBytes(2); // attribute_name_index;174int length = in.readInt();175in.skipBytes(length); // info176}177return attributes_count;178}179180String javap(File f) {181StringWriter sw = new StringWriter();182PrintWriter out = new PrintWriter(sw);183int rc = com.sun.tools.javap.Main.run(new String[] { "-v", f.getPath() }, out);184if (rc != 0)185throw new Error("javap failed. rc=" + rc);186out.close();187return sw.toString();188}189190void verify(String output) {191System.out.println(output);192output = output.substring(output.indexOf("Test.java"));193if (output.indexOf("-") >= 0)194throw new Error("- found in output");195if (output.indexOf("FFFFFF") >= 0)196throw new Error("FFFFFF found in output");197}198}199200201