1 /*
2  * Copyright (c) 2007, 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 /**
26  * @test
27 
28  * @bug 6490436
29  * @summary Verify that protected constructor calls are not allowed for classfile version >= 50 (but that they are allowed for lesser versions).
30  * @author Keith McGuigan
31  */
32 
33 public class VerifyProtectedConstructor extends ClassLoader {
main(String argv[])34   public static void main(String argv[]) throws Exception {
35     VerifyProtectedConstructor t = new VerifyProtectedConstructor();
36 
37     t.loadSuperClass();
38 
39     try {
40       t.checkClassVersion(49); // should not throw VerifyError
41     }
42     catch(VerifyError e) {
43        throw new Exception("FAIL: should be no VerifyError for CF version 49");
44     }
45 
46     try {
47       t.checkClassVersion(50); // should throw VerifyError
48       throw new Exception("FAIL: should be a VerifyError for CF version 50");
49     }
50     catch(VerifyError e) {
51        System.out.println("PASS");
52     }
53   }
54 
loadSuperClass()55   private void loadSuperClass() {
56     /* -- code for super class A.A --
57        package A;
58        public class A {
59          protected A() {}
60        }
61     */
62     long[] cls_data = {
63       0xcafebabe00000032L, 0x000a0a0003000707L,
64       0x0008070009010006L, 0x3c696e69743e0100L,
65       0x0328295601000443L, 0x6f64650c00040005L,
66       0x010003412f410100L, 0x106a6176612f6c61L,
67       0x6e672f4f626a6563L, 0x7400210002000300L,
68       0x0000000001000400L, 0x0400050001000600L,
69       0x0000110001000100L, 0x0000052ab70001b1L,
70       0x0000000000000000L // 2 bytes extra
71     };
72     final int EXTRA = 2;
73     byte cf_bytes[] = toByteArray(cls_data);
74     defineClass("A.A", cf_bytes, 0, cf_bytes.length - EXTRA);
75   }
76 
77   private int num_calls;
78   private static String classNames[] = { "B.B", "C.C" };
79 
checkClassVersion(int version)80   private void checkClassVersion(int version) throws VerifyError {
81     // This class is in violation of the spec since it accesses
82     // a protected constructor of a superclass while not being in the
83     // same package.
84     /* -- code for test class --
85         package B;
86         public class B extends A.A {
87           public static void f() { new A.A(); }
88         }
89     */
90     long[] cls_data = {
91       0xcafebabe00000032L, 0x000b0a0002000807L,
92       0x000907000a010006L, 0x3c696e69743e0100L,
93       0x0328295601000443L, 0x6f6465010001660cL,
94       0x0004000501000341L, 0x2f41010003422f42L,
95       0x0021000300020000L, 0x0000000200010004L,
96       0x0005000100060000L, 0x0011000100010000L,
97       0x00052ab70001b100L, 0x0000000009000700L,
98       0x0500010006000000L, 0x1500020000000000L,
99       0x09bb000259b70001L, 0x57b1000000000000L // no extra bytes
100     };
101     final int EXTRA = 0;
102 
103     byte cf_bytes[] = toByteArray(cls_data);
104 
105     // set version
106     cf_bytes[7] = (byte)version;
107 
108     // Change B.B to C.C, D.D, ... for subsequent calls so we can call this
109     // multiple times and define different classes.
110     cf_bytes[61] += num_calls;
111     cf_bytes[63] += num_calls;
112     String name = classNames[num_calls];
113     num_calls++;
114 
115     Class c = defineClass(name, cf_bytes, 0, cf_bytes.length - EXTRA);
116 
117     try { c.newInstance(); } // to force linking, thus verification
118     catch(InstantiationException e) {}
119     catch(IllegalAccessException e) {}
120   }
121 
toByteArray(long arr[])122   static private byte[] toByteArray(long arr[]) {
123     // convert long array to byte array
124     java.nio.ByteBuffer bbuf = java.nio.ByteBuffer.allocate(arr.length * 8);
125     bbuf.asLongBuffer().put(java.nio.LongBuffer.wrap(arr));
126     return bbuf.array();
127   }
128 }
129