handle cases of malformed bencode data
This commit is contained in:
parent
d40e1cbe4e
commit
09f0e7dcee
3 changed files with 37 additions and 3 deletions
|
|
@ -4,8 +4,8 @@ import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import com.mykola2312.retracker.bencode.error.BDecodeError;
|
import com.mykola2312.retracker.bencode.error.BDecodeError;
|
||||||
|
import com.mykola2312.retracker.bencode.error.BDecodeMalformed;
|
||||||
import com.mykola2312.retracker.bencode.error.BDecodeParseError;
|
import com.mykola2312.retracker.bencode.error.BDecodeParseError;
|
||||||
import com.mykola2312.retracker.bencode.error.BDecodeUnknown;
|
|
||||||
|
|
||||||
public class BTree {
|
public class BTree {
|
||||||
private BValue root = null;
|
private BValue root = null;
|
||||||
|
|
@ -40,22 +40,31 @@ public class BTree {
|
||||||
|
|
||||||
public BValue decode() throws BDecodeError {
|
public BValue decode() throws BDecodeError {
|
||||||
BType type;
|
BType type;
|
||||||
|
if (data.length < 2) {
|
||||||
|
/* no bencode data can be less than 2 bytes: for integer must be 'i0e' atleast,
|
||||||
|
* strings must be at least '0:' and lists and dicts can be empty
|
||||||
|
*/
|
||||||
|
throw new BDecodeMalformed(data, offset, "data is shorter than 2 bytes");
|
||||||
|
}
|
||||||
|
|
||||||
// consume and determine type
|
// consume and determine type
|
||||||
switch (data[offset]) {
|
switch (data[offset]) {
|
||||||
case BE_INTEGER: type = BType.INTEGER; break;
|
case BE_INTEGER: type = BType.INTEGER; break;
|
||||||
case BE_LIST: type = BType.LIST; break;
|
case BE_LIST: type = BType.LIST; break;
|
||||||
case BE_DICT: type = BType.DICT; break;
|
case BE_DICT: type = BType.DICT; break;
|
||||||
default: throw new BDecodeUnknown(data, offset, data[offset]);
|
default: type = BType.STRING;
|
||||||
}
|
}
|
||||||
offset++;
|
offset++;
|
||||||
|
|
||||||
if (type.equals(BType.INTEGER)) {
|
if (type.equals(BType.INTEGER)) {
|
||||||
// advance until we hit end marker
|
// advance until we hit end marker
|
||||||
int end = offset;
|
int end = offset;
|
||||||
while (data[end] != BDecoder.BE_END) {
|
while (end < data.length && data[end] != BDecoder.BE_END) {
|
||||||
end++;
|
end++;
|
||||||
}
|
}
|
||||||
|
if (end == data.length) {
|
||||||
|
throw new BDecodeMalformed(data, offset, "no integer terminator");
|
||||||
|
}
|
||||||
// convert bytes to string and string to integer
|
// convert bytes to string and string to integer
|
||||||
byte[] bytes = Arrays.copyOfRange(data, offset, end);
|
byte[] bytes = Arrays.copyOfRange(data, offset, end);
|
||||||
return new BInteger(parseLong(bytes));
|
return new BInteger(parseLong(bytes));
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.mykola2312.retracker.bencode.error;
|
||||||
|
|
||||||
|
/* this exception should be thrown in cases buffer overrun,
|
||||||
|
* missing terminators and other nasty stuff. but it also
|
||||||
|
* could signal that there is parsing logic error
|
||||||
|
*/
|
||||||
|
public class BDecodeMalformed extends BDecodeError {
|
||||||
|
private static final long serialVersionUID = -8134440302174728903L;
|
||||||
|
|
||||||
|
public BDecodeMalformed(byte[] data, int offset, String reason) {
|
||||||
|
super(data, offset, reason);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,10 +3,12 @@ package com.mykola2312.retracker.bencode;
|
||||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import com.mykola2312.retracker.bencode.error.BDecodeError;
|
import com.mykola2312.retracker.bencode.error.BDecodeError;
|
||||||
|
import com.mykola2312.retracker.bencode.error.BDecodeMalformed;
|
||||||
|
|
||||||
public class BTreeTest {
|
public class BTreeTest {
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -24,4 +26,14 @@ public class BTreeTest {
|
||||||
System.out.println("testParseInt: " + root.toString());
|
System.out.println("testParseInt: " + root.toString());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParseIntOverrun() throws BDecodeError {
|
||||||
|
final byte[] data = "i696969".getBytes();
|
||||||
|
|
||||||
|
BTree tree = new BTree();
|
||||||
|
assertThrows(BDecodeMalformed.class, () -> {
|
||||||
|
tree.decode(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue