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..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,6 +2227,11 @@ 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) { + _throwInternal(); + } 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..814167f5b --- /dev/null +++ b/cbor/src/test/java/com/fasterxml/jackson/dataformat/cbor/fuzz/CBORFuzz458_65768_NPETest.java @@ -0,0 +1,41 @@ +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; + +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 { + 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, "Current token (VALUE_EMBEDDED_OBJECT) not numeric"); + } + } + } +} 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 000000000..430ee0462 Binary files /dev/null and b/cbor/src/test/resources/data/clusterfuzz-cbor-65768.cbor differ 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)