From bcccd3e82241db25a2f34ed655dab88395089f39 Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Tue, 28 Oct 2014 20:32:47 -0700 Subject: [PATCH] Fix #592 --- release-notes/CREDITS | 7 ++- release-notes/VERSION | 2 + .../jackson/databind/util/TokenBuffer.java | 21 +++++++-- .../creators/TestCreatorsDelegating.java | 43 ++++++++++++++++++- 4 files changed, 66 insertions(+), 7 deletions(-) diff --git a/release-notes/CREDITS b/release-notes/CREDITS index 8931ad8cce..c161eeee27 100644 --- a/release-notes/CREDITS +++ b/release-notes/CREDITS @@ -145,6 +145,9 @@ Steve Sanbeg: (sanbeg@github) (2.4.1) Ian Barfield: (tea-dragon@github) - * Reported #580: delegate deserializers choke on a (single) abstract/polymorphic parameter - + * Reported #580: delegate deserializers choke on a (single) abstract/polymorphic parameter + (2.4.4) +Eugene Lukash + * Reported #592: Wrong `TokenBuffer` delegate deserialization using `@JsonCreator` + (2.4.4) diff --git a/release-notes/VERSION b/release-notes/VERSION index 493c34ee0e..fa5feb70c9 100644 --- a/release-notes/VERSION +++ b/release-notes/VERSION @@ -12,6 +12,8 @@ Project: jackson-databind (reported by Ian B, tea-dragon@github) #590: Binding invalid Currency gives nonsense at end of the message (reported by Jerbell@github) +#592: Wrong `TokenBuffer` delegate deserialization using `@JsonCreator` + (reported by Eugene L) 2.4.3 (02-Oct-2014) diff --git a/src/main/java/com/fasterxml/jackson/databind/util/TokenBuffer.java b/src/main/java/com/fasterxml/jackson/databind/util/TokenBuffer.java index caea328369..58d3e086f5 100644 --- a/src/main/java/com/fasterxml/jackson/databind/util/TokenBuffer.java +++ b/src/main/java/com/fasterxml/jackson/databind/util/TokenBuffer.java @@ -400,10 +400,25 @@ public void serialize(JsonGenerator jgen) * * @since 2.3 */ - public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) - throws IOException, JsonProcessingException + public TokenBuffer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { - copyCurrentStructure(jp); + if (jp.getCurrentTokenId() != JsonToken.FIELD_NAME.id()) { + copyCurrentStructure(jp); + return this; + } + /* 28-Oct-2014, tatu: As per #592, need to support a special case of starting from + * FIELD_NAME, which is taken to mean that we are missing START_OBJECT, but need + * to assume one did exist. + */ + JsonToken t; + writeStartObject(); + do { + copyCurrentStructure(jp); + } while ((t = jp.nextToken()) == JsonToken.FIELD_NAME); + if (t != JsonToken.END_OBJECT) { + throw ctxt.mappingException("Expected END_OBJECT after copying contents of a JsonParser into TokenBuffer, got "+t); + } + writeEndObject(); return this; } diff --git a/src/test/java/com/fasterxml/jackson/databind/creators/TestCreatorsDelegating.java b/src/test/java/com/fasterxml/jackson/databind/creators/TestCreatorsDelegating.java index aa750c243f..ffa1602cab 100644 --- a/src/test/java/com/fasterxml/jackson/databind/creators/TestCreatorsDelegating.java +++ b/src/test/java/com/fasterxml/jackson/databind/creators/TestCreatorsDelegating.java @@ -2,8 +2,10 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JacksonInject; - +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; import com.fasterxml.jackson.databind.*; +import com.fasterxml.jackson.databind.util.TokenBuffer; public class TestCreatorsDelegating extends BaseMapTest { @@ -51,7 +53,21 @@ public static FactoryBean711 create(@JacksonInject String n1, int a, @JacksonInj return new FactoryBean711(a, n1, n2); } } - + + static class Value592 + { + protected Object stuff; + + protected Value592(Object ob, boolean bogus) { + stuff = ob; + } + + @JsonCreator + public static Value592 from(TokenBuffer buffer) { + return new Value592(buffer, false); + } + } + /* /********************************************************** /* Unit tests @@ -103,4 +119,27 @@ public void testWithFactoryAndDelegate() throws Exception assertEquals("Fygar", bean.name1); assertEquals("Fygar", bean.name2); } + + // [databind#592] + public void testDelegateWithTokenBuffer() throws Exception + { + ObjectMapper mapper = new ObjectMapper(); + Value592 value = mapper.readValue("{\"a\":1,\"b\":2}", Value592.class); + assertNotNull(value); + Object ob = value.stuff; + assertEquals(TokenBuffer.class, ob.getClass()); + JsonParser jp = ((TokenBuffer) ob).asParser(); + assertToken(JsonToken.START_OBJECT, jp.nextToken()); + assertToken(JsonToken.FIELD_NAME, jp.nextToken()); + assertEquals("a", jp.getCurrentName()); + assertToken(JsonToken.VALUE_NUMBER_INT, jp.nextToken()); + assertEquals(1, jp.getIntValue()); + assertToken(JsonToken.FIELD_NAME, jp.nextToken()); + assertEquals("b", jp.getCurrentName()); + assertToken(JsonToken.VALUE_NUMBER_INT, jp.nextToken()); + assertEquals(2, jp.getIntValue()); + assertToken(JsonToken.END_OBJECT, jp.nextToken()); + jp.close(); + } + }