Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes for 449: Unexpected IOOBE handling #450

Merged
merged 4 commits into from
Jan 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -614,9 +614,8 @@ private final String _finishShortText(int len) throws IOException
_inputPtr += len;
final byte[] inputBuf = _inputBuffer;

// Let's actually do a tight loop for ASCII first:
final int end = inPtr + len;

// Let's actually do a tight loop for ASCII first:
int i;
while ((i = inputBuf[inPtr]) >= 0) {
outBuf[outPtr++] = (char) i;
Expand All @@ -628,9 +627,18 @@ private final String _finishShortText(int len) throws IOException
final int[] codes = sUtf8UnitLengths;
do {
i = inputBuf[inPtr++] & 0xFF;
switch (codes[i]) {
case 0:
break;
final int code = codes[i];
if (code == 0) { // still optimized for ASCII
outBuf[outPtr++] = (char) i;
continue;
}
if ((inPtr + code) > end) {
if (code < 4) {
throw _constructError(String.format(
"Malformed %d-byte UTF-8 character at the end of Unicode text block", code));
}
}
switch (code) {
case 1:
i = ((i & 0x1F) << 6) | (inputBuf[inPtr++] & 0x3F);
break;
Expand All @@ -650,7 +658,7 @@ private final String _finishShortText(int len) throws IOException
i = 0xDC00 | (i & 0x3FF);
break;
default: // invalid
_reportError("Invalid byte "+Integer.toHexString(i)+" in Unicode text block");
_reportError(String.format("Invalid byte 0x2X in Unicode text block", i));
}
outBuf[outPtr++] = (char) i;
} while (inPtr < end);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.fasterxml.jackson.dataformat.avro.fuzz;

import org.junit.Test;

import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.core.exc.StreamReadException;
import com.fasterxml.jackson.dataformat.avro.AvroFactory;
import com.fasterxml.jackson.dataformat.avro.AvroMapper;
import com.fasterxml.jackson.dataformat.avro.AvroParser;
import com.fasterxml.jackson.dataformat.avro.AvroSchema;
import com.fasterxml.jackson.dataformat.avro.AvroTestBase;

// [dataformats-binary#449]
public class AvroFuzz449_65618_IOOBETest extends AvroTestBase
{
@JsonPropertyOrder({ "name", "value" })
static class RootType {
public String name;
public int value;
}

@Test
public void testFuzz65618IOOBE() throws Exception {
final AvroFactory factory = AvroFactory.builderWithApacheDecoder().build();
final AvroMapper mapper = new AvroMapper(factory);

final byte[] doc = {
(byte) 2, (byte) 22, (byte) 36, (byte) 2, (byte) 0,
(byte) 0, (byte) 8, (byte) 3, (byte) 3, (byte) 3,
(byte) 122, (byte) 3, (byte) -24
};

final AvroSchema schema = mapper.schemaFor(RootType.class);
try (AvroParser p = factory.createParser(doc)) {
p.setSchema(schema);
assertToken(JsonToken.START_OBJECT, p.nextToken());
assertToken(JsonToken.FIELD_NAME, p.nextToken());
p.nextToken();
fail("Should not pass (invalid content)");
} catch (StreamReadException e) {
verifyException(e, "Malformed 2-byte UTF-8 character at the end of");
}
}
}
6 changes: 5 additions & 1 deletion release-notes/CREDITS-2.x
Original file line number Diff line number Diff line change
Expand Up @@ -295,5 +295,9 @@ Arthur Chan (@arthurscchan)
* Contributed #432 (ion) More methods from `IonReader` could throw an unexpected
`AssertionError`
(2.17.0)
* Contributed #434 (ion) Unexpected `NullPointerException` thrown from `IonParser::getNumberType()`
* Contributed #434: (ion) Unexpected `NullPointerException` thrown from
`IonParser::getNumberType()`
(2.17.0)
* Contributed #449: (avro) `IndexOutOfBoundsException` in `JacksonAvroParserImpl`
for invalid input
(2.17.0)
2 changes: 2 additions & 0 deletions release-notes/VERSION-2.x
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ Active maintainers:
#434 (ion) Unexpected `NullPointerException` thrown from `IonParser::getNumberType()`
(fix contributed by Arthur C)
#437 (ion) `IonReader.next()` throws NPEs for some invalid content
#449 (avro) `IndexOutOfBoundsException` in `JacksonAvroParserImpl` for invalid input
(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)
Expand Down