1 /*
2  * Copyright (c) 2008, 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    @bug 4403848 6348426 6407730
26    @summary Check correctness of the UTF-16 converter in all its flavors
27  */
28 
29 import java.io.IOException;
30 import java.nio.BufferOverflowException;
31 import java.nio.*;
32 import java.nio.charset.*;
33 
34 public class TestUTF_16 {
35 
testDecode(String charset, String expected, byte[] input)36     private static void testDecode(String charset,
37                                    String expected,
38                                    byte[] input)
39     throws Exception
40     {
41         String out = new String(input, charset);
42         if (!out.equals(expected)) {
43             failureReport (out, expected);
44             throw new Exception("UTF_16 Decoding test failed " + charset);
45         }
46     }
47 
testEncode(String charset, String input, byte[] expected)48     private static void testEncode(String charset,
49                                    String input,
50                                    byte[] expected)
51     throws Exception
52     {
53         byte[] testBytes = input.getBytes(charset);
54         for (int i = 0; i< expected.length; i++)
55             if (testBytes[i] != expected[i])
56                 throw new Exception("UTF_16 Encoding test failed " + charset);
57 
58     }
59 
warn(String s)60     private static void warn(String s) {
61         System.err.println("FAILED Test 4403848 UTF-16" +
62                             s) ;
63     }
64 
failureReport(String testStr, String expected)65     private static void failureReport(String testStr,
66                                       String expected) {
67 
68         System.err.println ("Expected Characters:");
69         for (int i = 0; i < expected.length() ; i++) {
70             warn("expected char[" + i + "] : " +
71                   Integer.toHexString((int)expected.charAt(i)) +
72                  "obtained char[" + i + "] : " +
73                   Integer.toHexString((int)testStr.charAt(i)));
74         }
75     }
76 
77     /*
78     private static void checkResult(char[] expected,
79                                     String testStr,
80                                     String testName)
81     throws Exception
82     {
83         if (testStr.length() != expected.length)
84             failureReport(testStr, expected);
85 
86         for (int i = 0; i < testStr.length(); i++) {
87             if (testStr.charAt(i) != expected[i]) {
88                 failureReport(testStr, expected);
89                 throw new Exception ("REGTEST TestUTF16 failed: "
90                                         + testName);
91             }
92         }
93         System.err.println ("Test " + testName + " PASSED");
94         return;
95     }
96     */
97 
test()98     private static void test() throws Exception  {
99 
100             // Tests: Check decoding of UTF-16.
101             //        Ensures correct endian polarity
102             //        of the decoders and appropriate
103             //        interpretation of BOM bytes where
104             //        they are required.
105 
106             // Test 1: BigEndian UTF-16 Decoding
107 
108             testDecode("UTF_16BE", "\u0092\u0093",
109                         new byte[] { (byte) 0x00, (byte) 0x92,
110                                      (byte) 0x00, (byte) 0x93 });
111 
112             // Test 1a: BigEndian UTF-16 Decoding. BOM bytes provided.
113             testDecode("UTF_16BE", "\ufeff\u0092\u0093",
114                         new byte[] { (byte) 0xfe, (byte) 0xff,
115                                      (byte) 0x00, (byte) 0x92,
116                                      (byte) 0x00, (byte) 0x93 });
117 
118             testDecode("UTF_16LE", "\u9200\u9300",
119                         new byte[] { (byte) 0x00, (byte) 0x92,
120                                      (byte) 0x00, (byte) 0x93 });
121 
122             // Test 2a: LittleEndian  UTF-16 Decoding, BOM bytes provided.
123             testDecode("UTF_16LE", "\ufeff\u9200\u9300",
124                         new byte[] { (byte) 0xff, (byte) 0xfe,
125                                      (byte) 0x00, (byte) 0x92,
126                                      (byte) 0x00, (byte) 0x93 });
127 
128             // Test 3: UTF-16 (with mandatory byte order mark) Decoding
129 
130             testDecode("UTF-16", "\u9200\u9300",
131                         new byte[] { (byte) 0xfe, (byte) 0xff,
132                                      (byte) 0x92, (byte) 0x00,
133                                      (byte) 0x93, (byte) 0x00 });
134 
135 
136             // Test 3a: UTF-16 BOM omitted. This should decode OK.
137             testDecode("UTF-16", "\u9200\u9300",
138                         new byte[] { (byte) 0x92, (byte) 0x00,
139                                      (byte) 0x93, (byte) 0x00 });
140 
141 
142             // Test 4: encoding using UTF-16
143             // BOM must be emitted when encoding and must be BigEndian.
144 
145             testEncode("UTF-16", "\u0123",
146                         new byte[] { (byte) 0xfe, (byte) 0xff,
147                                      (byte) 0x01, (byte) 0x23 });
148 
149             // Test 5:
150             if (CoderResult.OVERFLOW !=
151                 Charset.forName("UTF_16")
152                 .newDecoder()
153                 .decode((ByteBuffer.allocate(4)
154                                      .put(new byte[]
155                                           {(byte)0xd8,(byte)0x00,
156                                            (byte)0xdc,(byte)0x01})
157                                      .flip()),
158                         CharBuffer.allocate(1),
159                         true)) {
160                 throw new Exception ("REGTEST TestUTF16 Overflow test failed");
161             }
162 
163             // Test 6: decoding using UTF_16LE_BOM/UnicodeLittle
164             // UnicodeLittle should accept non-BOM byte sequence
165 
166             testDecode("UnicodeLittle", "Arial",
167                         new byte[] { 'A', 0, 'r', 0, 'i', 0, 'a', 0, 'l', 0});
168 
169             System.err.println ("\nPASSED UTF-16 encoder test");
170 
171         // Reversed BOM in middle of stream Negative test.
172 
173         /*
174         boolean caughtException = false;
175         try {
176                 String out = new String(new byte[] {(byte)0x00,
177                                             (byte)0x92,
178                                             (byte)0xff,
179                                             (byte)0xfe},
180                                             "UTF-16");
181         } catch (IOException e) { caughtException = true; }
182 
183         if (caughtException == false)
184            throw new Exception ("Incorrectly parsed BOM in middle of input");
185         */
186 
187             // Fixed included with bug 4403848 fixes buffer sizing
188             // issue due to non provision of additional 2 bytes
189             // headroom for initial BOM bytes for UTF-16 encoding.
190           System.err.println ("OVERALL PASS OF UTF-16 Test");
191    }
192 
main(String[] args)193    public static void main (String[] args) throws Exception {
194      test();
195    }
196 }
197