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

Fix infinite loop in PackedInputStream when the supplied ArrayInputStream is smaller than needed #140

Merged
merged 1 commit into from
Jun 4, 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
11 changes: 7 additions & 4 deletions runtime/src/main/java/org/capnproto/ArrayInputStream.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,10 @@

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;

public final class ArrayInputStream implements BufferedInputStream {
public class ArrayInputStream implements BufferedInputStream {

public final ByteBuffer buf;
private final ByteBuffer buf;

public ArrayInputStream(ByteBuffer buf) {
this.buf = buf.asReadOnlyBuffer();
Expand All @@ -52,7 +51,11 @@ public final int read(ByteBuffer dst) throws IOException {

@Override
public final ByteBuffer getReadBuffer() {
return this.buf;
if (buf.remaining() > 0) {
return buf;
} else {
throw new DecodeException("Premature EOF while reading buffer");
}
}

@Override
Expand Down
11 changes: 10 additions & 1 deletion runtime/src/main/java/org/capnproto/BufferedInputStream.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,14 @@
import java.nio.channels.ReadableByteChannel;

public interface BufferedInputStream extends ReadableByteChannel {
public ByteBuffer getReadBuffer() throws java.io.IOException;

/**
* Returns a {@link ByteBuffer} to read data from.
* If there is no more data to read, throws a {@link DecodeException}.
*
* @return a {@link ByteBuffer} with data to read from, if any available
* @throws java.io.IOException when an I/O error occurs
* @throws DecodeException when trying to read more data than available
*/
ByteBuffer getReadBuffer() throws java.io.IOException;
}
12 changes: 12 additions & 0 deletions runtime/src/test/java/org/capnproto/SerializePackedTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,16 @@ private void assertPacksTo(byte[] unpacked, byte[] packed) {
Assert.assertTrue(Arrays.equals(bytes, unpacked));
}
}

@Test(timeout = 1000, expected = DecodeException.class)
public void read_shouldThrowDecodingExceptionOnEmptyArrayInputStream() throws IOException {
byte[] emptyByteArray = {};
MessageReader reader = SerializePacked.read(new ArrayInputStream(ByteBuffer.wrap(emptyByteArray)), ReaderOptions.DEFAULT_READER_OPTIONS);
}

@Test(timeout = 1000, expected = DecodeException.class)
public void read_shouldThrowDecodingExceptionWhenTryingToReadMoreThanAvailableFromArrayInputStream() throws IOException {
byte[] bytes = {17, 0, 127, 0, 0, 0, 0}; //segment0 size of 127 words, which is way larger than the tiny 7 byte input
MessageReader reader = SerializePacked.read(new ArrayInputStream(ByteBuffer.wrap(bytes)), ReaderOptions.DEFAULT_READER_OPTIONS);
}
}
Loading