/* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; // Note that $opt$ is a marker for the optimizing compiler to test // it does compile the method. public class Main extends TestCase { public static void main(String[] args) throws Exception { $opt$TestAllocations(); $opt$TestWithInitializations(); $opt$TestNegativeValueNewByteArray(); $opt$TestNegativeValueNewCharArray(); testNegativeArraySize(); testSmaliFilledNewArray(); testSmaliFillArrayData(); testSmaliVerifyError(); } static void $opt$TestAllocations() { float[] a = new float[1]; assertEquals(1, a.length); double[] b = new double[2]; assertEquals(2, b.length); long[] c = new long[3]; assertEquals(3, c.length); int[] d = new int[4]; assertEquals(4, d.length); short[] e = new short[5]; assertEquals(5, e.length); char[] f = new char[6]; assertEquals(6, f.length); byte[] g = new byte[7]; assertEquals(7, g.length); boolean[] h = new boolean[8]; assertEquals(8, h.length); Object[] i = new Object[9]; assertEquals(9, i.length); } static void $opt$TestWithInitializations() { float[] a = { 1.2f }; assertEquals(1, a.length); assertEquals(1.2f, a[0]); double[] b = { 4.3, 1.2 }; assertEquals(2, b.length); assertEquals(4.3, b[0]); assertEquals(1.2, b[1]); long[] c = { 4L, 5L }; assertEquals(2, c.length); assertEquals(4L, c[0]); assertEquals(5L, c[1]); int[] d = {1, 2, 3}; assertEquals(3, d.length); assertEquals(1, d[0]); assertEquals(2, d[1]); assertEquals(3, d[2]); short[] e = {4, 5, 6}; assertEquals(3, e.length); assertEquals(4, e[0]); assertEquals(5, e[1]); assertEquals(6, e[2]); char[] f = {'a', 'b'}; assertEquals(2, f.length); assertEquals('a', f[0]); assertEquals('b', f[1]); byte[] g = {7, 8, 9}; assertEquals(3, g.length); assertEquals(7, g[0]); assertEquals(8, g[1]); assertEquals(9, g[2]); boolean[] h = {true, false}; assertEquals(2, h.length); assertEquals(true, h[0]); assertEquals(false, h[1]); Object obj1 = new Object(); Object obj2 = new Object(); Object[] i = {obj1, obj2}; assertEquals(2, i.length); assertEquals(obj1, i[0]); assertEquals(obj2, i[1]); } static void $opt$TestNegativeValueNewByteArray() { // Use an array initializer to hint the use of filled-new-array. byte[] a = { (byte)0xa0, (byte)0xa1, (byte)0xa2, (byte)0xa3, (byte)0xa4, (byte)0xa5, (byte)0xa6, (byte)0xa7 }; for (int i = 0; i < a.length; i++) { assertEquals((byte)0xa0 + i, a[i]); } } static void $opt$TestNegativeValueNewCharArray() { // Use an array initializer to hint the use of filled-new-array. char[] a = { (char)0xa000, (char)0xa001, (char)0xa002, (char)0xa003, (char)0xa004, (char)0xa005, (char)0xa006, (char)0xa007 }; for (int i = 0; i < a.length; i++) { assertEquals((char)0xa000 + i, a[i]); } } static void testNegativeArraySize() { int i = 0; try { $opt$TestNegativeArraySize(); } catch (NegativeArraySizeException e) { i = 1; } assertEquals(i, 1); } static int[] $opt$TestNegativeArraySize() { int[] array = new int[-1]; return null; } public static void testSmaliFilledNewArray() throws Exception { Class<?> c = Class.forName("FilledNewArray"); { Method m = c.getMethod("newInt", Integer.TYPE, Integer.TYPE, Integer.TYPE); Object[] args = {new Integer(1), new Integer(2), new Integer(3)}; int[] result = (int[])m.invoke(null, args); assertEquals(3, result.length); assertEquals(1, result[0]); assertEquals(2, result[1]); assertEquals(3, result[2]); } { Method m = c.getMethod("newRef", Object.class, Object.class); Object[] args = {new Integer(1), new Integer(2)}; Object[] result = (Object[])m.invoke(null, args); assertEquals(2, result.length); assertEquals(args[0], result[0]); assertEquals(args[1], result[1]); } { Method m = c.getMethod("newArray", int[].class, int[].class); Object[] args = {new int[0], new int[1]}; Object[] result = (Object[])m.invoke(null, args); assertEquals(2, result.length); assertEquals(args[0], result[0]); assertEquals(args[1], result[1]); } { Method m = c.getMethod("newIntRange", Integer.TYPE, Integer.TYPE, Integer.TYPE); Object[] args = {new Integer(1), new Integer(2), new Integer(3)}; int[] result = (int[])m.invoke(null, args); assertEquals(3, result.length); assertEquals(1, result[0]); assertEquals(2, result[1]); assertEquals(3, result[2]); } { Method m = c.getMethod("newRefRange", Object.class, Object.class); Object[] args = {new Integer(1), new Integer(2)}; Object[] result = (Object[])m.invoke(null, args); assertEquals(2, result.length); assertEquals(args[0], result[0]); assertEquals(args[1], result[1]); } { Method m = c.getMethod("newArrayRange", int[].class, int[].class); Object[] args = {new int[0], new int[1]}; Object[] result = (Object[])m.invoke(null, args); assertEquals(2, result.length); assertEquals(args[0], result[0]); assertEquals(args[1], result[1]); } } public static void testSmaliVerifyError() throws Exception { Error error = null; // Ensure the elements in filled-new-array must be assignable // to the array component type. try { Class.forName("FilledNewArrayVerifyError"); } catch (VerifyError e) { error = e; } assertNotNull(error); } public static void testSmaliFillArrayData() throws Exception { Class<?> c = Class.forName("FillArrayData"); { Method m = c.getMethod("emptyIntArray", int[].class); int[] array = new int[0]; Object[] args = { array }; m.invoke(null, args); assertEquals(0, array.length); array = new int[2]; args[0] = array; m.invoke(null, args); // Test that nothing has been written to the array. assertEquals(0, array[0]); assertEquals(0, array[1]); array = new int[] { 42, -42 }; args[0] = array; m.invoke(null, args); // Test that nothing has been written to the array. assertEquals(42, array[0]); assertEquals(-42, array[1]); Throwable exception = null; args[0] = null; try { m.invoke(null, args); } catch (InvocationTargetException e) { exception = e.getCause(); assertTrue(exception instanceof NullPointerException); } assertNotNull(exception); } { Method m = c.getMethod("intArray", int[].class); int[] array = new int[7]; Object[] args = { array }; m.invoke(null, args); assertEquals(7, array.length); assertEquals(1, array[0]); assertEquals(2, array[1]); assertEquals(3, array[2]); assertEquals(4, array[3]); assertEquals(5, array[4]); assertEquals(0, array[5]); assertEquals(0, array[6]); array = new int[2]; args[0] = array; Throwable exception = null; try { m.invoke(null, args); } catch (InvocationTargetException e) { exception = e.getCause(); assertTrue(exception instanceof IndexOutOfBoundsException); } assertNotNull(exception); exception = null; // Test that nothing has been written to the array. assertEquals(0, array[0]); assertEquals(0, array[1]); args[0] = null; try { m.invoke(null, args); } catch (InvocationTargetException e) { exception = e.getCause(); assertTrue(exception instanceof NullPointerException); } assertNotNull(exception); } { Method m = c.getMethod("intArrayFillInstructionAfterData", int[].class); int[] array = new int[7]; Object[] args = { array }; m.invoke(null, args); assertEquals(7, array.length); assertEquals(1, array[0]); assertEquals(2, array[1]); assertEquals(3, array[2]); assertEquals(4, array[3]); assertEquals(5, array[4]); assertEquals(0, array[5]); assertEquals(0, array[6]); array = new int[2]; args[0] = array; Throwable exception = null; try { m.invoke(null, args); } catch (InvocationTargetException e) { exception = e.getCause(); assertTrue(exception instanceof IndexOutOfBoundsException); } assertNotNull(exception); exception = null; // Test that nothing has been written to the array. assertEquals(0, array[0]); assertEquals(0, array[1]); args[0] = null; try { m.invoke(null, args); } catch (InvocationTargetException e) { exception = e.getCause(); assertTrue(exception instanceof NullPointerException); } assertNotNull(exception); } { Method m = c.getMethod("shortArray", short[].class); short[] array = new short[7]; Object[] args = { array }; m.invoke(null, args); assertEquals(7, array.length); assertEquals(1, array[0]); assertEquals(2, array[1]); assertEquals(3, array[2]); assertEquals(4, array[3]); assertEquals(5, array[4]); assertEquals(0, array[5]); assertEquals(0, array[6]); array = new short[2]; args[0] = array; Throwable exception = null; try { m.invoke(null, args); } catch (InvocationTargetException e) { exception = e.getCause(); assertTrue(exception instanceof IndexOutOfBoundsException); } assertNotNull(exception); exception = null; // Test that nothing has been written to the array. assertEquals(0, array[0]); assertEquals(0, array[1]); args[0] = null; try { m.invoke(null, args); } catch (InvocationTargetException e) { exception = e.getCause(); assertTrue(exception instanceof NullPointerException); } assertNotNull(exception); } { Method m = c.getMethod("longArray", long[].class); long[] array = new long[7]; Object[] args = { array }; m.invoke(null, args); assertEquals(7, array.length); assertEquals(1L, array[0]); assertEquals(2L, array[1]); assertEquals(3L, array[2]); assertEquals(4L, array[3]); assertEquals(5L, array[4]); assertEquals(0L, array[5]); assertEquals(0L, array[6]); array = new long[2]; args[0] = array; Throwable exception = null; try { m.invoke(null, args); } catch (InvocationTargetException e) { exception = e.getCause(); assertTrue(exception instanceof IndexOutOfBoundsException); } assertNotNull(exception); exception = null; // Test that nothing has been written to the array. assertEquals(0, array[0]); assertEquals(0, array[1]); args[0] = null; try { m.invoke(null, args); } catch (InvocationTargetException e) { exception = e.getCause(); assertTrue(exception instanceof NullPointerException); } assertNotNull(exception); } { Method m = c.getMethod("charArray", char[].class); char[] array = new char[7]; Object[] args = { array }; m.invoke(null, args); assertEquals(7, array.length); assertEquals(1, array[0]); assertEquals(2, array[1]); assertEquals(3, array[2]); assertEquals(4, array[3]); assertEquals(5, array[4]); assertEquals(0, array[5]); assertEquals(0, array[6]); array = new char[2]; args[0] = array; Throwable exception = null; try { m.invoke(null, args); } catch (InvocationTargetException e) { exception = e.getCause(); assertTrue(exception instanceof IndexOutOfBoundsException); } assertNotNull(exception); exception = null; // Test that nothing has been written to the array. assertEquals(0, array[0]); assertEquals(0, array[1]); args[0] = null; try { m.invoke(null, args); } catch (InvocationTargetException e) { exception = e.getCause(); assertTrue(exception instanceof NullPointerException); } assertNotNull(exception); } { Method m = c.getMethod("byteArray", byte[].class); byte[] array = new byte[7]; Object[] args = { array }; m.invoke(null, args); assertEquals(7, array.length); assertEquals(1, array[0]); assertEquals(2, array[1]); assertEquals(3, array[2]); assertEquals(4, array[3]); assertEquals(5, array[4]); assertEquals(0, array[5]); assertEquals(0, array[6]); array = new byte[2]; args[0] = array; Throwable exception = null; try { m.invoke(null, args); } catch (InvocationTargetException e) { exception = e.getCause(); assertTrue(exception instanceof IndexOutOfBoundsException); } assertNotNull(exception); exception = null; // Test that nothing has been written to the array. assertEquals(0, array[0]); assertEquals(0, array[1]); args[0] = null; try { m.invoke(null, args); } catch (InvocationTargetException e) { exception = e.getCause(); assertTrue(exception instanceof NullPointerException); } assertNotNull(exception); } { Method m = c.getMethod("booleanArray", boolean[].class); boolean[] array = new boolean[5]; Object[] args = { array }; m.invoke(null, args); assertEquals(5, array.length); assertEquals(false, array[0]); assertEquals(true, array[1]); assertEquals(true, array[2]); assertEquals(false, array[3]); assertEquals(false, array[4]); array = new boolean[2]; args[0] = array; Throwable exception = null; try { m.invoke(null, args); } catch (InvocationTargetException e) { exception = e.getCause(); assertTrue(exception instanceof IndexOutOfBoundsException); } assertNotNull(exception); exception = null; // Test that nothing has been written to the array. assertEquals(false, array[0]); assertEquals(false, array[1]); args[0] = null; try { m.invoke(null, args); } catch (InvocationTargetException e) { exception = e.getCause(); assertTrue(exception instanceof NullPointerException); } assertNotNull(exception); } } }