1/*
2 * Copyright (c) 2002, 2006, 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 4472841 4703640 4705681 4705683 4833095 5005831
27 * @summary Verify that constructor exceptions are thrown as expected.
28 */
29
30import java.io.UnsupportedEncodingException;
31import java.nio.charset.Charset;
32
33public class Exceptions {
34    private static final byte [] b = { 0x48, 0x69, 0x2c, 0x20,
35                                       0x44, 0x75, 0x6b, 0x65, 0x21 };
36
37    private static final char [] c
38        = "Attack of the Killer Tomatoes!".toCharArray();
39
40    private static boolean ok = true;
41
42    private static void fail(Class ex, String s) {
43        ok = false;
44        System.err.println("expected " + ex.getName() + " for " + s
45                               + " - FAILED");
46    }
47
48    private static void pass(String s) {
49        System.out.println(s + " -- OK");
50    }
51
52    private static void tryCatch(String s, Class ex, Runnable thunk) {
53        Throwable t = null;
54        try {
55            thunk.run();
56        } catch (Throwable x) {
57            if (ex.isAssignableFrom(x.getClass()))
58                t = x;
59            else
60                x.printStackTrace();
61        }
62        if ((t == null) && (ex != null))
63            fail(ex, s);
64        else
65            pass(s);
66    }
67
68    // -- Constructors --
69
70    private static void noArgs() {
71        System.out.println("String()");
72        tryCatch("  default ctor", null, new Runnable() {
73                public void run() {
74                    new String();
75                }});
76    }
77
78    private static void string() {
79        System.out.println("String(String original)");
80        tryCatch("  \"foo\"", null, new Runnable() {
81                public void run() {
82                    new String("foo");
83                }});
84        tryCatch("  null", NullPointerException.class, new Runnable() {
85                public void run() {
86                    new String((String) null);
87                }});
88    }
89
90    private static void charArray() {
91        System.out.println("String(char value[])");
92        tryCatch("  char [] = \"Duke says \"Hi!\"\"", null, new Runnable() {
93                public void run() {
94                    new String("Duke says \"Hi!\"".toCharArray());
95                }});
96        tryCatch("  null", NullPointerException.class, new Runnable() {
97                public void run() {
98                    new String((char []) null);
99                }});
100    }
101
102    private static void charArrayOffCount() {
103        System.out.println("String(char value[], int offset, int count)");
104        tryCatch("  c, 0, 3", null, new Runnable() {
105                public void run() {
106                    new String(c, 0, 3);
107                }});
108        tryCatch("  null, 1, 2", NullPointerException.class, new Runnable() {
109                public void run() {
110                    new String((char []) null, 1, 2);
111                }});
112        tryCatch("  c, -1, 4", IndexOutOfBoundsException.class,
113                 new Runnable() {
114                         public void run() {
115                             new String(c, -1, 4);
116                         }});
117        tryCatch("  c, 1, -1", IndexOutOfBoundsException.class,
118                 new Runnable() {
119                         public void run() {
120                             new String(c, 1, -1);
121                         }});
122        tryCatch("  c, c.lengh + 1, 1", IndexOutOfBoundsException.class,
123                 new Runnable() {
124                         public void run() {
125                             new String(c, c.length + 1, 1);
126                         }});
127        tryCatch("  c, 0, c.length + 1", IndexOutOfBoundsException.class,
128                 new Runnable() {
129                         public void run() {
130                             new String(c, 0, c.length + 1);
131                         }});
132    }
133
134    private static void byteArrayHiOffCount() {
135        System.out.println("String(byte ascii[], int hibyte, int offset, "
136                           + "int count)");
137        tryCatch("  b, 0, 0, b.length", null, new Runnable() {
138                public void run() {
139                    System.out.println(new String(b, 0, 0, b.length));
140                }});
141
142        tryCatch("  b, -1, 4, 4", null, new Runnable() {
143                public void run() {
144                    new String(b, -1, 4, 4);
145                }});
146        tryCatch("  null, 0, 0, 0", NullPointerException.class,
147                 new Runnable() {
148                         public void run() {
149                             new String((byte[]) null, 0, 0, 0);
150                         }});
151        tryCatch("  b, 0, -1, r", IndexOutOfBoundsException.class,
152                 new Runnable() {
153                         public void run() {
154                             new String(b, 0, -1, 4);
155                         }});
156        tryCatch("  b, 0, 4, -1", IndexOutOfBoundsException.class,
157                 new Runnable() {
158                         public void run() {
159                             new String(b, 0, 4, -1);
160                         }});
161        tryCatch("  b, 0, b.length + 1, 1", IndexOutOfBoundsException.class,
162                 new Runnable() {
163                         public void run() {
164                             new String(b, 0, b.length + 1, 1);
165                         }});
166        tryCatch("  b, 0, 0, b.length + 1", IndexOutOfBoundsException.class,
167                 new Runnable() {
168                         public void run() {
169                             new String(b, 0, 0, b.length + 1);
170                         }});
171    }
172
173    private static void byteArrayHi() {
174        System.out.println("String(byte ascii[], int hibyte)");
175        tryCatch("  b, 0", null, new Runnable() {
176                public void run() {
177                    new String(b, 0);
178                }});
179        tryCatch("  null, 0", NullPointerException.class, new Runnable() {
180                public void run() {
181                    new String((byte []) null, 0);
182                }});
183    }
184
185    private static void byteArrayOffLengthCharset0(String s, Class ex,
186                                                   byte [] b, int off,
187                                                   int len, Object cs)
188    {
189        Throwable t = null;
190        try {
191            if (cs instanceof String)
192                new String(b, off, len, (String)cs);
193            else // (cs instanceof Charset)
194                new String(b, off, len, (Charset)cs);
195        } catch (Throwable x) {
196            if (ex.isAssignableFrom(x.getClass()))
197                t = x;
198            else
199                x.printStackTrace();
200        }
201        if ((t == null) && (ex != null))
202            fail(ex, s);
203        else
204            pass(s);
205    }
206
207    private static void byteArrayOffLengthCharsetName() {
208        System.out.println("String(byte bytes[], int offset, int length, "
209                           + "String charsetName)");
210        System.out.println("  throws UnsupportedEncodingException");
211        String enc = "UTF-8";
212        byteArrayOffLengthCharset0("  b, 0, 0," + enc, null, b, 0, 0, enc);
213        byteArrayOffLengthCharset0("  null, 0, 0," + enc,
214                                   NullPointerException.class,
215                                   (byte []) null, 0, 0, enc);
216        byteArrayOffLengthCharset0("  b, -1, 0, " + enc,
217                                   IndexOutOfBoundsException.class,
218                                   b, -1, 0, enc);
219        byteArrayOffLengthCharset0("  b, 0, -1, " + enc,
220                                   IndexOutOfBoundsException.class,
221                                   b, 0, -1, enc);
222        byteArrayOffLengthCharset0("  b, b.length + 1, 1, " + enc,
223                                   IndexOutOfBoundsException.class,
224                                   b, b.length + 1, 1, enc);
225        byteArrayOffLengthCharset0("  b, 0, b.length + 1 " + enc,
226                                   IndexOutOfBoundsException.class,
227                                   b, 0, b.length + 1, enc);
228        byteArrayOffLengthCharset0("  b, -1, 0, null",
229                                   NullPointerException.class,
230                                   b, -1, 0, null);
231        byteArrayOffLengthCharset0("  b, 0, b.length, foo",
232                                   UnsupportedEncodingException.class,
233                                   b, 0, b.length, "foo");
234    }
235
236    private static void byteArrayOffLengthCharset() {
237        System.out.println("String(byte bytes[], int offset, int length, "
238                           + "Charset charset)");
239        Charset cs = Charset.forName("UTF-16BE");
240        byteArrayOffLengthCharset0("  b, 0, 0," + cs, null, b, 0, 0, cs);
241        byteArrayOffLengthCharset0("  null, 0, 0," + cs,
242                                   NullPointerException.class,
243                                   (byte []) null, 0, 0, cs);
244        byteArrayOffLengthCharset0("  b, -1, 0, " + cs,
245                                   IndexOutOfBoundsException.class,
246                                   b, -1, 0, cs);
247        byteArrayOffLengthCharset0("  b, 0, -1, " + cs,
248                                   IndexOutOfBoundsException.class,
249                                   b, 0, -1, cs);
250        byteArrayOffLengthCharset0("  b, b.length + 1, 1, " + cs,
251                                   IndexOutOfBoundsException.class,
252                                   b, b.length + 1, 1, cs);
253        byteArrayOffLengthCharset0("  b, 0, b.length + 1 " + cs,
254                                   IndexOutOfBoundsException.class,
255                                   b, 0, b.length + 1, cs);
256        byteArrayOffLengthCharset0("  b, -1, 0, null",
257                                   NullPointerException.class,
258                                   b, -1, 0, null);
259    }
260
261    private static void byteArrayCharset0(String s, Class ex, byte [] b,
262                                          Object cs)
263    {
264        Throwable t = null;
265        try {
266            if (cs instanceof String)
267                new String(b, (String)cs);
268            else // (cs instanceof Charset)
269                new String(b, (Charset)cs);
270        } catch (Throwable x) {
271            if (ex.isAssignableFrom(x.getClass()))
272                t = x;
273            else
274                x.printStackTrace();
275        }
276        if ((t == null) && (ex != null))
277            fail(ex, s);
278        else
279            pass(s);
280    }
281
282    private static void byteArrayCharsetName() {
283        System.out.println("String(byte bytes[], String charsetName)");
284        System.out.println("  throws UnsupportedEncodingException");
285        String enc = "US-ASCII";
286        byteArrayCharset0("  b, " + enc, null, b, enc);
287        byteArrayCharset0("  null, " + enc, NullPointerException.class,
288                          (byte []) null, enc);
289        byteArrayCharset0("  b, null", NullPointerException.class, b, null);
290        byteArrayCharset0("  null, null", NullPointerException.class,
291                          (byte []) null, null);
292        byteArrayCharset0("  b, bar", UnsupportedEncodingException.class,
293                          b, "bar");
294    }
295
296    private static void byteArrayCharset() {
297        System.out.println("String(byte bytes[], Charset charset)");
298        Charset cs = Charset.forName("ISO-8859-1");
299        byteArrayCharset0("  b, " + cs, null, b, cs);
300        byteArrayCharset0("  null, " + cs, NullPointerException.class,
301                          (byte []) null, cs);
302        byteArrayCharset0("  b, null", NullPointerException.class, b, null);
303        byteArrayCharset0("  null, null", NullPointerException.class,
304                          (byte []) null, null);
305    }
306
307    private static void byteArrayOffLength() {
308        System.out.println("String(byte bytes[], int offset, int length)");
309        tryCatch("  b, 0, b.length", null, new Runnable() {
310                public void run() {
311                    new String(b, 0, b.length);
312                }});
313        tryCatch("  null, 0, 0", NullPointerException.class, new Runnable() {
314                public void run() {
315                    new String((byte []) null, 0, 0);
316                }});
317        tryCatch("  b, -1, b.length", IndexOutOfBoundsException.class,
318                 new Runnable() {
319                         public void run() {
320                             new String(b, -1, b.length);
321                         }});
322        tryCatch("  b, 0, -1", IndexOutOfBoundsException.class,
323                 new Runnable() {
324                         public void run() {
325                             new String(b, 0, -1);
326                         }});
327        tryCatch("  b, b.length + 1, 1", IndexOutOfBoundsException.class,
328                 new Runnable() {
329                         public void run() {
330                             new String(b, b.length + 1, 1);
331                         }});
332        tryCatch("  b, 0, b.length", IndexOutOfBoundsException.class,
333                 new Runnable() {
334                         public void run() {
335                             new String(b, 0, b.length + 1);
336                         }});
337    }
338
339    private static void byteArray() {
340        System.out.println("String(byte bytes[])");
341        tryCatch("  b", null, new Runnable() {
342                public void run() {
343                    new String(b);
344                }});
345        tryCatch("  null", NullPointerException.class, new Runnable() {
346                public void run() {
347                    new String((byte []) null);
348                }});
349    }
350
351    private static void stringBuffer() {
352        System.out.println("String(StringBuffer buffer)");
353        tryCatch("  \"bar\"", null, new Runnable() {
354                public void run() {
355                    new String(new StringBuffer("bar"));
356                }});
357        tryCatch("  null", NullPointerException.class, new Runnable() {
358                public void run() {
359                    new String((StringBuffer) null);
360                }});
361    }
362
363    // -- Methods --
364
365        private static void getChars() {
366        System.out.println("getChars.(int srcBegin, int srcEnd, char dst[], "
367                           + " int dstBegin");
368        tryCatch("  null", NullPointerException.class, new Runnable() {
369                public void run() {
370                    "foo".getChars(1, 2, null, 1);
371                }});
372    }
373
374    private static void getBytes() {
375        System.out.println("getChars.(int srcBegin, int srcEnd, char dst[], "
376                           + " int dstBegin");
377        tryCatch("  1, 2, null, 1", NullPointerException.class, new Runnable() {
378                public void run() {
379                    "foo".getBytes(1, 2, null, 1);
380                }});
381
382        System.out.println("getBytes.(String charsetName)"
383                           + " throws UnsupportedEncodingException");
384        tryCatch("  null", NullPointerException.class, new Runnable() {
385                public void run() {
386                    try {
387                        "foo".getBytes((String)null);
388                    } catch (UnsupportedEncodingException x) {
389                        throw new RuntimeException(x);
390                    }
391                }});
392
393        System.out.println("getBytes.(Charset charset)");
394        tryCatch("  null", NullPointerException.class, new Runnable() {
395                public void run() {
396                    "foo".getBytes((Charset)null);
397                }});
398    }
399
400    private static void contentEquals() {
401        System.out.println("contentEquals(StringBuffer sb)");
402        tryCatch("  null", NullPointerException.class, new Runnable() {
403                public void run() {
404                    "foo".contentEquals(null);
405                }});
406    }
407
408    private static void compareTo() {
409        System.out.println("compareTo(String anotherString)");
410        tryCatch("  (String) null", NullPointerException.class, new Runnable() {
411                public void run() {
412                    "foo".compareTo((String) null);
413                }});
414
415        /* 4830291 (javac generics bug) causes this test to fail
416        System.out.println("compareTo(Object o)");
417        tryCatch("  (Object) null", NullPointerException.class, new Runnable() {
418                public void run() {
419                    "foo".compareTo((Object) null);
420                }});
421        */
422    }
423
424    private static void compareToIgnoreCase() {
425        System.out.println("compareToIgnoreCase(String anotherString)");
426        tryCatch("  null", NullPointerException.class, new Runnable() {
427                public void run() {
428                    "foo".compareToIgnoreCase((String) null);
429                }});
430    }
431
432    private static void regionMatches() {
433        System.out.println("regionMatches(int toffset, String other,"
434                           + " int ooffset, int len)");
435        tryCatch("  1, null, 1, 1", NullPointerException.class, new Runnable() {
436                public void run() {
437                    "foo".regionMatches(1, null, 1, 1);
438                }});
439
440        System.out.println("regionMatches(boolean ignore, int toffset,"
441                           + " String other, int ooffset, int len)");
442        tryCatch("  true, 1, null, 1, 1", NullPointerException.class,
443                 new Runnable() {
444                         public void run() {
445                             "foo".regionMatches(true, 1, null, 1, 1);
446                         }});
447    }
448
449    private static void startsWith() {
450        System.out.println("startsWith(String prefix, int toffset)");
451        tryCatch("  null, 1", NullPointerException.class, new Runnable() {
452                public void run() {
453                    "foo".startsWith(null, 1);
454                }});
455
456        System.out.println("startsWith(String prefix)");
457        tryCatch("  null", NullPointerException.class, new Runnable() {
458                public void run() {
459                    "foo".startsWith(null);
460                }});
461    }
462
463    private static void endsWith() {
464        System.out.println("endsWith(String suffix)");
465        tryCatch("  null", NullPointerException.class, new Runnable() {
466                public void run() {
467                    "foo".endsWith(null);
468                }});
469    }
470
471    private static void indexOf() {
472        System.out.println("indexOf(String str)");
473        tryCatch("  null", NullPointerException.class, new Runnable() {
474                public void run() {
475                    "foo".indexOf(null);
476                }});
477
478        System.out.println("indexOf(String str, int fromIndex)");
479        tryCatch("  null, 1", NullPointerException.class, new Runnable() {
480                public void run() {
481                    "foo".indexOf(null, 1);
482                }});
483    }
484
485    private static void lastIndexOf() {
486        System.out.println("lastIndexOf(String str)");
487        tryCatch("  null", NullPointerException.class, new Runnable() {
488                public void run() {
489                    "foo".lastIndexOf(null);
490                }});
491
492        System.out.println("lastIndexOf(String str, int fromIndex)");
493        tryCatch("  null, 1", NullPointerException.class, new Runnable() {
494                public void run() {
495                    "foo".lastIndexOf(null, 1);
496                }});
497    }
498
499    private static void concat() {
500        System.out.println("concat(String str)");
501        tryCatch("  null", NullPointerException.class, new Runnable() {
502                public void run() {
503                    "foo".concat(null);
504                }});
505    }
506
507    private static void matches() {
508        System.out.println("matches(String regex)");
509        tryCatch("  null", NullPointerException.class, new Runnable() {
510                public void run() {
511                    "foo".matches(null);
512                }});
513    }
514
515    private static void replaceFirst() {
516        System.out.println("replaceFirst(String regex, String replacement)");
517        tryCatch("  \".\", null", NullPointerException.class, new Runnable() {
518                public void run() {
519                    "foo".replaceFirst(".", null);
520                }});
521        tryCatch("  null, \"-\"", NullPointerException.class, new Runnable() {
522                public void run() {
523                    "foo".replaceFirst(null, "-");
524                }});
525    }
526
527    private static void replaceAll() {
528        System.out.println("replaceAll(String regex, String replacement)");
529        tryCatch("  \".\", null", NullPointerException.class, new Runnable() {
530                public void run() {
531                    "foo".replaceAll(".", null);
532                }});
533        tryCatch("  null, \"-\"", NullPointerException.class, new Runnable() {
534                public void run() {
535                    "foo".replaceAll(null, "-");
536                }});
537    }
538
539    private static void split() {
540        System.out.println("split(String regex, int limit)");
541        tryCatch("  null, 1", NullPointerException.class, new Runnable() {
542                public void run() {
543                    "foo".split(null, 1);
544                }});
545
546        System.out.println("split(String regex, int limit)");
547        tryCatch("  null", NullPointerException.class, new Runnable() {
548                public void run() {
549                    "foo".split(null);
550                }});
551    }
552
553    private static void toLowerCase() {
554        System.out.println("toLowerCase(Locale locale)");
555        tryCatch("  null", NullPointerException.class, new Runnable() {
556                public void run() {
557                    "foo".toLowerCase(null);
558                }});
559    }
560
561    private static void toUpperCase() {
562        System.out.println("toUpperCase(Locale locale)");
563        tryCatch("  null", NullPointerException.class, new Runnable() {
564                public void run() {
565                    "foo".toUpperCase(null);
566                }});
567    }
568
569    private static void valueOf() {
570        System.out.println("valueOf(Object obj)");
571        tryCatch("  null", null, new Runnable() {
572                public void run() {
573                    String.valueOf((Object) null);
574                }});
575
576        System.out.println("valueOf(char data[])");
577        tryCatch("  null", NullPointerException.class, new Runnable() {
578                public void run() {
579                    String.valueOf((char []) null);
580                }});
581
582        System.out.println("valueOf(char data[], int offset, int count)");
583        tryCatch("  null, 1, 2", NullPointerException.class, new Runnable() {
584                public void run() {
585                    String.valueOf((char []) null, 1, 2);
586                }});
587
588    }
589
590    private static void copyValueOf() {
591        System.out.println("copyValueOf(char data[], int offset, int count)");
592        tryCatch("  null, 1, 2", NullPointerException.class, new Runnable() {
593                public void run() {
594                    "foo".copyValueOf((char []) null, 1, 2);
595                }});
596
597        System.out.println("copyVlueOf(char data[])");
598        tryCatch("  null", NullPointerException.class, new Runnable() {
599                public void run() {
600                    String.copyValueOf((char []) null);
601                }});
602    }
603
604    public static void main(String [] args) {
605
606        // -- Constructors --
607
608        noArgs();             // String()
609        string();             // String(String original)
610        charArray();          // String(char value[])
611        charArrayOffCount();  // String(char value[], int offset, int count)
612
613        // String(byte ascii[], int hibyte, int offset, int count)
614        byteArrayHiOffCount();
615
616        byteArrayHi();        // String(byte ascii[], int hibyte)
617
618        // String(byte bytes[], int offset, int length, String charsetName)
619        //   throws UnsupportedEncodingException
620        byteArrayOffLengthCharsetName();
621
622        // String(byte bytes[], int offset, int length, Charset charset)
623        byteArrayOffLengthCharset();
624
625        // String(byte bytes[], String charsetName)
626        //   throws UnsupportedEncodingException
627        byteArrayCharsetName();
628
629        // String(byte bytes[], Charset charset)
630        byteArrayCharset();
631
632        byteArrayOffLength(); // String(byte bytes[], int offset, int length)
633        byteArray();          // String(byte bytes[])
634        stringBuffer();       // String(StringBuffer buffer)
635
636        // -- Methods --
637
638        getChars();           // getChars(int, int. char [], int)
639        getBytes();           // getBytes(int, int, byte [], int),
640                              //   getBytes(Locale)
641                              //   getBytes(String)
642                              //   getBytes(Charset)
643        contentEquals();      // contentEquals(StringBuffer)
644        compareTo();          // compareTo(String), compareTo(Object)
645        compareToIgnoreCase();// compareToIgnoreCase(String)
646        regionMatches();      // regionMatches(int, String, int, int)
647                              //   regionMatches(boolean, int, String, int, int)
648        startsWith();         // startsWith(String, int), startsWith(String)
649        endsWith();           // endsWith(String)
650        indexOf();            // indexOf(String), indexOf(String, int),
651        lastIndexOf();        // lastIndexOf(String), lastIndexOf(String, int)
652        concat();             // concat(String)
653        matches();            // matches(String)
654        replaceFirst();       // replaceFirst(String, String)
655        replaceAll();         // replaceAll(String, String)
656        split();              // split(String, int), split(String)
657        toLowerCase();        // toLowerCase(Locale)
658        toUpperCase();        // toUpperCase(Locale)
659        valueOf();            // valueOf(Object), valueOf(char []),
660                              //   valueOf(char [], int, int)
661        copyValueOf();        // copyValueOf(char [], int, int),
662                              //    copyValueOf(char [])
663
664        if (!ok)
665            throw new RuntimeException("Some tests FAILED");
666        else
667            System.out.println("All tests PASSED");
668    }
669}
670