1 /* 2 * Copyright (c) 2014, 2016, 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 import java.io.File; 25 import java.io.FileOutputStream; 26 27 import jdk.internal.org.objectweb.asm.ClassWriter; 28 import jdk.internal.org.objectweb.asm.MethodVisitor; 29 import static jdk.internal.org.objectweb.asm.Opcodes.*; 30 31 import jdk.test.lib.process.ProcessTools; 32 import jdk.test.lib.process.OutputAnalyzer; 33 34 /* 35 * @test 36 * @summary Test that anewarray bytecode is valid only if it specifies 255 or fewer dimensions. 37 * @library /test/lib 38 * @modules java.base/jdk.internal.org.objectweb.asm 39 * java.base/jdk.internal.misc 40 * java.management 41 * @compile -XDignore.symbol.file TestANewArray.java 42 * @run main/othervm TestANewArray 49 43 * @run main/othervm TestANewArray 50 44 * @run main/othervm TestANewArray 51 45 * @run main/othervm TestANewArray 52 46 */ 47 48 /* 49 * Testing anewarray instruction with 254, 255 & 264 dimensions to verify JVMS 8, 50 * Section 4.9.1, Static Constraints that states the following: 51 * 52 * "No anewarray instruction may be used to create an array of more than 255 dimensions." 53 * 54 */ 55 56 public class TestANewArray { 57 58 static String classCName = null; // the generated class name 59 60 static final int test_Dimension_254 = 254; // should always pass 61 static final int test_Dimension_255 = 255; // should always pass, except for cfv 49 62 static final int test_Dimension_264 = 264; // should always fail 63 64 static final String array_Dimension_254 = genArrayDim(test_Dimension_254); 65 static final String array_Dimension_255 = genArrayDim(test_Dimension_255); 66 static final String array_Dimension_264 = genArrayDim(test_Dimension_264); 67 68 public static void main(String... args) throws Exception { 69 int cfv = Integer.parseInt(args[0]); 70 71 // 254 array dimensions 72 byte[] classFile_254 = dumpClassFile(cfv, test_Dimension_254, array_Dimension_254); 73 writeClassFileFromByteArray(classFile_254); 74 System.err.println("Running with cfv: " + cfv + ", test_Dimension_254"); 75 ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, "-verify", "-cp", ".", classCName); 76 OutputAnalyzer output = new OutputAnalyzer(pb.start()); 77 output.shouldNotContain("java.lang.VerifyError"); 78 output.shouldHaveExitValue(0); 79 80 // 255 array dimensions 81 byte[] classFile_255 = dumpClassFile(cfv, test_Dimension_255, array_Dimension_255); 82 writeClassFileFromByteArray(classFile_255); 83 System.err.println("Running with cfv: " + cfv + ", test_Dimension_255"); 84 pb = ProcessTools.createJavaProcessBuilder(true, "-verify", "-cp", ".", classCName); 85 output = new OutputAnalyzer(pb.start()); 86 if (cfv == 49) { 87 // The type-inferencing verifier used for <=49.0 ClassFiles detects an anewarray instruction 88 // with exactly 255 dimensions and incorrectly issues the "Array with too many dimensions" VerifyError. 89 output.shouldContain("Array with too many dimensions"); 90 output.shouldHaveExitValue(1); 91 } else { 92 // 255 dimensions should always pass, except for cfv 49 93 output.shouldNotContain("java.lang.VerifyError"); 94 output.shouldNotContain("java.lang.ClassFormatError"); 95 output.shouldHaveExitValue(0); 96 } 97 98 // 264 array dimensions 99 byte[] classFile_264 = dumpClassFile(cfv, test_Dimension_264, array_Dimension_264); 100 writeClassFileFromByteArray(classFile_264); 101 System.err.println("Running with cfv: " + cfv + ", test_Dimension_264"); 102 pb = ProcessTools.createJavaProcessBuilder(true, "-verify", "-cp", ".", classCName); 103 output = new OutputAnalyzer(pb.start()); 104 output.shouldContain("java.lang.ClassFormatError"); 105 output.shouldHaveExitValue(1); 106 } 107 108 public static byte[] dumpClassFile(int cfv, int testDimension264, String arrayDim) throws Exception { 109 ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); 110 MethodVisitor mv; 111 112 classCName = "classCName_" + cfv + "_" + testDimension264; 113 114 cw.visit(cfv, ACC_PUBLIC + ACC_SUPER, classCName, null, "java/lang/Object", null); 115 { 116 mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); | 1 /* 2 * Copyright (c) 2014, 2017, 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 import java.io.File; 25 import java.io.FileOutputStream; 26 27 import jdk.internal.org.objectweb.asm.ClassWriter; 28 import jdk.internal.org.objectweb.asm.MethodVisitor; 29 import static jdk.internal.org.objectweb.asm.Opcodes.*; 30 31 import jdk.test.lib.process.ProcessTools; 32 import jdk.test.lib.process.OutputAnalyzer; 33 34 /* 35 * @test 36 * @summary Test that anewarray bytecode is valid only if it specifies 254 or fewer dimensions. 37 * 255 is invalid because the anewarray would then create an array with 256 dimensions. 38 * @library /test/lib 39 * @modules java.base/jdk.internal.org.objectweb.asm 40 * @compile -XDignore.symbol.file TestANewArray.java 41 * @run main/othervm TestANewArray 49 42 * @run main/othervm TestANewArray 52 43 */ 44 45 /* 46 * Testing anewarray instruction with 254, 255 & 264 dimensions to verify JVM Spec 47 * Section 4.9.1, Static Constraints that states the following: 48 * 49 * "No anewarray instruction may be used to create an array of more than 255 dimensions." 50 * 51 */ 52 53 public class TestANewArray { 54 55 static String classCName = null; // the generated class name 56 57 static final int test_Dimension_254 = 254; // should always pass 58 static final int test_Dimension_255 = 255; // should always pass, except for cfv 49 59 static final int test_Dimension_264 = 264; // should always fail 60 61 static final String array_Dimension_254 = genArrayDim(test_Dimension_254); 62 static final String array_Dimension_255 = genArrayDim(test_Dimension_255); 63 static final String array_Dimension_264 = genArrayDim(test_Dimension_264); 64 65 public static void main(String... args) throws Exception { 66 int cfv = Integer.parseInt(args[0]); 67 68 // 254 array dimensions 69 byte[] classFile_254 = dumpClassFile(cfv, test_Dimension_254, array_Dimension_254); 70 writeClassFileFromByteArray(classFile_254); 71 System.err.println("Running with cfv: " + cfv + ", test_Dimension_254"); 72 ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, "-verify", "-cp", ".", classCName); 73 OutputAnalyzer output = new OutputAnalyzer(pb.start()); 74 output.shouldNotContain("java.lang.VerifyError"); 75 output.shouldHaveExitValue(0); 76 77 // 255 array dimensions 78 byte[] classFile_255 = dumpClassFile(cfv, test_Dimension_255, array_Dimension_255); 79 writeClassFileFromByteArray(classFile_255); 80 System.err.println("Running with cfv: " + cfv + ", test_Dimension_255"); 81 pb = ProcessTools.createJavaProcessBuilder(true, "-verify", "-cp", ".", classCName); 82 output = new OutputAnalyzer(pb.start()); 83 // If anewarray has an operand with 255 array dimensions then VerifyError should 84 // be thrown because the resulting array would have 256 dimensions. 85 output.shouldContain("java.lang.VerifyError"); 86 // VerifyError exception messages differ between verifiers. 87 if (cfv == 49) { 88 output.shouldContain("Array with too many dimensions"); 89 } else { 90 output.shouldContain("Illegal anewarray instruction, array has more than 255 dimensions"); 91 } 92 output.shouldHaveExitValue(1); 93 94 // 264 array dimensions 95 byte[] classFile_264 = dumpClassFile(cfv, test_Dimension_264, array_Dimension_264); 96 writeClassFileFromByteArray(classFile_264); 97 System.err.println("Running with cfv: " + cfv + ", test_Dimension_264"); 98 pb = ProcessTools.createJavaProcessBuilder(true, "-verify", "-cp", ".", classCName); 99 output = new OutputAnalyzer(pb.start()); 100 output.shouldContain("java.lang.ClassFormatError"); 101 output.shouldHaveExitValue(1); 102 } 103 104 public static byte[] dumpClassFile(int cfv, int testDimension264, String arrayDim) throws Exception { 105 ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); 106 MethodVisitor mv; 107 108 classCName = "classCName_" + cfv + "_" + testDimension264; 109 110 cw.visit(cfv, ACC_PUBLIC + ACC_SUPER, classCName, null, "java/lang/Object", null); 111 { 112 mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); |