make sure there is an exception if the file is corrupt
This commit is contained in:
@@ -13,9 +13,9 @@ enum ByteType {
|
||||
VERSION(1);// 00000001
|
||||
|
||||
interface ContinuationByte {
|
||||
long NUMBER_OF_VALUES_BITS = 7;
|
||||
int NUMBER_OF_VALUES_BITS = 7;
|
||||
|
||||
long CONTINUATION_BYTE_PREFIX = 1 << NUMBER_OF_VALUES_BITS; // 10000000
|
||||
int CONTINUATION_BYTE_PREFIX = 1 << NUMBER_OF_VALUES_BITS; // 10000000
|
||||
}
|
||||
|
||||
interface VersionByte {
|
||||
@@ -24,19 +24,23 @@ enum ByteType {
|
||||
* which cannot hold any value (unless it is 0). And the second byte is
|
||||
* the actual value.
|
||||
*/
|
||||
long MIN_LENGTH = 2;
|
||||
int MIN_LENGTH = 2;
|
||||
}
|
||||
|
||||
private final long firstBytePrefix;
|
||||
private final int firstBytePrefix;
|
||||
|
||||
private ByteType(final long firstBytePrefix) {
|
||||
private ByteType(final int firstBytePrefix) {
|
||||
this.firstBytePrefix = firstBytePrefix;
|
||||
}
|
||||
|
||||
public long getBytePrefix() {
|
||||
public int getBytePrefix() {
|
||||
return firstBytePrefix;
|
||||
}
|
||||
|
||||
public byte getBytePrefixAsByte() {
|
||||
return (byte) firstBytePrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* the max value for the first byte is the prefix minus 1, because prefixes
|
||||
* start with 0⋯010⋯0, so prefix -1 is 0⋯01⋯1 which is exactly the max value
|
||||
@@ -53,7 +57,7 @@ enum ByteType {
|
||||
*
|
||||
* @return bitmap with the value bits set
|
||||
*/
|
||||
public long getValueBits() {
|
||||
public int getValueBits() {
|
||||
return firstBytePrefix - 1;
|
||||
}
|
||||
|
||||
@@ -64,7 +68,7 @@ enum ByteType {
|
||||
return firstBytePrefix == (theByte & prefixBits);
|
||||
}
|
||||
|
||||
public long getPrefixBits() {
|
||||
public int getPrefixBits() {
|
||||
return (~getValueBits()) & 0xff;
|
||||
}
|
||||
|
||||
@@ -78,7 +82,7 @@ enum ByteType {
|
||||
return null;
|
||||
}
|
||||
|
||||
public long getValue(final int aByte) {
|
||||
public int getValue(final int aByte) {
|
||||
return aByte & getValueBits();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,6 +90,7 @@ class PdbReader implements AutoCloseable {
|
||||
}
|
||||
|
||||
Entry readNullableEntry() throws ReadRuntimeException {
|
||||
|
||||
try {
|
||||
final long epochMilliIncrement = readValue(ByteType.DATE_INCREMENT);
|
||||
if (epochMilliIncrement < 0) {
|
||||
@@ -127,6 +128,7 @@ class PdbReader implements AutoCloseable {
|
||||
|
||||
if (!byteType.isValid(firstByte)) {
|
||||
if (firstByte < 0) {
|
||||
// end of file reached
|
||||
return -1;
|
||||
} else if (ByteType.DATE_OFFSET.isValid(firstByte)) {
|
||||
final long dateOffsetInit = firstByte & ByteType.DATE_OFFSET.getValueBits();
|
||||
|
||||
@@ -4,6 +4,7 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.time.Instant;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.ZoneId;
|
||||
@@ -88,6 +89,39 @@ public class PdbReaderWriterTest {
|
||||
|
||||
Assert.assertEquals(actual, entry);
|
||||
}
|
||||
reader.readEntry().ifPresent(e -> {
|
||||
throw new AssertionError();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = FileCorruptException.class)
|
||||
public void testReadExceptionOnCorruptEntries() throws Exception {
|
||||
|
||||
final Entry entryA = new Entry(1, 1, TAGS);
|
||||
|
||||
final File file = Files.createTempFile(dataDirectory, "pdb", ".db").toFile();
|
||||
final PdbFile pdbFile = new PdbFile(file.toPath(), TAGS);
|
||||
|
||||
try (PdbWriter writer = new PdbWriter(pdbFile)) {
|
||||
writer.write(entryA);
|
||||
}
|
||||
|
||||
// make the file corrupt
|
||||
// two date consecutive increments will never happen in valid data
|
||||
final byte[] corruptEntries = new byte[] { //
|
||||
ByteType.DATE_INCREMENT.getBytePrefixAsByte(), //
|
||||
ByteType.DATE_INCREMENT.getBytePrefixAsByte() //
|
||||
};
|
||||
|
||||
Files.write(file.toPath(), corruptEntries, StandardOpenOption.APPEND);
|
||||
|
||||
try (final PdbReader reader = new PdbReader(pdbFile)) {
|
||||
|
||||
final Entry actualA = reader.readEntry().orElseThrow(() -> new AssertionError());
|
||||
Assert.assertEquals(actualA, entryA);
|
||||
|
||||
reader.readEntry(); // should throw FileCorruptException
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user