1 /* 2 * Copyright (c) 2001, 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 * @test 26 * @bug 4439631 27 * @bug 4448721 28 * @bug 4448603 29 * @summary Test access to ranges within ArrayReferences 30 * @author Robert Field 31 * 32 * @run build TestScaffold VMConnection TargetListener TargetAdapter 33 * @run compile -g ArrayRangeTest.java 34 * @run driver ArrayRangeTest 35 */ 36 import com.sun.jdi.*; 37 import com.sun.jdi.event.*; 38 import com.sun.jdi.request.*; 39 40 import java.util.*; 41 42 /********** target program **********/ 43 44 class ArrayRangeTarg { 45 static int[] emptyArray = {}; 46 static int[] fullArray = {0, 100, 200, 300, 400}; 47 48 public static void main(String[] args) { 49 System.out.println("Goodbye from ArrayRangeTarg!"); 50 } 51 } 52 53 /********** test program **********/ 54 55 public class ArrayRangeTest extends TestScaffold { 56 ReferenceType targetClass; 57 58 class Sample { 59 Sample(String name, ArrayReference arrRef, int[] expected) { 60 this.name = name; 61 this.arrRef = arrRef; 62 this.expected = expected; 63 } 64 String name; 65 ArrayReference arrRef; 66 int[] expected; 67 } 68 69 ArrayRangeTest (String args[]) { 70 super(args); 71 } 72 73 public static void main(String[] args) throws Exception { 74 new ArrayRangeTest(args).startTests(); 75 } 76 77 /********** test assist **********/ 78 79 String arr(int a[]) { 80 StringBuffer buf = new StringBuffer(); 81 buf.append('['); 82 if (a.length > 0) { 83 buf.append(a[0]); 84 for (int i = 1; i < a.length; ++i) { 85 buf.append(','); 86 buf.append(a[i]); 87 } 88 } 89 buf.append(']'); 90 return buf.toString(); 91 } 92 93 void getValueGood(Sample samp, int index) { 94 try { 95 Value val = samp.arrRef.getValue(index); 96 int ival = ((IntegerValue)val).value(); 97 if (ival != samp.expected[index]) { 98 failure("FAIL - " + samp.name + 99 ".getValue(" + index + ") - wrong value=" + ival); 100 } else { 101 println("pass - " + samp.name + 102 ".getValue(" + index + ") - value=" + ival); 103 } 104 } catch (Throwable exc) { 105 failure("FAIL - " + samp.name + 106 ".getValue(" + index + ") - unexpected: " + exc); 107 } 108 } 109 110 void getValueBad(Sample samp, int index) { 111 try { 112 Value val = samp.arrRef.getValue(index); 113 failure("FAIL - " + samp.name + 114 ".getValue(" + index + ") - no expected exception"); 115 } catch (IndexOutOfBoundsException exc) { 116 println("pass - " + samp.name + 117 ".getValue(" + index + ") - got expected: " + exc); 118 } catch (Throwable exc) { 119 failure("FAIL - " + samp.name + 120 ".getValue(" + index + ") - unexpected: " + exc); 121 } 122 } 123 124 void getValuesGood(Sample samp) { 125 String desc = samp.name + ".getValues()"; 126 try { 127 List vals = samp.arrRef.getValues(); 128 if (vals.size() != samp.expected.length) { 129 failure("FAIL - " + desc + 130 " - wrong size=" + vals.size() + 131 " , expected: " + samp.expected.length); 132 } 133 for (int index = 0; index < vals.size(); ++index) { 134 int ival = ((IntegerValue)vals.get(index)).value(); 135 if (ival != samp.expected[index]) { 136 failure("FAIL - " + desc + 137 " - wrong value=" + ival); 138 return; 139 } 140 } 141 println("pass - " + samp.name + ".getValues())"); 142 } catch (Throwable exc) { 143 failure("FAIL - " + desc + 144 " - unexpected: " + exc); 145 } 146 } 147 148 void getValuesGood(Sample samp, int index, int length) { 149 try { 150 List vals = samp.arrRef.getValues(index, length); 151 if (vals.size() != 152 ((length==-1)? (samp.expected.length - index) : length)) { 153 failure("FAIL - " + samp.name + ".getValues(" + 154 index + ", " + length + ") - wrong size=" + 155 vals.size()); 156 } 157 for (int i = 0; i < vals.size(); ++i) { 158 int ival = ((IntegerValue)vals.get(i)).value(); 159 if (ival != samp.expected[index + i]) { 160 failure("FAIL - " + samp.name + ".getValues(" + 161 index + ", " + length + ") - wrong value=" + 162 ival); 163 return; 164 } 165 } 166 println("pass - " + samp.name + ".getValues(" + 167 index + ", " + length + "))"); 168 } catch (Throwable exc) { 169 failure("FAIL - " + samp.name + ".getValues(" + 170 index + ", " + length + ") - unexpected: " + exc); 171 } 172 } 173 174 void getValuesBad(Sample samp, int index, int length) { 175 try { 176 List vals = samp.arrRef.getValues(index, length); 177 failure("FAIL - " + samp.name + ".getValues(" + 178 index + ", " + length + ") - no expected exception"); 179 } catch (IndexOutOfBoundsException exc) { 180 println("pass - " + samp.name + ".getValue(" + 181 index + ", " + length + ") - got expected: " + exc); 182 } catch (Throwable exc) { 183 failure("FAIL - " + samp.name + ".getValues(" + 184 index + ", " + length + ") - unexpected: " + exc); 185 } 186 } 187 188 void setValueGood(Sample samp, int index, int ival) { 189 try { 190 Value val = vm().mirrorOf(ival); 191 samp.arrRef.setValue(index, val); 192 println("pass - " + samp.name + 193 ".setValue(" + index + ", ..)"); 194 } catch (Throwable exc) { 195 failure("FAIL - " + samp.name + 196 ".setValue(" + index + ",...) - unexpected: " + exc); 197 } 198 } 199 200 void setValueBad(Sample samp, int index, int ival) { 201 try { 202 Value val = vm().mirrorOf(ival); 203 samp.arrRef.setValue(index, val); 204 failure("FAIL - " + samp.name + 205 ".setValue(" + index + ", ..) - no expected exception"); 206 } catch (IndexOutOfBoundsException exc) { 207 println("pass - " + samp.name + 208 ".setValue(" + index + ",...) - got expected: " + exc); 209 } catch (Throwable exc) { 210 failure("FAIL - " + samp.name + 211 ".setValue(" + index + ",...) - unexpected: " + exc); 212 } 213 } 214 215 void setValuesGood(Sample samp, int[] valArray) { 216 String desc = samp.name + ".setValues(" + arr(valArray) + ")"; 217 try { 218 List values = new ArrayList(); 219 for (int i = 0; i < valArray.length; ++i) { 220 Value val = vm().mirrorOf(valArray[i]); 221 values.add(val); 222 } 223 samp.arrRef.setValues(values); 224 println("pass - " + desc); 225 } catch (Throwable exc) { 226 failure("FAIL - " + desc + " - unexpected: " + exc); 227 } 228 } 229 230 void setValuesGood(Sample samp, int index, int[] valArray, 231 int srcInx, int length) { 232 String desc = samp.name + ".setValues(" + index + ", " + 233 arr(valArray) + ", " + srcInx + ", " + length + ")"; 234 try { 235 List values = new ArrayList(); 236 for (int i = 0; i < valArray.length; ++i) { 237 Value val = vm().mirrorOf(valArray[i]); 238 values.add(val); 239 } 240 samp.arrRef.setValues(index, values, srcInx, length); 241 println("pass - " + desc); 242 } catch (Throwable exc) { 243 failure("FAIL - " + desc + " - unexpected: " + exc); 244 } 245 } 246 247 void setValuesBad(Sample samp, int index, int[] valArray, 248 int srcInx, int length) { 249 String desc = samp.name + ".setValues(" + index + ", " + 250 arr(valArray) + ", " + srcInx + ", " + length + ")"; 251 try { 252 List values = new ArrayList(); 253 for (int i = 0; i < valArray.length; ++i) { 254 Value val = vm().mirrorOf(valArray[i]); 255 values.add(val); 256 } 257 samp.arrRef.setValues(index, values, srcInx, length); 258 failure("FAIL - " + desc + " - no expected exception"); 259 } catch (IndexOutOfBoundsException exc) { 260 println("pass - " + desc + " - got expected: " + exc); 261 } catch (Throwable exc) { 262 failure("FAIL - " + desc + " - unexpected: " + exc); 263 } 264 } 265 266 void check(Sample samp, int[] expectArray) { 267 String desc = samp.name + " - check - " + arr(expectArray); 268 269 try { 270 List vals = samp.arrRef.getValues(); 271 if (vals.size() != expectArray.length) { 272 failure("FAIL - " + desc + 273 " - wrong size=" + vals.size() + 274 " , expected: " + expectArray.length); 275 } 276 for (int index = 0; index < vals.size(); ++index) { 277 int ival = ((IntegerValue)vals.get(index)).value(); 278 if (ival != expectArray[index]) { 279 failure("FAIL - " + desc + 280 " - wrong value=" + ival); 281 return; 282 } 283 } 284 println("pass - " + desc); 285 } catch (Throwable exc) { 286 failure("FAIL - " + desc + 287 " - unexpected: " + exc); 288 } 289 } 290 291 /********** test core **********/ 292 293 protected void runTests() throws Exception { 294 /* 295 * Get to the top of main() to determine targetClass 296 */ 297 BreakpointEvent bpe = startToMain("ArrayRangeTarg"); 298 targetClass = bpe.location().declaringType(); 299 Field fullField = targetClass.fieldByName("fullArray"); 300 Field emptyField = targetClass.fieldByName("emptyArray"); 301 ArrayReference emptyAR = (ArrayReference)targetClass.getValue(emptyField); 302 ArrayReference fullAR = (ArrayReference)targetClass.getValue(fullField); 303 Sample full = new Sample("full", fullAR, ArrayRangeTarg.fullArray); 304 Sample empty = new Sample("empty", emptyAR, ArrayRangeTarg.emptyArray); 305 306 getValueGood(full, 0); 307 getValueGood(full, 4); 308 309 // index < 0 310 getValueBad(full, -1); 311 getValueBad(full, -2); 312 getValueBad(empty, -1); 313 getValueBad(empty, -2); 314 315 // index >= length 316 getValueBad(full, 5); 317 getValueBad(empty, 0); 318 getValueBad(empty, 5); 319 320 getValuesGood(full); 321 getValuesGood(empty); 322 323 getValuesGood(full, 0, 5); 324 getValuesGood(full, 0, 4); 325 getValuesGood(full, 1, 4); 326 getValuesGood(full, 5, 0); 327 getValuesGood(full, 0, 0); 328 getValuesGood(full, 0, -1); 329 getValuesGood(full, 1, -1); 330 getValuesGood(full, 5, -1); 331 332 getValuesGood(empty, 0, 0); 333 getValuesGood(empty, 0, -1); 334 335 // index < 0 336 getValuesBad(full, -1, 0); 337 getValuesBad(full, -1, 3); 338 getValuesBad(full, -1, -1); 339 getValuesBad(empty, -1, 0); 340 getValuesBad(full, -2, 0); 341 getValuesBad(full, -2, 3); 342 getValuesBad(full, -2, -1); 343 getValuesBad(empty, -2, 0); 344 345 // index > length() 346 getValuesBad(full, 6, 0); 347 getValuesBad(full, 6, -1); 348 getValuesBad(empty, 1, 0); 349 getValuesBad(empty, 1, -1); 350 351 // length < 0 352 getValuesBad(full, 0, -2); 353 getValuesBad(empty, 0, -2); 354 355 // index + length > length() 356 getValuesBad(full, 0, 6); 357 getValuesBad(full, 1, 5); 358 getValuesBad(full, 2, 4); 359 getValuesBad(full, 5, 1); 360 getValuesBad(empty, 0, 1); 361 362 setValueGood(full, 0, 55); 363 setValueGood(full, 4, 66); 364 365 // index < 0 366 setValueBad(full, -1, 77); 367 setValueBad(full, -2, 77); 368 369 // index > length() 370 setValueBad(full, 5, 77); 371 setValueBad(full, 6, 77); 372 373 check(full, new int[] {55, 100, 200, 300, 66}); 374 375 // index < 0 376 setValueBad(empty, -1, 77); 377 setValueBad(empty, -2, 77); 378 379 // index > length() 380 setValueBad(empty, 0, 77); 381 setValueBad(empty, 1, 77); 382 383 setValuesGood(full, new int[] {40, 41, 42}); 384 setValuesGood(full, new int[] {}); 385 386 check(full, new int[] {40, 41, 42, 300, 66}); 387 388 setValuesGood(full, new int[] {99, 51, 52, 53, 54, 55}); 389 setValuesGood(full, new int[] {50}); 390 391 check(full, new int[] {50, 51, 52, 53, 54}); 392 393 setValuesGood(empty, new int[] {}); 394 setValuesGood(empty, new int[] {88}); 395 396 setValuesGood(full, 2, new int[] {30, 31, 32, 33, 34, 35}, 0, 3); 397 setValuesGood(full, 0, new int[] {80}, 0, 1); 398 399 check(full, new int[] {80, 51, 30, 31, 32}); 400 401 setValuesGood(full, 0, new int[] {90, 91, 92, 93, 94, 95}, 3, 3); 402 setValuesGood(full, 4, new int[] {81}, 0, 1); 403 404 check(full, new int[] {93, 94, 95, 31, 81}); 405 406 setValuesGood(full, 3, new int[] {60, 61, 62, 63}, 0, -1); 407 setValuesGood(full, 0, new int[] {82}, 0, -1); 408 409 check(full, new int[] {82, 94, 95, 60, 61}); 410 411 setValuesGood(full, 3, new int[] {20, 21, 22, 23}, 1, -1); 412 setValuesGood(full, 1, new int[] {83, 84}, 1, -1); 413 setValuesGood(full, 1, new int[] {}, 0, -1); 414 setValuesGood(full, 2, new int[] {}, 0, 0); 415 setValuesGood(full, 3, new int[] {99}, 0, 0); 416 setValuesGood(full, 4, new int[] {99, 98}, 1, 0); 417 418 check(full, new int[] {82, 84, 95, 21, 22}); 419 420 setValuesGood(empty, 0, new int[] {}, 0, -1); 421 setValuesGood(empty, 0, new int[] {}, 0, 0); 422 setValuesGood(empty, 0, new int[] {99}, 0, 0); 423 setValuesGood(empty, 0, new int[] {99, 98}, 1, 0); 424 425 // index < 0 426 setValuesBad(full, -1, new int[] {30, 31, 32, 33, 34, 35}, 0, 0); 427 setValuesBad(full, -1, new int[] {30, 31, 32, 33, 34, 35}, 0, -1); 428 setValuesBad(full, -2, new int[] {30, 31, 32, 33, 34, 35}, 0, -1); 429 setValuesBad(empty, -1, new int[] {}, 0, 0); 430 setValuesBad(empty, -2, new int[] {}, 0, 0); 431 432 // index > length() 433 setValuesBad(full, 6, new int[] {30, 31, 32, 33, 34, 35}, 0, 1); 434 setValuesBad(full, 6, new int[] {30, 31, 32, 33, 34, 35}, 0, -1); 435 setValuesBad(empty, 1, new int[] {4}, 0, 0); 436 setValuesBad(empty, 1, new int[] {}, 0, 0); 437 setValuesBad(empty, 1, new int[] {}, 0, -1); 438 439 // srcIndex < 0 440 setValuesBad(full, 0, new int[] {90, 91, 92, 93, 94, 95}, -1, 3); 441 setValuesBad(full, 0, new int[] {90, 91, 92, 93, 94, 95}, -1, 0); 442 setValuesBad(full, 0, new int[] {90, 91, 92, 93, 94, 95}, -1, -1); 443 setValuesBad(full, 0, new int[] {90, 91, 92, 93, 94, 95}, -2, -1); 444 setValuesBad(full, 1, new int[] {}, -1, -1); 445 setValuesBad(full, 2, new int[] {}, -1, 0); 446 setValuesBad(empty, 0, new int[] {}, -1, 0); 447 448 // srcIndex > values.size() 449 setValuesBad(full, 0, new int[] {81}, 2, 0); 450 setValuesBad(full, 0, new int[] {81}, 2, 1); 451 setValuesBad(full, 0, new int[] {81}, 2, -1); 452 setValuesBad(full, 4, new int[] {}, 1, 0); 453 setValuesBad(full, 1, new int[] {}, 1, -1); 454 setValuesBad(full, 2, new int[] {}, 1, 0); 455 setValuesBad(empty, 0, new int[] {}, 1, 0); 456 setValuesBad(empty, 0, new int[] {5}, 2, 0); 457 458 // length < 0 (length != -1) 459 setValuesBad(full, 3, new int[] {60, 61, 62, 63}, 0, -2); 460 setValuesBad(full, 3, new int[] {}, 0, -2); 461 462 // index + length > length() 463 setValuesBad(full, 0, new int[] {20, 21, 22, 23, 24, 25, 26}, 0, 6); 464 setValuesBad(full, 1, new int[] {20, 21, 22, 23, 24, 25, 26}, 0, 5); 465 setValuesBad(full, 2, new int[] {20, 21, 22, 23, 24, 25, 26}, 0, 4); 466 setValuesBad(full, 3, new int[] {20, 21, 22, 23, 24, 25, 26}, 0, 3); 467 setValuesBad(full, 4, new int[] {20, 21, 22, 23, 24, 25, 26}, 0, 2); 468 setValuesBad(full, 5, new int[] {20, 21, 22, 23, 24, 25, 26}, 0, 1); 469 setValuesBad(full, 6, new int[] {20, 21, 22, 23, 24, 25, 26}, 0, 0); 470 setValuesBad(full, 2, new int[] {20, 21, 22, 23, 24, 25, 26}, 1, 4); 471 setValuesBad(full, 3, new int[] {20, 21, 22, 23, 24, 25, 26}, 1, 3); 472 setValuesBad(full, 4, new int[] {20, 21, 22, 23, 24, 25, 26}, 2, 2); 473 setValuesBad(full, 5, new int[] {20, 21, 22, 23, 24, 25, 26}, 3, 1); 474 setValuesBad(full, 6, new int[] {20, 21, 22, 23, 24, 25, 26}, 4, 0); 475 setValuesBad(empty, 0, new int[] {6}, 0, 1); 476 477 // srcIndex + length > values.size() 478 setValuesBad(full, 0, new int[] {82}, 0, 2); 479 setValuesBad(full, 0, new int[] {82}, 1, 1); 480 setValuesBad(full, 0, new int[] {82}, 2, 0); 481 setValuesBad(full, 0, new int[] {20, 21, 22}, 0, 4); 482 setValuesBad(full, 0, new int[] {20, 21, 22}, 1, 3); 483 setValuesBad(full, 0, new int[] {20, 21, 22}, 2, 2); 484 setValuesBad(full, 0, new int[] {20, 21, 22}, 3, 1); 485 setValuesBad(full, 0, new int[] {20, 21, 22}, 4, 0); 486 487 check(full, new int[] {82, 84, 95, 21, 22}); 488 489 /* 490 * resume the target until end 491 */ 492 listenUntilVMDisconnect(); 493 494 /* 495 * deal with results of test 496 * if anything has called failure("foo") testFailed will be true 497 */ 498 if (!testFailed) { 499 println("ArrayRangeTest: passed"); 500 } else { 501 throw new Exception("ArrayRangeTest: failed"); 502 } 503 } 504 }