diff --git a/release-notes/CREDITS b/release-notes/CREDITS index 0f593827f3..d399a7b0d4 100644 --- a/release-notes/CREDITS +++ b/release-notes/CREDITS @@ -83,3 +83,7 @@ Artur (@Artur-) Dónal Murtagh (@donalmurtagh) * Reported #5323: `UUID` serialization is broken in v3.0.0-rc9 [3.0.0] + +Phil Clay (@philsttr) + * Reported #5344: "Unexpected end-of-input" for `JsonParser.readValueAs()` (in 3.0) + [3.0.1] diff --git a/release-notes/VERSION b/release-notes/VERSION index 12593a2aba..7eebba8269 100644 --- a/release-notes/VERSION +++ b/release-notes/VERSION @@ -10,6 +10,8 @@ Versions: 3.x (for earlier see VERSION-2.x) #5340: `DeserializationFeature.ACCEPT_FLOAT_AS_INT` not respected for byte/short when deserializing from JsonNode (reported by @Artur) +#5344: "Unexpected end-of-input" for `JsonParser.readValueAs()` (in 3.0) + (reported by Phil C) 3.0.0 (03-Oct-2025) diff --git a/src/main/java/tools/jackson/databind/DeserializationContext.java b/src/main/java/tools/jackson/databind/DeserializationContext.java index 41b2114504..2457dd9740 100644 --- a/src/main/java/tools/jackson/databind/DeserializationContext.java +++ b/src/main/java/tools/jackson/databind/DeserializationContext.java @@ -397,6 +397,10 @@ public T readValue(JsonParser p, JavaType type) throws JacksonException { */ private Object _readValue(JsonParser p, ValueDeserializer deser) throws JacksonException { + // 12-Oct-2025, tatu: As per [databind#5344], need to ensure parser points to token + if (!p.hasCurrentToken()) { + p.nextToken(); + } if (p.hasToken(JsonToken.VALUE_NULL)) { return deser.getNullValue(this); } diff --git a/src/test/java/tools/jackson/databind/MapperViaParserTest.java b/src/test/java/tools/jackson/databind/MapperViaParserTest.java index 5c53403ccd..27ec0fbc94 100644 --- a/src/test/java/tools/jackson/databind/MapperViaParserTest.java +++ b/src/test/java/tools/jackson/databind/MapperViaParserTest.java @@ -1,7 +1,5 @@ package tools.jackson.databind; -import java.io.StringReader; - import org.junit.jupiter.api.Test; import tools.jackson.core.*; @@ -9,11 +7,11 @@ import tools.jackson.core.io.SerializedString; import tools.jackson.core.json.JsonFactory; import tools.jackson.core.json.JsonWriteFeature; +import tools.jackson.core.type.TypeReference; +import tools.jackson.databind.json.JsonMapper; import tools.jackson.databind.testutil.DatabindTestUtil; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - public class MapperViaParserTest extends DatabindTestUtil @@ -24,7 +22,7 @@ public class MapperViaParserTest final static SerializedString TWO_BYTE_ESCAPED_STRING = new SerializedString("&111;"); final static SerializedString THREE_BYTE_ESCAPED_STRING = new SerializedString("&1111;"); - final static class Pojo + static class Pojo { int _x; @@ -82,22 +80,51 @@ public SerializableString getEscapeSequence(int ch) private final ObjectMapper MAPPER = newJsonMapper(); - @SuppressWarnings("resource") @Test - public void testPojoReadingOk() throws Exception + public void testPojoReadingOkClass() throws Exception + { + try (JsonParser p = MAPPER.createParser(a2q("{ 'x' : 9 }"))) { + Pojo pojo = p.readValueAs(Pojo.class); + assertEquals(9, pojo._x); + } + } + + @Test + public void testPojoReadingOkTypeRef() throws Exception + { + try (JsonParser p = MAPPER.createParser(a2q("{ 'x' : 7 }"))) { + Pojo pojo = p.readValueAs(new TypeReference() { }); + assertEquals(7, pojo._x); + } + } + + @Test + public void testPojoReadingOkJavaType() throws Exception { - final String JSON = "{ \"x\" : 9 }"; - JsonParser jp = MAPPER.createParser(new StringReader(JSON)); - jp.nextToken(); - Pojo p = jp.readValueAs(Pojo.class); - assertNotNull(p); + try (JsonParser p = MAPPER.createParser(a2q("{ 'x' : 42 }"))) { + Pojo pojo = p.readValueAs(MAPPER.constructType(Pojo.class)); + assertEquals(42, pojo._x); + } + } + + @Test + public void testTreeReadingOk() throws Exception + { + final String JSON = a2q("{ 'x' : 9 }"); + try (JsonParser p = MAPPER.createParser(JSON)) { + JsonNode tree = p.readValueAsTree(); + assertEquals(MAPPER.createObjectNode().put("x", 9), tree); + } } + // // // Misc other tests + @Test public void testEscapingUsingMapper() throws Exception { - ObjectMapper mapper = new ObjectMapper(JsonFactory.builder() - .enable(JsonWriteFeature.ESCAPE_NON_ASCII).build()); + ObjectMapper mapper = JsonMapper.builder(JsonFactory.builder() + .enable(JsonWriteFeature.ESCAPE_NON_ASCII).build()) + .build(); final String json = mapper.writeValueAsString(String.valueOf((char) 258)); assertEquals(q("\\u0102"), json); } diff --git a/src/test/java/tools/jackson/databind/ObjectMapperTest.java b/src/test/java/tools/jackson/databind/ObjectMapperTest.java index 6568cc1098..9c8dfdbb33 100644 --- a/src/test/java/tools/jackson/databind/ObjectMapperTest.java +++ b/src/test/java/tools/jackson/databind/ObjectMapperTest.java @@ -4,7 +4,6 @@ import java.nio.charset.StandardCharsets; import java.nio.file.*; import java.util.*; -import java.util.stream.Collectors; import java.util.zip.ZipOutputStream; import org.junit.jupiter.api.Test; @@ -249,7 +248,6 @@ public void testDataInputViaMapper() throws Exception assertNotNull(n); } - @SuppressWarnings("serial") @Test public void testRegisterDependentModules() {