AsyncInvalidCharsTest.java
package com.fasterxml.jackson.core.json.async;
import java.io.ByteArrayOutputStream;
import org.junit.jupiter.api.Test;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.core.async.AsyncTestBase;
import com.fasterxml.jackson.core.testsupport.AsyncReaderWrapper;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
// Tests for verifying things such as handling of invalid control characters;
// decoding of UTF-8 BOM.
class AsyncInvalidCharsTest extends AsyncTestBase
{
private final JsonFactory JSON_F = new JsonFactory();
@Test
void utf8BOMHandling() throws Exception
{
_testUtf8BOMHandling(0, 99);
_testUtf8BOMHandling(0, 5);
_testUtf8BOMHandling(0, 3);
_testUtf8BOMHandling(0, 2);
_testUtf8BOMHandling(0, 1);
_testUtf8BOMHandling(2, 99);
_testUtf8BOMHandling(2, 1);
}
private void _testUtf8BOMHandling(int offset, int readSize) throws Exception
{
_testUTF8BomOk(offset, readSize);
_testUTF8BomFail(offset, readSize, 1,
"Unexpected byte 0x5b following 0xEF; should get 0xBB as second byte");
_testUTF8BomFail(offset, readSize, 2,
"Unexpected byte 0x5b following 0xEF 0xBB; should get 0xBF as third byte");
}
private void _testUTF8BomOk(int offset, int readSize) throws Exception
{
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
// first, write BOM:
bytes.write(0xEF);
bytes.write(0xBB);
bytes.write(0xBF);
bytes.write("[ 1 ]".getBytes("UTF-8"));
byte[] doc = bytes.toByteArray();
AsyncReaderWrapper p = asyncForBytes(JSON_F, readSize, doc, offset);
assertEquals(JsonToken.START_ARRAY, p.nextToken());
// should also have skipped first 3 bytes of BOM; but do we have offset available?
/* Alas, due to [core#111], we have to omit BOM in calculations
* as we do not know what the offset is due to -- may need to revisit, if this
* discrepancy becomes an issue. For now it just means that BOM is considered
* "out of stream" (not part of input).
*/
JsonLocation loc = p.parser().currentTokenLocation();
// so if BOM was consider in-stream (part of input), this should expect 3:
// (NOTE: this is location for START_ARRAY token, now)
assertEquals(-1, loc.getCharOffset());
// !!! TODO: fix location handling
/*
assertEquals(0, loc.getByteOffset());
assertEquals(1, loc.getLineNr());
assertEquals(1, loc.getColumnNr());
*/
assertEquals(JsonToken.VALUE_NUMBER_INT, p.nextToken());
assertEquals(JsonToken.END_ARRAY, p.nextToken());
p.close();
}
private void _testUTF8BomFail(int offset, int readSize,
int okBytes, String verify) throws Exception
{
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
bytes.write(0xEF);
if (okBytes > 1) {
bytes.write(0xBB);
}
bytes.write("[ 1 ]".getBytes("UTF-8"));
byte[] doc = bytes.toByteArray();
try (AsyncReaderWrapper p = asyncForBytes(JSON_F, readSize, doc, offset)) {
assertEquals(JsonToken.START_ARRAY, p.nextToken());
fail("Should not pass");
} catch (JsonParseException e) {
verifyException(e, verify);
}
}
@Test
void handlingOfInvalidSpace() throws Exception
{
_testHandlingOfInvalidSpace(0, 99);
_testHandlingOfInvalidSpace(0, 3);
_testHandlingOfInvalidSpace(0, 1);
_testHandlingOfInvalidSpace(1, 99);
_testHandlingOfInvalidSpace(2, 1);
}
private void _testHandlingOfInvalidSpace(int offset, int readSize) throws Exception
{
final String doc = "{ \u0008 \"a\":1}";
AsyncReaderWrapper p = asyncForBytes(JSON_F, readSize, _jsonDoc(doc), offset);
assertToken(JsonToken.START_OBJECT, p.nextToken());
try {
p.nextToken();
fail("Should have failed");
} catch (JsonParseException e) {
verifyException(e, "Illegal character");
// and correct error code
verifyException(e, "code 8");
}
p.close();
}
}