Skip to content

Commit

Permalink
Fix infinite loop on #transferFrom underflow
Browse files Browse the repository at this point in the history
  • Loading branch information
marschall committed May 14, 2023
1 parent 6f33c9f commit 3a3b9ab
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,11 @@ long transferFrom(ReadableByteChannel src, long position, long count) throws IOE
// Since ByteBuffer objects are quite small and don't copy the contents
// of the backing array allocating a ByteBuffer is probably cheaper.
ByteBuffer buffer = ByteBuffer.wrap(block, startIndexInBlock, lengthInBlock);
readFully(buffer, src, lengthInBlock);
transferred += lengthInBlock;
int read = readFully(buffer, src, lengthInBlock);
transferred += read;
if (read < lengthInBlock) {
break;
}

startIndexInBlock = 0;
currentBlock += 1;
Expand Down Expand Up @@ -362,11 +365,15 @@ private static int writeFully(ByteBuffer src, WritableByteChannel target, int to
}

private static int readFully(ByteBuffer src, ReadableByteChannel target, int toRead) throws IOException {
int read = 0;
while (read < toRead) {
read += target.read(src);
int total = 0;
while (total < toRead) {
int read = target.read(src);
if (read <= 0) {
return total;
}
total += read;
}
return read;
return total;
}

private void ensureCapacity(long capacity) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -634,7 +634,7 @@ void probeContent() throws IOException {
}

@Test
void trasferFrom() throws IOException {
void trasferTo() throws IOException {
FileSystem fileSystem = this.extension.getFileSystem();

Path from = fileSystem.getPath("from.txt");
Expand All @@ -654,7 +654,7 @@ void trasferFrom() throws IOException {
}

@Test
void trasferTo() throws IOException {
void transferFromExpectedSize() throws IOException {
FileSystem fileSystem = this.extension.getFileSystem();

Path from = fileSystem.getPath("from.txt");
Expand All @@ -674,6 +674,27 @@ void trasferTo() throws IOException {

}

@Test
void transferFromLarger() throws IOException {
FileSystem fileSystem = this.extension.getFileSystem();

Path from = fileSystem.getPath("from.txt");
Path to = fileSystem.getPath("to.txt");
byte[] content = "How could this be wrong?".getBytes(US_ASCII);
Files.write(from, content);
long expectedSize = content.length;
assertEquals(expectedSize, Files.size(from));

try (SeekableByteChannel fromChannel = Files.newByteChannel(from);
FileChannel toChannel = FileChannel.open(to, READ, WRITE, CREATE_NEW)) {
long count = toChannel.transferFrom(fromChannel, 0, content.length * 2);

assertEquals(expectedSize, count);
}
assertEquals(expectedSize, Files.size(to));
assertArrayEquals(content, Files.readAllBytes(to));
}

private void writeBigContents(Path path) throws IOException {
try (SeekableByteChannel channel = Files.newByteChannel(path, WRITE, CREATE_NEW)) {
ByteBuffer src = ByteBuffer.wrap(SAMPLE_DATA);
Expand Down Expand Up @@ -1760,7 +1781,6 @@ void pathOrderingIncompatible() {
assertThrows(ClassCastException.class, () -> a.compareTo(b));
}


@Test
void createDirectories() throws IOException {
FileSystem fileSystem = this.extension.getFileSystem();
Expand Down Expand Up @@ -1975,7 +1995,6 @@ void byteChannelDoubleClose() throws IOException {
}
}


/**
* Regression test for <a href="https://github.com/marschall/memoryfilesystem/issues/47">Issue 47</a>.
*/
Expand All @@ -1991,8 +2010,6 @@ void symLinkDirectory() throws IOException {
Files.write(link.resolve("kid"), "hallo".getBytes(US_ASCII));
}



/**
* Regression test for <a href="https://github.com/marschall/memoryfilesystem/issues/55">Issue 55</a>.
*/
Expand Down

0 comments on commit 3a3b9ab

Please sign in to comment.