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
+            }
+        }
+    }
+
 }