ARTEMIS-1810 JDBCSequentialFileFactoryDriver should check <=0 read length

In order to avoid out of bounds reads to happen, the reading of the file
should avoid those readings to hit the DMBS and just return the expected
value.
This commit is contained in:
Francesco Nigro 2018-04-16 13:20:22 +02:00 committed by Clebert Suconic
parent 95e9e6e2b6
commit 3d30a98b23
2 changed files with 76 additions and 6 deletions

View File

@ -294,17 +294,27 @@ public class JDBCSequentialFileFactoryDriver extends AbstractJDBCDriver {
if (rs.next()) { if (rs.next()) {
final Blob blob = rs.getBlob(1); final Blob blob = rs.getBlob(1);
if (blob != null) { if (blob != null) {
readLength = (int) calculateReadLength(blob.length(), bytes.remaining(), file.position()); final long blobLength = blob.length();
final int bytesRemaining = bytes.remaining();
final long filePosition = file.position();
readLength = (int) calculateReadLength(blobLength, bytesRemaining, filePosition);
if (logger.isDebugEnabled()) {
logger.debugf("trying read %d bytes: blobLength = %d bytesRemaining = %d filePosition = %d",
readLength, blobLength, bytesRemaining, filePosition);
}
if (readLength < 0) {
readLength = -1;
} else if (readLength > 0) {
byte[] data = blob.getBytes(file.position() + 1, readLength); byte[] data = blob.getBytes(file.position() + 1, readLength);
bytes.put(data); bytes.put(data);
} }
} }
}
connection.commit(); connection.commit();
return readLength; return readLength;
} catch (Throwable e) { } catch (SQLException e) {
throw e;
} finally {
connection.rollback(); connection.rollback();
throw e;
} }
} }
} }

View File

@ -96,6 +96,66 @@ public class JDBCSequentialFileFactoryTest {
assertTrue(factory.isStarted()); assertTrue(factory.isStarted());
} }
@Test
public void testReadZeroBytesOnEmptyFile() throws Exception {
JDBCSequentialFile file = (JDBCSequentialFile) factory.createSequentialFile("test.txt");
file.open();
try {
final ByteBuffer readBuffer = ByteBuffer.allocate(0);
final int bytes = file.read(readBuffer);
assertEquals(0, bytes);
} finally {
file.close();
}
}
@Test
public void testReadZeroBytesOnNotEmptyFile() throws Exception {
final int fileLength = 8;
JDBCSequentialFile file = (JDBCSequentialFile) factory.createSequentialFile("test.txt");
file.open();
try {
file.writeDirect(ByteBuffer.allocate(fileLength), true);
assertEquals(fileLength, file.size());
final ByteBuffer readBuffer = ByteBuffer.allocate(0);
final int bytes = file.read(readBuffer);
assertEquals(0, bytes);
} finally {
file.close();
}
}
@Test
public void testReadOutOfBoundsOnEmptyFile() throws Exception {
JDBCSequentialFile file = (JDBCSequentialFile) factory.createSequentialFile("test.txt");
file.open();
try {
final ByteBuffer readBuffer = ByteBuffer.allocate(1);
file.position(1);
final int bytes = file.read(readBuffer);
assertTrue("bytes read should be < 0", bytes < 0);
} finally {
file.close();
}
}
@Test
public void testReadOutOfBoundsOnNotEmptyFile() throws Exception {
final int fileLength = 8;
JDBCSequentialFile file = (JDBCSequentialFile) factory.createSequentialFile("test.txt");
file.open();
try {
file.writeDirect(ByteBuffer.allocate(fileLength), true);
assertEquals(fileLength, file.size());
file.position(fileLength + 1);
final ByteBuffer readBuffer = ByteBuffer.allocate(fileLength);
final int bytes = file.read(readBuffer);
assertTrue("bytes read should be < 0", bytes < 0);
} finally {
file.close();
}
}
@Test @Test
public void testCreateFiles() throws Exception { public void testCreateFiles() throws Exception {
int noFiles = 100; int noFiles = 100;