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 
main(String[] args)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 {
Sample(String name, ArrayReference arrRef, int[] expected)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 
ArrayRangeTest(String args[])69     ArrayRangeTest (String args[]) {
70         super(args);
71     }
72 
main(String[] args)73     public static void main(String[] args)      throws Exception {
74         new ArrayRangeTest(args).startTests();
75     }
76 
77     /********** test assist **********/
78 
arr(int a[])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 
getValueGood(Sample samp, int index)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 
getValueBad(Sample samp, int index)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 
getValuesGood(Sample samp)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 
getValuesGood(Sample samp, int index, int length)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 
getValuesBad(Sample samp, int index, int length)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 
setValueGood(Sample samp, int index, int ival)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 
setValueBad(Sample samp, int index, int ival)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 
setValuesGood(Sample samp, int[] valArray)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 
setValuesGood(Sample samp, int index, int[] valArray, int srcInx, int length)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 
setValuesBad(Sample samp, int index, int[] valArray, int srcInx, int length)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 
check(Sample samp, int[] expectArray)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 
runTests()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 }
505