Skip to content

Commit

Permalink
Additional fix for issue 449
Browse files Browse the repository at this point in the history
Signed-off-by: Arthur Chan <arthur.chan@adalogics.com>
  • Loading branch information
arthurscchan committed Jan 9, 2024
1 parent 973b3dc commit c0a056d
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -700,6 +700,12 @@ private final void _finishLongText(int len) throws IOException
break;
case 3: // 4-byte UTF
c = _decodeUTF8_4(c);
// if outPtr >= outBuf.length before adding
// the input is malformed.
if (outPtr >= outBuf.length) {
throw _constructError(String.format(
"Malformed %d-byte UTF-8 character at the end of Unicode text block", code));
}
// Let's add first part right away:
outBuf[outPtr++] = (char) (0xD800 | (c >> 10));
if (outPtr >= outBuf.length) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,34 +12,44 @@
import com.fasterxml.jackson.dataformat.avro.AvroTestBase;

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

@Test
public void testFuzz65618IOOBE() throws Exception {
private void testFuzzIOOBE(byte[] input, String msg) throws Exception {
final AvroFactory factory = AvroFactory.builderWithNativeDecoder().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 = (AvroParser) mapper.createParser(doc)) {
try (AvroParser p = (AvroParser) mapper.createParser(input)) {
p.setSchema(schema);
assertToken(JsonToken.START_OBJECT, p.nextToken());
assertToken(JsonToken.FIELD_NAME, p.nextToken());
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");
verifyException(e, msg);
}
}

@Test
public void testFuzz65618IOOBE() throws Exception {
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
};
testFuzzIOOBE(doc, "Malformed 2-byte UTF-8 character at the end of");
);
}

@Test
public void testFuzz65649IOOBE() throws Exception {
final byte[] doc = AvroFuzzTestUtil.readResource("/data/fuzz-65649.avro");
testFuzzIOOBE(doc, "Malformed 3-byte UTF-8 character at the end of");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.fasterxml.jackson.dataformat.avro.fuzz;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

public class AvroFuzzTestUtil
{
public static byte[] readResource(String ref)
{
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
final byte[] buf = new byte[4000];

InputStream in = AvroFuzzTestUtil.class.getResourceAsStream(ref);
if (in != null) {
try {
int len;
while ((len = in.read(buf)) > 0) {
bytes.write(buf, 0, len);
}
in.close();
} catch (IOException e) {
throw new RuntimeException("Failed to read resource '"+ref+"': "+e);
}
}
if (bytes.size() == 0) {
throw new IllegalArgumentException("Failed to read resource '"+ref+"': empty resource?");
}
return bytes.toByteArray();
}
}
Binary file added avro/src/test/resources/data/fuzz-65649.avro
Binary file not shown.

0 comments on commit c0a056d

Please sign in to comment.