/*
* 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]);
}
}