test/sun/nio/cs/MalformedSurrogates.java

Print this page


   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 4153987
  26    @summary Malformed surrogates should be handled by the converter in
  27    substitution mode.
  28  */
  29 
  30 import java.io.*;









  31 
  32 public class MalformedSurrogates {

























  33 
  34     public static void main(String[] args) throws Exception {


  35 
  36         String fe = System.getProperty("file.encoding");
  37         if (  fe.equalsIgnoreCase("UTF8")
  38               || fe.equalsIgnoreCase("UTF-8")
  39               || fe.equalsIgnoreCase("UTF_8"))
  40             // This test is meaningless if the default charset
  41             // does handle surrogates
  42             return;
  43 
  44         System.out.println("Testing string conversion...");
  45         /* Example with malformed surrogate, and an offset */
  46         String t = "abc\uD800\uDB00efgh";
  47         String t2 = t.substring(2);
  48         byte[] b = t2.getBytes();
  49         System.err.println(b.length);
  50         for (int i = 0; i < b.length; i++)
  51             System.err.println("[" + i + "]" + "=" + (char) b[i]
  52                                + "=" + (int) b[i]);
  53         if (b.length != 7) {
  54             throw new Exception("Bad string conversion for bad surrogate");
  55         }
  56 
  57         /* Example with a proper surrogate, no offset. Always worked */
  58         String t3 = "abc\uD800\uDC00efgh";
  59         byte[] b2 = t3.getBytes();
  60         System.out.println(b2.length);
  61         for(int i = 0; i < b2.length; i++)
  62             System.err.println("[" + i + "]" + "=" + (char) b2[i]);
  63         if (b2.length != 8) {
  64             throw new Exception("Bad string conversion for good surrogate");
  65         }
  66 
  67         OutputStream os = new ByteArrayOutputStream();
  68         OutputStreamWriter osw = new OutputStreamWriter(os);
  69         System.out.println("Testing flush....");
  70         /* Check for the case where the converter has a left over
  71            high surrogate when flush is called on the converter */
  72         osw.flush();
  73         String s = "abc\uD800"; // High surrogate
  74         char[] c = s.toCharArray();
  75         osw.write(s, 0, 4);
  76         osw.flush();













  77 
  78         System.out.println("Testing convert...");
  79         /* Verify that all other characters go through */
  80         for (int k = 1; k < 65535 ; k++) {
  81             osw.write("Char[" + k + "]=\"" + ((char) k) + "\"");




  82         }
  83 


















  84     }
  85 }
   1 /*
   2  * Copyright (c) 2002, 2013, 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 4153987
  26    @summary Malformed surrogates should be handled by the converter in
  27    substitution mode.
  28  */
  29 
  30 import java.io.*;
  31 import java.nio.charset.Charset;
  32 import java.nio.charset.CharsetDecoder;
  33 import java.nio.charset.CharsetEncoder;
  34 import java.nio.CharBuffer;
  35 import java.nio.ByteBuffer;
  36 import java.nio.charset.CodingErrorAction;
  37 import java.nio.charset.MalformedInputException;
  38 import java.nio.charset.UnmappableCharacterException;
  39 import java.util.SortedMap;
  40 
  41 public class MalformedSurrogates {
  42     private static final String PREFIX = "abc";
  43     private static final String SUFFIX = "efgh";
  44     private static final String MALFORMED_SURROGATE = PREFIX + "\uD800\uDB00" + SUFFIX;
  45     private static final String NORMAL_SURROGATE = PREFIX + "\uD800\uDC00" + SUFFIX;
  46     public static void main(String[] args) throws IOException {
  47         SortedMap<String, Charset> map = Charset.availableCharsets();
  48         for (String name : map.keySet()) {
  49             Charset charset = map.get(name);
  50             boolean canEncode = charset.canEncode();
  51             CharsetEncoder en = null;
  52             CharsetDecoder de = null;
  53             try {
  54                 en = charset.newEncoder();
  55             } catch (UnsupportedOperationException ex) {
  56                 if (canEncode) {
  57                     throw ex;
  58                 }
  59             }
  60             try {
  61                 de = charset.newDecoder();
  62             } catch (UnsupportedOperationException ex) {
  63                 if (canEncode) {
  64                     throw ex;
  65                 }
  66             }
  67             
  68             if (!canEncode) {
  69                 continue;
  70             }
  71             
  72             boolean supported =true;
  73             try {
  74                 supported = en.canEncode(NORMAL_SURROGATE);
  75             } catch (UnsupportedOperationException ex) {
  76                 supported = false;
  77             } finally {
  78                 en.reset();
  79             }
  80             String[] arr = new String[] {MALFORMED_SURROGATE, NORMAL_SURROGATE};
  81             for (String surrogate : arr) {
  82                 canEncode = false;
  83                 try {
  84                     canEncode = en.canEncode(surrogate);
  85                     en.encode(CharBuffer.wrap(surrogate));
  86                 } catch (MalformedInputException | UnmappableCharacterException ex) {
  87                     if (canEncode) {
  88                         throw ex;
  89                     }
  90                 } catch (UnsupportedOperationException ex) {
  91                     if (supported) {
  92                         throw ex;
  93                     }
  94                 }
  95                 finally {
  96                     en.reset();
  97                 }
  98                 
  99                 try (OutputStreamWriter osw = new OutputStreamWriter(new ByteArrayOutputStream(), en)) {
 100                     osw.write(surrogate);
 101                 } catch (MalformedInputException | UnmappableCharacterException ex) {
 102                     if (canEncode) {
 103                         throw ex;
 104                     }
 105                 } catch (IllegalStateException ex) {
 106                     if (supported) {
 107                         throw ex;
 108                     }
 109                 }finally {
 110                     en.reset();
 111                 }
 112                 
 113                 // Continue if charset doesn't support surrogate
 114                 if (!supported) {
 115                     continue;
 116                 }
 117                 
 118                 String expected = NORMAL_SURROGATE;
 119                 
 120                 try {
 121                     if (!canEncode) {
 122                         en.onMalformedInput(CodingErrorAction.REPLACE);
 123                         en.onUnmappableCharacter(CodingErrorAction.REPLACE);
 124                         expected = PREFIX + new String(en.replacement(), charset) + new String(en.replacement(), charset) + SUFFIX;
 125                     }
 126 
 127                     ByteBuffer bbuf = en.encode(CharBuffer.wrap(surrogate));
 128                     CharBuffer cbuf = de.decode(bbuf);
 129                     if (!cbuf.toString().equals(expected)) {
 130                         throw new RuntimeException("charset " + charset.name() + " (en)decoded the surrogate " + surrogate + " to " + cbuf.toString() + " which is not same as the expected " + expected);
 131                     }
 132                 } finally {
 133                     en.reset();
 134                     de.reset();
 135                 }
 136                 
 137                 try (ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
 138                      OutputStreamWriter osw = new OutputStreamWriter(bos, en);) {
 139                     osw.write(surrogate);
 140                     osw.flush();
 141                     try (InputStreamReader isr = new InputStreamReader(new ByteArrayInputStream(bos.toByteArray()), de)) {
 142                         CharBuffer cbuf = CharBuffer.allocate(expected.length());
 143                         isr.read(cbuf);
 144                         cbuf.rewind();               
 145                         if (!cbuf.toString().equals(expected)) {
 146                             throw new RuntimeException("charset " + charset.name() + " (en)decoded the surrogate " + surrogate + " to " + cbuf.toString() + " which is not same as the expected " + expected);
 147                         }
 148                     }
 149                 } finally {
 150                     en.reset();
 151                     de.reset();
 152                 }
 153             }
 154         }
 155     }
 156 }