UnquotedNameSymbolCollision1748Test.java
package tools.jackson.core.unittest.read;
import java.nio.charset.StandardCharsets;
import org.junit.jupiter.api.Test;
import tools.jackson.core.*;
import tools.jackson.core.json.JsonFactory;
import tools.jackson.core.json.JsonReadFeature;
import tools.jackson.core.unittest.JacksonCoreTestBase;
import tools.jackson.core.unittest.async.AsyncTestBase;
import tools.jackson.core.unittest.testutil.AsyncReaderWrapper;
import static org.junit.jupiter.api.Assertions.assertEquals;
// [core#1748]: Unquoted names must not share symbol table entries with quoted names
// that have leading `\u0000` escapes (see [core#148] for quoted names)
class UnquotedNameSymbolCollision1748Test extends JacksonCoreTestBase
{
private final JsonFactory UNQUOTED_F = JsonFactory.builder()
.enable(JsonReadFeature.ALLOW_UNQUOTED_PROPERTY_NAMES)
.build();
private final static String[][] CASES = {
// doc, first name, second name
{ "{ab:1, \"\\u0000\\u0000ab\":2}", "ab", "\u0000\u0000ab" },
{ "{\"\\u0000\\u0000ab\":1, ab:2}", "\u0000\u0000ab", "ab" },
{ "{abcdef:1, \"abcd\\u0000\\u0000ef\":2}", "abcdef", "abcd\u0000\u0000ef" },
{ "{\"\\u0000\\u00E9\":1, \u00E9:2}", "\u0000\u00E9", "\u00E9" }
};
@Test
void unquotedVsQuotedNames() throws Exception
{
for (String[] c : CASES) {
for (int mode : ALL_MODES) {
try (JsonParser p = createParser(UNQUOTED_F, mode, c[0])) {
_verify(p::nextToken, p::currentName, c, "mode " + mode);
}
}
byte[] b = c[0].getBytes(StandardCharsets.UTF_8);
for (int bytesPerRead : new int[] { 1, 3, 100 }) {
try (AsyncReaderWrapper p = AsyncTestBase.asyncForBytes(UNQUOTED_F, bytesPerRead, b, 0)) {
_verify(p::nextToken, p::currentName, c, "async");
}
try (AsyncReaderWrapper p = AsyncTestBase.asyncForByteBuffer(UNQUOTED_F, bytesPerRead, b, 0)) {
_verify(p::nextToken, p::currentName, c, "async ByteBuffer");
}
}
}
}
@FunctionalInterface
interface IOSupplier<T> {
T get() throws Exception;
}
private void _verify(IOSupplier<JsonToken> next, IOSupplier<String> currName,
String[] c, String desc) throws Exception
{
assertToken(JsonToken.START_OBJECT, next.get());
assertToken(JsonToken.PROPERTY_NAME, next.get());
assertEquals(c[1], currName.get(), c[0] + ", " + desc);
assertToken(JsonToken.VALUE_NUMBER_INT, next.get());
assertToken(JsonToken.PROPERTY_NAME, next.get());
assertEquals(c[2], currName.get(), c[0] + ", " + desc);
assertToken(JsonToken.VALUE_NUMBER_INT, next.get());
assertToken(JsonToken.END_OBJECT, next.get());
}
}