You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by te...@apache.org on 2008/07/22 14:56:45 UTC
svn commit: r678749 - in
/harmony/enhanced/classlib/trunk/modules/nio_char/src:
main/java/org/apache/harmony/niochar/charset/UTF_8.java
test/java/org/apache/harmony/nio_char/tests/java/nio/charset/CharsetDecoderTest.java
Author: tellison
Date: Tue Jul 22 05:56:45 2008
New Revision: 678749
URL: http://svn.apache.org/viewvc?rev=678749&view=rev
Log:
Ensure UTF-8 decoder throws MalformedInputException on invalid byte sequences.
Modified:
harmony/enhanced/classlib/trunk/modules/nio_char/src/main/java/org/apache/harmony/niochar/charset/UTF_8.java
harmony/enhanced/classlib/trunk/modules/nio_char/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/CharsetDecoderTest.java
Modified: harmony/enhanced/classlib/trunk/modules/nio_char/src/main/java/org/apache/harmony/niochar/charset/UTF_8.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/nio_char/src/main/java/org/apache/harmony/niochar/charset/UTF_8.java?rev=678749&r1=678748&r2=678749&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/nio_char/src/main/java/org/apache/harmony/niochar/charset/UTF_8.java (original)
+++ harmony/enhanced/classlib/trunk/modules/nio_char/src/main/java/org/apache/harmony/niochar/charset/UTF_8.java Tue Jul 22 05:56:45 2008
@@ -61,6 +61,8 @@
401536, // (011o0000b << 12)+(1o000000b << 6)+(1o000000b)
29892736 // (0111o000b << 18)+(1o000000b << 12)+(1o000000b << 6)+(1o000000b)
};
+
+ private static final int headerBits[] = { -1, 0x1F, 0x0F, 0x07 };
public UTF_8(String canonicalName, String[] aliases) {
super(canonicalName, aliases);
@@ -128,10 +130,10 @@
jchar = jchar & 0x7F;
int tail = remainingBytes[jchar];
- if (tail == -1) {
+ if (tail == -1 || (jchar & headerBits[tail]) == 0) {
in.position(inIndex - in.arrayOffset());
out.position(outIndex - out.arrayOffset());
- return CoderResult.unmappableForLength(1);
+ return CoderResult.malformedForLength(1);
}
if (inIndexLimit - inIndex < 1 + tail) {
break;
@@ -167,8 +169,8 @@
if (jchar < 0) {
jchar = jchar & 0x7F;
int tail = remainingBytes[jchar];
- if (tail == -1) {
- return CoderResult.unmappableForLength(1);
+ if ((tail == -1) || (jchar & headerBits[tail]) == 0) {
+ return CoderResult.malformedForLength(1);
}
if (limit - pos < 1 + tail) {
return CoderResult.UNDERFLOW;
Modified: harmony/enhanced/classlib/trunk/modules/nio_char/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/CharsetDecoderTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/nio_char/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/CharsetDecoderTest.java?rev=678749&r1=678748&r2=678749&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/nio_char/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/CharsetDecoderTest.java (original)
+++ harmony/enhanced/classlib/trunk/modules/nio_char/src/test/java/org/apache/harmony/nio_char/tests/java/nio/charset/CharsetDecoderTest.java Tue Jul 22 05:56:45 2008
@@ -16,6 +16,7 @@
package org.apache.harmony.nio_char.tests.java.nio.charset;
+import java.io.IOException;
import java.nio.BufferOverflowException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
@@ -27,6 +28,7 @@
import java.nio.charset.CoderResult;
import java.nio.charset.CodingErrorAction;
import java.nio.charset.MalformedInputException;
+import java.util.Arrays;
import junit.framework.TestCase;
@@ -228,4 +230,51 @@
return CoderResult.UNDERFLOW;
}
}
+
+
+ public void testInvalidDecoding() throws IOException {
+
+ byte[][] invalidSequences = new byte[][] {
+ // overlong NULL
+ { (byte) 0xC0, (byte) 0x80 },
+ // overlong ascii 'A'
+ { (byte) 0xC0, (byte) 0xC1 },
+ // overlong "/../"
+ { (byte) 0x2F, (byte) 0xC0, (byte) 0xAE, (byte) 0x2E, (byte) 0x2F },
+ // Invalid encoding 2r11111000 (sequence too long)
+ { (byte) 0xF8 },
+ // Invalid encoding 2r10000000 (sequence too short)
+ { (byte) 0x80 }
+ };
+
+ CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder();
+ decoder.onMalformedInput(CodingErrorAction.REPORT);
+
+ /*
+ * When bytebuffer has a backing array...
+ */
+ for (byte[] bytes : invalidSequences) {
+ try {
+ decoder.decode(ByteBuffer.wrap(bytes));
+ fail("No exception thrown on " + Arrays.toString(bytes));
+ } catch (MalformedInputException e) {
+ // expected
+ }
+ }
+
+ /*
+ * When bytebuffer has _not_ got a backing array...
+ */
+ for (byte[] bytes : invalidSequences) {
+ try {
+ ByteBuffer bb = ByteBuffer.allocateDirect(8);
+ bb.put(bytes).flip();
+ decoder.decode(bb);
+ fail("No exception thrown on " + Arrays.toString(bytes));
+ } catch (MalformedInputException e) {
+ // expected
+ }
+ }
+ }
+
}