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 43c19b18a..a4f1a5f38 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 @@ -2289,7 +2289,9 @@ protected void _finishToken() throws IOException // 29-Jan-2021, tatu: as per [dataformats-binary#238] must keep in mind that // the longest individual unit is 4 bytes (surrogate pair) so we // actually need len+3 bytes to avoid bounds checks - final int needed = len + 3; + // 18-Jan-2024, tatu: For malicious input / Fuzzers, need to worry about overflow + // like Integer.MAX_VALUE + final int needed = Math.max(len, len + 3); final int available = _inputEnd - _inputPtr; if ((available >= needed) diff --git a/cbor/src/test/java/com/fasterxml/jackson/dataformat/cbor/fuzz/CBORFuzz464_65722_IOOBETest.java b/cbor/src/test/java/com/fasterxml/jackson/dataformat/cbor/fuzz/CBORFuzz464_65722_IOOBETest.java new file mode 100644 index 000000000..1563eb91b --- /dev/null +++ b/cbor/src/test/java/com/fasterxml/jackson/dataformat/cbor/fuzz/CBORFuzz464_65722_IOOBETest.java @@ -0,0 +1,32 @@ +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 CBORFuzz464_65722_IOOBETest extends CBORTestBase +{ + private final ObjectMapper MAPPER = cborMapper(); + + public void testInvalidText() throws Exception + { + final byte[] input = { + (byte)-60, (byte)-49, (byte)122, (byte)127, (byte)-1, + (byte)-1, (byte)-1, (byte)15, (byte)110 + }; + try (JsonParser p = MAPPER.createParser(input)) { + try { + assertToken(JsonToken.VALUE_STRING, p.nextToken()); + // oddly enough `getText()` didn't do it but this: + p.getTextLength(); + fail("Should not reach here (invalid input)"); + } catch (StreamReadException e) { + verifyException(e, "Unexpected end-of-input in VALUE_STRING"); + } + } + } +} diff --git a/release-notes/CREDITS-2.x b/release-notes/CREDITS-2.x index 88f7ecb52..27533395f 100644 --- a/release-notes/CREDITS-2.x +++ b/release-notes/CREDITS-2.x @@ -307,3 +307,6 @@ Arthur Chan (@arthurscchan) (2.17.0) * Contributed #460: (protobuf) Unexpected `NullPointerException` in `ProtobufParser.currentName()` (2.17.0) + * Contributed #464: (cbor) Unexpected `ArrayIndexOutOfBoundsException` in `CBORParser` + for corrupt String value + (2.17.0) diff --git a/release-notes/VERSION-2.x b/release-notes/VERSION-2.x index 21696100d..390dff35b 100644 --- a/release-notes/VERSION-2.x +++ b/release-notes/VERSION-2.x @@ -40,6 +40,9 @@ Active maintainers: #460: (protobuf) Unexpected `NullPointerException` in `ProtobufParser.currentName()` (fix contributed by Arthur C) #462: (protobuf) `ProtobufParser.currentName()` returns wrong value at root level +#464: (cbor) Unexpected `ArrayIndexOutOfBoundsException` in `CBORParser` + for corrupt String value + (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)