1 /*
   2  * Copyright (c) 2010, 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 /* @test
  25  * @summary Check that error cases are replaced correctly in String/ISR/OSW
  26  * @bug 4457851 7096080
  27  *
  28  * @build Errors Util
  29  * @run main Errors
  30  */
  31 
  32 import java.io.*;
  33 import java.nio.*;
  34 
  35 
  36 public class Errors {
  37 
  38     static PrintStream log = System.err;
  39     static int failures = 0;
  40 
  41     static final byte Q = (byte)'?';
  42     static final byte X = (byte)'x';
  43     static final byte Y = (byte)'y';
  44     static final byte Z = (byte)'z';
  45 
  46     static abstract class Test {
  47 
  48         protected final String csn;
  49         protected final String what;
  50 
  51         Test(String csn, String what) {
  52             this.csn = csn;
  53             this.what = what;
  54         }
  55 
  56         abstract byte[] enc(String s) throws IOException;
  57 
  58         Test test(String s, byte[] ref) {
  59             log.print("  " + Util.toString(s.toCharArray()));
  60             byte[] ba = null;
  61             try {
  62                 ba = enc(s);
  63             } catch (IOException x) {
  64                 log.println(" -e-> ERROR: " + x.getClass().getName());
  65                 failures++;
  66                 return this;
  67             }
  68             log.println(" -e-> " + Util.toString(ba));
  69             int i = Util.cmp(ba, ref);
  70             if (i >= 0) {
  71                 log.println("    ERROR: Mismatch at index " + i
  72                             + ", expected: " + Util.toString(ref));
  73                 failures++;
  74             }
  75             return this;
  76         }
  77 
  78         abstract String dec(byte[] ba) throws IOException;
  79 
  80         Test test(byte[] ba, String ref) {
  81             log.print("  " + Util.toString(ba));
  82             String s = null;
  83             try {
  84                 s = dec(ba);
  85             } catch (IOException x) {
  86                 log.println(" -d-> ERROR: " + x.getClass().getName());
  87                 failures++;
  88                 return this;
  89             }
  90             log.println(" -d-> " + Util.toString(s.toCharArray()));
  91             char[] ca = s.toCharArray();
  92             char[] refa = ref.toCharArray();
  93             int i = Util.cmp(ca, refa);
  94             if (i >= 0) {
  95                 log.println("    ERROR: Mismatch at index " + i
  96                             + ", expected: " + Util.toString(refa));
  97                 failures++;
  98             }
  99             return this;
 100         }
 101 
 102         Test run() {
 103             log.println(csn + ", " + what);
 104 
 105             test("xyzzy", new byte[] { X, Y, Z, Z, Y });
 106 
 107             // Malformed surrogates
 108             test("\uD800x", new byte[] { Q, X });
 109             test("\uDC00x", new byte[] { Q, X });
 110             test("\uD800\uDB00x", new byte[] { Q, Q, X });
 111 
 112             return this;
 113         }
 114 
 115     }
 116 
 117     static class TestStream extends Test {
 118 
 119         TestStream(String csn) {
 120             super(csn, "I/O streams");
 121         }
 122 
 123         byte[] enc(String s) throws IOException {
 124             ByteArrayOutputStream bos = new ByteArrayOutputStream();
 125             Writer wr = new OutputStreamWriter(bos, csn);
 126             wr.write(s);
 127             wr.close();
 128             return bos.toByteArray();
 129         }
 130 
 131         String dec(byte[] ba) throws IOException {
 132             ByteArrayInputStream bis = new ByteArrayInputStream(ba);
 133             Reader rd = new InputStreamReader(bis, csn);
 134             char[] ca = new char[1024];
 135             int n = rd.read(ca);
 136             String s = new String(ca, 0, n);
 137             rd.close();
 138             return s;
 139         }
 140 
 141     }
 142 
 143     static class TestString extends Test {
 144 
 145         TestString(String csn) {
 146             super(csn, "strings");
 147         }
 148 
 149         byte[] enc(String s) throws IOException {
 150             return s.getBytes(csn);
 151         }
 152 
 153         String dec(byte[] ba) throws IOException {
 154             return new String(ba, 0, ba.length, csn);
 155         }
 156 
 157     }
 158 
 159     static void test_US_ASCII(Test t) {
 160         t.run();
 161         t.test("\u0080", new byte[] { Q });
 162         t.test("\u0100", new byte[] { Q });
 163         t.test("\uD800\uDC00", new byte[] { Q });
 164         t.test("\uF000", new byte[] { Q });
 165         t.test("\uFFFE", new byte[] { Q });
 166         t.test("\uFFFF", new byte[] { Q });
 167         t.test(new byte[] { X, (byte)0x7f, Y }, "x\u007Fy");
 168         t.test(new byte[] { X, (byte)0x80, Y }, "x\uFFFDy");
 169         t.test(new byte[] { (byte)0xf0, (byte)0xf0 }, "\uFFFD\uFFFD");
 170     }
 171 
 172     static void test_ISO_8859_1(Test t) {
 173         t.run();
 174         t.test("\u0080", new byte[] { (byte)0x80 });
 175         t.test("\u0100", new byte[] { Q });
 176         t.test("\uD800\uDC00x", new byte[] { Q, X });
 177         t.test("\uF000", new byte[] { Q });
 178         t.test("\uFFFE", new byte[] { Q });
 179         t.test("\uFFFF", new byte[] { Q });
 180         t.test(new byte[] { X, (byte)0x7f, Y }, "x\u007Fy");
 181         t.test(new byte[] { X, (byte)0x80, Y }, "x\u0080y");
 182         t.test(new byte[] { (byte)0xf0, (byte)0xf0 }, "\u00F0\u00F0");
 183     }
 184 
 185     static void test_UTF_8(Test t) {
 186         t.run();
 187         t.test("\u0080", new byte[] { (byte)0xC2, (byte)0x80 });
 188         t.test("\u0100", new byte[] { (byte)0xC4, (byte)0x80 });
 189         t.test("\uD800\uDC00",
 190                new byte[] { (byte)0xF0, (byte)0x90, (byte)0x80, (byte)0x80 });
 191         t.test("\uF000", new byte[] { (byte)0xEF, (byte)0x80, (byte)0x80 });
 192         t.test("\uFFFE", new byte[] { (byte)0xEF, (byte)0xBF, (byte)0xBE });
 193         t.test("\uFFFF", new byte[] { (byte)0xEF, (byte)0xBF, (byte)0xBF });
 194         t.test(new byte[] { X, (byte)0x7f, Y }, "x\u007Fy");
 195         t.test(new byte[] { X, (byte)0x80, Y }, "x\uFFFDy");
 196     }
 197 
 198     public static void main(String[] args) throws Exception {
 199         test_US_ASCII(new TestString("US-ASCII"));
 200         test_US_ASCII(new TestStream("US-ASCII"));
 201 
 202         test_ISO_8859_1(new TestString("ISO-8859-1"));
 203         test_ISO_8859_1(new TestStream("ISO-8859-1"));
 204 
 205         test_ISO_8859_1(new TestString("ISO-8859-15"));
 206         test_ISO_8859_1(new TestStream("ISO-8859-15"));
 207 
 208         test_UTF_8(new TestString("UTF-8"));
 209         test_UTF_8(new TestStream("UTF-8"));
 210 
 211         if (failures > 0) {
 212             log.println();
 213             throw new Exception("Tests failed: " + failures);
 214         }
 215 
 216     }
 217 
 218 }