Skip to content

Commit

Permalink
AVRO-3783: Read LONG length for bytes, only allow INT sizes (#2210)
Browse files Browse the repository at this point in the history
* Read long length for bytes. Only allow Int sizes

* Add test for VLE int long equality
  • Loading branch information
jklamer committed Jun 16, 2023
1 parent 3b77d40 commit 1a14a00
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -329,9 +329,10 @@ public void skipString() throws IOException {

@Override
public ByteBuffer readBytes(ByteBuffer old) throws IOException {
int length = readInt();
long length = readLong();
if (length > MAX_ARRAY_SIZE) {
throw new UnsupportedOperationException("Cannot read arrays longer than " + MAX_ARRAY_SIZE + " bytes");
throw new UnsupportedOperationException(
"Cannot read arrays longer than " + MAX_ARRAY_SIZE + " bytes in Java library");
}
if (length > maxBytesLength) {
throw new AvroRuntimeException("Bytes length " + length + " exceeds maximum allowed");
Expand All @@ -344,10 +345,10 @@ public ByteBuffer readBytes(ByteBuffer old) throws IOException {
result = old;
((Buffer) result).clear();
} else {
result = ByteBuffer.allocate(length);
result = ByteBuffer.allocate((int) length);
}
doReadBytes(result.array(), result.position(), length);
((Buffer) result).limit(length);
doReadBytes(result.array(), result.position(), (int) length);
((Buffer) result).limit((int) length);
return result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,26 +39,27 @@ class DirectBinaryDecoder extends BinaryDecoder {
private InputStream in;

private class ByteReader {
public ByteBuffer read(ByteBuffer old, int length) throws IOException {
public ByteBuffer read(ByteBuffer old, long length) throws IOException {
this.checkLength(length);
final ByteBuffer result;
if (old != null && length <= old.capacity()) {
result = old;
result.clear();
} else {
result = ByteBuffer.allocate(length);
result = ByteBuffer.allocate((int) length);
}
doReadBytes(result.array(), result.position(), length);
result.limit(length);
doReadBytes(result.array(), result.position(), (int) length);
result.limit((int) length);
return result;
}

protected final void checkLength(int length) {
protected final void checkLength(long length) {
if (length < 0L) {
throw new AvroRuntimeException("Malformed data. Length is negative: " + length);
}
if (length > MAX_ARRAY_SIZE) {
throw new UnsupportedOperationException("Cannot read arrays longer than " + MAX_ARRAY_SIZE + " bytes");
throw new UnsupportedOperationException(
"Cannot read arrays longer than " + MAX_ARRAY_SIZE + " bytes in Java library");
}
if (length > maxBytesLength) {
throw new AvroRuntimeException("Bytes length " + length + " exceeds maximum allowed");
Expand All @@ -74,12 +75,12 @@ public ReuseByteReader(ByteBufferInputStream bbi) {
}

@Override
public ByteBuffer read(ByteBuffer old, int length) throws IOException {
public ByteBuffer read(ByteBuffer old, long length) throws IOException {
this.checkLength(length);
if (old != null) {
return super.read(old, length);
} else {
return bbi.readBuffer(length);
return bbi.readBuffer((int) length);
}
}

Expand Down Expand Up @@ -170,7 +171,7 @@ public double readDouble() throws IOException {

@Override
public ByteBuffer readBytes(ByteBuffer old) throws IOException {
int length = readInt();
long length = readLong();
return byteReader.read(old, length);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

package org.apache.avro.io;

import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;

import org.junit.jupiter.api.Test;
Expand All @@ -39,4 +40,24 @@ void skipLong() {
assertEquals(nextIndex, 10);
}

@Test
void testIntLongVleEquality() {
byte[] intResult = new byte[9];
byte[] longResult = new byte[9];
BinaryData.encodeInt(0, intResult, 0);
BinaryData.encodeLong(0, longResult, 0);
assertArrayEquals(intResult, longResult);
BinaryData.encodeInt(42, intResult, 0);
BinaryData.encodeLong(42, longResult, 0);
assertArrayEquals(intResult, longResult);
BinaryData.encodeInt(-24, intResult, 0);
BinaryData.encodeLong(-24, longResult, 0);
assertArrayEquals(intResult, longResult);
BinaryData.encodeInt(Integer.MAX_VALUE, intResult, 0);
BinaryData.encodeLong(Integer.MAX_VALUE, longResult, 0);
assertArrayEquals(intResult, longResult);
BinaryData.encodeInt(Integer.MIN_VALUE, intResult, 0);
BinaryData.encodeLong(Integer.MIN_VALUE, longResult, 0);
assertArrayEquals(intResult, longResult);
}
}

0 comments on commit 1a14a00

Please sign in to comment.