1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 import java.lang.reflect.InvocationTargetException; 18 import java.lang.reflect.Method; 19 20 // Note that $opt$ is a marker for the optimizing compiler to test 21 // it does compile the method. 22 23 public class Main extends TestCase { main(String[] args)24 public static void main(String[] args) throws Exception { 25 $opt$TestAllocations(); 26 $opt$TestWithInitializations(); 27 $opt$TestNegativeValueNewByteArray(); 28 $opt$TestNegativeValueNewCharArray(); 29 testNegativeArraySize(); 30 testSmaliFilledNewArray(); 31 testSmaliFillArrayData(); 32 33 // Ensure the elements in filled-new-array must be assignable 34 // to the array component type. 35 testSmaliVerifyError("FilledNewArrayVerifyError"); 36 37 // Ensure invalid array types `[J` and `[D` are rejected. 38 testSmaliVerifyError("FilledNewArrayVerifyErrorJ"); 39 testSmaliVerifyError("FilledNewArrayVerifyErrorD"); 40 41 // Test that `filled-new-array` with `[Z`, `B`, `[C`, `[S` or `[F` throws `InternalError`. 42 testSmaliInternalError("FilledNewArrayInternalErrorZ"); 43 testSmaliInternalError("FilledNewArrayInternalErrorB"); 44 testSmaliInternalError("FilledNewArrayInternalErrorC"); 45 testSmaliInternalError("FilledNewArrayInternalErrorS"); 46 testSmaliInternalError("FilledNewArrayInternalErrorF"); 47 } 48 $opt$TestAllocations()49 static void $opt$TestAllocations() { 50 float[] a = new float[1]; 51 assertEquals(1, a.length); 52 53 double[] b = new double[2]; 54 assertEquals(2, b.length); 55 56 long[] c = new long[3]; 57 assertEquals(3, c.length); 58 59 int[] d = new int[4]; 60 assertEquals(4, d.length); 61 62 short[] e = new short[5]; 63 assertEquals(5, e.length); 64 65 char[] f = new char[6]; 66 assertEquals(6, f.length); 67 68 byte[] g = new byte[7]; 69 assertEquals(7, g.length); 70 71 boolean[] h = new boolean[8]; 72 assertEquals(8, h.length); 73 74 Object[] i = new Object[9]; 75 assertEquals(9, i.length); 76 } 77 $opt$TestWithInitializations()78 static void $opt$TestWithInitializations() { 79 float[] a = { 1.2f }; 80 assertEquals(1, a.length); 81 assertEquals(1.2f, a[0]); 82 83 double[] b = { 4.3, 1.2 }; 84 assertEquals(2, b.length); 85 assertEquals(4.3, b[0]); 86 assertEquals(1.2, b[1]); 87 88 long[] c = { 4L, 5L }; 89 assertEquals(2, c.length); 90 assertEquals(4L, c[0]); 91 assertEquals(5L, c[1]); 92 93 int[] d = {1, 2, 3}; 94 assertEquals(3, d.length); 95 assertEquals(1, d[0]); 96 assertEquals(2, d[1]); 97 assertEquals(3, d[2]); 98 99 short[] e = {4, 5, 6}; 100 assertEquals(3, e.length); 101 assertEquals(4, e[0]); 102 assertEquals(5, e[1]); 103 assertEquals(6, e[2]); 104 105 char[] f = {'a', 'b'}; 106 assertEquals(2, f.length); 107 assertEquals('a', f[0]); 108 assertEquals('b', f[1]); 109 110 byte[] g = {7, 8, 9}; 111 assertEquals(3, g.length); 112 assertEquals(7, g[0]); 113 assertEquals(8, g[1]); 114 assertEquals(9, g[2]); 115 116 boolean[] h = {true, false}; 117 assertEquals(2, h.length); 118 assertEquals(true, h[0]); 119 assertEquals(false, h[1]); 120 121 Object obj1 = new Object(); 122 Object obj2 = new Object(); 123 Object[] i = {obj1, obj2}; 124 assertEquals(2, i.length); 125 assertEquals(obj1, i[0]); 126 assertEquals(obj2, i[1]); 127 } 128 $opt$TestNegativeValueNewByteArray()129 static void $opt$TestNegativeValueNewByteArray() { 130 // Use an array initializer to hint the use of filled-new-array. 131 byte[] a = { (byte)0xa0, (byte)0xa1, (byte)0xa2, (byte)0xa3, 132 (byte)0xa4, (byte)0xa5, (byte)0xa6, (byte)0xa7 }; 133 for (int i = 0; i < a.length; i++) { 134 assertEquals((byte)0xa0 + i, a[i]); 135 } 136 } 137 $opt$TestNegativeValueNewCharArray()138 static void $opt$TestNegativeValueNewCharArray() { 139 // Use an array initializer to hint the use of filled-new-array. 140 char[] a = { (char)0xa000, (char)0xa001, (char)0xa002, (char)0xa003, 141 (char)0xa004, (char)0xa005, (char)0xa006, (char)0xa007 }; 142 for (int i = 0; i < a.length; i++) { 143 assertEquals((char)0xa000 + i, a[i]); 144 } 145 } 146 testNegativeArraySize()147 static void testNegativeArraySize() { 148 int i = 0; 149 try { 150 $opt$TestNegativeArraySize(); 151 } catch (NegativeArraySizeException e) { 152 i = 1; 153 } 154 assertEquals(i, 1); 155 } 156 $opt$TestNegativeArraySize()157 static int[] $opt$TestNegativeArraySize() { 158 int[] array = new int[-1]; 159 return null; 160 } 161 testSmaliFilledNewArray()162 public static void testSmaliFilledNewArray() throws Exception { 163 Class<?> c = Class.forName("FilledNewArray"); 164 165 { 166 Method m = c.getMethod("newInt", Integer.TYPE, Integer.TYPE, Integer.TYPE); 167 Object[] args = {new Integer(1), new Integer(2), new Integer(3)}; 168 int[] result = (int[])m.invoke(null, args); 169 assertEquals(3, result.length); 170 assertEquals(1, result[0]); 171 assertEquals(2, result[1]); 172 assertEquals(3, result[2]); 173 } 174 175 { 176 Method m = c.getMethod("newRef", Object.class, Object.class); 177 Object[] args = {new Integer(1), new Integer(2)}; 178 Object[] result = (Object[])m.invoke(null, args); 179 assertEquals(2, result.length); 180 assertEquals(args[0], result[0]); 181 assertEquals(args[1], result[1]); 182 } 183 184 { 185 Method m = c.getMethod("newArray", int[].class, int[].class); 186 Object[] args = {new int[0], new int[1]}; 187 Object[] result = (Object[])m.invoke(null, args); 188 assertEquals(2, result.length); 189 assertEquals(args[0], result[0]); 190 assertEquals(args[1], result[1]); 191 } 192 193 { 194 Method m = c.getMethod("newIntRange", Integer.TYPE, Integer.TYPE, Integer.TYPE); 195 Object[] args = {new Integer(1), new Integer(2), new Integer(3)}; 196 int[] result = (int[])m.invoke(null, args); 197 assertEquals(3, result.length); 198 assertEquals(1, result[0]); 199 assertEquals(2, result[1]); 200 assertEquals(3, result[2]); 201 } 202 203 { 204 Method m = c.getMethod("newRefRange", Object.class, Object.class); 205 Object[] args = {new Integer(1), new Integer(2)}; 206 Object[] result = (Object[])m.invoke(null, args); 207 assertEquals(2, result.length); 208 assertEquals(args[0], result[0]); 209 assertEquals(args[1], result[1]); 210 } 211 212 { 213 Method m = c.getMethod("newArrayRange", int[].class, int[].class); 214 Object[] args = {new int[0], new int[1]}; 215 Object[] result = (Object[])m.invoke(null, args); 216 assertEquals(2, result.length); 217 assertEquals(args[0], result[0]); 218 assertEquals(args[1], result[1]); 219 } 220 } 221 testSmaliVerifyError(String name)222 public static void testSmaliVerifyError(String name) throws Exception { 223 Error error = null; 224 try { 225 Class.forName(name); 226 } catch (VerifyError e) { 227 error = e; 228 } 229 assertNotNull(error); 230 } 231 testSmaliInternalError(String name)232 public static void testSmaliInternalError(String name) throws Exception { 233 Throwable t = null; 234 try { 235 Class<?> c = Class.forName(name); 236 Method m = c.getMethod("fail"); 237 m.invoke(null); 238 } catch (InvocationTargetException e) { 239 t = e.getCause(); 240 assertTrue(t instanceof InternalError); 241 } 242 assertNotNull(t); 243 } 244 testSmaliFillArrayData()245 public static void testSmaliFillArrayData() throws Exception { 246 Class<?> c = Class.forName("FillArrayData"); 247 { 248 Method m = c.getMethod("emptyIntArray", int[].class); 249 int[] array = new int[0]; 250 Object[] args = { array }; 251 m.invoke(null, args); 252 assertEquals(0, array.length); 253 254 array = new int[2]; 255 args[0] = array; 256 m.invoke(null, args); 257 // Test that nothing has been written to the array. 258 assertEquals(0, array[0]); 259 assertEquals(0, array[1]); 260 261 array = new int[] { 42, -42 }; 262 args[0] = array; 263 m.invoke(null, args); 264 // Test that nothing has been written to the array. 265 assertEquals(42, array[0]); 266 assertEquals(-42, array[1]); 267 268 Throwable exception = null; 269 args[0] = null; 270 try { 271 m.invoke(null, args); 272 } catch (InvocationTargetException e) { 273 exception = e.getCause(); 274 assertTrue(exception instanceof NullPointerException); 275 } 276 assertNotNull(exception); 277 } 278 279 { 280 Method m = c.getMethod("intArray", int[].class); 281 int[] array = new int[7]; 282 Object[] args = { array }; 283 m.invoke(null, args); 284 assertEquals(7, array.length); 285 assertEquals(1, array[0]); 286 assertEquals(2, array[1]); 287 assertEquals(3, array[2]); 288 assertEquals(4, array[3]); 289 assertEquals(5, array[4]); 290 assertEquals(0, array[5]); 291 assertEquals(0, array[6]); 292 293 array = new int[2]; 294 args[0] = array; 295 Throwable exception = null; 296 try { 297 m.invoke(null, args); 298 } catch (InvocationTargetException e) { 299 exception = e.getCause(); 300 assertTrue(exception instanceof IndexOutOfBoundsException); 301 } 302 assertNotNull(exception); 303 exception = null; 304 // Test that nothing has been written to the array. 305 assertEquals(0, array[0]); 306 assertEquals(0, array[1]); 307 308 args[0] = null; 309 try { 310 m.invoke(null, args); 311 } catch (InvocationTargetException e) { 312 exception = e.getCause(); 313 assertTrue(exception instanceof NullPointerException); 314 } 315 assertNotNull(exception); 316 } 317 318 { 319 Method m = c.getMethod("intArrayFillInstructionAfterData", int[].class); 320 int[] array = new int[7]; 321 Object[] args = { array }; 322 m.invoke(null, args); 323 assertEquals(7, array.length); 324 assertEquals(1, array[0]); 325 assertEquals(2, array[1]); 326 assertEquals(3, array[2]); 327 assertEquals(4, array[3]); 328 assertEquals(5, array[4]); 329 assertEquals(0, array[5]); 330 assertEquals(0, array[6]); 331 332 array = new int[2]; 333 args[0] = array; 334 Throwable exception = null; 335 try { 336 m.invoke(null, args); 337 } catch (InvocationTargetException e) { 338 exception = e.getCause(); 339 assertTrue(exception instanceof IndexOutOfBoundsException); 340 } 341 assertNotNull(exception); 342 exception = null; 343 // Test that nothing has been written to the array. 344 assertEquals(0, array[0]); 345 assertEquals(0, array[1]); 346 347 args[0] = null; 348 try { 349 m.invoke(null, args); 350 } catch (InvocationTargetException e) { 351 exception = e.getCause(); 352 assertTrue(exception instanceof NullPointerException); 353 } 354 assertNotNull(exception); 355 } 356 357 { 358 Method m = c.getMethod("shortArray", short[].class); 359 short[] array = new short[7]; 360 Object[] args = { array }; 361 m.invoke(null, args); 362 assertEquals(7, array.length); 363 assertEquals(1, array[0]); 364 assertEquals(2, array[1]); 365 assertEquals(3, array[2]); 366 assertEquals(4, array[3]); 367 assertEquals(5, array[4]); 368 assertEquals(0, array[5]); 369 assertEquals(0, array[6]); 370 371 array = new short[2]; 372 args[0] = array; 373 Throwable exception = null; 374 try { 375 m.invoke(null, args); 376 } catch (InvocationTargetException e) { 377 exception = e.getCause(); 378 assertTrue(exception instanceof IndexOutOfBoundsException); 379 } 380 assertNotNull(exception); 381 exception = null; 382 // Test that nothing has been written to the array. 383 assertEquals(0, array[0]); 384 assertEquals(0, array[1]); 385 386 args[0] = null; 387 try { 388 m.invoke(null, args); 389 } catch (InvocationTargetException e) { 390 exception = e.getCause(); 391 assertTrue(exception instanceof NullPointerException); 392 } 393 assertNotNull(exception); 394 } 395 396 { 397 Method m = c.getMethod("longArray", long[].class); 398 long[] array = new long[7]; 399 Object[] args = { array }; 400 m.invoke(null, args); 401 assertEquals(7, array.length); 402 assertEquals(1L, array[0]); 403 assertEquals(2L, array[1]); 404 assertEquals(3L, array[2]); 405 assertEquals(4L, array[3]); 406 assertEquals(5L, array[4]); 407 assertEquals(0L, array[5]); 408 assertEquals(0L, array[6]); 409 410 array = new long[2]; 411 args[0] = array; 412 Throwable exception = null; 413 try { 414 m.invoke(null, args); 415 } catch (InvocationTargetException e) { 416 exception = e.getCause(); 417 assertTrue(exception instanceof IndexOutOfBoundsException); 418 } 419 assertNotNull(exception); 420 exception = null; 421 // Test that nothing has been written to the array. 422 assertEquals(0, array[0]); 423 assertEquals(0, array[1]); 424 425 args[0] = null; 426 try { 427 m.invoke(null, args); 428 } catch (InvocationTargetException e) { 429 exception = e.getCause(); 430 assertTrue(exception instanceof NullPointerException); 431 } 432 assertNotNull(exception); 433 } 434 435 { 436 Method m = c.getMethod("charArray", char[].class); 437 char[] array = new char[7]; 438 Object[] args = { array }; 439 m.invoke(null, args); 440 assertEquals(7, array.length); 441 assertEquals(1, array[0]); 442 assertEquals(2, array[1]); 443 assertEquals(3, array[2]); 444 assertEquals(4, array[3]); 445 assertEquals(5, array[4]); 446 assertEquals(0, array[5]); 447 assertEquals(0, array[6]); 448 449 array = new char[2]; 450 args[0] = array; 451 Throwable exception = null; 452 try { 453 m.invoke(null, args); 454 } catch (InvocationTargetException e) { 455 exception = e.getCause(); 456 assertTrue(exception instanceof IndexOutOfBoundsException); 457 } 458 assertNotNull(exception); 459 exception = null; 460 // Test that nothing has been written to the array. 461 assertEquals(0, array[0]); 462 assertEquals(0, array[1]); 463 464 args[0] = null; 465 try { 466 m.invoke(null, args); 467 } catch (InvocationTargetException e) { 468 exception = e.getCause(); 469 assertTrue(exception instanceof NullPointerException); 470 } 471 assertNotNull(exception); 472 } 473 474 { 475 Method m = c.getMethod("byteArray", byte[].class); 476 byte[] array = new byte[7]; 477 Object[] args = { array }; 478 m.invoke(null, args); 479 assertEquals(7, array.length); 480 assertEquals(1, array[0]); 481 assertEquals(2, array[1]); 482 assertEquals(3, array[2]); 483 assertEquals(4, array[3]); 484 assertEquals(5, array[4]); 485 assertEquals(0, array[5]); 486 assertEquals(0, array[6]); 487 488 array = new byte[2]; 489 args[0] = array; 490 Throwable exception = null; 491 try { 492 m.invoke(null, args); 493 } catch (InvocationTargetException e) { 494 exception = e.getCause(); 495 assertTrue(exception instanceof IndexOutOfBoundsException); 496 } 497 assertNotNull(exception); 498 exception = null; 499 // Test that nothing has been written to the array. 500 assertEquals(0, array[0]); 501 assertEquals(0, array[1]); 502 503 args[0] = null; 504 try { 505 m.invoke(null, args); 506 } catch (InvocationTargetException e) { 507 exception = e.getCause(); 508 assertTrue(exception instanceof NullPointerException); 509 } 510 assertNotNull(exception); 511 } 512 513 { 514 Method m = c.getMethod("booleanArray", boolean[].class); 515 boolean[] array = new boolean[5]; 516 Object[] args = { array }; 517 m.invoke(null, args); 518 assertEquals(5, array.length); 519 assertEquals(false, array[0]); 520 assertEquals(true, array[1]); 521 assertEquals(true, array[2]); 522 assertEquals(false, array[3]); 523 assertEquals(false, array[4]); 524 525 array = new boolean[2]; 526 args[0] = array; 527 Throwable exception = null; 528 try { 529 m.invoke(null, args); 530 } catch (InvocationTargetException e) { 531 exception = e.getCause(); 532 assertTrue(exception instanceof IndexOutOfBoundsException); 533 } 534 assertNotNull(exception); 535 exception = null; 536 // Test that nothing has been written to the array. 537 assertEquals(false, array[0]); 538 assertEquals(false, array[1]); 539 540 args[0] = null; 541 try { 542 m.invoke(null, args); 543 } catch (InvocationTargetException e) { 544 exception = e.getCause(); 545 assertTrue(exception instanceof NullPointerException); 546 } 547 assertNotNull(exception); 548 } 549 } 550 } 551