Delimited structs - this will allow us to skip unrecognised structs.

This commit is contained in:
akwizgran
2013-11-19 18:05:44 +00:00
parent ab5389ce1f
commit 6764ade475
20 changed files with 310 additions and 224 deletions

View File

@@ -165,14 +165,17 @@ public class PacketReaderImplTest extends BriarTestCase {
private byte[] createAck(boolean tooBig) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
Writer w = writerFactory.createWriter(out);
w.writeStructId(ACK);
w.writeStructStart(ACK);
w.writeListStart();
while(out.size() + serial.getSerialisedUniqueIdLength()
+ serial.getSerialisedListEndLength()
+ serial.getSerialisedStructEndLength()
< MAX_PACKET_LENGTH) {
w.writeBytes(TestUtils.getRandomId());
}
if(tooBig) w.writeBytes(TestUtils.getRandomId());
w.writeListEnd();
w.writeStructEnd();
assertEquals(tooBig, out.size() > MAX_PACKET_LENGTH);
return out.toByteArray();
}
@@ -180,23 +183,27 @@ public class PacketReaderImplTest extends BriarTestCase {
private byte[] createEmptyAck() throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
Writer w = writerFactory.createWriter(out);
w.writeStructId(ACK);
w.writeStructStart(ACK);
w.writeListStart();
w.writeListEnd();
w.writeStructEnd();
return out.toByteArray();
}
private byte[] createOffer(boolean tooBig) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
Writer w = writerFactory.createWriter(out);
w.writeStructId(OFFER);
w.writeStructStart(OFFER);
w.writeListStart();
while(out.size() + serial.getSerialisedUniqueIdLength()
+ serial.getSerialisedListEndLength()
+ serial.getSerialisedStructEndLength()
< MAX_PACKET_LENGTH) {
w.writeBytes(TestUtils.getRandomId());
}
if(tooBig) w.writeBytes(TestUtils.getRandomId());
w.writeListEnd();
w.writeStructEnd();
assertEquals(tooBig, out.size() > MAX_PACKET_LENGTH);
return out.toByteArray();
}
@@ -204,24 +211,27 @@ public class PacketReaderImplTest extends BriarTestCase {
private byte[] createEmptyOffer() throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
Writer w = writerFactory.createWriter(out);
w.writeStructId(OFFER);
w.writeStructStart(OFFER);
w.writeListStart();
w.writeListEnd();
w.writeStructEnd();
return out.toByteArray();
}
private byte[] createRequest(boolean tooBig) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
Writer w = writerFactory.createWriter(out);
w.writeStructId(REQUEST);
// Allow one byte for the STRUCT tag, one byte for the REQUEST tag,
w.writeStructStart(REQUEST);
// Allow one byte for the STRUCT tag, one byte for the struct ID,
// one byte for the padding length as a uint7, one byte for the BYTES
// tag, and five bytes for the length of the byte array as an int32
int size = MAX_PACKET_LENGTH - 9;
// tag, five bytes for the length of the byte array as an int32, and
// one byte for the END tag
int size = MAX_PACKET_LENGTH - 10;
if(tooBig) size++;
assertTrue(size > Short.MAX_VALUE);
w.writeUint7((byte) 0);
w.writeBytes(new byte[size]);
w.writeStructEnd();
assertEquals(tooBig, out.size() > MAX_PACKET_LENGTH);
return out.toByteArray();
}
@@ -229,9 +239,10 @@ public class PacketReaderImplTest extends BriarTestCase {
private byte[] createRequest(byte[] bitmap) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
Writer w = writerFactory.createWriter(out);
w.writeStructId(REQUEST);
w.writeStructStart(REQUEST);
w.writeUint7((byte) 0);
w.writeBytes(bitmap);
w.writeStructEnd();
return out.toByteArray();
}
}

View File

@@ -61,9 +61,9 @@ public class PacketWriterImplTest extends BriarTestCase {
b.set(15);
w.writeRequest(new Request(b, 16));
// STRUCT tag, struct ID 5, 0 as uint7, BYTES tag, length 2 as uint7,
// 0xD959
// bitmap 0xD959, END tag
byte[] output = out.toByteArray();
assertEquals("F1" + "05" + "00" + "F6" + "02" + "D959",
assertEquals("F3" + "05" + "00" + "F6" + "02" + "D959" + "F2",
StringUtils.toHexString(output));
}
@@ -85,9 +85,9 @@ public class PacketWriterImplTest extends BriarTestCase {
b.set(12);
w.writeRequest(new Request(b, 13));
// STRUCT tag, struct ID 5, 3 as uint7, BYTES tag, length 2 as uint7,
// 0xD959
// bitmap 0x59D8, END tag
byte[] output = out.toByteArray();
assertEquals("F1" + "05" + "03" + "F6" + "02" + "59D8",
assertEquals("F3" + "05" + "03" + "F6" + "02" + "59D8" + "F2",
StringUtils.toHexString(output));
}
}

View File

@@ -122,8 +122,8 @@ public class ReaderImplTest extends BriarTestCase {
@Test
public void testReadString() throws Exception {
setContents("F703666F6F" + "F700");
assertEquals("foo", r.readString());
assertEquals("", r.readString());
assertEquals("foo", r.readString(1000));
assertEquals("", r.readString(1000));
assertTrue(r.eof());
}
@@ -140,8 +140,8 @@ public class ReaderImplTest extends BriarTestCase {
@Test
public void testReadBytes() throws Exception {
setContents("F603010203" + "F600");
assertArrayEquals(new byte[] {1, 2, 3}, r.readBytes());
assertArrayEquals(new byte[] {}, r.readBytes());
assertArrayEquals(new byte[] {1, 2, 3}, r.readBytes(1000));
assertArrayEquals(new byte[] {}, r.readBytes(1000));
assertTrue(r.eof());
}
@@ -157,7 +157,7 @@ public class ReaderImplTest extends BriarTestCase {
@Test
public void testReadList() throws Exception {
setContents("F5" + "01" + "F703666F6F" + "FC0080" + "F3");
setContents("F5" + "01" + "F703666F6F" + "FC0080" + "F2");
List<Object> l = r.readList(Object.class);
assertNotNull(l);
assertEquals(3, l.size());
@@ -169,7 +169,7 @@ public class ReaderImplTest extends BriarTestCase {
@Test
public void testReadListTypeSafe() throws Exception {
setContents("F5" + "01" + "02" + "03" + "F3");
setContents("F5" + "01" + "02" + "03" + "F2");
List<Byte> l = r.readList(Byte.class);
assertNotNull(l);
assertEquals(3, l.size());
@@ -181,7 +181,7 @@ public class ReaderImplTest extends BriarTestCase {
@Test
public void testReadListTypeSafeThrowsFormatException() throws Exception {
setContents("F5" + "01" + "F703666F6F" + "03" + "F3");
setContents("F5" + "01" + "F703666F6F" + "03" + "F2");
// Trying to read a mixed list as a list of bytes should throw a
// FormatException
try {
@@ -192,7 +192,7 @@ public class ReaderImplTest extends BriarTestCase {
@Test
public void testReadMap() throws Exception {
setContents("F4" + "F703666F6F" + "7B" + "F600" + "F2" + "F3");
setContents("F4" + "F703666F6F" + "7B" + "F600" + "F1" + "F2");
Map<Object, Object> m = r.readMap(Object.class, Object.class);
assertNotNull(m);
assertEquals(2, m.size());
@@ -205,7 +205,7 @@ public class ReaderImplTest extends BriarTestCase {
@Test
public void testReadMapTypeSafe() throws Exception {
setContents("F4" + "F703666F6F" + "7B" + "F700" + "F2" + "F3");
setContents("F4" + "F703666F6F" + "7B" + "F700" + "F1" + "F2");
Map<String, Byte> m = r.readMap(String.class, Byte.class);
assertNotNull(m);
assertEquals(2, m.size());
@@ -217,8 +217,8 @@ public class ReaderImplTest extends BriarTestCase {
@Test
public void testMapKeysMustBeUnique() throws Exception {
setContents("F4" + "F703666F6F" + "01" + "F703626172" + "02" + "F3"
+ "F4" + "F703666F6F" + "01" + "F703666F6F" + "02" + "F3");
setContents("F4" + "F703666F6F" + "01" + "F703626172" + "02" + "F2"
+ "F4" + "F703666F6F" + "01" + "F703666F6F" + "02" + "F2");
// The first map has unique keys
Map<String, Byte> m = r.readMap(String.class, Byte.class);
assertNotNull(m);
@@ -234,13 +234,13 @@ public class ReaderImplTest extends BriarTestCase {
@Test
public void testReadDelimitedListElements() throws Exception {
setContents("F5" + "01" + "F703666F6F" + "FC0080" + "F3");
assertTrue(r.hasListStart());
setContents("F5" + "01" + "F703666F6F" + "FC0080" + "F2");
assertTrue(r.hasList());
r.readListStart();
assertFalse(r.hasListEnd());
assertEquals((byte) 1, r.readIntAny());
assertFalse(r.hasListEnd());
assertEquals("foo", r.readString());
assertEquals("foo", r.readString(1000));
assertFalse(r.hasListEnd());
assertEquals((short) 128, r.readIntAny());
assertTrue(r.hasListEnd());
@@ -250,7 +250,7 @@ public class ReaderImplTest extends BriarTestCase {
@Test
public void testReadDelimitedListTypeSafe() throws Exception {
setContents("F5" + "01" + "02" + "03" + "F3");
setContents("F5" + "01" + "02" + "03" + "F2");
List<Byte> l = r.readList(Byte.class);
assertNotNull(l);
assertEquals(3, l.size());
@@ -262,15 +262,15 @@ public class ReaderImplTest extends BriarTestCase {
@Test
public void testReadDelimitedMapEntries() throws Exception {
setContents("F4" + "F703666F6F" + "7B" + "F600" + "F2" + "F3");
assertTrue(r.hasMapStart());
setContents("F4" + "F703666F6F" + "7B" + "F600" + "F1" + "F2");
assertTrue(r.hasMap());
r.readMapStart();
assertFalse(r.hasMapEnd());
assertEquals("foo", r.readString());
assertEquals("foo", r.readString(1000));
assertFalse(r.hasMapEnd());
assertEquals((byte) 123, r.readIntAny());
assertFalse(r.hasMapEnd());
assertArrayEquals(new byte[] {}, r.readBytes());
assertArrayEquals(new byte[] {}, r.readBytes(1000));
assertFalse(r.hasMapEnd());
assertTrue(r.hasNull());
r.readNull();
@@ -281,7 +281,7 @@ public class ReaderImplTest extends BriarTestCase {
@Test
public void testReadDelimitedMapTypeSafe() throws Exception {
setContents("F4" + "F703666F6F" + "7B" + "F700" + "F2" + "F3");
setContents("F4" + "F703666F6F" + "7B" + "F700" + "F1" + "F2");
Map<String, Byte> m = r.readMap(String.class, Byte.class);
assertNotNull(m);
assertEquals(2, m.size());
@@ -294,8 +294,8 @@ public class ReaderImplTest extends BriarTestCase {
@Test
@SuppressWarnings("unchecked")
public void testReadNestedMapsAndLists() throws Exception {
setContents("F4" + "F4" + "F703666F6F" + "7B" + "F3"
+ "F5" + "01" + "F3" + "F3");
setContents("F4" + "F4" + "F703666F6F" + "7B" + "F2"
+ "F5" + "01" + "F2" + "F2");
Map<Object, Object> m = r.readMap(Object.class, Object.class);
assertNotNull(m);
assertEquals(1, m.size());
@@ -313,23 +313,34 @@ public class ReaderImplTest extends BriarTestCase {
@Test
public void testMaxLengthAppliesInsideMap() throws Exception {
setContents("F4" + "F703666F6F" + "F603010203" + "F3");
public void testMaxStringLengthAppliesInsideMap() throws Exception {
setContents("F4" + "F703666F6F" + "F603010203" + "F2");
r.setMaxStringLength(3);
r.setMaxBytesLength(3);
Map<String, Bytes> m = r.readMap(String.class, Bytes.class);
assertTrue(r.eof());
String key = "foo";
Bytes value = new Bytes(new byte[] {1, 2, 3});
assertEquals(Collections.singletonMap(key, value), m);
// The max string length should be applied inside the map
setContents("F4" + "F703666F6F" + "F603010203" + "F3");
setContents("F4" + "F703666F6F" + "F603010203" + "F2");
r.setMaxStringLength(2);
try {
r.readMap(String.class, Bytes.class);
fail();
} catch(FormatException expected) {}
}
@Test
public void testMaxBytesLengthAppliesInsideMap() throws Exception {
setContents("F4" + "F703666F6F" + "F603010203" + "F2");
r.setMaxBytesLength(3);
Map<String, Bytes> m = r.readMap(String.class, Bytes.class);
assertTrue(r.eof());
String key = "foo";
Bytes value = new Bytes(new byte[] {1, 2, 3});
assertEquals(Collections.singletonMap(key, value), m);
// The max bytes length should be applied inside the map
setContents("F4" + "F703666F6F" + "F603010203" + "F3");
setContents("F4" + "F703666F6F" + "F603010203" + "F2");
r.setMaxBytesLength(2);
try {
r.readMap(String.class, Bytes.class);
@@ -337,6 +348,19 @@ public class ReaderImplTest extends BriarTestCase {
} catch(FormatException expected) {}
}
@Test
public void testReadStruct() throws Exception {
// Two structs with IDs 0 and 255, each containing 1 as a uint7
setContents("F300" + "01" + "F2" + "F3FF" + "01" + "F2");
r.readStructStart(0);
assertEquals(1, r.readUint7());
r.readStructEnd();
r.readStructStart(255);
assertEquals(1, r.readUint7());
r.readStructEnd();
assertTrue(r.eof());
}
@Test
public void testReadEmptyInput() throws Exception {
setContents("");

View File

@@ -155,7 +155,7 @@ public class WriterImplTest extends BriarTestCase {
for(int i = 0; i < 16; i++) l.add(i);
w.writeList(l);
// LIST tag, elements as uint7, END tag
checkContents("F5" + "000102030405060708090A0B0C0D0E0F" + "F3");
checkContents("F5" + "000102030405060708090A0B0C0D0E0F" + "F2");
}
@Test
@@ -166,7 +166,7 @@ public class WriterImplTest extends BriarTestCase {
l.add(2);
w.writeList(l);
// LIST tag, 1 as uint7, null, 2 as uint7, END tag
checkContents("F5" + "01" + "F2" + "02" + "F3");
checkContents("F5" + "01" + "F1" + "02" + "F2");
}
@Test
@@ -178,7 +178,7 @@ public class WriterImplTest extends BriarTestCase {
// MAP tag, entries as uint7, END tag
checkContents("F4" + "0001" + "0102" + "0203" + "0304" + "0405"
+ "0506" + "0607" + "0708" + "0809" + "090A" + "0A0B" + "0B0C"
+ "0C0D" + "0D0E" + "0E0F" + "0F10" + "F3");
+ "0C0D" + "0D0E" + "0E0F" + "0F10" + "F2");
}
@Test
@@ -189,7 +189,7 @@ public class WriterImplTest extends BriarTestCase {
w.writeIntAny(128L); // Written as int16
w.writeListEnd();
// LIST tag, 1 as uint7, "foo" as string, 128 as int16, END tag
checkContents("F5" + "01" + "F703666F6F" + "FC0080" + "F3");
checkContents("F5" + "01" + "F703666F6F" + "FC0080" + "F2");
}
@Test
@@ -202,7 +202,7 @@ public class WriterImplTest extends BriarTestCase {
w.writeMapEnd();
// MAP tag, "foo" as string, 123 as uint7, byte[0] as bytes,
// NULL tag, END tag
checkContents("F4" + "F703666F6F" + "7B" + "F600" + "F2" + "F3");
checkContents("F4" + "F703666F6F" + "7B" + "F600" + "F1" + "F2");
}
@Test
@@ -216,22 +216,22 @@ public class WriterImplTest extends BriarTestCase {
w.writeMap(m1);
// MAP tag, MAP tag, "foo" as string, 123 as uint7, END tag,
// LIST tag, 1 as uint7, END tag, END tag
checkContents("F4" + "F4" + "F703666F6F" + "7B" + "F3"
+ "F5" + "01" + "F3" + "F3");
checkContents("F4" + "F4" + "F703666F6F" + "7B" + "F2"
+ "F5" + "01" + "F2" + "F2");
}
@Test
public void testWriteStruct() throws IOException {
w.writeStructStart(123);
w.writeStructEnd();
// STRUCT tag, 123 as struct ID, END tag
checkContents("F3" + "7B" + "F2");
}
@Test
public void testWriteNull() throws IOException {
w.writeNull();
checkContents("F2");
}
@Test
public void testWriteStructId() throws IOException {
w.writeStructId(32);
w.writeStructId(255);
// STRUCT tag, 32 as uint8, STRUCT tag, 255 as uint8
checkContents("F1" + "20" + "F1" + "FF");
checkContents("F1");
}
private void checkContents(String hex) throws IOException {