From b587eb047b8d04c9ea79a11f61aa1e1922e49c29 Mon Sep 17 00:00:00 2001 From: Arthur Chan Date: Tue, 16 Jan 2024 13:48:52 +0000 Subject: [PATCH 1/2] Fix issue 458: Add null checking Signed-off-by: Arthur Chan --- .../jackson/dataformat/cbor/CBORParser.java | 3 ++ .../cbor/fuzz/CBORFuzz458_65768_NPETest.java | 38 ++++++++++++++++++ .../data/clusterfuzz-cbor-65768.cbor | Bin 0 -> 93 bytes 3 files changed, 41 insertions(+) create mode 100644 cbor/src/test/java/com/fasterxml/jackson/dataformat/cbor/fuzz/CBORFuzz458_65768_NPETest.java create mode 100644 cbor/src/test/resources/data/clusterfuzz-cbor-65768.cbor 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 dc52821d7..5dc8ff55d 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 @@ -2224,6 +2224,9 @@ protected void convertNumberToBigDecimal() throws IOException // Let's parse from String representation, to avoid rounding errors that //non-decimal floating operations would incur final String text = getText(); + if (text == null) { + throw _constructReadException("No more values"); + } streamReadConstraints().validateFPLength(text.length()); _numberBigDecimal = NumberInput.parseBigDecimal( text, isEnabled(StreamReadFeature.USE_FAST_BIG_NUMBER_PARSER)); diff --git a/cbor/src/test/java/com/fasterxml/jackson/dataformat/cbor/fuzz/CBORFuzz458_65768_NPETest.java b/cbor/src/test/java/com/fasterxml/jackson/dataformat/cbor/fuzz/CBORFuzz458_65768_NPETest.java new file mode 100644 index 000000000..3288cab04 --- /dev/null +++ b/cbor/src/test/java/com/fasterxml/jackson/dataformat/cbor/fuzz/CBORFuzz458_65768_NPETest.java @@ -0,0 +1,38 @@ +package com.fasterxml.jackson.dataformat.cbor.fuzz; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.exc.StreamReadException; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import com.fasterxml.jackson.dataformat.cbor.CBORTestBase; + +public class CBORFuzz458_65768_NPETest extends CBORTestBase +{ + private final ObjectMapper MAPPER = cborMapper(); + + public void testInvalidText() throws Exception + { + final byte[] input = readResource("/data/clusterfuzz-cbor-65768.cbor"); + try (JsonParser p = MAPPER.createParser(input)) { + try { + p.nextTextValue(); + p.getIntValue(); + p.nextTextValue(); + p.nextTextValue(); + p.nextTextValue(); + p.nextTextValue(); + p.nextTextValue(); + p.nextTextValue(); + p.nextTextValue(); + p.nextTextValue(); + p.nextTextValue(); + p.getFloatValue(); + p.getDecimalValue(); + fail("Should not reach here (invalid input)"); + } catch (StreamReadException e) { + verifyException(e, "No more values"); + } + } + } +} diff --git a/cbor/src/test/resources/data/clusterfuzz-cbor-65768.cbor b/cbor/src/test/resources/data/clusterfuzz-cbor-65768.cbor new file mode 100644 index 0000000000000000000000000000000000000000..430ee0462f1d884fe30a31973db7caa658c0f31a GIT binary patch literal 93 zcmeyh01R$1FfcOQ+JEcTyzQY{Obj0wFu@H;hOONR(p$UHkS>US1qk^60|7q-BqSs- HBqjm?A}1lG literal 0 HcmV?d00001 From 843862290afb849d4131b319ea1848d2221dd40c Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Tue, 16 Jan 2024 15:45:58 -0800 Subject: [PATCH 2/2] Change fix a bit, update release notes --- .../jackson/dataformat/cbor/CBORParser.java | 11 +++++--- .../cbor/fuzz/CBORFuzz458_65768_NPETest.java | 27 ++++++++++--------- release-notes/CREDITS-2.x | 2 ++ release-notes/VERSION-2.x | 2 ++ 4 files changed, 27 insertions(+), 15 deletions(-) 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 5dc8ff55d..e342df939 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 @@ -777,13 +777,13 @@ protected void _releaseBuffers() throws IOException @Override public JsonToken nextToken() throws IOException { - _numTypesValid = NR_UNKNOWN; // For longer tokens (text, binary), we'll only read when requested if (_tokenIncomplete) { _skipIncomplete(); } _tokenInputTotal = _currInputProcessed + _inputPtr; // also: clear any data retained so far + _numTypesValid = NR_UNKNOWN; _binaryValue = null; // First: need to keep track of lengths of defined-length Arrays and @@ -1112,6 +1112,9 @@ protected JsonToken _handleTaggedBinary(TagList tags) throws IOException } else { // 12-May-2016, tatu: Since that's all we know, let's otherwise // just return default Binary data marker + // 16-Jan-2024, tatu: Esoteric edge case where we have marked + // `int` as being tokenized + _numTypesValid = NR_UNKNOWN; return (_currToken = JsonToken.VALUE_EMBEDDED_OBJECT); } @@ -1558,7 +1561,7 @@ public String nextFieldName() throws IOException return name; } // otherwise just fall back to default handling; should occur rarely - return (nextToken() == JsonToken.FIELD_NAME) ? getCurrentName() : null; + return (nextToken() == JsonToken.FIELD_NAME) ? currentName() : null; } // 06-Apr-2023, tatu: Before Jackson 2.15, we had optimized variant, but @@ -2224,8 +2227,10 @@ protected void convertNumberToBigDecimal() throws IOException // Let's parse from String representation, to avoid rounding errors that //non-decimal floating operations would incur final String text = getText(); + // 16-Jan-2024, tatu: OSS-Fuzz managed to trigger this; let's fail + // explicitly if (text == null) { - throw _constructReadException("No more values"); + _throwInternal(); } streamReadConstraints().validateFPLength(text.length()); _numberBigDecimal = NumberInput.parseBigDecimal( diff --git a/cbor/src/test/java/com/fasterxml/jackson/dataformat/cbor/fuzz/CBORFuzz458_65768_NPETest.java b/cbor/src/test/java/com/fasterxml/jackson/dataformat/cbor/fuzz/CBORFuzz458_65768_NPETest.java index 3288cab04..814167f5b 100644 --- a/cbor/src/test/java/com/fasterxml/jackson/dataformat/cbor/fuzz/CBORFuzz458_65768_NPETest.java +++ b/cbor/src/test/java/com/fasterxml/jackson/dataformat/cbor/fuzz/CBORFuzz458_65768_NPETest.java @@ -1,6 +1,7 @@ package com.fasterxml.jackson.dataformat.cbor.fuzz; import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; import com.fasterxml.jackson.core.exc.StreamReadException; import com.fasterxml.jackson.databind.ObjectMapper; @@ -16,22 +17,24 @@ public void testInvalidText() throws Exception final byte[] input = readResource("/data/clusterfuzz-cbor-65768.cbor"); try (JsonParser p = MAPPER.createParser(input)) { try { - p.nextTextValue(); - p.getIntValue(); - p.nextTextValue(); - p.nextTextValue(); - p.nextTextValue(); - p.nextTextValue(); - p.nextTextValue(); - p.nextTextValue(); - p.nextTextValue(); - p.nextTextValue(); - p.nextTextValue(); + assertNull(p.nextTextValue()); + assertToken(JsonToken.VALUE_NUMBER_FLOAT, p.currentToken()); + assertEquals(0, p.getIntValue()); + assertNull(p.nextTextValue()); + assertNull(p.nextTextValue()); + assertNull(p.nextTextValue()); + assertNull(p.nextTextValue()); + assertNull(p.nextTextValue()); + assertNull(p.nextTextValue()); + assertNull(p.nextTextValue()); + assertNull(p.nextTextValue()); + assertNull(p.nextTextValue()); + assertToken(JsonToken.VALUE_EMBEDDED_OBJECT, p.currentToken()); p.getFloatValue(); p.getDecimalValue(); fail("Should not reach here (invalid input)"); } catch (StreamReadException e) { - verifyException(e, "No more values"); + verifyException(e, "Current token (VALUE_EMBEDDED_OBJECT) not numeric"); } } } diff --git a/release-notes/CREDITS-2.x b/release-notes/CREDITS-2.x index 463ae69ef..245bb7c84 100644 --- a/release-notes/CREDITS-2.x +++ b/release-notes/CREDITS-2.x @@ -303,3 +303,5 @@ Arthur Chan (@arthurscchan) (2.17.0) * Contributed #451: (cbor) `IndexOutOfBoundsException` in `CBORParser` for invalid input (2.17.0) + * Contributed #458: (cbor) Unexpected NullPointerException in `CBORParser` + (2.17.0) diff --git a/release-notes/VERSION-2.x b/release-notes/VERSION-2.x index a45d3a029..12dd3942f 100644 --- a/release-notes/VERSION-2.x +++ b/release-notes/VERSION-2.x @@ -35,6 +35,8 @@ Active maintainers: (fix contributed by Arthur C) #451: (cbor) `IndexOutOfBoundsException` in `CBORParser` for invalid input (fix contributed by Arthur C) +#458: (cbor) Unexpected NullPointerException in `CBORParser` + (fix contributed by Arthur C) - (ion) Update `com.amazon.ion:ion-java` to 1.11.0 (from 1.10.5) 2.16.1 (24-Dec-2023)