From dabe16a2aa0f3b1d1b5a320ac5bd2c197e3eea4c Mon Sep 17 00:00:00 2001 From: John Hudson Date: Mon, 30 Dec 2024 17:33:00 -0600 Subject: [PATCH 1/7] Test reproducing SmileParser getValueAsString() issue with JsonToken.FIELD_NAME and tentative bugfix. --- .../com/fasterxml/jackson/dataformat/smile/SmileParser.java | 3 +++ .../jackson/dataformat/smile/parse/BasicParserTest.java | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/smile/src/main/java/com/fasterxml/jackson/dataformat/smile/SmileParser.java b/smile/src/main/java/com/fasterxml/jackson/dataformat/smile/SmileParser.java index 06115c7f4..2c149be5b 100644 --- a/smile/src/main/java/com/fasterxml/jackson/dataformat/smile/SmileParser.java +++ b/smile/src/main/java/com/fasterxml/jackson/dataformat/smile/SmileParser.java @@ -1173,6 +1173,9 @@ public String getValueAsString() throws IOException if (_currToken == JsonToken.VALUE_STRING) { return _textBuffer.contentsAsString(); } + if (_currToken == JsonToken.FIELD_NAME) { + return currentName(); + } if (_currToken == null || _currToken == JsonToken.VALUE_NULL || !_currToken.isScalarValue()) { return null; } diff --git a/smile/src/test/java/com/fasterxml/jackson/dataformat/smile/parse/BasicParserTest.java b/smile/src/test/java/com/fasterxml/jackson/dataformat/smile/parse/BasicParserTest.java index abe4c14cf..6826a9293 100644 --- a/smile/src/test/java/com/fasterxml/jackson/dataformat/smile/parse/BasicParserTest.java +++ b/smile/src/test/java/com/fasterxml/jackson/dataformat/smile/parse/BasicParserTest.java @@ -231,8 +231,8 @@ public void testSimpleObject() throws IOException assertToken(JsonToken.START_OBJECT, p.nextToken()); assertToken(JsonToken.FIELD_NAME, p.nextToken()); - assertEquals("a", p.currentName()); assertEquals("a", p.getText()); + assertEquals("a", p.getValueAsString()); assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken()); assertEquals(8, p.getIntValue()); From d9a8b87a24775b28fc4803c6024f81d9ec2ca323 Mon Sep 17 00:00:00 2001 From: John Hudson Date: Mon, 30 Dec 2024 17:34:53 -0600 Subject: [PATCH 2/7] Add back assertion accidentally removed. --- .../jackson/dataformat/smile/parse/BasicParserTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/smile/src/test/java/com/fasterxml/jackson/dataformat/smile/parse/BasicParserTest.java b/smile/src/test/java/com/fasterxml/jackson/dataformat/smile/parse/BasicParserTest.java index 6826a9293..c6da67d22 100644 --- a/smile/src/test/java/com/fasterxml/jackson/dataformat/smile/parse/BasicParserTest.java +++ b/smile/src/test/java/com/fasterxml/jackson/dataformat/smile/parse/BasicParserTest.java @@ -231,6 +231,7 @@ public void testSimpleObject() throws IOException assertToken(JsonToken.START_OBJECT, p.nextToken()); assertToken(JsonToken.FIELD_NAME, p.nextToken()); + assertEquals("a", p.currentName()); assertEquals("a", p.getText()); assertEquals("a", p.getValueAsString()); assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken()); From fd98da487718c0567ccda388741413b8d9241ca4 Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Fri, 3 Jan 2025 18:22:23 -0800 Subject: [PATCH 3/7] Add test & fix for CBOR too --- .../jackson/dataformat/cbor/CBORParser.java | 6 ++++++ .../dataformat/cbor/parse/BasicParserTest.java | 14 ++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/cbor/src/main/java/com/fasterxml/jackson/dataformat/cbor/CBORParser.java b/cbor/src/main/java/com/fasterxml/jackson/dataformat/cbor/CBORParser.java index a87cf82d3..52f1d3514 100644 --- a/cbor/src/main/java/com/fasterxml/jackson/dataformat/cbor/CBORParser.java +++ b/cbor/src/main/java/com/fasterxml/jackson/dataformat/cbor/CBORParser.java @@ -1702,6 +1702,9 @@ public String getValueAsString() throws IOException if (_currToken == JsonToken.VALUE_STRING) { return _sharedString == null ? _textBuffer.contentsAsString() : _sharedString; } + if (_currToken == JsonToken.FIELD_NAME) { + return currentName(); + } if (_currToken == null || _currToken == JsonToken.VALUE_NULL || !_currToken.isScalarValue()) { return null; } @@ -1712,6 +1715,9 @@ public String getValueAsString() throws IOException public String getValueAsString(String defaultValue) throws IOException { if (_currToken != JsonToken.VALUE_STRING) { + if (_currToken == JsonToken.FIELD_NAME) { + return currentName(); + } if (_currToken == null || _currToken == JsonToken.VALUE_NULL || !_currToken.isScalarValue()) { return defaultValue; } diff --git a/cbor/src/test/java/com/fasterxml/jackson/dataformat/cbor/parse/BasicParserTest.java b/cbor/src/test/java/com/fasterxml/jackson/dataformat/cbor/parse/BasicParserTest.java index 3767bf826..55889ae4e 100644 --- a/cbor/src/test/java/com/fasterxml/jackson/dataformat/cbor/parse/BasicParserTest.java +++ b/cbor/src/test/java/com/fasterxml/jackson/dataformat/cbor/parse/BasicParserTest.java @@ -248,9 +248,14 @@ public void testStringField() throws IOException { assertEquals(JsonToken.START_OBJECT, parser.nextToken()); assertEquals(JsonToken.FIELD_NAME, parser.nextToken()); assertEquals("a", parser.currentName()); + assertEquals("a", parser.getText()); + assertEquals("a", parser.getValueAsString()); + assertEquals("a", parser.getValueAsString("x")); assertEquals(JsonToken.VALUE_STRING, parser.nextToken()); assertEquals("a", parser.currentName()); assertEquals("b", parser.getText()); + assertEquals("b", parser.getValueAsString()); + assertEquals("b", parser.getValueAsString("x")); assertEquals(1, parser.getTextLength()); assertEquals(JsonToken.END_OBJECT, parser.nextToken()); @@ -281,14 +286,23 @@ public void testNestedObject() throws IOException assertEquals(JsonToken.FIELD_NAME, parser.nextToken()); assertEquals("ob", parser.currentName()); + assertEquals("ob", parser.getText()); + assertEquals("ob", parser.getValueAsString()); + assertEquals("ob", parser.getValueAsString("x")); assertEquals(JsonToken.START_OBJECT, parser.nextToken()); assertEquals(JsonToken.FIELD_NAME, parser.nextToken()); assertEquals("num", parser.currentName()); + assertEquals("num", parser.getText()); + assertEquals("num", parser.getValueAsString()); + assertEquals("num", parser.getValueAsString("y")); assertEquals(JsonToken.VALUE_NUMBER_INT, parser.nextToken()); assertEquals(JsonToken.END_OBJECT, parser.nextToken()); assertEquals(JsonToken.FIELD_NAME, parser.nextToken()); assertEquals("arr", parser.currentName()); + assertEquals("arr", parser.getText()); + assertEquals("arr", parser.getValueAsString()); + assertEquals("arr", parser.getValueAsString("z")); assertEquals(JsonToken.START_ARRAY, parser.nextToken()); assertEquals(JsonToken.END_ARRAY, parser.nextToken()); From 61bdbff7875f80a9804f88e55dd1da0086bd3799 Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Fri, 3 Jan 2025 18:24:09 -0800 Subject: [PATCH 4/7] Add more Smile tests, extend fix --- .../jackson/dataformat/smile/SmileParser.java | 3 ++ .../smile/parse/BasicParserTest.java | 42 +++++++++++-------- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/smile/src/main/java/com/fasterxml/jackson/dataformat/smile/SmileParser.java b/smile/src/main/java/com/fasterxml/jackson/dataformat/smile/SmileParser.java index 2c149be5b..fe3e65e22 100644 --- a/smile/src/main/java/com/fasterxml/jackson/dataformat/smile/SmileParser.java +++ b/smile/src/main/java/com/fasterxml/jackson/dataformat/smile/SmileParser.java @@ -1186,6 +1186,9 @@ public String getValueAsString() throws IOException public String getValueAsString(String defaultValue) throws IOException { if (_currToken != JsonToken.VALUE_STRING) { + if (_currToken == JsonToken.FIELD_NAME) { + return currentName(); + } if (_currToken == null || _currToken == JsonToken.VALUE_NULL || !_currToken.isScalarValue()) { return defaultValue; } diff --git a/smile/src/test/java/com/fasterxml/jackson/dataformat/smile/parse/BasicParserTest.java b/smile/src/test/java/com/fasterxml/jackson/dataformat/smile/parse/BasicParserTest.java index c6da67d22..2510da851 100644 --- a/smile/src/test/java/com/fasterxml/jackson/dataformat/smile/parse/BasicParserTest.java +++ b/smile/src/test/java/com/fasterxml/jackson/dataformat/smile/parse/BasicParserTest.java @@ -217,31 +217,39 @@ public void testTrivialObject() throws IOException assertToken(JsonToken.FIELD_NAME, p.nextToken()); assertEquals("abc", p.currentName()); assertEquals("abc", p.getText()); + assertEquals("abc", p.getValueAsString()); + assertEquals("abc", p.getValueAsString("xyz")); assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken()); assertEquals(13, p.getIntValue()); - assertToken(JsonToken.END_OBJECT, p.nextToken()); - p.close(); + assertToken(JsonToken.END_OBJECT, p.nextToken()); + p.close(); } public void testSimpleObject() throws IOException { - byte[] data = _smileDoc("{\"a\":8, \"b\" : [ true ], \"c\" : { }, \"d\":{\"e\":null}}"); - SmileParser p = _smileParser(data); - assertNull(p.getCurrentToken()); - assertToken(JsonToken.START_OBJECT, p.nextToken()); + byte[] data = _smileDoc("{\"a\":8, \"b\" : [ true ], \"c\" : { }, \"d\":{\"e\":null}}"); + SmileParser p = _smileParser(data); + assertNull(p.currentToken()); + assertToken(JsonToken.START_OBJECT, p.nextToken()); - assertToken(JsonToken.FIELD_NAME, p.nextToken()); + assertToken(JsonToken.FIELD_NAME, p.nextToken()); assertEquals("a", p.currentName()); - assertEquals("a", p.getText()); + assertEquals("a", p.getText()); assertEquals("a", p.getValueAsString()); - assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken()); - assertEquals(8, p.getIntValue()); + assertEquals("a", p.getValueAsString("x")); - assertToken(JsonToken.FIELD_NAME, p.nextToken()); - assertEquals("b", p.currentName()); - assertToken(JsonToken.START_ARRAY, p.nextToken()); - assertToken(JsonToken.VALUE_TRUE, p.nextToken()); - assertToken(JsonToken.END_ARRAY, p.nextToken()); + assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken()); + assertEquals(8, p.getIntValue()); + + assertToken(JsonToken.FIELD_NAME, p.nextToken()); + assertEquals("b", p.currentName()); + assertEquals("b", p.getText()); + assertEquals("b", p.getValueAsString()); + assertEquals("b", p.getValueAsString("y")); + + assertToken(JsonToken.START_ARRAY, p.nextToken()); + assertToken(JsonToken.VALUE_TRUE, p.nextToken()); + assertToken(JsonToken.END_ARRAY, p.nextToken()); assertToken(JsonToken.FIELD_NAME, p.nextToken()); assertEquals("c", p.currentName()); @@ -286,8 +294,8 @@ public void testNestedObject() throws IOException public void testJsonSampleDoc() throws IOException { - byte[] data = _smileDoc(SAMPLE_DOC_JSON_SPEC); - verifyJsonSpecSampleDoc(_smileParser(data), true); + byte[] data = _smileDoc(SAMPLE_DOC_JSON_SPEC); + verifyJsonSpecSampleDoc(_smileParser(data), true); } public void testUnicodeStringValues() throws IOException From b13301902783245d2a035169a2b588491225d4ff Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Fri, 3 Jan 2025 18:28:14 -0800 Subject: [PATCH 5/7] Add tests to verify Avro handling --- .../jackson/dataformat/avro/POJOSimpleReadTest.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/avro/src/test/java/com/fasterxml/jackson/dataformat/avro/POJOSimpleReadTest.java b/avro/src/test/java/com/fasterxml/jackson/dataformat/avro/POJOSimpleReadTest.java index c4077a969..8ededee38 100644 --- a/avro/src/test/java/com/fasterxml/jackson/dataformat/avro/POJOSimpleReadTest.java +++ b/avro/src/test/java/com/fasterxml/jackson/dataformat/avro/POJOSimpleReadTest.java @@ -60,6 +60,8 @@ private void _testSimplePojoViaParser(Employee empl, byte[] avro, assertFalse(p.hasTextCharacters()); assertEquals("name", p.currentName()); assertEquals("name", p.getText()); + assertEquals("name", p.getValueAsString()); + assertEquals("name", p.getValueAsString("x")); assertToken(JsonToken.VALUE_STRING, p.nextToken()); assertEquals(empl.name, p.getText()); @@ -70,6 +72,9 @@ private void _testSimplePojoViaParser(Employee empl, byte[] avro, assertTrue(p.hasTextCharacters()); assertToken(JsonToken.FIELD_NAME, p.nextToken()); assertEquals("age", p.currentName()); + assertEquals("age", p.getText()); + assertEquals("age", p.getValueAsString()); + assertEquals("age", p.getValueAsString("x")); assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken()); assertEquals(NumberType.INT, p.getNumberType()); assertEquals(Integer.valueOf(empl.age), p.getNumberValue()); @@ -82,6 +87,9 @@ private void _testSimplePojoViaParser(Employee empl, byte[] avro, sw = new StringWriter(); assertEquals(6, p.getText(sw)); assertEquals("emails", sw.toString()); + assertEquals("emails", p.getText()); + assertEquals("emails", p.getValueAsString()); + assertEquals("emails", p.getValueAsString("x")); assertToken(JsonToken.START_ARRAY, p.nextToken()); assertToken(JsonToken.VALUE_STRING, p.nextToken()); From 59e5847de5f638996b3beb8478c4cf7970ea9654 Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Fri, 3 Jan 2025 18:31:56 -0800 Subject: [PATCH 6/7] Add tests to verify Ion handling --- .../jackson/dataformat/ion/IonParserTest.java | 3 ++ .../dataformat/ion/SimpleIonReadTest.java | 46 ++++++++++--------- 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/ion/src/test/java/com/fasterxml/jackson/dataformat/ion/IonParserTest.java b/ion/src/test/java/com/fasterxml/jackson/dataformat/ion/IonParserTest.java index 6d907e4ac..6c66a4eaf 100644 --- a/ion/src/test/java/com/fasterxml/jackson/dataformat/ion/IonParserTest.java +++ b/ion/src/test/java/com/fasterxml/jackson/dataformat/ion/IonParserTest.java @@ -169,6 +169,9 @@ public void testUnknownSymbolExceptionForFieldNameIsWrapped() throws IOException Assert.assertEquals(JsonToken.START_OBJECT, parser.nextToken()); Assert.assertEquals(JsonToken.FIELD_NAME, parser.nextToken()); Assert.assertEquals("a", parser.currentName()); + Assert.assertEquals("a", parser.getText()); + Assert.assertEquals("a", parser.getValueAsString()); + Assert.assertEquals("a", parser.getValueAsString("b")); Assert.assertEquals(JsonToken.VALUE_NUMBER_INT, parser.nextValue()); Assert.assertEquals(1, parser.getIntValue()); parser.nextValue(); // Should encounter unknown symbol and fail diff --git a/ion/src/test/java/com/fasterxml/jackson/dataformat/ion/SimpleIonReadTest.java b/ion/src/test/java/com/fasterxml/jackson/dataformat/ion/SimpleIonReadTest.java index a5829edda..c73db94a2 100644 --- a/ion/src/test/java/com/fasterxml/jackson/dataformat/ion/SimpleIonReadTest.java +++ b/ion/src/test/java/com/fasterxml/jackson/dataformat/ion/SimpleIonReadTest.java @@ -23,32 +23,37 @@ import com.fasterxml.jackson.core.JsonToken; public class SimpleIonReadTest { + private final IonFactory ION_F = new IonFactory(); // // // Actual tests; low level @Test public void testSimpleStructRead() throws IOException { - IonFactory f = new IonFactory(); - JsonParser jp = f.createParser("{a:\"value\",b:42, c:null}"); - assertEquals(JsonToken.START_OBJECT, jp.nextToken()); - assertEquals(JsonToken.FIELD_NAME, jp.nextToken()); - assertEquals("a", jp.currentName()); - assertEquals(JsonToken.VALUE_STRING, jp.nextToken()); - assertEquals("value", jp.getText()); - assertEquals(JsonToken.VALUE_NUMBER_INT, jp.nextValue()); - assertEquals("b", jp.currentName()); - assertEquals(42, jp.getIntValue()); - assertEquals(JsonToken.VALUE_NULL, jp.nextValue()); - assertEquals("c", jp.currentName()); - assertEquals(JsonToken.END_OBJECT, jp.nextToken()); - jp.close(); + try (JsonParser p = ION_F.createParser("{a:\"value\",b:42, c:null}")) { + assertEquals(JsonToken.START_OBJECT, p.nextToken()); + assertEquals(JsonToken.FIELD_NAME, p.nextToken()); + assertEquals("a", p.currentName()); + assertEquals("a", p.getText()); + assertEquals("a", p.getValueAsString()); + assertEquals("a", p.getValueAsString("x")); + assertEquals(JsonToken.VALUE_STRING, p.nextToken()); + assertEquals("value", p.getText()); + assertEquals("value", p.getText()); + assertEquals("value", p.getValueAsString()); + assertEquals("value", p.getValueAsString("x")); + assertEquals(JsonToken.VALUE_NUMBER_INT, p.nextValue()); + assertEquals("b", p.currentName()); + assertEquals(42, p.getIntValue()); + assertEquals(JsonToken.VALUE_NULL, p.nextValue()); + assertEquals("c", p.currentName()); + assertEquals(JsonToken.END_OBJECT, p.nextToken()); + } } @Test public void testSimpleListRead() throws IOException { - IonFactory f = new IonFactory(); - JsonParser jp = f.createParser("[ 12, true, null, \"abc\" ]"); + JsonParser jp = ION_F.createParser("[ 12, true, null, \"abc\" ]"); assertEquals(JsonToken.START_ARRAY, jp.nextToken()); assertEquals(JsonToken.VALUE_NUMBER_INT, jp.nextValue()); assertEquals(12, jp.getIntValue()); @@ -63,8 +68,7 @@ public void testSimpleListRead() throws IOException @Test public void testSimpleStructAndArray() throws IOException { - IonFactory f = new IonFactory(); - JsonParser jp = f.createParser("{a:[\"b\",\"c\"], b:null}"); + JsonParser jp = ION_F.createParser("{a:[\"b\",\"c\"], b:null}"); assertEquals(JsonToken.START_OBJECT, jp.nextToken()); assertEquals(JsonToken.FIELD_NAME, jp.nextToken()); assertEquals("a", jp.currentName()); @@ -85,8 +89,7 @@ public void testSimpleStructAndArray() throws IOException @Test public void testMixed() throws IOException { - IonFactory f = new IonFactory(); - JsonParser jp = f.createParser("{a:[ 1, { b: 13}, \"xyz\" ], c:null, d:true}"); + JsonParser jp = ION_F.createParser("{a:[ 1, { b: 13}, \"xyz\" ], c:null, d:true}"); assertEquals(JsonToken.START_OBJECT, jp.nextToken()); assertEquals(JsonToken.START_ARRAY, jp.nextValue()); //assertEquals("a", jp.currentName()); @@ -113,8 +116,7 @@ public void testMixed() throws IOException @Test public void testNullIonType() throws IOException { - IonFactory f = new IonFactory(); - JsonParser jp = f.createParser("{a:\"value\",b:42, c:null.int}"); + JsonParser jp = ION_F.createParser("{a:\"value\",b:42, c:null.int}"); assertEquals(JsonToken.START_OBJECT, jp.nextToken()); assertEquals(JsonToken.FIELD_NAME, jp.nextToken()); assertEquals("a", jp.currentName()); From de6e7f0c6c30cb920481d241f548fbd5a0a42954 Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Fri, 3 Jan 2025 18:34:10 -0800 Subject: [PATCH 7/7] Add tests, fix, for protobuf parser --- .../jackson/dataformat/protobuf/ProtobufParser.java | 6 ++++++ .../jackson/dataformat/protobuf/ReadSimpleTest.java | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/protobuf/src/main/java/com/fasterxml/jackson/dataformat/protobuf/ProtobufParser.java b/protobuf/src/main/java/com/fasterxml/jackson/dataformat/protobuf/ProtobufParser.java index 0a1cfc28e..6f673bd1b 100644 --- a/protobuf/src/main/java/com/fasterxml/jackson/dataformat/protobuf/ProtobufParser.java +++ b/protobuf/src/main/java/com/fasterxml/jackson/dataformat/protobuf/ProtobufParser.java @@ -1395,6 +1395,9 @@ public String getValueAsString() throws IOException } return _textBuffer.contentsAsString(); } + if (_currToken == JsonToken.FIELD_NAME) { + return currentName(); + } if (_currToken == null || _currToken == JsonToken.VALUE_NULL || !_currToken.isScalarValue()) { return null; } @@ -1405,6 +1408,9 @@ public String getValueAsString() throws IOException public String getValueAsString(String defaultValue) throws IOException { if (_currToken != JsonToken.VALUE_STRING) { + if (_currToken == JsonToken.FIELD_NAME) { + return currentName(); + } if (_currToken == null || _currToken == JsonToken.VALUE_NULL || !_currToken.isScalarValue()) { return defaultValue; } diff --git a/protobuf/src/test/java/com/fasterxml/jackson/dataformat/protobuf/ReadSimpleTest.java b/protobuf/src/test/java/com/fasterxml/jackson/dataformat/protobuf/ReadSimpleTest.java index 6494fc0ce..cfef5430b 100644 --- a/protobuf/src/test/java/com/fasterxml/jackson/dataformat/protobuf/ReadSimpleTest.java +++ b/protobuf/src/test/java/com/fasterxml/jackson/dataformat/protobuf/ReadSimpleTest.java @@ -137,12 +137,18 @@ public void testReadPointLong() throws Exception assertNull(p.currentName()); assertToken(JsonToken.FIELD_NAME, p.nextToken()); assertEquals("x", p.currentName()); + assertEquals("x", p.getText()); + assertEquals("x", p.getValueAsString()); + assertEquals("x", p.getValueAsString("y")); assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken()); assertEquals(NumberType.LONG, p.getNumberType()); assertEquals(NumberTypeFP.UNKNOWN, p.getNumberTypeFP()); assertEquals(input.x, p.getIntValue()); assertToken(JsonToken.FIELD_NAME, p.nextToken()); assertEquals("y", p.currentName()); + assertEquals("y", p.getText()); + assertEquals("y", p.getValueAsString()); + assertEquals("y", p.getValueAsString("abc")); assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken()); assertEquals(input.y, p.getIntValue()); assertToken(JsonToken.END_OBJECT, p.nextToken());