summaryrefslogtreecommitdiffstats
path: root/nio_char
diff options
context:
space:
mode:
authorMihai Preda <preda@google.com>2009-05-25 22:00:34 +0200
committerMihai Preda <preda@google.com>2009-05-26 15:29:52 +0200
commit9932735d0306721523082f77b0a9ba4aa4db8cdb (patch)
tree8088541c6ad2671fa0afd1a0f582630e1c161ecf /nio_char
parent4a18dac1dae17aefb889a458497f3b9a5a6a64ef (diff)
downloadlibcore-9932735d0306721523082f77b0a9ba4aa4db8cdb.zip
libcore-9932735d0306721523082f77b0a9ba4aa4db8cdb.tar.gz
libcore-9932735d0306721523082f77b0a9ba4aa4db8cdb.tar.bz2
Bug 1844104: Fix buffer overwrite bugs in CharsetEncoderICU and CharsetDecoderICU.
And add unit test.
Diffstat (limited to 'nio_char')
-rw-r--r--nio_char/src/test/java/tests/api/java/nio/charset/AllTests.java2
-rw-r--r--nio_char/src/test/java/tests/api/java/nio/charset/CharsetEncoderDecoderBufferTest.java182
2 files changed, 184 insertions, 0 deletions
diff --git a/nio_char/src/test/java/tests/api/java/nio/charset/AllTests.java b/nio_char/src/test/java/tests/api/java/nio/charset/AllTests.java
index 35e7129..f318960 100644
--- a/nio_char/src/test/java/tests/api/java/nio/charset/AllTests.java
+++ b/nio_char/src/test/java/tests/api/java/nio/charset/AllTests.java
@@ -112,6 +112,8 @@ public class AllTests {
suite.addTestSuite(Charset_macintosh.class);
suite.addTestSuite(Charset_GSM0338.class);
+ suite.addTestSuite(CharsetEncoderDecoderBufferTest.class);
+
return suite;
}
}
diff --git a/nio_char/src/test/java/tests/api/java/nio/charset/CharsetEncoderDecoderBufferTest.java b/nio_char/src/test/java/tests/api/java/nio/charset/CharsetEncoderDecoderBufferTest.java
new file mode 100644
index 0000000..5e4c3d0
--- /dev/null
+++ b/nio_char/src/test/java/tests/api/java/nio/charset/CharsetEncoderDecoderBufferTest.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.java.nio.charset;
+
+import junit.framework.TestCase;
+
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestLevel;
+
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+
+
+/* See bug 1844104.
+ * Checks for ICU encoder/decoder buffer corruption.
+ */
+@TestTargetClass(CharsetDecoder.class)
+public class CharsetEncoderDecoderBufferTest extends TestCase {
+
+ /* Checks for a buffer corruption that happens in ICU
+ * (CharsetDecoderICU) when a decode operation
+ * is done first with an out-buffer with hasArray()==true, and next with an out-buffer with
+ * hasArray()==false. In that situation ICU may overwrite the first out-buffer.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "decode",
+ args = {}
+ )
+ })
+ public void testDecoderOutputBuffer() {
+ CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder();
+
+ char[] cBuf = new char[10];
+ CharBuffer out = CharBuffer.wrap(cBuf);
+ assertTrue(out.hasArray());
+ decoder.decode(ByteBuffer.wrap(new byte[]{(byte)'a', (byte)'b', (byte)'c', (byte)'d'}),
+ out, false);
+
+ assertEquals("abcd", new String(cBuf, 0, 4));
+ assertEquals(0, cBuf[4]);
+ assertEquals(0, cBuf[5]);
+
+ byte[] bBuf = new byte[10];
+ out = ByteBuffer.wrap(bBuf).asCharBuffer();
+ assertFalse(out.hasArray());
+ decoder.decode(ByteBuffer.wrap(new byte[]{(byte)'x'}), out, true);
+
+ assertEquals('x', bBuf[1]);
+ assertEquals(0, bBuf[3]);
+
+ // check if the first buffer was corrupted by the second decode
+ assertEquals("abcd", new String(cBuf, 0, 4));
+ assertEquals(0, cBuf[4]);
+ assertEquals(0, cBuf[5]);
+ }
+
+ /* Checks for a buffer corruption that happens in ICU
+ * (CharsetDecoderICU) when a decode operation
+ * is done first with an in-buffer with hasArray()==true, and next with an in-buffer with
+ * hasArray()==false. In that situation ICU may overwrite the array of the first in-buffer.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "decode",
+ args = {}
+ )
+ })
+ public void testDecoderInputBuffer() {
+ CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder();
+ CharBuffer out = CharBuffer.wrap(new char[10]);
+
+ byte[] inArray = {(byte)'a', (byte)'b'};
+ ByteBuffer inWithArray = ByteBuffer.wrap(inArray);
+ assertTrue(inWithArray.hasArray());
+ decoder.decode(inWithArray, out, false);
+ assertEquals('a', inArray[0]);
+ assertEquals('b', inArray[1]);
+
+ ByteBuffer inWithoutArray = ByteBuffer.allocateDirect(1);
+ inWithoutArray.put(0, (byte)'x');
+ assertFalse(inWithoutArray.hasArray());
+ decoder.decode(inWithoutArray, out, true);
+
+ // check whether the first buffer was corrupted by the second decode
+ assertEquals('a', inArray[0]);
+ assertEquals('b', inArray[1]);
+ }
+
+ /* Checks for a buffer corruption that happens in ICU
+ * (CharsetEncoderICU) when an encode operation
+ * is done first with an out-buffer with hasArray()==true, and next with an out-buffer with
+ * hasArray()==false. In that situation ICU may overwrite the first out-buffer.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "encode",
+ args = {}
+ )
+ })
+ public void testEncoderOutputBuffer() {
+ CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder();
+
+ byte[] buffer = new byte[10];
+ ByteBuffer out = ByteBuffer.wrap(buffer);
+
+ assertTrue(out.hasArray());
+ encoder.encode(CharBuffer.wrap("ab"), out, false);
+
+ assertEquals('a', buffer[0]);
+ assertEquals('b', buffer[1]);
+ assertEquals(0, buffer[2]);
+
+ out = ByteBuffer.allocateDirect(10);
+ assertFalse(out.hasArray());
+ encoder.encode(CharBuffer.wrap("x"), out, true);
+
+ // check whether the second decode corrupted the first buffer
+ assertEquals('a', buffer[0]);
+ assertEquals('b', buffer[1]);
+ assertEquals(0, buffer[2]);
+ }
+
+ /* Checks for a buffer corruption that happens in ICU
+ * (CharsetEncoderICU) when an encode operation
+ * is done first with an in-buffer with hasArray()==true, and next with an in-buffer with
+ * hasArray()==false. In that situation ICU may overwrite the array of the first in-buffer.
+ */
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "encode",
+ args = {}
+ )
+ })
+ public void testEncoderInputBuffer() {
+ CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder();
+ ByteBuffer out = ByteBuffer.wrap(new byte[10]);
+
+ char[] inArray = {'a', 'b'};
+ CharBuffer inWithArray = CharBuffer.wrap(inArray);
+ assertTrue(inWithArray.hasArray());
+ encoder.encode(inWithArray, out, false);
+
+ assertEquals('a', inArray[0]);
+ assertEquals('b', inArray[1]);
+
+ CharBuffer inWithoutArray = CharBuffer.wrap("x");
+ assertFalse(inWithoutArray.hasArray());
+ encoder.encode(inWithoutArray, out, true);
+
+ // check whether the second decode corrupted the first buffer
+ assertEquals('a', inArray[0]);
+ assertEquals('b', inArray[1]);
+ }
+}