1 /* 2 * Copyright (c) 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 /* 27 * @test 28 * @bug 8157246 29 * @run testng/othervm test.java.lang.invoke.InvokeMethodHandleWithBadArgument 30 */ 31 32 package test.java.lang.invoke; 33 34 import java.lang.invoke.MethodHandle; 35 import java.lang.invoke.MethodHandles; 36 import java.lang.invoke.MethodHandles.Lookup; 37 import java.lang.invoke.MethodType; 38 import java.lang.invoke.VarHandle; 39 40 import static java.lang.invoke.MethodType.methodType; 41 42 import static org.testng.AssertJUnit.*; 43 44 import org.testng.annotations.*; 45 46 /** 47 * Tests invocation of MethodHandle with invalid leading argument such as 48 * MethodHandle, VarHandle, and array object 49 */ 50 public class InvokeMethodHandleWithBadArgument { 51 // ---- null array reference ---- 52 53 @Test(expectedExceptions = {NullPointerException.class}) 54 public static void testAsSpreaderPosInvokeWithNull() throws Throwable { 55 MethodHandle spreader = MH_spread.asSpreader(1, int[].class, 3); 56 spreader.invoke("A", null, "B"); 57 } 58 59 @Test(expectedExceptions = {NullPointerException.class}) 60 public static void testAsSpreaderInvokeWithNull() throws Throwable { 61 MethodHandle spreader = MH_String_equals.asSpreader(String[].class, 2); 62 assert ((boolean) spreader.invokeExact(new String[]{"me", "me"})); 63 boolean eq = (boolean) spreader.invokeExact((String[]) null); 64 } 65 66 // ---- incorrect array element count ---- 67 @Test(expectedExceptions = {IllegalArgumentException.class}) 68 public static void testAsSpreaderPosInvokeWithBadElementCount() throws Throwable { 69 MethodHandle spreader = MH_spread.asSpreader(1, int[].class, 3); 70 spreader.invoke("A", new int[]{1, 2}, "B"); 71 } 72 73 @Test(expectedExceptions = {IllegalArgumentException.class}) 74 public static void testAsSpreaderInvokeWithBadElementCount() throws Throwable { 75 MethodHandle spreader = MH_String_equals.asSpreader(String[].class, 2); 76 assert (!(boolean) spreader.invokeExact(new String[]{"me", "thee"})); 77 boolean eq = (boolean) spreader.invokeExact(new String[0]); 78 } 79 80 // ---- spread no argument ---- 81 @Test 82 public static void testAsSpreaderPosInvokeWithZeroLength() throws Throwable { 83 MethodHandle spreader = MH_spread.asSpreader(1, int[].class, 0); 84 assert("A123B".equals(spreader.invoke("A", (int[])null, 1, 2, 3, "B"))); 85 } 86 87 @Test 88 public static void testAsSpreaderInvokeWithZeroLength() throws Throwable { 89 MethodHandle spreader = MH_String_equals.asSpreader(String[].class, 0); 90 assert ((boolean) spreader.invokeExact("me", "me", new String[0])); 91 boolean eq = (boolean) spreader.invokeExact("me", (Object)"me", (String[]) null); 92 } 93 94 // ---- invokers with null method/var handle argument ---- 95 @Test(expectedExceptions = {NullPointerException.class}) 96 public static void testInvokerWithNull() throws Throwable { 97 MethodType type = methodType(int.class, int.class, int.class); 98 MethodHandle invoker = MethodHandles.invoker(type); 99 assert((int) invoker.invoke(MH_add, 1, 2) == 3); 100 int sum = (int)invoker.invoke((MethodHandle)null, 1, 2); 101 } 102 103 @Test(expectedExceptions = {NullPointerException.class}) 104 public static void testExactInvokerWithNull() throws Throwable { 105 MethodType type = methodType(int.class, int.class, int.class); 106 MethodHandle invoker = MethodHandles.exactInvoker(type); 107 assert((int) invoker.invoke(MH_add, 1, 2) == 3); 108 int sum = (int)invoker.invokeExact((MethodHandle)null, 1, 2); 109 } 110 111 @Test(expectedExceptions = {NullPointerException.class}) 112 public static void testSpreadInvokerWithNull() throws Throwable { 113 MethodType type = methodType(boolean.class, String.class, String.class); 114 MethodHandle invoker = MethodHandles.spreadInvoker(type, 0); 115 assert ((boolean) invoker.invoke(MH_spread, new String[]{"me", "me"})); 116 boolean eq = (boolean) invoker.invoke((MethodHandle)null, new String[]{"me", "me"}); 117 } 118 119 @Test(expectedExceptions = {NullPointerException.class}) 120 public static void testVarHandleInvokerWithNull() throws Throwable { 121 VarHandle.AccessMode am = VarHandle.AccessMode.GET; 122 MethodHandle invoker = MethodHandles.varHandleInvoker(am, VH_array.accessModeType(am)); 123 assert ((int) invoker.invoke(VH_array, array, 3) == 3); 124 int value = (int)invoker.invoke((VarHandle)null, array, 3); 125 } 126 127 @Test(expectedExceptions = {NullPointerException.class}) 128 public static void testVarHandleExactInvokerWithNull() throws Throwable { 129 VarHandle.AccessMode am = VarHandle.AccessMode.GET; 130 MethodHandle invoker = MethodHandles.varHandleExactInvoker(am, VH_array.accessModeType(am)); 131 assert ((int) invoker.invoke(VH_array, array, 3) == 3); 132 int value = (int)invoker.invokeExact((VarHandle)null, array, 3); 133 } 134 135 static final Lookup LOOKUP = MethodHandles.lookup(); 136 static final MethodHandle MH_add; 137 static final MethodHandle MH_spread; 138 static final MethodHandle MH_String_equals; 139 static final VarHandle VH_array; 140 141 static final int[] array = new int[] { 0, 1, 2, 3, 4, 5}; 142 static { 143 try { 144 Class<?> arrayClass = Class.forName("[I"); 145 VH_array = MethodHandles.arrayElementVarHandle(arrayClass); 146 MH_add = LOOKUP.findStatic(InvokeMethodHandleWithBadArgument.class, "add", 147 methodType(int.class, int.class, int.class)); 148 MH_spread = LOOKUP.findStatic(InvokeMethodHandleWithBadArgument.class, "spread", 149 methodType(String.class, String.class, int.class, int.class, int.class, String.class)); 150 MH_String_equals = LOOKUP.findVirtual(String.class, "equals", methodType(boolean.class, Object.class)); 151 } catch (Exception e) { 152 throw new ExceptionInInitializerError(e); 153 } 154 } 155 156 static String spread(String s1, int i1, int i2, int i3, String s2) { 157 return s1 + i1 + i2 + i3 + s2; 158 } 159 160 static int add(int x, int y) { 161 return x+y; 162 } 163 }