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