8001750: CharsetDecoder.replacement should not be changeable except via replaceWith method
authorsherman
Tue, 28 May 2013 10:42:52 -0700
changeset 17723 ae7be7852a99
parent 17722 d891aa9e1b74
child 17724 3d31ab54bbc5
8001750: CharsetDecoder.replacement should not be changeable except via replaceWith method Summary: to make defensive copy for set/get replacement byte array Reviewed-by: martin
jdk/src/share/classes/java/nio/charset/Charset-X-Coder.java.template
jdk/src/share/classes/sun/nio/cs/UTF_8.java
jdk/src/share/classes/sun/nio/cs/ext/DoubleByte.java
jdk/src/share/classes/sun/nio/cs/ext/HKSCS.java
--- a/jdk/src/share/classes/java/nio/charset/Charset-X-Coder.java.template	Tue May 28 16:35:17 2013 +0100
+++ b/jdk/src/share/classes/java/nio/charset/Charset-X-Coder.java.template	Tue May 28 10:42:52 2013 -0700
@@ -34,6 +34,7 @@
 import java.nio.BufferUnderflowException;
 import java.lang.ref.WeakReference;
 import java.nio.charset.CoderMalfunctionError;                  // javadoc
+import java.util.Arrays;
 
 
 /**
@@ -244,7 +245,12 @@
      *          which is never <tt>null</tt> and is never empty
      */
     public final $replType$ replacement() {
+#if[decoder]
         return replacement;
+#end[decoder]
+#if[encoder]
+        return Arrays.copyOf(replacement, replacement.$replLength$);
+#end[encoder]
     }
 
     /**
@@ -280,12 +286,15 @@
             throw new IllegalArgumentException("Empty replacement");
         if (len > max$ItypesPerOtype$)
             throw new IllegalArgumentException("Replacement too long");
+#if[decoder]
+        this.replacement = newReplacement;
+#end[decoder]
 #if[encoder]
         if (!isLegalReplacement(newReplacement))
             throw new IllegalArgumentException("Illegal replacement");
+        this.replacement = Arrays.copyOf(newReplacement, newReplacement.$replLength$);
 #end[encoder]
-        this.replacement = newReplacement;
-        implReplaceWith(newReplacement);
+        implReplaceWith(this.replacement);
         return this;
     }
 
--- a/jdk/src/share/classes/sun/nio/cs/UTF_8.java	Tue May 28 16:35:17 2013 +0100
+++ b/jdk/src/share/classes/sun/nio/cs/UTF_8.java	Tue May 28 10:42:52 2013 -0700
@@ -682,6 +682,11 @@
                 return encodeBufferLoop(src, dst);
         }
 
+        private byte repl = (byte)'?';
+        protected void implReplaceWith(byte[] newReplacement) {
+            repl = newReplacement[0];
+        }
+
         // returns -1 if there is malformed char(s) and the
         // "action" for malformed input is not REPLACE.
         public int encode(char[] sa, int sp, int len, byte[] da) {
@@ -709,7 +714,7 @@
                     if (uc < 0) {
                         if (malformedInputAction() != CodingErrorAction.REPLACE)
                             return -1;
-                        da[dp++] = replacement()[0];
+                        da[dp++] = repl;
                     } else {
                         da[dp++] = (byte)(0xf0 | ((uc >> 18)));
                         da[dp++] = (byte)(0x80 | ((uc >> 12) & 0x3f));
--- a/jdk/src/share/classes/sun/nio/cs/ext/DoubleByte.java	Tue May 28 16:35:17 2013 +0100
+++ b/jdk/src/share/classes/sun/nio/cs/ext/DoubleByte.java	Tue May 28 10:42:52 2013 -0700
@@ -610,6 +610,11 @@
                 return encodeBufferLoop(src, dst);
         }
 
+        protected byte[] repl = replacement();
+        protected void implReplaceWith(byte[] newReplacement) {
+            repl = newReplacement;
+        }
+
         public int encode(char[] src, int sp, int len, byte[] dst) {
             int dp = 0;
             int sl = sp + len;
@@ -622,7 +627,6 @@
                         Character.isLowSurrogate(src[sp])) {
                         sp++;
                     }
-                    byte[] repl = replacement();
                     dst[dp++] = repl[0];
                     if (repl.length > 1)
                         dst[dp++] = repl[1];
@@ -877,7 +881,6 @@
                         Character.isLowSurrogate(src[sp])) {
                         sp++;
                     }
-                    byte[] repl = replacement();
                     dst[dp++] = repl[0];
                     if (repl.length > 1)
                         dst[dp++] = repl[1];
--- a/jdk/src/share/classes/sun/nio/cs/ext/HKSCS.java	Tue May 28 16:35:17 2013 +0100
+++ b/jdk/src/share/classes/sun/nio/cs/ext/HKSCS.java	Tue May 28 10:42:52 2013 -0700
@@ -356,6 +356,11 @@
                 return encodeBufferLoop(src, dst);
         }
 
+        private byte[] repl = replacement();
+        protected void implReplaceWith(byte[] newReplacement) {
+            repl = newReplacement;
+        }
+
         public int encode(char[] src, int sp, int len, byte[] dst) {
             int dp = 0;
             int sl = sp + len;
@@ -367,7 +372,6 @@
                         !Character.isLowSurrogate(src[sp]) ||
                         (bb = encodeSupp(Character.toCodePoint(c, src[sp++])))
                         == UNMAPPABLE_ENCODING) {
-                        byte[] repl = replacement();
                         dst[dp++] = repl[0];
                         if (repl.length > 1)
                             dst[dp++] = repl[1];