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
--- 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];