mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 10:49:06 +01:00
Nested user-defined objects (and collections of them) can now be read
by registering ObjectReaders with the Reader.
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
<test name='net.sf.briar.invitation.InvitationWorkerTest'/>
|
||||
<test name='net.sf.briar.protocol.BundleReadWriteTest'/>
|
||||
<test name='net.sf.briar.protocol.ConsumersTest'/>
|
||||
<test name='net.sf.briar.protocol.SigningDigestingOutputStreamTest'/>
|
||||
<test name='net.sf.briar.serial.ReaderImplTest'/>
|
||||
<test name='net.sf.briar.serial.WriterImplTest'/>
|
||||
<test name='net.sf.briar.setup.SetupWorkerTest'/>
|
||||
|
||||
@@ -125,7 +125,7 @@ public class BundleReadWriteTest extends TestCase {
|
||||
testWriteBundle();
|
||||
|
||||
MessageReader messageReader =
|
||||
new MessageReaderImpl(keyParser, sig1, dig1);
|
||||
new MessageReader(keyParser, sig1, dig1);
|
||||
FileInputStream in = new FileInputStream(bundle);
|
||||
Reader reader = rf.createReader(in);
|
||||
BundleReader r = new BundleReaderImpl(reader, keyPair.getPublic(), sig,
|
||||
@@ -158,14 +158,14 @@ public class BundleReadWriteTest extends TestCase {
|
||||
testWriteBundle();
|
||||
|
||||
RandomAccessFile f = new RandomAccessFile(bundle, "rw");
|
||||
f.seek(bundle.length() - 150);
|
||||
f.seek(bundle.length() - 100);
|
||||
byte b = f.readByte();
|
||||
f.seek(bundle.length() - 150);
|
||||
f.seek(bundle.length() - 100);
|
||||
f.writeByte(b + 1);
|
||||
f.close();
|
||||
|
||||
MessageReader messageReader =
|
||||
new MessageReaderImpl(keyParser, sig1, dig1);
|
||||
new MessageReader(keyParser, sig1, dig1);
|
||||
FileInputStream in = new FileInputStream(bundle);
|
||||
Reader reader = rf.createReader(in);
|
||||
BundleReader r = new BundleReaderImpl(reader, keyPair.getPublic(), sig,
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
package net.sf.briar.protocol;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.Signature;
|
||||
import java.util.Arrays;
|
||||
import java.util.Random;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class SigningDigestingOutputStreamTest extends TestCase {
|
||||
|
||||
private static final String SIGNATURE_ALGO = "SHA256withRSA";
|
||||
private static final String KEY_PAIR_ALGO = "RSA";
|
||||
private static final String DIGEST_ALGO = "SHA-256";
|
||||
|
||||
private KeyPair keyPair = null;
|
||||
private Signature sig = null;
|
||||
private MessageDigest dig = null;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
keyPair = KeyPairGenerator.getInstance(KEY_PAIR_ALGO).generateKeyPair();
|
||||
sig = Signature.getInstance(SIGNATURE_ALGO);
|
||||
dig = MessageDigest.getInstance(DIGEST_ALGO);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStopAndStart() throws Exception {
|
||||
byte[] input = new byte[1024];
|
||||
new Random().nextBytes(input);
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream(input.length);
|
||||
SigningDigestingOutputStream s =
|
||||
new SigningDigestingOutputStream(out, sig, dig);
|
||||
sig.initSign(keyPair.getPrivate());
|
||||
dig.reset();
|
||||
// Sign the first 256 bytes, digest all but the last 256 bytes
|
||||
s.setDigesting(true);
|
||||
s.setSigning(true);
|
||||
s.write(input, 0, 256);
|
||||
s.setSigning(false);
|
||||
s.write(input, 256, 512);
|
||||
s.setDigesting(false);
|
||||
s.write(input, 768, 256);
|
||||
s.close();
|
||||
// Get the signature and the digest
|
||||
byte[] signature = sig.sign();
|
||||
byte[] digest = dig.digest();
|
||||
// Check that the output matches the input
|
||||
assertTrue(Arrays.equals(input, out.toByteArray()));
|
||||
// Check that the signature matches a signature over the first 256 bytes
|
||||
sig.initSign(keyPair.getPrivate());
|
||||
sig.update(input, 0, 256);
|
||||
byte[] directSignature = sig.sign();
|
||||
assertTrue(Arrays.equals(directSignature, signature));
|
||||
// Check that the digest matches a digest over all but the last 256
|
||||
// bytes
|
||||
dig.reset();
|
||||
dig.update(input, 0, 768);
|
||||
byte[] directDigest = dig.digest();
|
||||
assertTrue(Arrays.equals(directDigest, digest));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSignatureExceptionThrowsIOException() throws Exception {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
SigningDigestingOutputStream s =
|
||||
new SigningDigestingOutputStream(out, sig, dig);
|
||||
s.setSigning(true); // Signature hasn't been initialised yet
|
||||
try {
|
||||
s.write((byte) 0);
|
||||
assertTrue(false);
|
||||
} catch(IOException expected) {};
|
||||
}
|
||||
}
|
||||
@@ -8,8 +8,10 @@ import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import net.sf.briar.api.serial.ObjectReader;
|
||||
import net.sf.briar.api.serial.Raw;
|
||||
import net.sf.briar.api.serial.RawByteArray;
|
||||
import net.sf.briar.api.serial.Reader;
|
||||
import net.sf.briar.util.StringUtils;
|
||||
|
||||
import org.junit.Test;
|
||||
@@ -326,6 +328,56 @@ public class ReaderImplTest extends TestCase {
|
||||
assertTrue(r.eof());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadUserDefinedObject() throws IOException {
|
||||
setContents("C0" + "83666F6F");
|
||||
// Add an object reader for a user-defined type
|
||||
r.addObjectReader(0, new ObjectReader<Foo>() {
|
||||
public Foo readObject(Reader r) throws IOException {
|
||||
return new Foo(r.readString());
|
||||
}
|
||||
});
|
||||
assertEquals(0, r.readUserDefinedTag());
|
||||
assertEquals("foo", r.<Foo>readUserDefinedObject(0).s);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadListUsingObjectReader() throws IOException {
|
||||
setContents("A" + "1" + "C0" + "83666F6F");
|
||||
// Add an object reader for a user-defined type
|
||||
r.addObjectReader(0, new ObjectReader<Foo>() {
|
||||
public Foo readObject(Reader r) throws IOException {
|
||||
return new Foo(r.readString());
|
||||
}
|
||||
});
|
||||
// Check that the object reader is used for lists
|
||||
List<Foo> l = r.readList(Foo.class);
|
||||
assertEquals(1, l.size());
|
||||
assertEquals("foo", l.get(0).s);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadMapUsingObjectReader() throws IOException {
|
||||
setContents("B" + "1" + "C0" + "83666F6F" + "C1" + "83626172");
|
||||
// Add object readers for two user-defined types
|
||||
r.addObjectReader(0, new ObjectReader<Foo>() {
|
||||
public Foo readObject(Reader r) throws IOException {
|
||||
return new Foo(r.readString());
|
||||
}
|
||||
});
|
||||
r.addObjectReader(1, new ObjectReader<Bar>() {
|
||||
public Bar readObject(Reader r) throws IOException {
|
||||
return new Bar(r.readString());
|
||||
}
|
||||
});
|
||||
// Check that the object readers are used for maps
|
||||
Map<Foo, Bar> m = r.readMap(Foo.class, Bar.class);
|
||||
assertEquals(1, m.size());
|
||||
Entry<Foo, Bar> e = m.entrySet().iterator().next();
|
||||
assertEquals("foo", e.getKey().s);
|
||||
assertEquals("bar", e.getValue().s);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadEmptyInput() throws IOException {
|
||||
setContents("");
|
||||
@@ -336,4 +388,22 @@ public class ReaderImplTest extends TestCase {
|
||||
in = new ByteArrayInputStream(StringUtils.fromHexString(hex));
|
||||
r = new ReaderImpl(in);
|
||||
}
|
||||
|
||||
private static class Foo {
|
||||
|
||||
private final String s;
|
||||
|
||||
private Foo(String s) {
|
||||
this.s = s;
|
||||
}
|
||||
}
|
||||
|
||||
private static class Bar {
|
||||
|
||||
private final String s;
|
||||
|
||||
private Bar(String s) {
|
||||
this.s = s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,12 +4,15 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import net.sf.briar.api.serial.RawByteArray;
|
||||
import net.sf.briar.api.serial.Writable;
|
||||
import net.sf.briar.api.serial.Writer;
|
||||
import net.sf.briar.util.StringUtils;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -300,6 +303,20 @@ public class WriterImplTest extends TestCase {
|
||||
checkContents("EF" + "20" + "EF" + "FB7FFFFFFF");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWriteCollectionOfWritables() throws IOException {
|
||||
Writable writable = new Writable() {
|
||||
public void writeTo(Writer w) throws IOException {
|
||||
w.writeUserDefinedTag(0);
|
||||
w.writeString("foo");
|
||||
}
|
||||
};
|
||||
w.writeList(Collections.singleton(writable));
|
||||
// SHORT_LIST tag, length 1, SHORT_USER tag (3 bits), 0 (5 bits),
|
||||
// "foo" as short string
|
||||
checkContents("A" + "1" + "C0" + "83666F6F");
|
||||
}
|
||||
|
||||
private void checkContents(String hex) throws IOException {
|
||||
out.flush();
|
||||
out.close();
|
||||
|
||||
Reference in New Issue
Block a user