Fix out-of-bounds read in ByteBufferChannel

Introduced in fa122a56cf by the looks of
it, so shouldn't have ever made it into a release.
This commit is contained in:
Jonathan Coates 2022-12-14 21:21:47 +00:00
parent 99a2b26fc5
commit 551f6ba60c
No known key found for this signature in database
GPG Key ID: B9E431FF07C98D06
4 changed files with 92 additions and 1 deletions

View File

@ -33,7 +33,9 @@ public int read(ByteBuffer destination) throws ClosedChannelException {
var remaining = Math.min(backing.limit() - position, destination.remaining());
destination.put(position, backing, position, remaining);
var destPos = destination.position();
destination.put(destPos, backing, position, remaining);
destination.position(destPos + remaining);
position += remaining;
return remaining;
}

View File

@ -0,0 +1,17 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.core.apis.handles;
import dan200.computercraft.test.core.filesystem.ReadableChannelContract;
import java.nio.channels.SeekableByteChannel;
public class ArrayByteChannelTest implements ReadableChannelContract {
@Override
public SeekableByteChannel wrap(byte[] contents) {
return new ArrayByteChannel(contents);
}
}

View File

@ -0,0 +1,18 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.core.apis.handles;
import dan200.computercraft.test.core.filesystem.ReadableChannelContract;
import java.nio.ByteBuffer;
import java.nio.channels.SeekableByteChannel;
public class ByteBufferChannelTest implements ReadableChannelContract {
@Override
public SeekableByteChannel wrap(byte[] contents) {
return new ByteBufferChannel(ByteBuffer.wrap(contents));
}
}

View File

@ -0,0 +1,54 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.test.core.filesystem;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SeekableByteChannel;
import static org.junit.jupiter.api.Assertions.assertEquals;
public interface ReadableChannelContract {
SeekableByteChannel wrap(byte[] contents);
@Test
default void testReadAdvancesPosition() throws IOException {
try (var buffer = wrap(new byte[]{ 1, 2, 3, 4 })) {
var read = ByteBuffer.allocate(2);
assertEquals(2, buffer.read(read));
assertEquals(2, read.position());
assertEquals(2, buffer.position());
}
}
@Test
default void testAtOffsetReadAdvancesPosition() throws IOException {
try (var buffer = wrap(new byte[]{ 1, 2, 3, 4 })) {
buffer.position(2);
var read = ByteBuffer.allocate(2);
assertEquals(2, buffer.read(read));
assertEquals(2, read.position());
assertEquals(4, buffer.position());
}
}
@Test
default void testReadAtOffset() throws IOException {
try (var buffer = wrap(new byte[]{ 1, 2, 3, 4 })) {
buffer.position(2);
var read = ByteBuffer.allocate(2);
assertEquals(2, buffer.read(read));
read.flip();
assertEquals(3, read.get(0));
assertEquals(4, read.get(1));
}
}
}