test/sun/nio/cs/MalformedSurrogates.java
Print this page
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
@@ -26,60 +26,131 @@
@summary Malformed surrogates should be handled by the converter in
substitution mode.
*/
import java.io.*;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
+import java.nio.CharBuffer;
+import java.nio.ByteBuffer;
+import java.nio.charset.CodingErrorAction;
+import java.nio.charset.MalformedInputException;
+import java.nio.charset.UnmappableCharacterException;
+import java.util.SortedMap;
public class MalformedSurrogates {
+ private static final String PREFIX = "abc";
+ private static final String SUFFIX = "efgh";
+ private static final String MALFORMED_SURROGATE = PREFIX + "\uD800\uDB00" + SUFFIX;
+ private static final String NORMAL_SURROGATE = PREFIX + "\uD800\uDC00" + SUFFIX;
+ public static void main(String[] args) throws IOException {
+ SortedMap<String, Charset> map = Charset.availableCharsets();
+ for (String name : map.keySet()) {
+ Charset charset = map.get(name);
+ boolean canEncode = charset.canEncode();
+ CharsetEncoder en = null;
+ CharsetDecoder de = null;
+ try {
+ en = charset.newEncoder();
+ } catch (UnsupportedOperationException ex) {
+ if (canEncode) {
+ throw ex;
+ }
+ }
+ try {
+ de = charset.newDecoder();
+ } catch (UnsupportedOperationException ex) {
+ if (canEncode) {
+ throw ex;
+ }
+ }
- public static void main(String[] args) throws Exception {
+ if (!canEncode) {
+ continue;
+ }
- String fe = System.getProperty("file.encoding");
- if ( fe.equalsIgnoreCase("UTF8")
- || fe.equalsIgnoreCase("UTF-8")
- || fe.equalsIgnoreCase("UTF_8"))
- // This test is meaningless if the default charset
- // does handle surrogates
- return;
-
- System.out.println("Testing string conversion...");
- /* Example with malformed surrogate, and an offset */
- String t = "abc\uD800\uDB00efgh";
- String t2 = t.substring(2);
- byte[] b = t2.getBytes();
- System.err.println(b.length);
- for (int i = 0; i < b.length; i++)
- System.err.println("[" + i + "]" + "=" + (char) b[i]
- + "=" + (int) b[i]);
- if (b.length != 7) {
- throw new Exception("Bad string conversion for bad surrogate");
- }
-
- /* Example with a proper surrogate, no offset. Always worked */
- String t3 = "abc\uD800\uDC00efgh";
- byte[] b2 = t3.getBytes();
- System.out.println(b2.length);
- for(int i = 0; i < b2.length; i++)
- System.err.println("[" + i + "]" + "=" + (char) b2[i]);
- if (b2.length != 8) {
- throw new Exception("Bad string conversion for good surrogate");
- }
-
- OutputStream os = new ByteArrayOutputStream();
- OutputStreamWriter osw = new OutputStreamWriter(os);
- System.out.println("Testing flush....");
- /* Check for the case where the converter has a left over
- high surrogate when flush is called on the converter */
- osw.flush();
- String s = "abc\uD800"; // High surrogate
- char[] c = s.toCharArray();
- osw.write(s, 0, 4);
- osw.flush();
+ boolean supported =true;
+ try {
+ supported = en.canEncode(NORMAL_SURROGATE);
+ } catch (UnsupportedOperationException ex) {
+ supported = false;
+ } finally {
+ en.reset();
+ }
+ String[] arr = new String[] {MALFORMED_SURROGATE, NORMAL_SURROGATE};
+ for (String surrogate : arr) {
+ canEncode = false;
+ try {
+ canEncode = en.canEncode(surrogate);
+ en.encode(CharBuffer.wrap(surrogate));
+ } catch (MalformedInputException | UnmappableCharacterException ex) {
+ if (canEncode) {
+ throw ex;
+ }
+ } catch (UnsupportedOperationException ex) {
+ if (supported) {
+ throw ex;
+ }
+ }
+ finally {
+ en.reset();
+ }
+
+ try (OutputStreamWriter osw = new OutputStreamWriter(new ByteArrayOutputStream(), en)) {
+ osw.write(surrogate);
+ } catch (MalformedInputException | UnmappableCharacterException ex) {
+ if (canEncode) {
+ throw ex;
+ }
+ } catch (IllegalStateException ex) {
+ if (supported) {
+ throw ex;
+ }
+ }finally {
+ en.reset();
+ }
+
+ // Continue if charset doesn't support surrogate
+ if (!supported) {
+ continue;
+ }
+
+ String expected = NORMAL_SURROGATE;
+
+ try {
+ if (!canEncode) {
+ en.onMalformedInput(CodingErrorAction.REPLACE);
+ en.onUnmappableCharacter(CodingErrorAction.REPLACE);
+ expected = PREFIX + new String(en.replacement(), charset) + new String(en.replacement(), charset) + SUFFIX;
+ }
- System.out.println("Testing convert...");
- /* Verify that all other characters go through */
- for (int k = 1; k < 65535 ; k++) {
- osw.write("Char[" + k + "]=\"" + ((char) k) + "\"");
+ ByteBuffer bbuf = en.encode(CharBuffer.wrap(surrogate));
+ CharBuffer cbuf = de.decode(bbuf);
+ if (!cbuf.toString().equals(expected)) {
+ throw new RuntimeException("charset " + charset.name() + " (en)decoded the surrogate " + surrogate + " to " + cbuf.toString() + " which is not same as the expected " + expected);
+ }
+ } finally {
+ en.reset();
+ de.reset();
}
+ try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ OutputStreamWriter osw = new OutputStreamWriter(bos, en);) {
+ osw.write(surrogate);
+ osw.flush();
+ try (InputStreamReader isr = new InputStreamReader(new ByteArrayInputStream(bos.toByteArray()), de)) {
+ CharBuffer cbuf = CharBuffer.allocate(expected.length());
+ isr.read(cbuf);
+ cbuf.rewind();
+ if (!cbuf.toString().equals(expected)) {
+ throw new RuntimeException("charset " + charset.name() + " (en)decoded the surrogate " + surrogate + " to " + cbuf.toString() + " which is not same as the expected " + expected);
+ }
+ }
+ } finally {
+ en.reset();
+ de.reset();
+ }
+ }
+ }
}
}