Path: blob/master/test/langtools/tools/javap/BadAttributeLength.java
41144 views
/*1* Copyright (c) 2014, 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 804707226* @summary javap OOM on fuzzed classfile27* @modules jdk.jdeps/com.sun.tools.javap28* @run main BadAttributeLength29*/303132import java.io.*;3334public class BadAttributeLength {3536public static String source = "public class Test {\n" +37" public static void main(String[] args) {}\n" +38"}";3940public static void main(String[] args) throws Exception {41final File sourceFile = new File("Test.java");42if (sourceFile.exists()) {43if (!sourceFile.delete()) {44throw new IOException("Can't override the Test.java file. " +45"Check permissions.");46}47}48try (FileWriter fw = new FileWriter(sourceFile)) {49fw.write(source);50}5152final String[] javacOpts = {"Test.java"};5354if (com.sun.tools.javac.Main.compile(javacOpts) != 0) {55throw new Exception("Can't compile embedded test.");56}5758RandomAccessFile raf = new RandomAccessFile("Test.class", "rw");59long attPos = getFirstAttributePos(raf);60if (attPos < 0) {61throw new Exception("The class file contains no attributes at all.");62}63raf.seek(attPos + 2); // Jump to the attribute length64raf.writeInt(Integer.MAX_VALUE - 1);65raf.close();6667String[] opts = { "-v", "Test.class" };68StringWriter sw = new StringWriter();69PrintWriter pout = new PrintWriter(sw);7071com.sun.tools.javap.Main.run(opts, pout);72pout.flush();7374if (sw.getBuffer().indexOf("OutOfMemoryError") != -1) {75throw new Exception("javap exited with OutOfMemoryError " +76"instead of giving the proper error message.");77}78}7980private static long getFirstAttributePos(RandomAccessFile cfile) throws Exception {81cfile.seek(0);82int v1, v2;83v1 = cfile.readInt();84// System.out.println("Magic: " + String.format("%X", v1));8586v1 = cfile.readUnsignedShort();87v2 = cfile.readUnsignedShort();88// System.out.println("Version: " + String.format("%d.%d", v1, v2));8990v1 = cfile.readUnsignedShort();91// System.out.println("CPool size: " + v1);92// Exhaust the constant pool93for (; v1 > 1; v1--) {94// System.out.print(".");95byte tag = cfile.readByte();96switch (tag) {97case 7 : // Class98case 8 : // String99// Data is 2 bytes long100cfile.skipBytes(2);101break;102case 3 : // Integer103case 4 : // Float104case 9 : // FieldRef105case 10 : // MethodRef106case 11 : // InterfaceMethodRef107case 12 : // Name and Type108// Data is 4 bytes long109cfile.skipBytes(4);110break;111case 5 : // Long112case 6 : // Double113// Data is 8 bytes long114cfile.skipBytes(8);115break;116case 1 : // Utf8117v2 = cfile.readUnsignedShort(); // Read buffer size118cfile.skipBytes(v2); // Skip buffer119break;120default :121throw new Exception("Unexpected tag in CPool: [" + tag + "] at "122+ Long.toHexString(cfile.getFilePointer()));123}124}125// System.out.println();126127cfile.skipBytes(6); // Access flags, this_class and super_class128v1 = cfile.readUnsignedShort(); // Number of interfaces129// System.out.println("Interfaces: " + v1);130cfile.skipBytes(3 * v1); // Each interface_info record is 3 bytes long131v1 = cfile.readUnsignedShort(); // Number of fields132// System.out.println("Fields: " + v1);133// Exhaust the fields table134for (; v1 > 0; v1--) {135// System.out.print(".");136cfile.skipBytes(6); // Skip access_flags, name_index and descriptor_index137v2 = cfile.readUnsignedShort(); // Field attributes count138if (v2 > 0) {139// This field has some attributes - suits our needs140// System.out.println();141return cfile.getFilePointer();142}143}144// System.out.println();145v1 = cfile.readUnsignedShort(); // Number of methods146// System.out.println("Methods: " + v1);147// Exhaust the methods table148for (; v1 > 0; v1--) {149// System.out.print(".");150cfile.skipBytes(6); // Skip access_flags, name_index and descriptor_index151v2 = cfile.readUnsignedShort(); // Method attributes count152if (v2 > 0) {153// This method got attributes - Ok with us,154// return position of the first one155// System.out.println();156return cfile.getFilePointer();157}158}159// System.out.println();160// Class attributes section161v1 = cfile.readUnsignedShort(); // Counts of attributes in class162if (v1 > 0) {163// Class has some attributes, return position of the first one164return cfile.getFilePointer();165}166// Bummer! No attributes in the entire class file. Not fair!167return -1L;168}169}170171172