make sure no invalid keys pass into dicts
This commit is contained in:
parent
679670b468
commit
c978925f70
5 changed files with 60 additions and 4 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
package com.mykola2312.retracker.bencode;
|
package com.mykola2312.retracker.bencode;
|
||||||
|
|
||||||
|
import com.mykola2312.retracker.bencode.error.BErrorInvalidKey;
|
||||||
import com.mykola2312.retracker.bencode.error.BErrorKeyNotFound;
|
import com.mykola2312.retracker.bencode.error.BErrorKeyNotFound;
|
||||||
import com.mykola2312.retracker.bencode.error.BErrorNoChildren;
|
import com.mykola2312.retracker.bencode.error.BErrorNoChildren;
|
||||||
import com.mykola2312.retracker.bencode.error.BErrorValueCast;
|
import com.mykola2312.retracker.bencode.error.BErrorValueCast;
|
||||||
|
|
@ -11,7 +12,20 @@ public class BDict extends BList {
|
||||||
return BType.DICT;
|
return BType.DICT;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BDict set(BValue key, BValue value) {
|
public BDict set(BValue key, BValue value) throws BErrorInvalidKey {
|
||||||
|
if (key == null || value == null) {
|
||||||
|
throw new BErrorInvalidKey(this, key, "key or value is null");
|
||||||
|
}
|
||||||
|
/* key type cannot have child, because it messes up tree,
|
||||||
|
* in other words, key cannot be a list or dict
|
||||||
|
*/
|
||||||
|
if (key.getChild() != null) {
|
||||||
|
throw new BErrorInvalidKey(this, key, "key has child, because its list or a dict");
|
||||||
|
}
|
||||||
|
if (key.getType().equals(BType.LIST) || key.getType().equals(BType.DICT)) {
|
||||||
|
throw new BErrorInvalidKey(this, key, "key shall not be list or a dict");
|
||||||
|
}
|
||||||
|
|
||||||
BValue node = find(key);
|
BValue node = find(key);
|
||||||
if (node != null) {
|
if (node != null) {
|
||||||
node.setNext(value);
|
node.setNext(value);
|
||||||
|
|
@ -24,7 +38,14 @@ public class BDict extends BList {
|
||||||
}
|
}
|
||||||
|
|
||||||
public BDict set(String key, BValue value) {
|
public BDict set(String key, BValue value) {
|
||||||
return set(new BString(key), value);
|
/* we "suppress" here exceptions since this method is used
|
||||||
|
* for building BTrees, not when decoding
|
||||||
|
*/
|
||||||
|
try {
|
||||||
|
return set(new BString(key), value);
|
||||||
|
} catch (BErrorInvalidKey e) {
|
||||||
|
throw new RuntimeException("this shouldn't have happened in BDict set: " + e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* since we're going to employ builder pattern, we can't return null.
|
/* since we're going to employ builder pattern, we can't return null.
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,14 @@
|
||||||
package com.mykola2312.retracker.bencode;
|
package com.mykola2312.retracker.bencode;
|
||||||
|
|
||||||
import static io.netty.buffer.Unpooled.buffer;
|
import static io.netty.buffer.Unpooled.buffer;
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
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.BDecodeMalformed;
|
||||||
import com.mykola2312.retracker.bencode.error.BDecodeParseError;
|
import com.mykola2312.retracker.bencode.error.BDecodeParseError;
|
||||||
|
import com.mykola2312.retracker.bencode.error.BErrorInvalidKey;
|
||||||
import com.mykola2312.retracker.bencode.error.BErrorNoRoot;
|
import com.mykola2312.retracker.bencode.error.BErrorNoRoot;
|
||||||
import com.mykola2312.retracker.bencode.error.BErrorValueCast;
|
import com.mykola2312.retracker.bencode.error.BErrorValueCast;
|
||||||
|
|
||||||
|
|
@ -102,7 +104,11 @@ public class BTree {
|
||||||
while (offset < data.length && data[offset] != BTree.BE_END) {
|
while (offset < data.length && data[offset] != BTree.BE_END) {
|
||||||
BValue key = decode();
|
BValue key = decode();
|
||||||
BValue value = decode();
|
BValue value = decode();
|
||||||
dict.set(key, value);
|
try {
|
||||||
|
dict.set(key, value);
|
||||||
|
} catch (BErrorInvalidKey e) {
|
||||||
|
throw new BDecodeMalformed(data, offset, e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// advance past terminator
|
// advance past terminator
|
||||||
offset++;
|
offset++;
|
||||||
|
|
@ -171,6 +177,7 @@ public class BTree {
|
||||||
case LIST:
|
case LIST:
|
||||||
buffer.writeByte(BE_LIST);
|
buffer.writeByte(BE_LIST);
|
||||||
for (BValue item : node) {
|
for (BValue item : node) {
|
||||||
|
System.err.println("encoding list item: " + item);
|
||||||
encode(item);
|
encode(item);
|
||||||
}
|
}
|
||||||
buffer.writeByte(BE_END);
|
buffer.writeByte(BE_END);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.mykola2312.retracker.bencode.error;
|
||||||
|
|
||||||
|
import com.mykola2312.retracker.bencode.BValue;
|
||||||
|
|
||||||
|
public class BErrorInvalidKey extends BValueError {
|
||||||
|
private static final long serialVersionUID = 8821935501326704941L;
|
||||||
|
|
||||||
|
public BErrorInvalidKey(BValue node, BValue key, String message) {
|
||||||
|
super(node, String.format("key \"%s\" invalid: %s", key, message));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -8,6 +8,7 @@ import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import com.mykola2312.retracker.bencode.error.BErrorInvalidKey;
|
||||||
import com.mykola2312.retracker.bencode.error.BErrorKeyNotFound;
|
import com.mykola2312.retracker.bencode.error.BErrorKeyNotFound;
|
||||||
import com.mykola2312.retracker.bencode.error.BErrorValueCast;
|
import com.mykola2312.retracker.bencode.error.BErrorValueCast;
|
||||||
import com.mykola2312.retracker.bencode.error.BValueError;
|
import com.mykola2312.retracker.bencode.error.BValueError;
|
||||||
|
|
@ -37,7 +38,7 @@ public class BDictTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testKeyChild() {
|
public void testKeyChild() throws BErrorInvalidKey {
|
||||||
BDict dict = new BDict();
|
BDict dict = new BDict();
|
||||||
dict.set(new BInteger(1), new BInteger(2));
|
dict.set(new BInteger(1), new BInteger(2));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
|
@ -15,6 +16,7 @@ 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;
|
import com.mykola2312.retracker.bencode.error.BDecodeMalformed;
|
||||||
import com.mykola2312.retracker.bencode.error.BError;
|
import com.mykola2312.retracker.bencode.error.BError;
|
||||||
|
import com.mykola2312.retracker.bencode.error.BErrorInvalidKey;
|
||||||
|
|
||||||
public class BTreeTest {
|
public class BTreeTest {
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -141,6 +143,17 @@ public class BTreeTest {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInvalidKeys() {
|
||||||
|
assertThrows(BErrorInvalidKey.class, () -> {
|
||||||
|
new BTree().setRoot(new BDict()).set(new BList(), new BList());
|
||||||
|
});
|
||||||
|
|
||||||
|
assertThrows(BDecodeMalformed.class, () -> {
|
||||||
|
new BTree().decode("dlelee".getBytes());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEncode() {
|
public void testEncode() {
|
||||||
assertDoesNotThrow(() -> {
|
assertDoesNotThrow(() -> {
|
||||||
|
|
@ -148,6 +161,9 @@ public class BTreeTest {
|
||||||
|
|
||||||
tree.setRoot(new BInteger(1));
|
tree.setRoot(new BInteger(1));
|
||||||
assertArrayEquals("i1e".getBytes(), tree.encode());
|
assertArrayEquals("i1e".getBytes(), tree.encode());
|
||||||
|
|
||||||
|
tree.setRoot(new BString("test"));
|
||||||
|
assertArrayEquals("4:test".getBytes(), tree.encode());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue