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