diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/client/BdfMessageValidator.java b/bramble-api/src/main/java/org/briarproject/bramble/api/client/BdfMessageValidator.java index 4caed6438..468c64126 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/client/BdfMessageValidator.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/client/BdfMessageValidator.java @@ -16,6 +16,7 @@ import java.util.logging.Logger; import javax.annotation.concurrent.Immutable; +import static java.util.logging.Logger.getLogger; import static org.briarproject.bramble.api.transport.TransportConstants.MAX_CLOCK_DIFFERENCE; @Immutable @@ -23,17 +24,24 @@ import static org.briarproject.bramble.api.transport.TransportConstants.MAX_CLOC public abstract class BdfMessageValidator implements MessageValidator { protected static final Logger LOG = - Logger.getLogger(BdfMessageValidator.class.getName()); + getLogger(BdfMessageValidator.class.getName()); protected final ClientHelper clientHelper; protected final MetadataEncoder metadataEncoder; protected final Clock clock; + protected final boolean canonical; protected BdfMessageValidator(ClientHelper clientHelper, - MetadataEncoder metadataEncoder, Clock clock) { + MetadataEncoder metadataEncoder, Clock clock, boolean canonical) { this.clientHelper = clientHelper; this.metadataEncoder = metadataEncoder; this.clock = clock; + this.canonical = canonical; + } + + protected BdfMessageValidator(ClientHelper clientHelper, + MetadataEncoder metadataEncoder, Clock clock) { + this(clientHelper, metadataEncoder, clock, true); } protected abstract BdfMessageContext validateMessage(Message m, Group g, @@ -49,7 +57,7 @@ public abstract class BdfMessageValidator implements MessageValidator { "Timestamp is too far in the future"); } try { - BdfList bodyList = clientHelper.toList(m.getBody()); + BdfList bodyList = clientHelper.toList(m, canonical); BdfMessageContext result = validateMessage(m, g, bodyList); Metadata meta = metadataEncoder.encode(result.getDictionary()); return new MessageContext(meta, result.getDependencies()); diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/client/ClientHelper.java b/bramble-api/src/main/java/org/briarproject/bramble/api/client/ClientHelper.java index 9ccd18f1d..ff8ee773c 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/client/ClientHelper.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/client/ClientHelper.java @@ -49,6 +49,9 @@ public interface ClientHelper { BdfList getMessageAsList(Transaction txn, MessageId m) throws DbException, FormatException; + BdfList getMessageAsList(Transaction txn, MessageId m, boolean canonical) + throws DbException, FormatException; + BdfDictionary getGroupMetadataAsDictionary(GroupId g) throws DbException, FormatException; @@ -106,6 +109,8 @@ public interface ClientHelper { BdfList toList(Message m) throws FormatException; + BdfList toList(Message m, boolean canonical) throws FormatException; + BdfList toList(Author a); byte[] sign(String label, BdfList toSign, PrivateKey privateKey) diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfDictionary.java b/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfDictionary.java index c17c19bca..11d6f8a08 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfDictionary.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfDictionary.java @@ -11,7 +11,7 @@ import javax.annotation.Nullable; import javax.annotation.concurrent.NotThreadSafe; @NotThreadSafe -public class BdfDictionary extends TreeMap { +public final class BdfDictionary extends TreeMap { public static final Object NULL_VALUE = new Object(); @@ -39,9 +39,9 @@ public class BdfDictionary extends TreeMap { } public Boolean getBoolean(String key) throws FormatException { - Object o = get(key); - if (o instanceof Boolean) return (Boolean) o; - throw new FormatException(); + Boolean value = getOptionalBoolean(key); + if (value == null) throw new FormatException(); + return value; } @Nullable @@ -52,19 +52,16 @@ public class BdfDictionary extends TreeMap { throw new FormatException(); } - public Boolean getBoolean(String key, Boolean defaultValue) { - Object o = get(key); - if (o instanceof Boolean) return (Boolean) o; - return defaultValue; + public Boolean getBoolean(String key, Boolean defaultValue) + throws FormatException { + Boolean value = getOptionalBoolean(key); + return value == null ? defaultValue : value; } public Long getLong(String key) throws FormatException { - Object o = get(key); - if (o instanceof Long) return (Long) o; - if (o instanceof Integer) return ((Integer) o).longValue(); - if (o instanceof Short) return ((Short) o).longValue(); - if (o instanceof Byte) return ((Byte) o).longValue(); - throw new FormatException(); + Long value = getOptionalLong(key); + if (value == null) throw new FormatException(); + return value; } @Nullable @@ -78,20 +75,37 @@ public class BdfDictionary extends TreeMap { throw new FormatException(); } - public Long getLong(String key, Long defaultValue) { - Object o = get(key); - if (o instanceof Long) return (Long) o; - if (o instanceof Integer) return ((Integer) o).longValue(); - if (o instanceof Short) return ((Short) o).longValue(); - if (o instanceof Byte) return ((Byte) o).longValue(); - return defaultValue; + public Long getLong(String key, Long defaultValue) throws FormatException { + Long value = getOptionalLong(key); + return value == null ? defaultValue : value; + } + + public Integer getInt(String key) throws FormatException { + Integer value = getOptionalInt(key); + if (value == null) throw new FormatException(); + return value; + } + + @Nullable + public Integer getOptionalInt(String key) throws FormatException { + Long value = getOptionalLong(key); + if (value == null) return null; + if (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) { + throw new FormatException(); + } + return value.intValue(); + } + + public Integer getInt(String key, Integer defaultValue) + throws FormatException { + Integer value = getOptionalInt(key); + return value == null ? defaultValue : value; } public Double getDouble(String key) throws FormatException { - Object o = get(key); - if (o instanceof Double) return (Double) o; - if (o instanceof Float) return ((Float) o).doubleValue(); - throw new FormatException(); + Double value = getOptionalDouble(key); + if (value == null) throw new FormatException(); + return value; } @Nullable @@ -103,17 +117,16 @@ public class BdfDictionary extends TreeMap { throw new FormatException(); } - public Double getDouble(String key, Double defaultValue) { - Object o = get(key); - if (o instanceof Double) return (Double) o; - if (o instanceof Float) return ((Float) o).doubleValue(); - return defaultValue; + public Double getDouble(String key, Double defaultValue) + throws FormatException { + Double value = getOptionalDouble(key); + return value == null ? defaultValue : value; } public String getString(String key) throws FormatException { - Object o = get(key); - if (o instanceof String) return (String) o; - throw new FormatException(); + String value = getOptionalString(key); + if (value == null) throw new FormatException(); + return value; } @Nullable @@ -124,17 +137,16 @@ public class BdfDictionary extends TreeMap { throw new FormatException(); } - public String getString(String key, String defaultValue) { - Object o = get(key); - if (o instanceof String) return (String) o; - return defaultValue; + public String getString(String key, String defaultValue) + throws FormatException { + String value = getOptionalString(key); + return value == null ? defaultValue : value; } public byte[] getRaw(String key) throws FormatException { - Object o = get(key); - if (o instanceof byte[]) return (byte[]) o; - if (o instanceof Bytes) return ((Bytes) o).getBytes(); - throw new FormatException(); + byte[] value = getOptionalRaw(key); + if (value == null) throw new FormatException(); + return value; } @Nullable @@ -146,17 +158,16 @@ public class BdfDictionary extends TreeMap { throw new FormatException(); } - public byte[] getRaw(String key, byte[] defaultValue) { - Object o = get(key); - if (o instanceof byte[]) return (byte[]) o; - if (o instanceof Bytes) return ((Bytes) o).getBytes(); - return defaultValue; + public byte[] getRaw(String key, byte[] defaultValue) + throws FormatException { + byte[] value = getOptionalRaw(key); + return value == null ? defaultValue : value; } public BdfList getList(String key) throws FormatException { - Object o = get(key); - if (o instanceof BdfList) return (BdfList) o; - throw new FormatException(); + BdfList value = getOptionalList(key); + if (value == null) throw new FormatException(); + return value; } @Nullable @@ -167,16 +178,16 @@ public class BdfDictionary extends TreeMap { throw new FormatException(); } - public BdfList getList(String key, BdfList defaultValue) { - Object o = get(key); - if (o instanceof BdfList) return (BdfList) o; - return defaultValue; + public BdfList getList(String key, BdfList defaultValue) + throws FormatException { + BdfList value = getOptionalList(key); + return value == null ? defaultValue : value; } public BdfDictionary getDictionary(String key) throws FormatException { - Object o = get(key); - if (o instanceof BdfDictionary) return (BdfDictionary) o; - throw new FormatException(); + BdfDictionary value = getOptionalDictionary(key); + if (value == null) throw new FormatException(); + return value; } @Nullable @@ -188,9 +199,9 @@ public class BdfDictionary extends TreeMap { throw new FormatException(); } - public BdfDictionary getDictionary(String key, BdfDictionary defaultValue) { - Object o = get(key); - if (o instanceof BdfDictionary) return (BdfDictionary) o; - return defaultValue; + public BdfDictionary getDictionary(String key, BdfDictionary defaultValue) + throws FormatException { + BdfDictionary value = getOptionalDictionary(key); + return value == null ? defaultValue : value; } } diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfList.java b/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfList.java index 21ec22728..6ba6747cc 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfList.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfList.java @@ -13,7 +13,7 @@ import javax.annotation.concurrent.NotThreadSafe; import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE; @NotThreadSafe -public class BdfList extends ArrayList { +public final class BdfList extends ArrayList { /** * Factory method for constructing lists inline. @@ -33,15 +33,15 @@ public class BdfList extends ArrayList { super(items); } + @SuppressWarnings("BooleanMethodIsAlwaysInverted") private boolean isInRange(int index) { return index >= 0 && index < size(); } public Boolean getBoolean(int index) throws FormatException { - if (!isInRange(index)) throw new FormatException(); - Object o = get(index); - if (o instanceof Boolean) return (Boolean) o; - throw new FormatException(); + Boolean value = getOptionalBoolean(index); + if (value == null) throw new FormatException(); + return value; } @Nullable @@ -53,21 +53,16 @@ public class BdfList extends ArrayList { throw new FormatException(); } - public Boolean getBoolean(int index, Boolean defaultValue) { - if (!isInRange(index)) return defaultValue; - Object o = get(index); - if (o instanceof Boolean) return (Boolean) o; - return defaultValue; + public Boolean getBoolean(int index, Boolean defaultValue) + throws FormatException { + Boolean value = getOptionalBoolean(index); + return value == null ? defaultValue : value; } public Long getLong(int index) throws FormatException { - if (!isInRange(index)) throw new FormatException(); - Object o = get(index); - if (o instanceof Long) return (Long) o; - if (o instanceof Integer) return ((Integer) o).longValue(); - if (o instanceof Short) return ((Short) o).longValue(); - if (o instanceof Byte) return ((Byte) o).longValue(); - throw new FormatException(); + Long value = getOptionalLong(index); + if (value == null) throw new FormatException(); + return value; } @Nullable @@ -82,22 +77,37 @@ public class BdfList extends ArrayList { throw new FormatException(); } - public Long getLong(int index, Long defaultValue) { - if (!isInRange(index)) return defaultValue; - Object o = get(index); - if (o instanceof Long) return (Long) o; - if (o instanceof Integer) return ((Integer) o).longValue(); - if (o instanceof Short) return ((Short) o).longValue(); - if (o instanceof Byte) return ((Byte) o).longValue(); - return defaultValue; + public Long getLong(int index, Long defaultValue) throws FormatException { + Long value = getOptionalLong(index); + return value == null ? defaultValue : value; + } + + public Integer getInt(int index) throws FormatException { + Integer value = getOptionalInt(index); + if (value == null) throw new FormatException(); + return value; + } + + @Nullable + public Integer getOptionalInt(int index) throws FormatException { + Long value = getOptionalLong(index); + if (value == null) return null; + if (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) { + throw new FormatException(); + } + return value.intValue(); + } + + public Integer getInt(int index, Integer defaultValue) + throws FormatException { + Integer value = getOptionalInt(index); + return value == null ? defaultValue : value; } public Double getDouble(int index) throws FormatException { - if (!isInRange(index)) throw new FormatException(); - Object o = get(index); - if (o instanceof Double) return (Double) o; - if (o instanceof Float) return ((Float) o).doubleValue(); - throw new FormatException(); + Double value = getOptionalDouble(index); + if (value == null) throw new FormatException(); + return value; } @Nullable @@ -110,19 +120,16 @@ public class BdfList extends ArrayList { throw new FormatException(); } - public Double getDouble(int index, Double defaultValue) { - if (!isInRange(index)) return defaultValue; - Object o = get(index); - if (o instanceof Double) return (Double) o; - if (o instanceof Float) return ((Float) o).doubleValue(); - return defaultValue; + public Double getDouble(int index, Double defaultValue) + throws FormatException { + Double value = getOptionalDouble(index); + return value == null ? defaultValue : value; } public String getString(int index) throws FormatException { - if (!isInRange(index)) throw new FormatException(); - Object o = get(index); - if (o instanceof String) return (String) o; - throw new FormatException(); + String value = getOptionalString(index); + if (value == null) throw new FormatException(); + return value; } @Nullable @@ -134,19 +141,16 @@ public class BdfList extends ArrayList { throw new FormatException(); } - public String getString(int index, String defaultValue) { - if (!isInRange(index)) return defaultValue; - Object o = get(index); - if (o instanceof String) return (String) o; - return defaultValue; + public String getString(int index, String defaultValue) + throws FormatException { + String value = getOptionalString(index); + return value == null ? defaultValue : value; } public byte[] getRaw(int index) throws FormatException { - if (!isInRange(index)) throw new FormatException(); - Object o = get(index); - if (o instanceof byte[]) return (byte[]) o; - if (o instanceof Bytes) return ((Bytes) o).getBytes(); - throw new FormatException(); + byte[] value = getOptionalRaw(index); + if (value == null) throw new FormatException(); + return value; } @Nullable @@ -159,19 +163,16 @@ public class BdfList extends ArrayList { throw new FormatException(); } - public byte[] getRaw(int index, byte[] defaultValue) { - if (!isInRange(index)) return defaultValue; - Object o = get(index); - if (o instanceof byte[]) return (byte[]) o; - if (o instanceof Bytes) return ((Bytes) o).getBytes(); - return defaultValue; + public byte[] getRaw(int index, byte[] defaultValue) + throws FormatException { + byte[] value = getOptionalRaw(index); + return value == null ? defaultValue : value; } public BdfList getList(int index) throws FormatException { - if (!isInRange(index)) throw new FormatException(); - Object o = get(index); - if (o instanceof BdfList) return (BdfList) o; - throw new FormatException(); + BdfList value = getOptionalList(index); + if (value == null) throw new FormatException(); + return value; } @Nullable @@ -183,18 +184,16 @@ public class BdfList extends ArrayList { throw new FormatException(); } - public BdfList getList(int index, BdfList defaultValue) { - if (!isInRange(index)) return defaultValue; - Object o = get(index); - if (o instanceof BdfList) return (BdfList) o; - return defaultValue; + public BdfList getList(int index, BdfList defaultValue) + throws FormatException { + BdfList value = getOptionalList(index); + return value == null ? defaultValue : value; } public BdfDictionary getDictionary(int index) throws FormatException { - if (!isInRange(index)) throw new FormatException(); - Object o = get(index); - if (o instanceof BdfDictionary) return (BdfDictionary) o; - throw new FormatException(); + BdfDictionary value = getOptionalDictionary(index); + if (value == null) throw new FormatException(); + return value; } @Nullable @@ -207,10 +206,9 @@ public class BdfList extends ArrayList { throw new FormatException(); } - public BdfDictionary getDictionary(int index, BdfDictionary defaultValue) { - if (!isInRange(index)) return defaultValue; - Object o = get(index); - if (o instanceof BdfDictionary) return (BdfDictionary) o; - return defaultValue; + public BdfDictionary getDictionary(int index, BdfDictionary defaultValue) + throws FormatException { + BdfDictionary value = getOptionalDictionary(index); + return value == null ? defaultValue : value; } } diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfReader.java b/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfReader.java index ab81a39cb..fe710becd 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfReader.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfReader.java @@ -32,6 +32,12 @@ public interface BdfReader { void skipLong() throws IOException; + boolean hasInt() throws IOException; + + int readInt() throws IOException; + + void skipInt() throws IOException; + boolean hasDouble() throws IOException; double readDouble() throws IOException; @@ -54,23 +60,11 @@ public interface BdfReader { BdfList readList() throws IOException; - void readListStart() throws IOException; - - boolean hasListEnd() throws IOException; - - void readListEnd() throws IOException; - void skipList() throws IOException; boolean hasDictionary() throws IOException; BdfDictionary readDictionary() throws IOException; - void readDictionaryStart() throws IOException; - - boolean hasDictionaryEnd() throws IOException; - - void readDictionaryEnd() throws IOException; - void skipDictionary() throws IOException; } diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfReaderFactory.java b/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfReaderFactory.java index bc41a66d3..5ff95dfa1 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfReaderFactory.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfReaderFactory.java @@ -9,6 +9,8 @@ public interface BdfReaderFactory { BdfReader createReader(InputStream in); + BdfReader createReader(InputStream in, boolean canonical); + BdfReader createReader(InputStream in, int nestedLimit, - int maxBufferSize); + int maxBufferSize, boolean canonical); } diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfWriter.java b/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfWriter.java index 8e0e11d73..1427859a6 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfWriter.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfWriter.java @@ -24,13 +24,5 @@ public interface BdfWriter { void writeList(Collection c) throws IOException; - void writeListStart() throws IOException; - - void writeListEnd() throws IOException; - void writeDictionary(Map m) throws IOException; - - void writeDictionaryStart() throws IOException; - - void writeDictionaryEnd() throws IOException; } diff --git a/bramble-api/src/main/java/org/briarproject/bramble/util/StringUtils.java b/bramble-api/src/main/java/org/briarproject/bramble/util/StringUtils.java index d9a19e70a..59beeeee2 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/util/StringUtils.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/util/StringUtils.java @@ -14,6 +14,7 @@ import java.util.regex.Pattern; import javax.annotation.Nullable; import static java.nio.charset.CodingErrorAction.IGNORE; +import static java.nio.charset.CodingErrorAction.REPORT; import static java.util.regex.Pattern.CASE_INSENSITIVE; @SuppressWarnings("CharsetObjectCanBeUsed") @@ -52,26 +53,38 @@ public class StringUtils { return s.getBytes(UTF_8); } - public static String fromUtf8(byte[] bytes) { - return fromUtf8(bytes, 0, bytes.length); + public static String fromUtf8(byte[] bytes) throws FormatException { + return fromUtf8(bytes, 0, bytes.length, true); } - public static String fromUtf8(byte[] bytes, int off, int len) { + public static String fromUtf8(byte[] bytes, int off, int len) + throws FormatException { + return fromUtf8(bytes, off, len, true); + } + + private static String fromUtf8(byte[] bytes, int off, int len, + boolean strict) throws FormatException { CharsetDecoder decoder = UTF_8.newDecoder(); - decoder.onMalformedInput(IGNORE); - decoder.onUnmappableCharacter(IGNORE); + decoder.onMalformedInput(strict ? REPORT : IGNORE); + decoder.onUnmappableCharacter(strict ? REPORT : IGNORE); ByteBuffer buffer = ByteBuffer.wrap(bytes, off, len); try { return decoder.decode(buffer).toString(); } catch (CharacterCodingException e) { - throw new AssertionError(e); + throw new FormatException(); } } public static String truncateUtf8(String s, int maxUtf8Length) { byte[] utf8 = toUtf8(s); if (utf8.length <= maxUtf8Length) return s; - return fromUtf8(utf8, 0, maxUtf8Length); + // Don't be strict when converting back, so that if we truncate a + // multi-byte character the whole character gets dropped + try { + return fromUtf8(utf8, 0, maxUtf8Length, false); + } catch (FormatException e) { + throw new AssertionError(e); + } } /** diff --git a/bramble-api/src/test/java/org/briarproject/bramble/api/data/BdfDictionaryTest.java b/bramble-api/src/test/java/org/briarproject/bramble/api/data/BdfDictionaryTest.java index 17bb65116..274834cb3 100644 --- a/bramble-api/src/test/java/org/briarproject/bramble/api/data/BdfDictionaryTest.java +++ b/bramble-api/src/test/java/org/briarproject/bramble/api/data/BdfDictionaryTest.java @@ -1,6 +1,7 @@ package org.briarproject.bramble.api.data; import org.briarproject.bramble.api.Bytes; +import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.test.BrambleTestCase; import org.junit.Test; @@ -8,9 +9,12 @@ import java.util.Collections; import java.util.Iterator; import java.util.Map.Entry; +import static java.lang.Boolean.TRUE; +import static java.util.Collections.singletonMap; import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; public class BdfDictionaryTest extends BrambleTestCase { @@ -19,20 +23,20 @@ public class BdfDictionaryTest extends BrambleTestCase { public void testConstructors() { assertEquals(Collections.emptyMap(), new BdfDictionary()); - assertEquals(Collections.singletonMap("foo", NULL_VALUE), - new BdfDictionary(Collections.singletonMap("foo", NULL_VALUE))); + assertEquals(singletonMap("foo", NULL_VALUE), + new BdfDictionary(singletonMap("foo", NULL_VALUE))); } @Test public void testFactoryMethod() { assertEquals(Collections.emptyMap(), BdfDictionary.of()); - assertEquals(Collections.singletonMap("foo", NULL_VALUE), + assertEquals(singletonMap("foo", NULL_VALUE), BdfDictionary.of(new BdfEntry("foo", NULL_VALUE))); } @Test - public void testIntegerPromotion() throws Exception { + public void testLongPromotion() throws Exception { BdfDictionary d = new BdfDictionary(); d.put("foo", (byte) 1); d.put("bar", (short) 2); @@ -44,6 +48,33 @@ public class BdfDictionaryTest extends BrambleTestCase { assertEquals(Long.valueOf(4), d.getLong("bam")); } + @Test + public void testIntPromotionAndDemotion() throws Exception { + BdfDictionary d = new BdfDictionary(); + d.put("foo", (byte) 1); + d.put("bar", (short) 2); + d.put("baz", 3); + d.put("bam", 4L); + assertEquals(Integer.valueOf(1), d.getInt("foo")); + assertEquals(Integer.valueOf(2), d.getInt("bar")); + assertEquals(Integer.valueOf(3), d.getInt("baz")); + assertEquals(Integer.valueOf(4), d.getInt("bam")); + } + + @Test(expected = FormatException.class) + public void testIntUnderflow() throws Exception { + BdfDictionary d = + BdfDictionary.of(new BdfEntry("foo", Integer.MIN_VALUE - 1L)); + d.getInt("foo"); + } + + @Test(expected = FormatException.class) + public void testIntOverflow() throws Exception { + BdfDictionary d = + BdfDictionary.of(new BdfEntry("foo", Integer.MAX_VALUE + 1L)); + d.getInt("foo"); + } + @Test public void testFloatPromotion() throws Exception { BdfDictionary d = new BdfDictionary(); @@ -67,7 +98,7 @@ public class BdfDictionaryTest extends BrambleTestCase { } @Test - public void testKeySetIteratorIsOrderedByKeys() throws Exception { + public void testKeySetIteratorIsOrderedByKeys() { BdfDictionary d = new BdfDictionary(); d.put("a", 1); d.put("d", 4); @@ -86,7 +117,7 @@ public class BdfDictionaryTest extends BrambleTestCase { } @Test - public void testValuesIteratorIsOrderedByKeys() throws Exception { + public void testValuesIteratorIsOrderedByKeys() { BdfDictionary d = new BdfDictionary(); d.put("a", 1); d.put("d", 4); @@ -105,7 +136,7 @@ public class BdfDictionaryTest extends BrambleTestCase { } @Test - public void testEntrySetIteratorIsOrderedByKeys() throws Exception { + public void testEntrySetIteratorIsOrderedByKeys() { BdfDictionary d = new BdfDictionary(); d.put("a", 1); d.put("d", 4); @@ -130,4 +161,284 @@ public class BdfDictionaryTest extends BrambleTestCase { assertEquals("d", e.getKey()); assertEquals(4, e.getValue()); } + + @Test(expected = FormatException.class) + public void testMissingValueForBooleanThrowsFormatException() + throws Exception { + new BdfDictionary().getBoolean("foo"); + } + + @Test(expected = FormatException.class) + public void testMissingValueForLongThrowsFormatException() + throws Exception { + new BdfDictionary().getLong("foo"); + } + + @Test(expected = FormatException.class) + public void testMissingValueForIntThrowsFormatException() throws Exception { + new BdfDictionary().getInt("foo"); + } + + @Test(expected = FormatException.class) + public void testMissingValueForDoubleThrowsFormatException() + throws Exception { + new BdfDictionary().getDouble("foo"); + } + + @Test(expected = FormatException.class) + public void testMissingValueForStringThrowsFormatException() + throws Exception { + new BdfDictionary().getString("foo"); + } + + @Test(expected = FormatException.class) + public void testMissingValueForRawThrowsFormatException() throws Exception { + new BdfDictionary().getRaw("foo"); + } + + @Test(expected = FormatException.class) + public void testMissingValueForListThrowsFormatException() + throws Exception { + new BdfDictionary().getList("foo"); + } + + @Test(expected = FormatException.class) + public void testMissingValueForDictionaryThrowsFormatException() + throws Exception { + new BdfDictionary().getDictionary("foo"); + } + + @Test(expected = FormatException.class) + public void testNullValueForBooleanThrowsFormatException() + throws Exception { + BdfDictionary.of(new BdfEntry("foo", NULL_VALUE)).getBoolean("foo"); + } + + @Test(expected = FormatException.class) + public void testNullValueForLongThrowsFormatException() throws Exception { + BdfDictionary.of(new BdfEntry("foo", NULL_VALUE)).getLong("foo"); + } + + @Test(expected = FormatException.class) + public void testNullValueForIntThrowsFormatException() throws Exception { + BdfDictionary.of(new BdfEntry("foo", NULL_VALUE)).getInt("foo"); + } + + @Test(expected = FormatException.class) + public void testNullValueForDoubleThrowsFormatException() throws Exception { + BdfDictionary.of(new BdfEntry("foo", NULL_VALUE)).getDouble("foo"); + } + + @Test(expected = FormatException.class) + public void testNullValueForStringThrowsFormatException() throws Exception { + BdfDictionary.of(new BdfEntry("foo", NULL_VALUE)).getString("foo"); + } + + @Test(expected = FormatException.class) + public void testNullValueForRawThrowsFormatException() throws Exception { + BdfDictionary.of(new BdfEntry("foo", NULL_VALUE)).getRaw("foo"); + } + + @Test(expected = FormatException.class) + public void testNullValueForListThrowsFormatException() throws Exception { + BdfDictionary.of(new BdfEntry("foo", NULL_VALUE)).getList("foo"); + } + + @Test(expected = FormatException.class) + public void testNullValueForDictionaryThrowsFormatException() + throws Exception { + BdfDictionary.of(new BdfEntry("foo", NULL_VALUE)).getDictionary("foo"); + } + + @Test + public void testOptionalMethodsReturnNullForMissingValue() + throws Exception { + testOptionalMethodsReturnNull(new BdfDictionary()); + } + + @Test + public void testOptionalMethodsReturnNullForNullValue() throws Exception { + BdfDictionary d = BdfDictionary.of(new BdfEntry("foo", NULL_VALUE)); + testOptionalMethodsReturnNull(d); + } + + private void testOptionalMethodsReturnNull(BdfDictionary d) + throws Exception { + assertNull(d.getOptionalBoolean("foo")); + assertNull(d.getOptionalLong("foo")); + assertNull(d.getOptionalInt("foo")); + assertNull(d.getOptionalDouble("foo")); + assertNull(d.getOptionalString("foo")); + assertNull(d.getOptionalRaw("foo")); + assertNull(d.getOptionalList("foo")); + assertNull(d.getOptionalDictionary("foo")); + } + + @Test + public void testDefaultMethodsReturnDefaultForMissingValue() + throws Exception { + testDefaultMethodsReturnDefault(new BdfDictionary()); + } + + @Test + public void testDefaultMethodsReturnDefaultForNullValue() throws Exception { + BdfDictionary d = BdfDictionary.of(new BdfEntry("foo", NULL_VALUE)); + testDefaultMethodsReturnDefault(d); + } + + private void testDefaultMethodsReturnDefault(BdfDictionary d) + throws Exception { + assertEquals(TRUE, d.getBoolean("foo", TRUE)); + assertEquals(Long.valueOf(123L), d.getLong("foo", 123L)); + assertEquals(Integer.valueOf(123), d.getInt("foo", 123)); + assertEquals(Double.valueOf(123D), d.getDouble("foo", 123D)); + assertEquals("123", d.getString("foo", "123")); + byte[] defaultRaw = {1, 2, 3}; + assertArrayEquals(defaultRaw, d.getRaw("foo", defaultRaw)); + BdfList defaultList = BdfList.of(1, 2, 3); + assertEquals(defaultList, d.getList("foo", defaultList)); + BdfDictionary defaultDict = BdfDictionary.of(new BdfEntry("123", 123)); + assertEquals(defaultDict, d.getDictionary("foo", defaultDict)); + } + + @Test(expected = FormatException.class) + public void testWrongTypeForBooleanThrowsFormatException() + throws Exception { + BdfDictionary.of(new BdfEntry("foo", 123)).getBoolean("foo"); + } + + @Test(expected = FormatException.class) + public void testWrongTypeForOptionalBooleanThrowsFormatException() + throws Exception { + BdfDictionary.of(new BdfEntry("foo", 123)).getOptionalBoolean("foo"); + } + + @Test(expected = FormatException.class) + public void testWrongTypeForDefaultBooleanThrowsFormatException() + throws Exception { + BdfDictionary.of(new BdfEntry("foo", 123)).getBoolean("foo", true); + } + + @Test(expected = FormatException.class) + public void testWrongTypeForLongThrowsFormatException() throws Exception { + BdfDictionary.of(new BdfEntry("foo", 1.23)).getLong("foo"); + } + + @Test(expected = FormatException.class) + public void testWrongTypeForOptionalLongThrowsFormatException() + throws Exception { + BdfDictionary.of(new BdfEntry("foo", 1.23)).getOptionalLong("foo"); + } + + @Test(expected = FormatException.class) + public void testWrongTypeForDefaultLongThrowsFormatException() + throws Exception { + BdfDictionary.of(new BdfEntry("foo", 1.23)).getLong("foo", 1L); + } + + @Test(expected = FormatException.class) + public void testWrongTypeForIntThrowsFormatException() throws Exception { + BdfDictionary.of(new BdfEntry("foo", 1.23)).getInt("foo"); + } + + @Test(expected = FormatException.class) + public void testWrongTypeForOptionalIntThrowsFormatException() + throws Exception { + BdfDictionary.of(new BdfEntry("foo", 1.23)).getOptionalInt("foo"); + } + + @Test(expected = FormatException.class) + public void testWrongTypeForDefaultIntThrowsFormatException() + throws Exception { + BdfDictionary.of(new BdfEntry("foo", 1.23)).getInt("foo", 1); + } + + @Test(expected = FormatException.class) + public void testWrongTypeForDoubleThrowsFormatException() throws Exception { + BdfDictionary.of(new BdfEntry("foo", 123)).getDouble("foo"); + } + + @Test(expected = FormatException.class) + public void testWrongTypeForOptionalDoubleThrowsFormatException() + throws Exception { + BdfDictionary.of(new BdfEntry("foo", 123)).getOptionalDouble("foo"); + } + + @Test(expected = FormatException.class) + public void testWrongTypeForDefaultDoubleThrowsFormatException() + throws Exception { + BdfDictionary.of(new BdfEntry("foo", 123)).getDouble("foo", 1D); + } + + @Test(expected = FormatException.class) + public void testWrongTypeForStringThrowsFormatException() throws Exception { + BdfDictionary.of(new BdfEntry("foo", 123)).getString("foo"); + } + + @Test(expected = FormatException.class) + public void testWrongTypeForOptionalStringThrowsFormatException() + throws Exception { + BdfDictionary.of(new BdfEntry("foo", 123)).getOptionalString("foo"); + } + + @Test(expected = FormatException.class) + public void testWrongTypeForDefaultStringThrowsFormatException() + throws Exception { + BdfDictionary.of(new BdfEntry("foo", 123)).getString("foo", ""); + } + + @Test(expected = FormatException.class) + public void testWrongTypeForRawThrowsFormatException() throws Exception { + BdfDictionary.of(new BdfEntry("foo", 123)).getRaw("foo"); + } + + @Test(expected = FormatException.class) + public void testWrongTypeForOptionalRawThrowsFormatException() + throws Exception { + BdfDictionary.of(new BdfEntry("foo", 123)).getOptionalRaw("foo"); + } + + @Test(expected = FormatException.class) + public void testWrongTypeForDefaultRawThrowsFormatException() + throws Exception { + BdfDictionary.of(new BdfEntry("foo", 123)).getRaw("foo", new byte[0]); + } + + @Test(expected = FormatException.class) + public void testWrongTypeForListThrowsFormatException() + throws Exception { + BdfDictionary.of(new BdfEntry("foo", 123)).getList("foo"); + } + + @Test(expected = FormatException.class) + public void testWrongTypeForOptionalListThrowsFormatException() + throws Exception { + BdfDictionary.of(new BdfEntry("foo", 123)).getOptionalList("foo"); + } + + @Test(expected = FormatException.class) + public void testWrongTypeForDefaultListThrowsFormatException() + throws Exception { + BdfDictionary.of(new BdfEntry("foo", 123)).getList("foo", + new BdfList()); + } + + @Test(expected = FormatException.class) + public void testWrongTypeForDictionaryThrowsFormatException() + throws Exception { + BdfDictionary.of(new BdfEntry("foo", 123)).getDictionary("foo"); + } + + @Test(expected = FormatException.class) + public void testWrongTypeForOptionalDictionaryThrowsFormatException() + throws Exception { + BdfDictionary.of(new BdfEntry("foo", 123)).getOptionalDictionary("foo"); + } + + @Test(expected = FormatException.class) + public void testWrongTypeForDefaultDictionaryThrowsFormatException() + throws Exception { + BdfDictionary.of(new BdfEntry("foo", 123)).getDictionary("foo", + new BdfDictionary()); + } } diff --git a/bramble-api/src/test/java/org/briarproject/bramble/api/data/BdfListTest.java b/bramble-api/src/test/java/org/briarproject/bramble/api/data/BdfListTest.java index 55fbf39db..7ee0ba799 100644 --- a/bramble-api/src/test/java/org/briarproject/bramble/api/data/BdfListTest.java +++ b/bramble-api/src/test/java/org/briarproject/bramble/api/data/BdfListTest.java @@ -5,31 +5,31 @@ import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.test.BrambleTestCase; import org.junit.Test; -import java.util.Arrays; -import java.util.Collections; - +import static java.lang.Boolean.TRUE; +import static java.util.Arrays.asList; +import static java.util.Collections.emptyList; import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; public class BdfListTest extends BrambleTestCase { @Test public void testConstructors() { - assertEquals(Collections.emptyList(), new BdfList()); - assertEquals(Arrays.asList(1, 2, NULL_VALUE), - new BdfList(Arrays.asList(1, 2, NULL_VALUE))); + assertEquals(emptyList(), new BdfList()); + assertEquals(asList(1, 2, NULL_VALUE), + new BdfList(asList(1, 2, NULL_VALUE))); } @Test public void testFactoryMethod() { - assertEquals(Collections.emptyList(), BdfList.of()); - assertEquals(Arrays.asList(1, 2, NULL_VALUE), - BdfList.of(1, 2, NULL_VALUE)); + assertEquals(emptyList(), BdfList.of()); + assertEquals(asList(1, 2, NULL_VALUE), BdfList.of(1, 2, NULL_VALUE)); } @Test - public void testIntegerPromotion() throws Exception { + public void testLongPromotion() throws Exception { BdfList list = new BdfList(); list.add((byte) 1); list.add((short) 2); @@ -41,6 +41,31 @@ public class BdfListTest extends BrambleTestCase { assertEquals(Long.valueOf(4), list.getLong(3)); } + @Test + public void testIntPromotionAndDemotion() throws Exception { + BdfList list = new BdfList(); + list.add((byte) 1); + list.add((short) 2); + list.add(3); + list.add(4L); + assertEquals(Integer.valueOf(1), list.getInt(0)); + assertEquals(Integer.valueOf(2), list.getInt(1)); + assertEquals(Integer.valueOf(3), list.getInt(2)); + assertEquals(Integer.valueOf(4), list.getInt(3)); + } + + @Test(expected = FormatException.class) + public void testIntUnderflow() throws Exception { + BdfList list = BdfList.of(Integer.MIN_VALUE - 1L); + list.getInt(0); + } + + @Test(expected = FormatException.class) + public void testIntOverflow() throws Exception { + BdfList list = BdfList.of(Integer.MAX_VALUE + 1L); + list.getInt(0); + } + @Test public void testFloatPromotion() throws Exception { BdfList list = new BdfList(); @@ -63,61 +88,6 @@ public class BdfListTest extends BrambleTestCase { assertArrayEquals(new byte[123], second); } - @Test - @SuppressWarnings("ConstantConditions") - public void testIndexOutOfBoundsReturnsDefaultValue() throws Exception { - BdfList list = BdfList.of(1, 2, 3); - boolean defaultBoolean = true; - assertEquals(defaultBoolean, list.getBoolean(-1, defaultBoolean)); - assertEquals(defaultBoolean, list.getBoolean(3, defaultBoolean)); - Long defaultLong = 123L; - assertEquals(defaultLong, list.getLong(-1, defaultLong)); - assertEquals(defaultLong, list.getLong(3, defaultLong)); - Double defaultDouble = 1.23; - assertEquals(defaultDouble, list.getDouble(-1, defaultDouble)); - assertEquals(defaultDouble, list.getDouble(3, defaultDouble)); - String defaultString = "123"; - assertEquals(defaultString, list.getString(-1, defaultString)); - assertEquals(defaultString, list.getString(3, defaultString)); - byte[] defaultBytes = new byte[] {1, 2, 3}; - assertArrayEquals(defaultBytes, list.getRaw(-1, defaultBytes)); - assertArrayEquals(defaultBytes, list.getRaw(3, defaultBytes)); - BdfList defaultList = BdfList.of(1, 2, 3); - assertEquals(defaultList, list.getList(-1, defaultList)); - assertEquals(defaultList, list.getList(3, defaultList)); - BdfDictionary defaultDict = BdfDictionary.of( - new BdfEntry("1", 1), - new BdfEntry("2", 2), - new BdfEntry("3", 3) - ); - assertEquals(defaultDict, list.getDictionary(-1, defaultDict)); - assertEquals(defaultDict, list.getDictionary(3, defaultDict)); - } - - @Test - @SuppressWarnings("ConstantConditions") - public void testWrongTypeReturnsDefaultValue() throws Exception { - BdfList list = BdfList.of(1, 2, 3, true); - boolean defaultBoolean = true; - assertEquals(defaultBoolean, list.getBoolean(0, defaultBoolean)); - Long defaultLong = 123L; - assertEquals(defaultLong, list.getLong(3, defaultLong)); - Double defaultDouble = 1.23; - assertEquals(defaultDouble, list.getDouble(0, defaultDouble)); - String defaultString = "123"; - assertEquals(defaultString, list.getString(0, defaultString)); - byte[] defaultBytes = new byte[] {1, 2, 3}; - assertArrayEquals(defaultBytes, list.getRaw(0, defaultBytes)); - BdfList defaultList = BdfList.of(1, 2, 3); - assertEquals(defaultList, list.getList(0, defaultList)); - BdfDictionary defaultDict = BdfDictionary.of( - new BdfEntry("1", 1), - new BdfEntry("2", 2), - new BdfEntry("3", 3) - ); - assertEquals(defaultDict, list.getDictionary(0, defaultDict)); - } - @Test(expected = FormatException.class) public void testNegativeIndexForBooleanThrowsFormatException() throws Exception { @@ -130,6 +100,12 @@ public class BdfListTest extends BrambleTestCase { new BdfList().getOptionalBoolean(-1); } + @Test(expected = FormatException.class) + public void testNegativeIndexForDefaultBooleanThrowsFormatException() + throws Exception { + new BdfList().getBoolean(-1, true); + } + @Test(expected = FormatException.class) public void testNegativeIndexForLongThrowsFormatException() throws Exception { @@ -142,6 +118,30 @@ public class BdfListTest extends BrambleTestCase { new BdfList().getOptionalLong(-1); } + @Test(expected = FormatException.class) + public void testNegativeIndexForDefaultLongThrowsFormatException() + throws Exception { + new BdfList().getLong(-1, 1L); + } + + @Test(expected = FormatException.class) + public void testNegativeIndexForIntThrowsFormatException() + throws Exception { + new BdfList().getInt(-1); + } + + @Test(expected = FormatException.class) + public void testNegativeIndexForOptionalIntThrowsFormatException() + throws Exception { + new BdfList().getOptionalInt(-1); + } + + @Test(expected = FormatException.class) + public void testNegativeIndexForDefaultIntThrowsFormatException() + throws Exception { + new BdfList().getInt(-1, 1); + } + @Test(expected = FormatException.class) public void testNegativeIndexForDoubleThrowsFormatException() throws Exception { @@ -154,6 +154,12 @@ public class BdfListTest extends BrambleTestCase { new BdfList().getOptionalDouble(-1); } + @Test(expected = FormatException.class) + public void testNegativeIndexForDefaultDoubleThrowsFormatException() + throws Exception { + new BdfList().getDouble(-1, 1D); + } + @Test(expected = FormatException.class) public void testNegativeIndexForStringThrowsFormatException() throws Exception { @@ -166,6 +172,12 @@ public class BdfListTest extends BrambleTestCase { new BdfList().getOptionalString(-1); } + @Test(expected = FormatException.class) + public void testNegativeIndexForDefaultStringThrowsFormatException() + throws Exception { + new BdfList().getString(-1, ""); + } + @Test(expected = FormatException.class) public void testNegativeIndexForRawThrowsFormatException() throws Exception { @@ -178,6 +190,12 @@ public class BdfListTest extends BrambleTestCase { new BdfList().getOptionalRaw(-1); } + @Test(expected = FormatException.class) + public void testNegativeIndexForDefaultRawThrowsFormatException() + throws Exception { + new BdfList().getRaw(-1, new byte[0]); + } + @Test(expected = FormatException.class) public void testNegativeIndexForListThrowsFormatException() throws Exception { @@ -190,6 +208,11 @@ public class BdfListTest extends BrambleTestCase { new BdfList().getOptionalList(-1); } + @Test(expected = FormatException.class) + public void testNegativeIndexForDefaultListThrowsFormatException() + throws Exception { + new BdfList().getList(-1, new BdfList()); + } @Test(expected = FormatException.class) public void testNegativeIndexForDictionaryThrowsFormatException() @@ -203,6 +226,12 @@ public class BdfListTest extends BrambleTestCase { new BdfList().getOptionalDictionary(-1); } + @Test(expected = FormatException.class) + public void testNegativeIndexForDefaultDictionaryThrowsFormatException() + throws Exception { + new BdfList().getDictionary(-1, new BdfDictionary()); + } + @Test(expected = FormatException.class) public void testTooLargeIndexForBooleanThrowsFormatException() throws Exception { @@ -215,6 +244,12 @@ public class BdfListTest extends BrambleTestCase { new BdfList().getOptionalBoolean(0); } + @Test(expected = FormatException.class) + public void testTooLargeIndexForDefaultBooleanThrowsFormatException() + throws Exception { + new BdfList().getBoolean(0, true); + } + @Test(expected = FormatException.class) public void testTooLargeIndexForLongThrowsFormatException() throws Exception { @@ -227,6 +262,30 @@ public class BdfListTest extends BrambleTestCase { new BdfList().getOptionalLong(0); } + @Test(expected = FormatException.class) + public void testTooLargeIndexForDefaultLongThrowsFormatException() + throws Exception { + new BdfList().getLong(0, 1L); + } + + @Test(expected = FormatException.class) + public void testTooLargeIndexForIntThrowsFormatException() + throws Exception { + new BdfList().getInt(0); + } + + @Test(expected = FormatException.class) + public void testTooLargeIndexForOptionalIntThrowsFormatException() + throws Exception { + new BdfList().getOptionalInt(0); + } + + @Test(expected = FormatException.class) + public void testTooLargeIndexForDefaultIntThrowsFormatException() + throws Exception { + new BdfList().getInt(0, 1); + } + @Test(expected = FormatException.class) public void testTooLargeIndexForDoubleThrowsFormatException() throws Exception { @@ -239,6 +298,12 @@ public class BdfListTest extends BrambleTestCase { new BdfList().getOptionalDouble(0); } + @Test(expected = FormatException.class) + public void testTooLargeIndexForDefaultDoubleThrowsFormatException() + throws Exception { + new BdfList().getDouble(0, 1D); + } + @Test(expected = FormatException.class) public void testTooLargeIndexForStringThrowsFormatException() throws Exception { @@ -251,6 +316,12 @@ public class BdfListTest extends BrambleTestCase { new BdfList().getOptionalString(0); } + @Test(expected = FormatException.class) + public void testTooLargeIndexForDefaultStringThrowsFormatException() + throws Exception { + new BdfList().getString(0, ""); + } + @Test(expected = FormatException.class) public void testTooLargeIndexForRawThrowsFormatException() throws Exception { @@ -263,6 +334,12 @@ public class BdfListTest extends BrambleTestCase { new BdfList().getOptionalRaw(0); } + @Test(expected = FormatException.class) + public void testTooLargeIndexForDefaultRawThrowsFormatException() + throws Exception { + new BdfList().getRaw(0, new byte[0]); + } + @Test(expected = FormatException.class) public void testTooLargeIndexForListThrowsFormatException() throws Exception { @@ -275,6 +352,11 @@ public class BdfListTest extends BrambleTestCase { new BdfList().getOptionalList(0); } + @Test(expected = FormatException.class) + public void testTooLargeIndexForDefaultListThrowsFormatException() + throws Exception { + new BdfList().getList(0, new BdfList()); + } @Test(expected = FormatException.class) public void testTooLargeIndexForDictionaryThrowsFormatException() @@ -287,6 +369,13 @@ public class BdfListTest extends BrambleTestCase { throws Exception { new BdfList().getOptionalDictionary(0); } + + @Test(expected = FormatException.class) + public void testTooLargeIndexForDefaultDictionaryThrowsFormatException() + throws Exception { + new BdfList().getDictionary(0, new BdfDictionary()); + } + @Test(expected = FormatException.class) public void testWrongTypeForBooleanThrowsFormatException() throws Exception { @@ -299,6 +388,12 @@ public class BdfListTest extends BrambleTestCase { BdfList.of(123).getOptionalBoolean(0); } + @Test(expected = FormatException.class) + public void testWrongTypeForDefaultBooleanThrowsFormatException() + throws Exception { + BdfList.of(123).getBoolean(0, true); + } + @Test(expected = FormatException.class) public void testWrongTypeForLongThrowsFormatException() throws Exception { BdfList.of(1.23).getLong(0); @@ -310,6 +405,29 @@ public class BdfListTest extends BrambleTestCase { BdfList.of(1.23).getOptionalLong(0); } + @Test(expected = FormatException.class) + public void testWrongTypeForDefaultLongThrowsFormatException() + throws Exception { + BdfList.of(1.23).getLong(0, 1L); + } + + @Test(expected = FormatException.class) + public void testWrongTypeForIntThrowsFormatException() throws Exception { + BdfList.of(1.23).getInt(0); + } + + @Test(expected = FormatException.class) + public void testWrongTypeForOptionalIntThrowsFormatException() + throws Exception { + BdfList.of(1.23).getOptionalInt(0); + } + + @Test(expected = FormatException.class) + public void testWrongTypeForDefaultIntThrowsFormatException() + throws Exception { + BdfList.of(1.23).getInt(0, 1); + } + @Test(expected = FormatException.class) public void testWrongTypeForDoubleThrowsFormatException() throws Exception { BdfList.of(123).getDouble(0); @@ -321,6 +439,12 @@ public class BdfListTest extends BrambleTestCase { BdfList.of(123).getOptionalDouble(0); } + @Test(expected = FormatException.class) + public void testWrongTypeForDefaultDoubleThrowsFormatException() + throws Exception { + BdfList.of(123).getDouble(0, 1D); + } + @Test(expected = FormatException.class) public void testWrongTypeForStringThrowsFormatException() throws Exception { BdfList.of(123).getString(0); @@ -332,6 +456,12 @@ public class BdfListTest extends BrambleTestCase { BdfList.of(123).getOptionalString(0); } + @Test(expected = FormatException.class) + public void testWrongTypeForDefaultStringThrowsFormatException() + throws Exception { + BdfList.of(123).getString(0, ""); + } + @Test(expected = FormatException.class) public void testWrongTypeForRawThrowsFormatException() throws Exception { BdfList.of(123).getRaw(0); @@ -343,6 +473,12 @@ public class BdfListTest extends BrambleTestCase { BdfList.of(123).getOptionalRaw(0); } + @Test(expected = FormatException.class) + public void testWrongTypeForDefaultRawThrowsFormatException() + throws Exception { + BdfList.of(123).getRaw(0, new byte[0]); + } + @Test(expected = FormatException.class) public void testWrongTypeForListThrowsFormatException() throws Exception { BdfList.of(123).getList(0); @@ -354,6 +490,11 @@ public class BdfListTest extends BrambleTestCase { BdfList.of(123).getOptionalList(0); } + @Test(expected = FormatException.class) + public void testWrongTypeForDefaultListThrowsFormatException() + throws Exception { + BdfList.of(123).getList(0, new BdfList()); + } @Test(expected = FormatException.class) public void testWrongTypeForDictionaryThrowsFormatException() @@ -366,4 +507,81 @@ public class BdfListTest extends BrambleTestCase { throws Exception { BdfList.of(123).getOptionalDictionary(0); } + + @Test(expected = FormatException.class) + public void testWrongTypeForDefaultDictionaryThrowsFormatException() + throws Exception { + BdfList.of(123).getDictionary(0, new BdfDictionary()); + } + + @Test(expected = FormatException.class) + public void testNullValueForBooleanThrowsFormatException() + throws Exception { + BdfList.of(NULL_VALUE).getBoolean(0); + } + + @Test(expected = FormatException.class) + public void testNullValueForLongThrowsFormatException() throws Exception { + BdfList.of(NULL_VALUE).getLong(0); + } + + @Test(expected = FormatException.class) + public void testNullValueForIntThrowsFormatException() throws Exception { + BdfList.of(NULL_VALUE).getInt(0); + } + + @Test(expected = FormatException.class) + public void testNullValueForDoubleThrowsFormatException() throws Exception { + BdfList.of(NULL_VALUE).getDouble(0); + } + + @Test(expected = FormatException.class) + public void testNullValueForStringThrowsFormatException() throws Exception { + BdfList.of(NULL_VALUE).getString(0); + } + + @Test(expected = FormatException.class) + public void testNullValueForRawThrowsFormatException() throws Exception { + BdfList.of(NULL_VALUE).getRaw(0); + } + + @Test(expected = FormatException.class) + public void testNullValueForListThrowsFormatException() throws Exception { + BdfList.of(NULL_VALUE).getList(0); + } + + @Test(expected = FormatException.class) + public void testNullValueForDictionaryThrowsFormatException() + throws Exception { + BdfList.of(NULL_VALUE).getDictionary(0); + } + + @Test + public void testOptionalMethodsReturnNullForNullValue() throws Exception { + BdfList list = BdfList.of(NULL_VALUE); + assertNull(list.getOptionalBoolean(0)); + assertNull(list.getOptionalLong(0)); + assertNull(list.getOptionalInt(0)); + assertNull(list.getOptionalDouble(0)); + assertNull(list.getOptionalString(0)); + assertNull(list.getOptionalRaw(0)); + assertNull(list.getOptionalList(0)); + assertNull(list.getOptionalDictionary(0)); + } + + @Test + public void testDefaultMethodsReturnDefaultForNullValue() throws Exception { + BdfList list = BdfList.of(NULL_VALUE); + assertEquals(TRUE, list.getBoolean(0, TRUE)); + assertEquals(Long.valueOf(123L), list.getLong(0, 123L)); + assertEquals(Integer.valueOf(123), list.getInt(0, 123)); + assertEquals(Double.valueOf(123D), list.getDouble(0, 123D)); + assertEquals("123", list.getString(0, "123")); + byte[] defaultRaw = {1, 2, 3}; + assertArrayEquals(defaultRaw, list.getRaw(0, defaultRaw)); + BdfList defaultList = BdfList.of(1, 2, 3); + assertEquals(defaultList, list.getList(0, defaultList)); + BdfDictionary defaultDict = BdfDictionary.of(new BdfEntry("123", 123)); + assertEquals(defaultDict, list.getDictionary(0, defaultDict)); + } } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/client/ClientHelperImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/client/ClientHelperImpl.java index 1e1939cd8..34635142d 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/client/ClientHelperImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/client/ClientHelperImpl.java @@ -155,7 +155,13 @@ class ClientHelperImpl implements ClientHelper { @Override public BdfList getMessageAsList(Transaction txn, MessageId m) throws DbException, FormatException { - return toList(db.getMessage(txn, m).getBody()); + return getMessageAsList(txn, m, true); + } + + @Override + public BdfList getMessageAsList(Transaction txn, MessageId m, + boolean canonical) throws DbException, FormatException { + return toList(db.getMessage(txn, m), canonical); } @Override @@ -313,8 +319,13 @@ class ClientHelperImpl implements ClientHelper { @Override public BdfList toList(byte[] b, int off, int len) throws FormatException { + return toList(b, off, len, true); + } + + private BdfList toList(byte[] b, int off, int len, boolean canonical) + throws FormatException { ByteArrayInputStream in = new ByteArrayInputStream(b, off, len); - BdfReader reader = bdfReaderFactory.createReader(in); + BdfReader reader = bdfReaderFactory.createReader(in, canonical); try { BdfList list = reader.readList(); if (!reader.eof()) throw new FormatException(); @@ -328,7 +339,7 @@ class ClientHelperImpl implements ClientHelper { @Override public BdfList toList(byte[] b) throws FormatException { - return toList(b, 0, b.length); + return toList(b, 0, b.length, true); } @Override @@ -336,6 +347,12 @@ class ClientHelperImpl implements ClientHelper { return toList(m.getBody()); } + @Override + public BdfList toList(Message m, boolean canonical) throws FormatException { + byte[] b = m.getBody(); + return toList(b, 0, b.length, canonical); + } + @Override public BdfList toList(Author a) { return BdfList.of(a.getFormatVersion(), a.getName(), a.getPublicKey()); @@ -361,7 +378,7 @@ class ClientHelperImpl implements ClientHelper { public Author parseAndValidateAuthor(BdfList author) throws FormatException { checkSize(author, 3); - int formatVersion = author.getLong(0).intValue(); + int formatVersion = author.getInt(0); if (formatVersion != FORMAT_VERSION) throw new FormatException(); String name = author.getString(1); checkLength(name, 1, MAX_AUTHOR_NAME_LENGTH); @@ -472,8 +489,7 @@ class ClientHelperImpl implements ClientHelper { if (element.size() != 2) { throw new FormatException(); } - list.add(new MailboxVersion(element.getLong(0).intValue(), - element.getLong(1).intValue())); + list.add(new MailboxVersion(element.getInt(0), element.getInt(1))); } // Sort the list of versions for easier comparison sort(list); @@ -486,7 +502,7 @@ class ClientHelperImpl implements ClientHelper { try { BdfDictionary meta = getGroupMetadataAsDictionary(txn, contactGroupId); - return new ContactId(meta.getLong(GROUP_KEY_CONTACT_ID).intValue()); + return new ContactId(meta.getInt(GROUP_KEY_CONTACT_ID)); } catch (FormatException e) { throw new DbException(e); // Invalid group metadata } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/data/BdfReaderFactoryImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/data/BdfReaderFactoryImpl.java index 48d61ca63..a106b1d1c 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/data/BdfReaderFactoryImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/data/BdfReaderFactoryImpl.java @@ -18,12 +18,18 @@ class BdfReaderFactoryImpl implements BdfReaderFactory { @Override public BdfReader createReader(InputStream in) { return new BdfReaderImpl(in, DEFAULT_NESTED_LIMIT, - DEFAULT_MAX_BUFFER_SIZE); + DEFAULT_MAX_BUFFER_SIZE, true); + } + + @Override + public BdfReader createReader(InputStream in, boolean canonical) { + return new BdfReaderImpl(in, DEFAULT_NESTED_LIMIT, + DEFAULT_MAX_BUFFER_SIZE, canonical); } @Override public BdfReader createReader(InputStream in, int nestedLimit, - int maxBufferSize) { - return new BdfReaderImpl(in, nestedLimit, maxBufferSize); + int maxBufferSize, boolean canonical) { + return new BdfReaderImpl(in, nestedLimit, maxBufferSize, canonical); } } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/data/BdfReaderImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/data/BdfReaderImpl.java index d5badb88e..352c440d1 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/data/BdfReaderImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/data/BdfReaderImpl.java @@ -33,21 +33,24 @@ import static org.briarproject.bramble.util.StringUtils.fromUtf8; @NotThreadSafe @NotNullByDefault -class BdfReaderImpl implements BdfReader { +final class BdfReaderImpl implements BdfReader { private static final byte[] EMPTY_BUFFER = new byte[0]; private final InputStream in; private final int nestedLimit, maxBufferSize; + private final boolean canonical; private boolean hasLookahead = false, eof = false; private byte next; private byte[] buf = new byte[8]; - BdfReaderImpl(InputStream in, int nestedLimit, int maxBufferSize) { + BdfReaderImpl(InputStream in, int nestedLimit, int maxBufferSize, + boolean canonical) { this.in = in; this.nestedLimit = nestedLimit; this.maxBufferSize = maxBufferSize; + this.canonical = canonical; } private void readLookahead() throws IOException { @@ -188,13 +191,22 @@ class BdfReaderImpl implements BdfReader { private short readInt16() throws IOException { readIntoBuffer(2); - return (short) (((buf[0] & 0xFF) << 8) + (buf[1] & 0xFF)); + short value = (short) (((buf[0] & 0xFF) << 8) + (buf[1] & 0xFF)); + if (canonical && value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) { + // Value could have been encoded as an INT_8 + throw new FormatException(); + } + return value; } private int readInt32() throws IOException { readIntoBuffer(4); int value = 0; for (int i = 0; i < 4; i++) value |= (buf[i] & 0xFF) << (24 - i * 8); + if (canonical && value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) { + // Value could have been encoded as an INT_16 + throw new FormatException(); + } return value; } @@ -202,6 +214,11 @@ class BdfReaderImpl implements BdfReader { readIntoBuffer(8); long value = 0; for (int i = 0; i < 8; i++) value |= (buf[i] & 0xFFL) << (56 - i * 8); + if (canonical && value >= Integer.MIN_VALUE && + value <= Integer.MAX_VALUE) { + // Value could have been encoded as an INT_32 + throw new FormatException(); + } return value; } @@ -215,6 +232,31 @@ class BdfReaderImpl implements BdfReader { hasLookahead = false; } + @Override + public boolean hasInt() throws IOException { + if (!hasLookahead) readLookahead(); + if (eof) return false; + return next == INT_8 || next == INT_16 || next == INT_32; + } + + @Override + public int readInt() throws IOException { + if (!hasInt()) throw new FormatException(); + hasLookahead = false; + if (next == INT_8) return readInt8(); + if (next == INT_16) return readInt16(); + return readInt32(); + } + + @Override + public void skipInt() throws IOException { + if (!hasInt()) throw new FormatException(); + if (next == INT_8) skip(1); + else if (next == INT_16) skip(2); + else skip(4); + hasLookahead = false; + } + @Override public boolean hasDouble() throws IOException { if (!hasLookahead) readLookahead(); @@ -323,22 +365,11 @@ class BdfReaderImpl implements BdfReader { private BdfList readList(int level) throws IOException { if (!hasList()) throw new FormatException(); if (level > nestedLimit) throw new FormatException(); - BdfList list = new BdfList(); - readListStart(); - while (!hasListEnd()) list.add(readObject(level + 1)); - readListEnd(); - return list; - } - - @Override - public void readListStart() throws IOException { - if (!hasList()) throw new FormatException(); hasLookahead = false; - } - - @Override - public boolean hasListEnd() throws IOException { - return hasEnd(); + BdfList list = new BdfList(); + while (!hasEnd()) list.add(readObject(level + 1)); + readEnd(); + return list; } private boolean hasEnd() throws IOException { @@ -347,11 +378,6 @@ class BdfReaderImpl implements BdfReader { return next == END; } - @Override - public void readListEnd() throws IOException { - readEnd(); - } - private void readEnd() throws IOException { if (!hasEnd()) throw new FormatException(); hasLookahead = false; @@ -361,7 +387,7 @@ class BdfReaderImpl implements BdfReader { public void skipList() throws IOException { if (!hasList()) throw new FormatException(); hasLookahead = false; - while (!hasListEnd()) skipObject(); + while (!hasEnd()) skipObject(); hasLookahead = false; } @@ -380,35 +406,27 @@ class BdfReaderImpl implements BdfReader { private BdfDictionary readDictionary(int level) throws IOException { if (!hasDictionary()) throw new FormatException(); if (level > nestedLimit) throw new FormatException(); - BdfDictionary dictionary = new BdfDictionary(); - readDictionaryStart(); - while (!hasDictionaryEnd()) - dictionary.put(readString(), readObject(level + 1)); - readDictionaryEnd(); - return dictionary; - } - - @Override - public void readDictionaryStart() throws IOException { - if (!hasDictionary()) throw new FormatException(); hasLookahead = false; - } - - @Override - public boolean hasDictionaryEnd() throws IOException { - return hasEnd(); - } - - @Override - public void readDictionaryEnd() throws IOException { + BdfDictionary dictionary = new BdfDictionary(); + String prevKey = null; + while (!hasEnd()) { + String key = readString(); + if (canonical && prevKey != null && key.compareTo(prevKey) <= 0) { + // Keys not unique and sorted + throw new FormatException(); + } + dictionary.put(key, readObject(level + 1)); + prevKey = key; + } readEnd(); + return dictionary; } @Override public void skipDictionary() throws IOException { if (!hasDictionary()) throw new FormatException(); hasLookahead = false; - while (!hasDictionaryEnd()) { + while (!hasEnd()) { skipString(); skipObject(); } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/data/BdfWriterImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/data/BdfWriterImpl.java index aa862e572..ca9204923 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/data/BdfWriterImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/data/BdfWriterImpl.java @@ -2,11 +2,13 @@ package org.briarproject.bramble.data; import org.briarproject.bramble.api.Bytes; import org.briarproject.bramble.api.FormatException; +import org.briarproject.bramble.api.data.BdfDictionary; import org.briarproject.bramble.api.data.BdfWriter; import org.briarproject.nullsafety.NotNullByDefault; import java.io.IOException; import java.io.OutputStream; +import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; @@ -15,6 +17,7 @@ import java.util.Map.Entry; import javax.annotation.Nullable; import javax.annotation.concurrent.NotThreadSafe; +import static java.util.Collections.sort; import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE; import static org.briarproject.bramble.data.Types.DICTIONARY; import static org.briarproject.bramble.data.Types.END; @@ -33,10 +36,11 @@ import static org.briarproject.bramble.data.Types.STRING_16; import static org.briarproject.bramble.data.Types.STRING_32; import static org.briarproject.bramble.data.Types.STRING_8; import static org.briarproject.bramble.data.Types.TRUE; +import static org.briarproject.bramble.util.StringUtils.UTF_8; @NotThreadSafe @NotNullByDefault -class BdfWriterImpl implements BdfWriter { +final class BdfWriterImpl implements BdfWriter { private final OutputStream out; @@ -113,7 +117,7 @@ class BdfWriterImpl implements BdfWriter { @Override public void writeString(String s) throws IOException { - byte[] b = s.getBytes("UTF-8"); + byte[] b = s.getBytes(UTF_8); if (b.length <= Byte.MAX_VALUE) { out.write(STRING_8); out.write((byte) b.length); @@ -161,39 +165,33 @@ class BdfWriterImpl implements BdfWriter { else if (o instanceof String) writeString((String) o); else if (o instanceof byte[]) writeRaw((byte[]) o); else if (o instanceof Bytes) writeRaw(((Bytes) o).getBytes()); - else if (o instanceof List) writeList((List) o); - else if (o instanceof Map) writeDictionary((Map) o); + else if (o instanceof List) writeList((List) o); + else if (o instanceof Map) writeDictionary((Map) o); else throw new FormatException(); } - @Override - public void writeListStart() throws IOException { - out.write(LIST); - } - - @Override - public void writeListEnd() throws IOException { - out.write(END); - } - @Override public void writeDictionary(Map m) throws IOException { out.write(DICTIONARY); - for (Entry e : m.entrySet()) { - if (!(e.getKey() instanceof String)) throw new FormatException(); - writeString((String) e.getKey()); - writeObject(e.getValue()); + if (m instanceof BdfDictionary) { + // Entries are already sorted and keys are known to be strings + for (Entry e : ((BdfDictionary) m).entrySet()) { + writeString(e.getKey()); + writeObject(e.getValue()); + } + } else { + // Check that keys are strings, write entries in canonical order + List keys = new ArrayList<>(m.size()); + for (Object k : m.keySet()) { + if (!(k instanceof String)) throw new FormatException(); + keys.add((String) k); + } + sort(keys); + for (String key : keys) { + writeString(key); + writeObject(m.get(key)); + } } out.write(END); } - - @Override - public void writeDictionaryStart() throws IOException { - out.write(DICTIONARY); - } - - @Override - public void writeDictionaryEnd() throws IOException { - out.write(END); - } } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/keyagreement/PayloadEncoderImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/keyagreement/PayloadEncoderImpl.java index ca90f5f96..86b4109fe 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/keyagreement/PayloadEncoderImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/keyagreement/PayloadEncoderImpl.java @@ -1,5 +1,6 @@ package org.briarproject.bramble.keyagreement; +import org.briarproject.bramble.api.data.BdfList; import org.briarproject.bramble.api.data.BdfWriter; import org.briarproject.bramble.api.data.BdfWriterFactory; import org.briarproject.bramble.api.keyagreement.Payload; @@ -32,13 +33,14 @@ class PayloadEncoderImpl implements PayloadEncoder { ByteArrayOutputStream out = new ByteArrayOutputStream(); int formatIdAndVersion = (QR_FORMAT_ID << 5) | QR_FORMAT_VERSION; out.write(formatIdAndVersion); + BdfList payload = new BdfList(); + payload.add(p.getCommitment()); + for (TransportDescriptor d : p.getTransportDescriptors()) { + payload.add(d.getDescriptor()); + } BdfWriter w = bdfWriterFactory.createWriter(out); try { - w.writeListStart(); // Payload start - w.writeRaw(p.getCommitment()); - for (TransportDescriptor d : p.getTransportDescriptors()) - w.writeList(d.getDescriptor()); - w.writeListEnd(); // Payload end + w.writeList(payload); } catch (IOException e) { // Shouldn't happen with ByteArrayOutputStream throw new AssertionError(e); diff --git a/bramble-core/src/main/java/org/briarproject/bramble/keyagreement/PayloadParserImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/keyagreement/PayloadParserImpl.java index d41cffa99..6715faf3c 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/keyagreement/PayloadParserImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/keyagreement/PayloadParserImpl.java @@ -73,7 +73,7 @@ class PayloadParserImpl implements PayloadParser { List recognised = new ArrayList<>(); for (int i = 1; i < payload.size(); i++) { BdfList descriptor = payload.getList(i); - long transportId = descriptor.getLong(0); + int transportId = descriptor.getInt(0); if (transportId == TRANSPORT_ID_BLUETOOTH) { TransportId id = BluetoothConstants.ID; recognised.add(new TransportDescriptor(id, descriptor)); diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/LanTcpPlugin.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/LanTcpPlugin.java index 1354900a7..a4250c7a8 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/LanTcpPlugin.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tcp/LanTcpPlugin.java @@ -419,7 +419,7 @@ class LanTcpPlugin extends TcpPlugin { private InetSocketAddress parseSocketAddress(BdfList descriptor) throws FormatException { byte[] address = descriptor.getRaw(1); - int port = descriptor.getLong(2).intValue(); + int port = descriptor.getInt(2); if (port < 1 || port > MAX_16_BIT_UNSIGNED) throw new FormatException(); try { InetAddress addr = InetAddress.getByAddress(address); diff --git a/bramble-core/src/main/java/org/briarproject/bramble/properties/TransportPropertyManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/properties/TransportPropertyManagerImpl.java index 7f17fed48..e1641d6e9 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/properties/TransportPropertyManagerImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/properties/TransportPropertyManagerImpl.java @@ -201,7 +201,7 @@ class TransportPropertyManagerImpl implements TransportPropertyManager, // Retrieve and parse the latest local properties for (Entry e : latest.entrySet()) { BdfList message = clientHelper.getMessageAsList(txn, - e.getValue().messageId); + e.getValue().messageId, false); local.put(e.getKey(), parseProperties(message)); } return local; @@ -222,7 +222,7 @@ class TransportPropertyManagerImpl implements TransportPropertyManager, if (latest != null) { // Retrieve and parse the latest local properties BdfList message = clientHelper.getMessageAsList(txn, - latest.messageId); + latest.messageId, false); p = parseProperties(message); } return p == null ? new TransportProperties() : p; @@ -252,7 +252,7 @@ class TransportPropertyManagerImpl implements TransportPropertyManager, local = new TransportProperties(); } else { BdfList message = clientHelper.getMessageAsList(txn, - latest.messageId); + latest.messageId, false); local = parseProperties(message); } storeLocalProperties(txn, c, t, local); @@ -272,8 +272,8 @@ class TransportPropertyManagerImpl implements TransportPropertyManager, remote = new TransportProperties(); } else { // Retrieve and parse the latest remote properties - BdfList message = - clientHelper.getMessageAsList(txn, latest.messageId); + BdfList message = clientHelper.getMessageAsList(txn, + latest.messageId, false); remote = parseProperties(message); } // Merge in any discovered properties @@ -317,7 +317,7 @@ class TransportPropertyManagerImpl implements TransportPropertyManager, changed = true; } else { BdfList message = clientHelper.getMessageAsList(txn, - latest.messageId); + latest.messageId, false); TransportProperties old = parseProperties(message); merged = new TransportProperties(old); for (Entry e : p.entrySet()) { diff --git a/bramble-core/src/main/java/org/briarproject/bramble/properties/TransportPropertyValidator.java b/bramble-core/src/main/java/org/briarproject/bramble/properties/TransportPropertyValidator.java index d0dd2b91b..6a4c0abb4 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/properties/TransportPropertyValidator.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/properties/TransportPropertyValidator.java @@ -27,7 +27,10 @@ class TransportPropertyValidator extends BdfMessageValidator { TransportPropertyValidator(ClientHelper clientHelper, MetadataEncoder metadataEncoder, Clock clock) { - super(clientHelper, metadataEncoder, clock); + // Accept transport properties in non-canonical form + // TODO: Remove this after a reasonable migration period + // (added 2023-02-17) + super(clientHelper, metadataEncoder, clock, false); } @Override diff --git a/bramble-core/src/main/java/org/briarproject/bramble/transport/agreement/SessionParserImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/transport/agreement/SessionParserImpl.java index a0d18f380..160a134a8 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/transport/agreement/SessionParserImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/transport/agreement/SessionParserImpl.java @@ -32,8 +32,7 @@ class SessionParserImpl implements SessionParser { @Override public Session parseSession(BdfDictionary meta) throws FormatException { - State state = - State.fromValue(meta.getLong(SESSION_KEY_STATE).intValue()); + State state = State.fromValue(meta.getInt(SESSION_KEY_STATE)); MessageId lastLocalMessageId = null; byte[] lastLocalMessageIdBytes = @@ -56,9 +55,9 @@ class SessionParserImpl implements SessionParser { Long localTimestamp = meta.getOptionalLong(SESSION_KEY_LOCAL_TIMESTAMP); KeySetId keySetId = null; - Long keySetIdLong = meta.getOptionalLong(SESSION_KEY_KEY_SET_ID); - if (keySetIdLong != null) { - keySetId = new KeySetId(keySetIdLong.intValue()); + Integer keySetIdInt = meta.getOptionalInt(SESSION_KEY_KEY_SET_ID); + if (keySetIdInt != null) { + keySetId = new KeySetId(keySetIdInt); } return new Session(state, lastLocalMessageId, localKeyPair, diff --git a/bramble-core/src/main/java/org/briarproject/bramble/transport/agreement/TransportKeyAgreementManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/transport/agreement/TransportKeyAgreementManagerImpl.java index 82a17af1e..d092709ae 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/transport/agreement/TransportKeyAgreementManagerImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/transport/agreement/TransportKeyAgreementManagerImpl.java @@ -177,8 +177,8 @@ class TransportKeyAgreementManagerImpl extends BdfIncomingMessageHook protected DeliveryAction incomingMessage(Transaction txn, Message m, BdfList body, BdfDictionary meta) throws DbException, FormatException { - MessageType type = MessageType.fromValue( - meta.getLong(MSG_KEY_MESSAGE_TYPE).intValue()); + MessageType type = + MessageType.fromValue(meta.getInt(MSG_KEY_MESSAGE_TYPE)); TransportId t = new TransportId(meta.getString(MSG_KEY_TRANSPORT_ID)); if (LOG.isLoggable(INFO)) { LOG.info("Received " + type + " message for " + t); diff --git a/bramble-core/src/main/java/org/briarproject/bramble/transport/agreement/TransportKeyAgreementValidator.java b/bramble-core/src/main/java/org/briarproject/bramble/transport/agreement/TransportKeyAgreementValidator.java index ca43a94c4..9133d3e8b 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/transport/agreement/TransportKeyAgreementValidator.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/transport/agreement/TransportKeyAgreementValidator.java @@ -42,7 +42,7 @@ class TransportKeyAgreementValidator extends BdfMessageValidator { @Override protected BdfMessageContext validateMessage(Message m, Group g, BdfList body) throws FormatException { - MessageType type = MessageType.fromValue(body.getLong(0).intValue()); + MessageType type = MessageType.fromValue(body.getInt(0)); if (type == KEY) return validateKeyMessage(m.getTimestamp(), body); else if (type == ACTIVATE) return validateActivateMessage(body); else throw new AssertionError(); diff --git a/bramble-core/src/main/java/org/briarproject/bramble/versioning/ClientVersioningManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/versioning/ClientVersioningManagerImpl.java index 232b71f1b..1dc50702e 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/versioning/ClientVersioningManagerImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/versioning/ClientVersioningManagerImpl.java @@ -301,8 +301,8 @@ class ClientVersioningManagerImpl implements ClientVersioningManager, for (int i = 0; i < size; i++) { BdfList cv = body.getList(i); ClientId clientId = new ClientId(cv.getString(0)); - int majorVersion = cv.getLong(1).intValue(); - int minorVersion = cv.getLong(2).intValue(); + int majorVersion = cv.getInt(1); + int minorVersion = cv.getInt(2); parsed.add(new ClientVersion(clientId, majorVersion, minorVersion)); } return parsed; @@ -408,8 +408,8 @@ class ClientVersioningManagerImpl implements ClientVersioningManager, throws FormatException { // Client ID, major version, minor version, active ClientId clientId = new ClientId(clientState.getString(0)); - int majorVersion = clientState.getLong(1).intValue(); - int minorVersion = clientState.getLong(2).intValue(); + int majorVersion = clientState.getInt(1); + int minorVersion = clientState.getInt(2); boolean active = clientState.getBoolean(3); return new ClientState(clientId, majorVersion, minorVersion, active); } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/versioning/ClientVersioningValidator.java b/bramble-core/src/main/java/org/briarproject/bramble/versioning/ClientVersioningValidator.java index b6fbb0c5d..2171a3d75 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/versioning/ClientVersioningValidator.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/versioning/ClientVersioningValidator.java @@ -43,9 +43,9 @@ class ClientVersioningValidator extends BdfMessageValidator { checkSize(clientState, 4); String clientId = clientState.getString(0); checkLength(clientId, 1, MAX_CLIENT_ID_LENGTH); - int majorVersion = clientState.getLong(1).intValue(); + int majorVersion = clientState.getInt(1); if (majorVersion < 0) throw new FormatException(); - int minorVersion = clientState.getLong(2).intValue(); + int minorVersion = clientState.getInt(2); if (minorVersion < 0) throw new FormatException(); clientState.getBoolean(3); } diff --git a/bramble-core/src/test/java/org/briarproject/bramble/client/BdfMessageValidatorTest.java b/bramble-core/src/test/java/org/briarproject/bramble/client/BdfMessageValidatorTest.java index a6b93c6cc..6794367df 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/client/BdfMessageValidatorTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/client/BdfMessageValidatorTest.java @@ -56,7 +56,7 @@ public class BdfMessageValidatorTest extends ValidatorTestCase { context.checking(new Expectations() {{ oneOf(clock).currentTimeMillis(); will(returnValue(timestamp - MAX_CLOCK_DIFFERENCE)); - oneOf(clientHelper).toList(message.getBody()); + oneOf(clientHelper).toList(message, true); will(returnValue(body)); oneOf(metadataEncoder).encode(dictionary); will(returnValue(meta)); @@ -86,7 +86,7 @@ public class BdfMessageValidatorTest extends ValidatorTestCase { context.checking(new Expectations() {{ oneOf(clock).currentTimeMillis(); will(returnValue(timestamp)); - oneOf(clientHelper).toList(shortMessage.getBody()); + oneOf(clientHelper).toList(shortMessage, true); will(returnValue(body)); oneOf(metadataEncoder).encode(dictionary); will(returnValue(meta)); @@ -114,7 +114,7 @@ public class BdfMessageValidatorTest extends ValidatorTestCase { context.checking(new Expectations() {{ oneOf(clock).currentTimeMillis(); will(returnValue(timestamp)); - oneOf(clientHelper).toList(message.getBody()); + oneOf(clientHelper).toList(message, true); will(throwException(new FormatException())); }}); @@ -126,7 +126,7 @@ public class BdfMessageValidatorTest extends ValidatorTestCase { context.checking(new Expectations() {{ oneOf(clock).currentTimeMillis(); will(returnValue(timestamp)); - oneOf(clientHelper).toList(message.getBody()); + oneOf(clientHelper).toList(message, true); will(returnValue(body)); }}); diff --git a/bramble-core/src/test/java/org/briarproject/bramble/client/ClientHelperImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/client/ClientHelperImplTest.java index 7c39128a1..a4f8149f1 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/client/ClientHelperImplTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/client/ClientHelperImplTest.java @@ -546,7 +546,7 @@ public class ClientHelperImplTest extends BrambleMockTestCase { context.checking(new Expectations() {{ oneOf(bdfReaderFactory) - .createReader(with(any(InputStream.class))); + .createReader(with(any(InputStream.class)), with(true)); will(returnValue(bdfReader)); oneOf(bdfReader).readList(); will(returnValue(list)); diff --git a/bramble-core/src/test/java/org/briarproject/bramble/data/BdfReaderImplFuzzingTest.java b/bramble-core/src/test/java/org/briarproject/bramble/data/BdfReaderImplFuzzingTest.java index 852e66853..fcbf6bfb9 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/data/BdfReaderImplFuzzingTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/data/BdfReaderImplFuzzingTest.java @@ -1,5 +1,6 @@ package org.briarproject.bramble.data; +import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.test.BrambleTestCase; import org.junit.Before; import org.junit.Test; @@ -31,11 +32,14 @@ public class BdfReaderImplFuzzingTest extends BrambleTestCase { buf[1] = 0x14; // Length 20 bytes in.reset(); BdfReaderImpl r = new BdfReaderImpl(in, DEFAULT_NESTED_LIMIT, - DEFAULT_MAX_BUFFER_SIZE); - int length = r.readString().length(); - assertTrue(length >= 0); - assertTrue(length <= 20); - assertTrue(r.eof()); + DEFAULT_MAX_BUFFER_SIZE, true); + try { + int length = r.readString().length(); + assertTrue(length <= 20); + assertTrue(r.eof()); + } catch (FormatException e) { + // Expected when bytes are not valid UTF-8 + } } } } diff --git a/bramble-core/src/test/java/org/briarproject/bramble/data/BdfReaderImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/data/BdfReaderImplTest.java index f59584b57..f34935cf3 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/data/BdfReaderImplTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/data/BdfReaderImplTest.java @@ -11,6 +11,7 @@ import java.io.ByteArrayInputStream; import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE; import static org.briarproject.bramble.api.data.BdfReader.DEFAULT_MAX_BUFFER_SIZE; import static org.briarproject.bramble.data.BdfReaderImpl.DEFAULT_NESTED_LIMIT; +import static org.briarproject.bramble.util.StringUtils.UTF_8; import static org.briarproject.bramble.util.StringUtils.fromHexString; import static org.briarproject.bramble.util.StringUtils.getRandomString; import static org.briarproject.bramble.util.StringUtils.toHexString; @@ -88,6 +89,18 @@ public class BdfReaderImplTest extends BrambleTestCase { assertTrue(r.eof()); } + @Test(expected = FormatException.class) + public void testReadLong16CouldHaveBeenLong8Max() throws Exception { + setContents("22" + "007F"); + r.readLong(); + } + + @Test(expected = FormatException.class) + public void testReadLong16CouldHaveBeenLong8Min() throws Exception { + setContents("22" + "FF80"); + r.readLong(); + } + @Test public void testSkipLong16() throws Exception { setContents("22" + "0080"); @@ -106,6 +119,18 @@ public class BdfReaderImplTest extends BrambleTestCase { assertTrue(r.eof()); } + @Test(expected = FormatException.class) + public void testReadLong32CouldHaveBeenLong16Max() throws Exception { + setContents("24" + "00007FFF"); + r.readLong(); + } + + @Test(expected = FormatException.class) + public void testReadLong32CouldHaveBeenLong16Min() throws Exception { + setContents("24" + "FFFF8000"); + r.readLong(); + } + @Test public void testSkipLong32() throws Exception { setContents("24" + "00008000"); @@ -124,13 +149,48 @@ public class BdfReaderImplTest extends BrambleTestCase { assertTrue(r.eof()); } + @Test(expected = FormatException.class) + public void testReadLong64CouldHaveBeenLong32Max() throws Exception { + setContents("28" + "000000007FFFFFFF"); + r.readLong(); + } + + @Test(expected = FormatException.class) + public void testReadLong64CouldHaveBeenLong32Min() throws Exception { + setContents("28" + "FFFFFFFF80000000"); + r.readLong(); + } + @Test - public void testSkipLong() throws Exception { + public void testSkipLong64() throws Exception { setContents("28" + "0000000080000000"); r.skipLong(); assertTrue(r.eof()); } + @Test + public void testReadInt() throws Exception { + setContents("21" + "7F" + "21" + "80" + + "22" + "7FFF" + "22" + "8000" + + "24" + "7FFFFFFF" + "24" + "80000000"); + assertEquals(Byte.MAX_VALUE, r.readInt()); + assertEquals(Byte.MIN_VALUE, r.readInt()); + assertEquals(Short.MAX_VALUE, r.readInt()); + assertEquals(Short.MIN_VALUE, r.readInt()); + assertEquals(Integer.MAX_VALUE, r.readInt()); + assertEquals(Integer.MIN_VALUE, r.readInt()); + assertTrue(r.eof()); + } + + @Test + public void testSkipInt() throws Exception { + setContents("21" + "7F" + "22" + "7FFF" + "24" + "7FFFFFFF"); + r.skipInt(); + r.skipInt(); + r.skipInt(); + assertTrue(r.eof()); + } + @Test public void testReadDouble() throws Exception { // http://babbage.cs.qc.edu/IEEE-754/Decimal.html @@ -162,7 +222,7 @@ public class BdfReaderImplTest extends BrambleTestCase { @Test public void testReadString8() throws Exception { String longest = getRandomString(Byte.MAX_VALUE); - String longHex = toHexString(longest.getBytes("UTF-8")); + String longHex = toHexString(longest.getBytes(UTF_8)); // "foo", the empty string, and 127 random letters setContents("41" + "03" + "666F6F" + "41" + "00" + "41" + "7F" + longHex); @@ -186,7 +246,7 @@ public class BdfReaderImplTest extends BrambleTestCase { @Test public void testSkipString8() throws Exception { String longest = getRandomString(Byte.MAX_VALUE); - String longHex = toHexString(longest.getBytes("UTF-8")); + String longHex = toHexString(longest.getBytes(UTF_8)); // "foo", the empty string, and 127 random letters setContents("41" + "03" + "666F6F" + "41" + "00" + "41" + "7F" + longHex); @@ -199,9 +259,9 @@ public class BdfReaderImplTest extends BrambleTestCase { @Test public void testReadString16() throws Exception { String shortest = getRandomString(Byte.MAX_VALUE + 1); - String shortHex = toHexString(shortest.getBytes("UTF-8")); + String shortHex = toHexString(shortest.getBytes(UTF_8)); String longest = getRandomString(Short.MAX_VALUE); - String longHex = toHexString(longest.getBytes("UTF-8")); + String longHex = toHexString(longest.getBytes(UTF_8)); // 128 random letters and 2^15 -1 random letters setContents("42" + "0080" + shortHex + "42" + "7FFF" + longHex); assertEquals(shortest, r.readString()); @@ -213,7 +273,7 @@ public class BdfReaderImplTest extends BrambleTestCase { public void testReadString16ChecksMaxLength() throws Exception { int maxBufferSize = Byte.MAX_VALUE + 1; String valid = getRandomString(Byte.MAX_VALUE + 1); - String validHex = toHexString(valid.getBytes("UTF-8")); + String validHex = toHexString(valid.getBytes(UTF_8)); String invalidhex = validHex + "20"; // 128 random letters, the same plus a space setContents("42" + "0080" + validHex @@ -223,12 +283,20 @@ public class BdfReaderImplTest extends BrambleTestCase { r.readString(); } + @Test(expected = FormatException.class) + public void testReadString16CouldHaveBeenString8() throws Exception { + String longest = getRandomString(Byte.MAX_VALUE); + String longHex = toHexString(longest.getBytes(UTF_8)); + setContents("42" + "007F" + longHex); + r.readString(); + } + @Test public void testSkipString16() throws Exception { String shortest = getRandomString(Byte.MAX_VALUE + 1); - String shortHex = toHexString(shortest.getBytes("UTF-8")); + String shortHex = toHexString(shortest.getBytes(UTF_8)); String longest = getRandomString(Short.MAX_VALUE); - String longHex = toHexString(longest.getBytes("UTF-8")); + String longHex = toHexString(longest.getBytes(UTF_8)); // 128 random letters and 2^15 - 1 random letters setContents("42" + "0080" + shortHex + "42" + "7FFF" + longHex); r.skipString(); @@ -239,7 +307,7 @@ public class BdfReaderImplTest extends BrambleTestCase { @Test public void testReadString32() throws Exception { String shortest = getRandomString(Short.MAX_VALUE + 1); - String shortHex = toHexString(shortest.getBytes("UTF-8")); + String shortHex = toHexString(shortest.getBytes(UTF_8)); // 2^15 random letters setContents("44" + "00008000" + shortHex); assertEquals(shortest, r.readString()); @@ -250,7 +318,7 @@ public class BdfReaderImplTest extends BrambleTestCase { public void testReadString32ChecksMaxLength() throws Exception { int maxBufferSize = Short.MAX_VALUE + 1; String valid = getRandomString(maxBufferSize); - String validHex = toHexString(valid.getBytes("UTF-8")); + String validHex = toHexString(valid.getBytes(UTF_8)); String invalidHex = validHex + "20"; // 2^15 random letters, the same plus a space setContents("44" + "00008000" + validHex + @@ -260,10 +328,18 @@ public class BdfReaderImplTest extends BrambleTestCase { r.readString(); } + @Test(expected = FormatException.class) + public void testReadString32CouldHaveBeenString16() throws Exception { + String longest = getRandomString(Short.MAX_VALUE); + String longHex = toHexString(longest.getBytes(UTF_8)); + setContents("44" + "00007FFF" + longHex); + r.readString(); + } + @Test public void testSkipString32() throws Exception { String shortest = getRandomString(Short.MAX_VALUE + 1); - String shortHex = toHexString(shortest.getBytes("UTF-8")); + String shortHex = toHexString(shortest.getBytes(UTF_8)); // 2^15 random letters, twice setContents("44" + "00008000" + shortHex + "44" + "00008000" + shortHex); @@ -275,7 +351,7 @@ public class BdfReaderImplTest extends BrambleTestCase { @Test public void testReadUtf8String() throws Exception { String unicode = "\uFDD0\uFDD1\uFDD2\uFDD3"; - String hex = toHexString(unicode.getBytes("UTF-8")); + String hex = toHexString(unicode.getBytes(UTF_8)); // STRING_8 tag, "foo", the empty string, and the test string setContents("41" + "03" + "666F6F" + "41" + "00" + "41" + "0C" + hex); assertEquals("foo", r.readString()); @@ -348,6 +424,14 @@ public class BdfReaderImplTest extends BrambleTestCase { r.readRaw(); } + @Test(expected = FormatException.class) + public void testReadRaw16CouldHaveBeenRaw8() throws Exception { + byte[] longest = new byte[Byte.MAX_VALUE]; + String longHex = toHexString(longest); + setContents("52" + "007F" + longHex); + r.readRaw(); + } + @Test public void testSkipRaw16() throws Exception { byte[] shortest = new byte[Byte.MAX_VALUE + 1]; @@ -385,6 +469,14 @@ public class BdfReaderImplTest extends BrambleTestCase { r.readRaw(); } + @Test(expected = FormatException.class) + public void testReadRaw32CouldHaveBeenRaw16() throws Exception { + byte[] longest = new byte[Short.MAX_VALUE]; + String longHex = toHexString(longest); + setContents("54" + "00007FFF" + longHex); + r.readRaw(); + } + @Test public void testSkipRaw32() throws Exception { byte[] shortest = new byte[Short.MAX_VALUE + 1]; @@ -434,25 +526,6 @@ public class BdfReaderImplTest extends BrambleTestCase { r.readList(); } - @Test - public void testReadListManually() throws Exception { - // A list containing 1, "foo", and null - setContents("60" + "21" + "01" + - "41" + "03" + "666F6F" + - "00" + "80"); - r.readListStart(); - assertFalse(r.hasListEnd()); - assertEquals(1, r.readLong()); - assertFalse(r.hasListEnd()); - assertEquals("foo", r.readString()); - assertFalse(r.hasListEnd()); - assertTrue(r.hasNull()); - r.readNull(); - assertTrue(r.hasListEnd()); - r.readListEnd(); - assertTrue(r.eof()); - } - @Test public void testSkipList() throws Exception { // A list containing 1, "foo", and 128 @@ -465,9 +538,9 @@ public class BdfReaderImplTest extends BrambleTestCase { @Test public void testReadDictionary() throws Exception { - // A dictionary containing "foo" -> 123 and "bar" -> null - setContents("70" + "41" + "03" + "666F6F" + "21" + "7B" + - "41" + "03" + "626172" + "00" + "80"); + // A dictionary containing "bar" -> null and "foo" -> 123 + setContents("70" + "41" + "03" + "626172" + "00" + + "41" + "03" + "666F6F" + "21" + "7B" + "80"); BdfDictionary dictionary = r.readDictionary(); assertEquals(2, dictionary.size()); assertTrue(dictionary.containsKey("foo")); @@ -517,26 +590,6 @@ public class BdfReaderImplTest extends BrambleTestCase { r.readDictionary(); } - @Test - public void testReadDictionaryManually() throws Exception { - // A dictionary containing "foo" -> 123 and "bar" -> null - setContents("70" + "41" + "03" + "666F6F" + "21" + "7B" + - "41" + "03" + "626172" + "00" + "80"); - r.readDictionaryStart(); - assertFalse(r.hasDictionaryEnd()); - assertEquals("foo", r.readString()); - assertFalse(r.hasDictionaryEnd()); - assertEquals(123, r.readLong()); - assertFalse(r.hasDictionaryEnd()); - assertEquals("bar", r.readString()); - assertFalse(r.hasDictionaryEnd()); - assertTrue(r.hasNull()); - r.readNull(); - assertTrue(r.hasDictionaryEnd()); - r.readDictionaryEnd(); - assertTrue(r.eof()); - } - @Test public void testSkipDictionary() throws Exception { // A map containing "foo" -> 123 and "bar" -> null @@ -557,10 +610,10 @@ public class BdfReaderImplTest extends BrambleTestCase { @Test public void testNestedListWithinDepthLimit() throws Exception { // A list containing a list containing a list containing a list... - String lists = ""; - for (int i = 1; i <= DEFAULT_NESTED_LIMIT; i++) lists += "60"; - for (int i = 1; i <= DEFAULT_NESTED_LIMIT; i++) lists += "80"; - setContents(lists); + StringBuilder lists = new StringBuilder(); + for (int i = 1; i <= DEFAULT_NESTED_LIMIT; i++) lists.append("60"); + for (int i = 1; i <= DEFAULT_NESTED_LIMIT; i++) lists.append("80"); + setContents(lists.toString()); r.readList(); assertTrue(r.eof()); } @@ -568,23 +621,25 @@ public class BdfReaderImplTest extends BrambleTestCase { @Test(expected = FormatException.class) public void testNestedListOutsideDepthLimit() throws Exception { // A list containing a list containing a list containing a list... - String lists = ""; - for (int i = 1; i <= DEFAULT_NESTED_LIMIT + 1; i++) lists += "60"; - for (int i = 1; i <= DEFAULT_NESTED_LIMIT + 1; i++) lists += "80"; - setContents(lists); + StringBuilder lists = new StringBuilder(); + for (int i = 1; i <= DEFAULT_NESTED_LIMIT + 1; i++) lists.append("60"); + for (int i = 1; i <= DEFAULT_NESTED_LIMIT + 1; i++) lists.append("80"); + setContents(lists.toString()); r.readList(); } @Test public void testNestedDictionaryWithinDepthLimit() throws Exception { // A dictionary containing a dictionary containing a dictionary... - String dicts = ""; - for (int i = 1; i <= DEFAULT_NESTED_LIMIT; i++) - dicts += "70" + "41" + "03" + "666F6F"; - dicts += "11"; - for (int i = 1; i <= DEFAULT_NESTED_LIMIT; i++) - dicts += "80"; - setContents(dicts); + StringBuilder dicts = new StringBuilder(); + for (int i = 1; i <= DEFAULT_NESTED_LIMIT; i++) { + dicts.append("70").append("41").append("03").append("666F6F"); + } + dicts.append("11"); + for (int i = 1; i <= DEFAULT_NESTED_LIMIT; i++) { + dicts.append("80"); + } + setContents(dicts.toString()); r.readDictionary(); assertTrue(r.eof()); } @@ -592,13 +647,15 @@ public class BdfReaderImplTest extends BrambleTestCase { @Test(expected = FormatException.class) public void testNestedDictionaryOutsideDepthLimit() throws Exception { // A dictionary containing a dictionary containing a dictionary... - String dicts = ""; - for (int i = 1; i <= DEFAULT_NESTED_LIMIT + 1; i++) - dicts += "70" + "41" + "03" + "666F6F"; - dicts += "11"; - for (int i = 1; i <= DEFAULT_NESTED_LIMIT + 1; i++) - dicts += "80"; - setContents(dicts); + StringBuilder dicts = new StringBuilder(); + for (int i = 1; i <= DEFAULT_NESTED_LIMIT + 1; i++) { + dicts.append("70").append("41").append("03").append("666F6F"); + } + dicts.append("11"); + for (int i = 1; i <= DEFAULT_NESTED_LIMIT + 1; i++) { + dicts.append("80"); + } + setContents(dicts.toString()); r.readDictionary(); } @@ -625,6 +682,6 @@ public class BdfReaderImplTest extends BrambleTestCase { private void setContents(String hex, int maxBufferSize) throws FormatException { ByteArrayInputStream in = new ByteArrayInputStream(fromHexString(hex)); - r = new BdfReaderImpl(in, DEFAULT_NESTED_LIMIT, maxBufferSize); + r = new BdfReaderImpl(in, DEFAULT_NESTED_LIMIT, maxBufferSize, true); } } diff --git a/bramble-core/src/test/java/org/briarproject/bramble/data/BdfReaderWriterIntegrationTest.java b/bramble-core/src/test/java/org/briarproject/bramble/data/BdfReaderWriterIntegrationTest.java new file mode 100644 index 000000000..777aa2daf --- /dev/null +++ b/bramble-core/src/test/java/org/briarproject/bramble/data/BdfReaderWriterIntegrationTest.java @@ -0,0 +1,80 @@ +package org.briarproject.bramble.data; + +import org.briarproject.bramble.api.data.BdfDictionary; +import org.briarproject.bramble.api.data.BdfReader; +import org.briarproject.bramble.api.data.BdfWriter; +import org.briarproject.bramble.test.BrambleTestCase; +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Map.Entry; + +import static org.briarproject.bramble.api.data.BdfReader.DEFAULT_MAX_BUFFER_SIZE; +import static org.briarproject.bramble.api.data.BdfReader.DEFAULT_NESTED_LIMIT; +import static org.briarproject.bramble.util.StringUtils.fromHexString; +import static org.briarproject.bramble.util.StringUtils.toHexString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class BdfReaderWriterIntegrationTest extends BrambleTestCase { + + @Test + public void testConvertStringToCanonicalForm() throws Exception { + // 'foo' as a STRING_16 (not canonical, should be a STRING_8) + String hexIn = "42" + "0003" + "666F6F"; + InputStream in = new ByteArrayInputStream(fromHexString(hexIn)); + BdfReader r = new BdfReaderImpl(in, DEFAULT_NESTED_LIMIT, + DEFAULT_MAX_BUFFER_SIZE, false); // Accept non-canonical + String s = r.readString(); + assertEquals("foo", s); + assertTrue(r.eof()); + // Convert the string back to BDF + ByteArrayOutputStream out = new ByteArrayOutputStream(); + BdfWriter w = new BdfWriterImpl(out); + w.writeString(s); + w.flush(); + String hexOut = toHexString(out.toByteArray()); + // The BDF should now be in canonical form + assertEquals("41" + "03" + "666F6F", hexOut); + } + + @Test + public void testConvertDictionaryToCanonicalForm() throws Exception { + // A dictionary with keys in non-canonical order: 'foo' then 'bar' + String hexIn = "70" + "41" + "03" + "666F6F" + "21" + "01" + + "41" + "03" + "626172" + "21" + "02" + "80"; + InputStream in = new ByteArrayInputStream(fromHexString(hexIn)); + BdfReader r = new BdfReaderImpl(in, DEFAULT_NESTED_LIMIT, + DEFAULT_MAX_BUFFER_SIZE, false); // Accept non-canonical + BdfDictionary d = r.readDictionary(); + assertEquals(2, d.size()); + assertTrue(r.eof()); + // The entries should be returned in canonical order + Iterator> it = d.entrySet().iterator(); + Entry first = it.next(); + assertEquals("bar", first.getKey()); + assertEquals(2L, first.getValue()); + Entry second = it.next(); + assertEquals("foo", second.getKey()); + assertEquals(1L, second.getValue()); + + // Convert a non-canonical map to BDF (use LinkedHashMap so we know + // the entries will be iterated over in non-canonical order) + Map m = new LinkedHashMap<>(); + m.put("foo", 1); + m.put("bar", 2); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + BdfWriter w = new BdfWriterImpl(out); + w.writeDictionary(m); + w.flush(); + String hexOut = toHexString(out.toByteArray()); + // The entries should be in canonical order: 'bar' then 'foo' + assertEquals("70" + "41" + "03" + "626172" + "21" + "02" + + "41" + "03" + "666F6F" + "21" + "01" + "80", hexOut); + } +} diff --git a/bramble-core/src/test/java/org/briarproject/bramble/data/BdfWriterImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/data/BdfWriterImplTest.java index d643a9b62..0d3af445c 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/data/BdfWriterImplTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/data/BdfWriterImplTest.java @@ -1,5 +1,6 @@ package org.briarproject.bramble.data; +import org.briarproject.bramble.api.data.BdfDictionary; import org.briarproject.bramble.test.BrambleTestCase; import org.briarproject.bramble.util.StringUtils; import org.junit.Test; @@ -168,9 +169,11 @@ public class BdfWriterImplTest extends BrambleTestCase { @Test public void testWriteDictionary() throws IOException { - // Use LinkedHashMap to get predictable iteration order + // Add entries to dictionary in descending order - they should be + // output in ascending order. Use LinkedHashMap to get predictable + // iteration order Map m = new LinkedHashMap<>(); - for (int i = 0; i < 4; i++) m.put(String.valueOf(i), i); + for (int i = 3; i >= 0; i--) m.put(String.valueOf(i), i); w.writeDictionary(m); // DICTIONARY tag, keys as strings and values as integers, END tag checkContents("70" + "41" + "01" + "30" + "21" + "00" + @@ -180,30 +183,17 @@ public class BdfWriterImplTest extends BrambleTestCase { } @Test - public void testWriteDelimitedList() throws IOException { - w.writeListStart(); - w.writeLong(1); - w.writeString("foo"); - w.writeLong(128); - w.writeListEnd(); - // LIST tag, 1 as integer, "foo" as string, 128 as integer, END tag - checkContents("60" + "21" + "01" + - "41" + "03" + "666F6F" + - "22" + "0080" + "80"); - } - - @Test - public void testWriteDelimitedDictionary() throws IOException { - w.writeDictionaryStart(); - w.writeString("foo"); - w.writeLong(123); - w.writeString("bar"); - w.writeNull(); - w.writeDictionaryEnd(); - // DICTIONARY tag, "foo" as string, 123 as integer, "bar" as string, - // NULL tag, END tag - checkContents("70" + "41" + "03" + "666F6F" + - "21" + "7B" + "41" + "03" + "626172" + "00" + "80"); + public void testWriteBdfDictionary() throws IOException { + // Add entries to dictionary in descending order - they should be + // output in ascending order + BdfDictionary d = new BdfDictionary(); + for (int i = 3; i >= 0; i--) d.put(String.valueOf(i), i); + w.writeDictionary(d); + // DICTIONARY tag, keys as strings and values as integers, END tag + checkContents("70" + "41" + "01" + "30" + "21" + "00" + + "41" + "01" + "31" + "21" + "01" + + "41" + "01" + "32" + "21" + "02" + + "41" + "01" + "33" + "21" + "03" + "80"); } @Test diff --git a/bramble-core/src/test/java/org/briarproject/bramble/plugin/tcp/LanTcpPluginTest.java b/bramble-core/src/test/java/org/briarproject/bramble/plugin/tcp/LanTcpPluginTest.java index 6f6881599..8c41437e4 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/plugin/tcp/LanTcpPluginTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/plugin/tcp/LanTcpPluginTest.java @@ -217,13 +217,13 @@ public class LanTcpPluginTest extends BrambleTestCase { // The plugin should have bound a socket and stored the port number BdfList descriptor = kal.getDescriptor(); assertEquals(3, descriptor.size()); - assertEquals(TRANSPORT_ID_LAN, descriptor.getLong(0).longValue()); + assertEquals(TRANSPORT_ID_LAN, descriptor.getInt(0).intValue()); byte[] address = descriptor.getRaw(1); InetAddress addr = InetAddress.getByAddress(address); assertTrue(addr instanceof Inet4Address); assertFalse(addr.isLoopbackAddress()); assertTrue(addr.isLinkLocalAddress() || addr.isSiteLocalAddress()); - int port = descriptor.getLong(2).intValue(); + int port = descriptor.getInt(2); assertTrue(port > 0 && port < 65536); // The plugin should be listening on the port InetSocketAddress socketAddr = new InetSocketAddress(addr, port); diff --git a/bramble-core/src/test/java/org/briarproject/bramble/properties/TransportPropertyManagerImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/properties/TransportPropertyManagerImplTest.java index 7c7396f6e..27251be97 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/properties/TransportPropertyManagerImplTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/properties/TransportPropertyManagerImplTest.java @@ -404,7 +404,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase { oneOf(clientHelper).getMessageMetadataAsDictionary(txn, localGroup.getId()); will(returnValue(messageMetadata)); - oneOf(clientHelper).getMessageAsList(txn, fooUpdateId); + oneOf(clientHelper).getMessageAsList(txn, fooUpdateId, false); will(returnValue(fooUpdate)); oneOf(clientHelper).parseAndValidateTransportProperties( fooPropertiesDict); @@ -471,7 +471,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase { oneOf(clientHelper).getMessageMetadataAsDictionary(txn, contactGroup2.getId()); will(returnValue(messageMetadata)); - oneOf(clientHelper).getMessageAsList(txn, fooUpdateId); + oneOf(clientHelper).getMessageAsList(txn, fooUpdateId, false); will(returnValue(fooUpdate)); oneOf(clientHelper).parseAndValidateTransportProperties( fooPropertiesDict); @@ -526,7 +526,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase { oneOf(clientHelper).getMessageMetadataAsDictionary(txn, contactGroup.getId()); will(returnValue(messageMetadata)); - oneOf(clientHelper).getMessageAsList(txn, updateId); + oneOf(clientHelper).getMessageAsList(txn, updateId, false); will(returnValue(update)); oneOf(clientHelper).parseAndValidateTransportProperties( fooPropertiesDict); @@ -564,7 +564,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase { oneOf(clientHelper).getMessageMetadataAsDictionary(txn, localGroup.getId()); will(returnValue(messageMetadata)); - oneOf(clientHelper).getMessageAsList(txn, updateId); + oneOf(clientHelper).getMessageAsList(txn, updateId, false); will(returnValue(update)); oneOf(clientHelper).parseAndValidateTransportProperties( fooPropertiesDict); @@ -695,7 +695,8 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase { oneOf(clientHelper).getMessageMetadataAsDictionary(txn, localGroup.getId()); will(returnValue(localGroupMessageMetadata)); - oneOf(clientHelper).getMessageAsList(txn, localGroupUpdateId); + oneOf(clientHelper).getMessageAsList(txn, localGroupUpdateId, + false); will(returnValue(oldUpdate)); oneOf(clientHelper).parseAndValidateTransportProperties( oldPropertiesDict); @@ -760,7 +761,8 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase { oneOf(clientHelper).getMessageMetadataAsDictionary(txn, localGroup.getId()); will(returnValue(localGroupMessageMetadata)); - oneOf(clientHelper).getMessageAsList(txn, localGroupUpdateId); + oneOf(clientHelper).getMessageAsList(txn, localGroupUpdateId, + false); will(returnValue(oldUpdate)); oneOf(clientHelper).parseAndValidateTransportProperties( oldPropertiesDict); @@ -819,12 +821,12 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase { localGroup.getId()); will(returnValue(messageMetadata)); // Retrieve and parse the latest local properties - oneOf(clientHelper).getMessageAsList(txn, fooVersion999); + oneOf(clientHelper).getMessageAsList(txn, fooVersion999, false); will(returnValue(fooUpdate)); oneOf(clientHelper).parseAndValidateTransportProperties( fooPropertiesDict); will(returnValue(fooProperties)); - oneOf(clientHelper).getMessageAsList(txn, barVersion3); + oneOf(clientHelper).getMessageAsList(txn, barVersion3, false); will(returnValue(barUpdate)); oneOf(clientHelper).parseAndValidateTransportProperties( barPropertiesDict); diff --git a/bramble-core/src/test/java/org/briarproject/bramble/util/StringUtilsTest.java b/bramble-core/src/test/java/org/briarproject/bramble/util/StringUtilsTest.java index 593640824..b3c13c27b 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/util/StringUtilsTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/util/StringUtilsTest.java @@ -88,51 +88,58 @@ public class StringUtilsTest extends BrambleTestCase { } @Test - public void testFromUtf8AcceptsNullCharacterUsingStandardUtf8() { + public void testFromUtf8AcceptsNullCharacterUsingStandardUtf8() + throws Exception { // The UTF-8 encoding of the null character is valid - assertEquals("\u0000", StringUtils.fromUtf8(new byte[1])); + byte[] utf8 = new byte[1]; + String actual = StringUtils.fromUtf8(utf8); + assertEquals("\u0000", actual); + // When we convert back to UTF-8 we should get the original encoding + assertArrayEquals(utf8, StringUtils.toUtf8(actual)); } - @Test - public void testFromUtf8RemovesNullCharacterUsingModifiedUtf8() { + @Test(expected = FormatException.class) + public void testFromUtf8RejectsNullCharacterUsingModifiedUtf8() + throws Exception { // The modified UTF-8 encoding of the null character is not valid byte[] b = new byte[] { (byte) 0xC0, (byte) 0x80, // Null character as modified UTF-8 (byte) 0xC8, (byte) 0x85 // U+0205 }; - // Conversion should ignore the invalid character and return the rest - String expected = "\u0205"; - assertEquals(expected, StringUtils.fromUtf8(b)); + StringUtils.fromUtf8(b); } @Test - public void testFromUtf8AcceptsSupplementaryCharacterUsingStandardUtf8() { + public void testFromUtf8AcceptsSupplementaryCharacterUsingStandardUtf8() + throws Exception { // The UTF-8 encoding of a supplementary character is valid and should // be converted to a surrogate pair - byte[] b = new byte[] { + byte[] utf8 = new byte[] { (byte) 0xF0, (byte) 0x90, (byte) 0x90, (byte) 0x80, // U+10400 (byte) 0xC8, (byte) 0x85 // U+0205 }; String expected = "\uD801\uDC00\u0205"; // Surrogate pair - assertEquals(expected, StringUtils.fromUtf8(b)); + String actual = StringUtils.fromUtf8(utf8); + assertEquals(expected, actual); + // When we convert back to UTF-8 we should get the original encoding + assertArrayEquals(utf8, StringUtils.toUtf8(actual)); } - @Test - public void testFromUtf8RemovesSupplementaryCharacterUsingModifiedUtf8() { + @Test(expected = FormatException.class) + public void testFromUtf8RejectsSupplementaryCharacterUsingModifiedUtf8() + throws Exception { // The CESU-8 or modified UTF-8 encoding of a supplementary character // is not valid - byte[] b = new byte[] { + byte[] utf8 = new byte[] { (byte) 0xED, (byte) 0xA0, (byte) 0x81, // U+10400 as CSEU-8 (byte) 0xED, (byte) 0xB0, (byte) 0x80, (byte) 0xC8, (byte) 0x85 // U+0205 }; - // Conversion should ignore the invalid character and return the rest - String expected = "\u0205"; - assertEquals(expected, StringUtils.fromUtf8(b)); + StringUtils.fromUtf8(utf8); } @Test - public void testFromUtf8EmptyInput() { + public void testFromUtf8EmptyInput() throws Exception { assertEquals("", StringUtils.fromUtf8(new byte[0])); } diff --git a/briar-core/src/main/java/org/briarproject/briar/attachment/AttachmentReaderImpl.java b/briar-core/src/main/java/org/briarproject/briar/attachment/AttachmentReaderImpl.java index 69d5f963f..fb981a6b4 100644 --- a/briar-core/src/main/java/org/briarproject/briar/attachment/AttachmentReaderImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/attachment/AttachmentReaderImpl.java @@ -56,7 +56,7 @@ public class AttachmentReaderImpl implements AttachmentReader { String contentType = meta.getString(MSG_KEY_CONTENT_TYPE); if (!contentType.equals(h.getContentType())) throw new NoSuchMessageException(); - int offset = meta.getLong(MSG_KEY_DESCRIPTOR_LENGTH).intValue(); + int offset = meta.getInt(MSG_KEY_DESCRIPTOR_LENGTH); InputStream stream = new ByteArrayInputStream(body, offset, body.length - offset); return new Attachment(h, stream); diff --git a/briar-core/src/main/java/org/briarproject/briar/avatar/AvatarManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/avatar/AvatarManagerImpl.java index 2c720367c..4e8875eec 100644 --- a/briar-core/src/main/java/org/briarproject/briar/avatar/AvatarManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/avatar/AvatarManagerImpl.java @@ -250,7 +250,7 @@ class AvatarManagerImpl implements AvatarManager, OpenDatabaseHook, ContactHook, try { BdfDictionary meta = clientHelper.getGroupMetadataAsDictionary(txn, g); - return new ContactId(meta.getLong(GROUP_KEY_CONTACT_ID).intValue()); + return new ContactId(meta.getInt(GROUP_KEY_CONTACT_ID)); } catch (FormatException e) { throw new DbException(e); } diff --git a/briar-core/src/main/java/org/briarproject/briar/avatar/AvatarValidator.java b/briar-core/src/main/java/org/briarproject/briar/avatar/AvatarValidator.java index 30ec7cb37..ce8ed9c0a 100644 --- a/briar-core/src/main/java/org/briarproject/briar/avatar/AvatarValidator.java +++ b/briar-core/src/main/java/org/briarproject/briar/avatar/AvatarValidator.java @@ -76,7 +76,7 @@ class AvatarValidator implements MessageValidator { // 0.0: Message Type, Version, Content-Type checkSize(body, 3); // Message Type - long messageType = body.getLong(0); + int messageType = body.getInt(0); if (messageType != MSG_TYPE_UPDATE) throw new FormatException(); // Version long version = body.getLong(1); diff --git a/briar-core/src/main/java/org/briarproject/briar/blog/BlogManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/blog/BlogManagerImpl.java index 2c55ff4fd..77786f026 100644 --- a/briar-core/src/main/java/org/briarproject/briar/blog/BlogManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/blog/BlogManagerImpl.java @@ -487,7 +487,7 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager, } private String getPostText(BdfList message) throws FormatException { - MessageType type = MessageType.valueOf(message.getLong(0).intValue()); + MessageType type = MessageType.valueOf(message.getInt(0)); if (type == POST) { // Type, text, signature return message.getString(1); @@ -621,7 +621,6 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager, } private MessageType getMessageType(BdfDictionary d) throws FormatException { - Long longType = d.getLong(KEY_TYPE); - return MessageType.valueOf(longType.intValue()); + return MessageType.valueOf(d.getInt(KEY_TYPE)); } } diff --git a/briar-core/src/main/java/org/briarproject/briar/blog/BlogPostFactoryImpl.java b/briar-core/src/main/java/org/briarproject/briar/blog/BlogPostFactoryImpl.java index 4bef7fe85..64ae88196 100644 --- a/briar-core/src/main/java/org/briarproject/briar/blog/BlogPostFactoryImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/blog/BlogPostFactoryImpl.java @@ -167,6 +167,6 @@ class BlogPostFactoryImpl implements BlogPostFactory { } private MessageType getType(BdfList body) throws FormatException { - return MessageType.valueOf(body.getLong(0).intValue()); + return MessageType.valueOf(body.getInt(0)); } } diff --git a/briar-core/src/main/java/org/briarproject/briar/blog/BlogPostValidator.java b/briar-core/src/main/java/org/briarproject/briar/blog/BlogPostValidator.java index d4c135281..b17953892 100644 --- a/briar-core/src/main/java/org/briarproject/briar/blog/BlogPostValidator.java +++ b/briar-core/src/main/java/org/briarproject/briar/blog/BlogPostValidator.java @@ -72,7 +72,7 @@ class BlogPostValidator extends BdfMessageValidator { BdfMessageContext c; - int type = body.getLong(0).intValue(); + int type = body.getInt(0); body.remove(0); switch (MessageType.valueOf(type)) { case POST: diff --git a/briar-core/src/main/java/org/briarproject/briar/client/MessageTrackerImpl.java b/briar-core/src/main/java/org/briarproject/briar/client/MessageTrackerImpl.java index 1da615926..43a2ef207 100644 --- a/briar-core/src/main/java/org/briarproject/briar/client/MessageTrackerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/client/MessageTrackerImpl.java @@ -114,8 +114,8 @@ class MessageTrackerImpl implements MessageTracker { try { BdfDictionary d = clientHelper.getGroupMetadataAsDictionary(txn, g); return new GroupCount( - d.getLong(GROUP_KEY_MSG_COUNT, 0L).intValue(), - d.getLong(GROUP_KEY_UNREAD_COUNT, 0L).intValue(), + d.getInt(GROUP_KEY_MSG_COUNT, 0), + d.getInt(GROUP_KEY_UNREAD_COUNT, 0), d.getLong(GROUP_KEY_LATEST_MSG, 0L) ); } catch (FormatException e) { diff --git a/briar-core/src/main/java/org/briarproject/briar/introduction/IntroductionValidator.java b/briar-core/src/main/java/org/briarproject/briar/introduction/IntroductionValidator.java index 02fa86274..a13c045a7 100644 --- a/briar-core/src/main/java/org/briarproject/briar/introduction/IntroductionValidator.java +++ b/briar-core/src/main/java/org/briarproject/briar/introduction/IntroductionValidator.java @@ -47,7 +47,7 @@ class IntroductionValidator extends BdfMessageValidator { @Override protected BdfMessageContext validateMessage(Message m, Group g, BdfList body) throws FormatException { - MessageType type = MessageType.fromValue(body.getLong(0).intValue()); + MessageType type = MessageType.fromValue(body.getInt(0)); switch (type) { case REQUEST: diff --git a/briar-core/src/main/java/org/briarproject/briar/introduction/MessageParserImpl.java b/briar-core/src/main/java/org/briarproject/briar/introduction/MessageParserImpl.java index 5fd50c59c..5d1ae3c28 100644 --- a/briar-core/src/main/java/org/briarproject/briar/introduction/MessageParserImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/introduction/MessageParserImpl.java @@ -59,8 +59,8 @@ class MessageParserImpl implements MessageParser { @Override public MessageMetadata parseMetadata(BdfDictionary d) throws FormatException { - MessageType type = MessageType - .fromValue(d.getLong(MSG_KEY_MESSAGE_TYPE).intValue()); + MessageType type = + MessageType.fromValue(d.getInt(MSG_KEY_MESSAGE_TYPE)); byte[] sessionIdBytes = d.getOptionalRaw(MSG_KEY_SESSION_ID); SessionId sessionId = sessionIdBytes == null ? null : new SessionId(sessionIdBytes); diff --git a/briar-core/src/main/java/org/briarproject/briar/introduction/SessionParserImpl.java b/briar-core/src/main/java/org/briarproject/briar/introduction/SessionParserImpl.java index 203ebec57..ccf2da794 100644 --- a/briar-core/src/main/java/org/briarproject/briar/introduction/SessionParserImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/introduction/SessionParserImpl.java @@ -72,7 +72,7 @@ class SessionParserImpl implements SessionParser { @Override public Role getRole(BdfDictionary d) throws FormatException { - return Role.fromValue(d.getLong(SESSION_KEY_ROLE).intValue()); + return Role.fromValue(d.getInt(SESSION_KEY_ROLE)); } @Override @@ -97,7 +97,7 @@ class SessionParserImpl implements SessionParser { MessageId lastRemoteMessageId = getMessageId(d, SESSION_KEY_LAST_REMOTE_MESSAGE_ID); long localTimestamp = d.getLong(SESSION_KEY_LOCAL_TIMESTAMP); - GroupId groupId = getGroupId(d, SESSION_KEY_GROUP_ID); + GroupId groupId = getGroupId(d); Author author = getAuthor(d, SESSION_KEY_AUTHOR); return new Introducee(sessionId, groupId, author, localTimestamp, lastLocalMessageId, lastRemoteMessageId); @@ -126,12 +126,10 @@ class SessionParserImpl implements SessionParser { MessageId lastLocalMessageId = getMessageId(d, SESSION_KEY_LAST_LOCAL_MESSAGE_ID); long localTimestamp = d.getLong(SESSION_KEY_LOCAL_TIMESTAMP); - PublicKey ephemeralPublicKey = - getEphemeralPublicKey(d, SESSION_KEY_EPHEMERAL_PUBLIC_KEY); + PublicKey ephemeralPublicKey = getEphemeralPublicKey(d); BdfDictionary tpDict = d.getOptionalDictionary(SESSION_KEY_TRANSPORT_PROPERTIES); - PrivateKey ephemeralPrivateKey = - getEphemeralPrivateKey(d, SESSION_KEY_EPHEMERAL_PRIVATE_KEY); + PrivateKey ephemeralPrivateKey = getEphemeralPrivateKey(d); Map transportProperties = tpDict == null ? null : clientHelper .parseAndValidateTransportPropertiesMap(tpDict); @@ -147,8 +145,7 @@ class SessionParserImpl implements SessionParser { Author remoteAuthor = getAuthor(d, SESSION_KEY_REMOTE_AUTHOR); MessageId lastRemoteMessageId = getMessageId(d, SESSION_KEY_LAST_REMOTE_MESSAGE_ID); - PublicKey ephemeralPublicKey = - getEphemeralPublicKey(d, SESSION_KEY_EPHEMERAL_PUBLIC_KEY); + PublicKey ephemeralPublicKey = getEphemeralPublicKey(d); BdfDictionary tpDict = d.getOptionalDictionary(SESSION_KEY_TRANSPORT_PROPERTIES); Map transportProperties = @@ -162,7 +159,7 @@ class SessionParserImpl implements SessionParser { } private int getState(BdfDictionary d) throws FormatException { - return d.getLong(SESSION_KEY_STATE).intValue(); + return d.getInt(SESSION_KEY_STATE); } private SessionId getSessionId(BdfDictionary d) throws FormatException { @@ -177,9 +174,8 @@ class SessionParserImpl implements SessionParser { return b == null ? null : new MessageId(b); } - private GroupId getGroupId(BdfDictionary d, String key) - throws FormatException { - return new GroupId(d.getRaw(key)); + private GroupId getGroupId(BdfDictionary d) throws FormatException { + return new GroupId(d.getRaw(SESSION_KEY_GROUP_ID)); } private Author getAuthor(BdfDictionary d, String key) @@ -193,23 +189,22 @@ class SessionParserImpl implements SessionParser { if (d == null) return null; Map map = new HashMap<>(d.size()); for (String key : d.keySet()) { - map.put(new TransportId(key), - new KeySetId(d.getLong(key).intValue())); + map.put(new TransportId(key), new KeySetId(d.getInt(key))); } return map; } @Nullable - private PublicKey getEphemeralPublicKey(BdfDictionary d, String key) - throws FormatException { - byte[] keyBytes = d.getOptionalRaw(key); + private PublicKey getEphemeralPublicKey(BdfDictionary d) + throws FormatException { + byte[] keyBytes = d.getOptionalRaw(SESSION_KEY_EPHEMERAL_PUBLIC_KEY); return keyBytes == null ? null : new AgreementPublicKey(keyBytes); } @Nullable - private PrivateKey getEphemeralPrivateKey(BdfDictionary d, String key) - throws FormatException { - byte[] keyBytes = d.getOptionalRaw(key); + private PrivateKey getEphemeralPrivateKey(BdfDictionary d) + throws FormatException { + byte[] keyBytes = d.getOptionalRaw(SESSION_KEY_EPHEMERAL_PRIVATE_KEY); return keyBytes == null ? null : new AgreementPrivateKey(keyBytes); } } diff --git a/briar-core/src/main/java/org/briarproject/briar/messaging/MessagingManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/messaging/MessagingManagerImpl.java index af0460fd9..0a6a9c055 100644 --- a/briar-core/src/main/java/org/briarproject/briar/messaging/MessagingManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/messaging/MessagingManagerImpl.java @@ -182,7 +182,7 @@ class MessagingManagerImpl implements MessagingManager, IncomingMessageHook, try { BdfDictionary metaDict = metadataParser.parse(meta); // Message type is null for version 0.0 private messages - Long messageType = metaDict.getOptionalLong(MSG_KEY_MSG_TYPE); + Integer messageType = metaDict.getOptionalInt(MSG_KEY_MSG_TYPE); if (messageType == null) { incomingPrivateMessage(txn, m, metaDict, true, emptyList()); } else if (messageType == PRIVATE_MESSAGE) { @@ -371,7 +371,7 @@ class MessagingManagerImpl implements MessagingManager, IncomingMessageHook, try { BdfDictionary meta = clientHelper.getGroupMetadataAsDictionary(txn, g); - return new ContactId(meta.getLong(GROUP_KEY_CONTACT_ID).intValue()); + return new ContactId(meta.getInt(GROUP_KEY_CONTACT_ID)); } catch (FormatException e) { throw new DbException(e); } @@ -381,7 +381,7 @@ class MessagingManagerImpl implements MessagingManager, IncomingMessageHook, public ContactId getContactId(GroupId g) throws DbException { try { BdfDictionary meta = clientHelper.getGroupMetadataAsDictionary(g); - return new ContactId(meta.getLong(GROUP_KEY_CONTACT_ID).intValue()); + return new ContactId(meta.getInt(GROUP_KEY_CONTACT_ID)); } catch (FormatException e) { throw new DbException(e); } @@ -419,7 +419,7 @@ class MessagingManagerImpl implements MessagingManager, IncomingMessageHook, if (meta == null) continue; try { // Message type is null for version 0.0 private messages - Long messageType = meta.getOptionalLong(MSG_KEY_MSG_TYPE); + Integer messageType = meta.getOptionalInt(MSG_KEY_MSG_TYPE); if (messageType != null && messageType != PRIVATE_MESSAGE) continue; long timestamp = meta.getLong(MSG_KEY_TIMESTAMP); @@ -453,7 +453,8 @@ class MessagingManagerImpl implements MessagingManager, IncomingMessageHook, Map messages = clientHelper.getMessageMetadataAsDictionary(txn, g); for (Entry entry : messages.entrySet()) { - Long type = entry.getValue().getOptionalLong(MSG_KEY_MSG_TYPE); + Integer type = + entry.getValue().getOptionalInt(MSG_KEY_MSG_TYPE); if (type == null || type == PRIVATE_MESSAGE) result.add(entry.getKey()); } @@ -527,7 +528,7 @@ class MessagingManagerImpl implements MessagingManager, IncomingMessageHook, try { BdfDictionary meta = clientHelper.getMessageMetadataAsDictionary(txn, m); - Long messageType = meta.getOptionalLong(MSG_KEY_MSG_TYPE); + Integer messageType = meta.getOptionalInt(MSG_KEY_MSG_TYPE); if (messageType != null && messageType == PRIVATE_MESSAGE) { for (AttachmentHeader h : parseAttachmentHeaders(g, meta)) { try { @@ -554,7 +555,7 @@ class MessagingManagerImpl implements MessagingManager, IncomingMessageHook, int unreadCount = 0; for (Entry entry : metadata.entrySet()) { BdfDictionary meta = entry.getValue(); - Long messageType = meta.getOptionalLong(MSG_KEY_MSG_TYPE); + Integer messageType = meta.getOptionalInt(MSG_KEY_MSG_TYPE); if (messageType == null || messageType == PRIVATE_MESSAGE) { msgCount++; if (!meta.getBoolean(MSG_KEY_READ)) unreadCount++; diff --git a/briar-core/src/main/java/org/briarproject/briar/messaging/PrivateMessageValidator.java b/briar-core/src/main/java/org/briarproject/briar/messaging/PrivateMessageValidator.java index 161ea062f..83e8b3036 100644 --- a/briar-core/src/main/java/org/briarproject/briar/messaging/PrivateMessageValidator.java +++ b/briar-core/src/main/java/org/briarproject/briar/messaging/PrivateMessageValidator.java @@ -84,7 +84,7 @@ class PrivateMessageValidator implements MessageValidator { context = validateLegacyPrivateMessage(m, list); } else { // Private message or attachment - int messageType = list.getLong(0).intValue(); + int messageType = list.getInt(0); if (messageType == PRIVATE_MESSAGE) { if (!reader.eof()) throw new FormatException(); context = validatePrivateMessage(m, list); diff --git a/briar-core/src/main/java/org/briarproject/briar/privategroup/GroupMessageValidator.java b/briar-core/src/main/java/org/briarproject/briar/privategroup/GroupMessageValidator.java index 02abed607..0ca99a1f2 100644 --- a/briar-core/src/main/java/org/briarproject/briar/privategroup/GroupMessageValidator.java +++ b/briar-core/src/main/java/org/briarproject/briar/privategroup/GroupMessageValidator.java @@ -63,7 +63,7 @@ class GroupMessageValidator extends BdfMessageValidator { checkSize(body, 4, 6); // Message type (int) - int type = body.getLong(0).intValue(); + int type = body.getInt(0); // Member (author) BdfList memberList = body.getList(1); diff --git a/briar-core/src/main/java/org/briarproject/briar/privategroup/PrivateGroupManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/privategroup/PrivateGroupManagerImpl.java index 3a5ca662a..088cbc4ce 100644 --- a/briar-core/src/main/java/org/briarproject/briar/privategroup/PrivateGroupManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/privategroup/PrivateGroupManagerImpl.java @@ -366,7 +366,7 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook // parse the metadata for (Entry entry : metadata.entrySet()) { BdfDictionary meta = entry.getValue(); - if (meta.getLong(KEY_TYPE) == JOIN.getInt()) { + if (meta.getInt(KEY_TYPE) == JOIN.getInt()) { headers.add(getJoinMessageHeader(txn, g, entry.getKey(), meta, authorInfos)); } else { @@ -530,8 +530,7 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook BdfList body, BdfDictionary meta) throws DbException, FormatException { - MessageType type = - MessageType.valueOf(meta.getLong(KEY_TYPE).intValue()); + MessageType type = MessageType.valueOf(meta.getInt(KEY_TYPE)); switch (type) { case JOIN: handleJoinMessage(txn, m, meta); @@ -576,8 +575,8 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook .getMessageMetadataAsDictionary(txn, parentId); if (timestamp <= parentMeta.getLong(KEY_TIMESTAMP)) throw new FormatException(); - MessageType parentType = MessageType - .valueOf(parentMeta.getLong(KEY_TYPE).intValue()); + MessageType parentType = + MessageType.valueOf(parentMeta.getInt(KEY_TYPE)); if (parentType != POST) throw new FormatException(); } @@ -592,8 +591,8 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook if (!getAuthor(meta).equals(getAuthor(previousMeta))) throw new FormatException(); // previous message must be a POST or JOIN - MessageType previousType = MessageType - .valueOf(previousMeta.getLong(KEY_TYPE).intValue()); + MessageType previousType = + MessageType.valueOf(previousMeta.getInt(KEY_TYPE)); if (previousType != JOIN && previousType != POST) throw new FormatException(); // track message and broadcast event @@ -641,8 +640,7 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook private Visibility getVisibility(BdfDictionary meta) throws FormatException { - return Visibility - .valueOf(meta.getLong(GROUP_KEY_VISIBILITY).intValue()); + return Visibility.valueOf(meta.getInt(GROUP_KEY_VISIBILITY)); } } diff --git a/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImpl.java index cd78802a5..26742b104 100644 --- a/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImpl.java @@ -712,9 +712,9 @@ class GroupInvitationManagerImpl extends ConversationClientImpl // get all sessions and their states Map sessions = new HashMap<>(); for (BdfDictionary d : metadata.values()) { - if (!sessionParser.isSession(d)) continue; Session session; try { + if (!sessionParser.isSession(d)) continue; session = sessionParser.parseSession(g, d); } catch (FormatException e) { throw new DbException(e); @@ -776,13 +776,12 @@ class GroupInvitationManagerImpl extends ConversationClientImpl // assign protocol messages to their sessions for (Entry entry : metadata.entrySet()) { - // skip all sessions, we are only interested in messages - BdfDictionary d = entry.getValue(); - if (sessionParser.isSession(d)) continue; - // parse message metadata and skip messages not visible in UI MessageMetadata m; try { + // skip all sessions, we are only interested in messages + BdfDictionary d = entry.getValue(); + if (sessionParser.isSession(d)) continue; m = messageParser.parseMetadata(d); } catch (FormatException e) { throw new DbException(e); diff --git a/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/GroupInvitationValidator.java b/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/GroupInvitationValidator.java index f04d38fa5..616bfad25 100644 --- a/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/GroupInvitationValidator.java +++ b/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/GroupInvitationValidator.java @@ -56,7 +56,7 @@ class GroupInvitationValidator extends BdfMessageValidator { @Override protected BdfMessageContext validateMessage(Message m, Group g, BdfList body) throws FormatException { - MessageType type = MessageType.fromValue(body.getLong(0).intValue()); + MessageType type = MessageType.fromValue(body.getInt(0)); switch (type) { case INVITE: return validateInviteMessage(m, body); diff --git a/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/MessageParserImpl.java b/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/MessageParserImpl.java index 244ac6853..33725f426 100644 --- a/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/MessageParserImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/MessageParserImpl.java @@ -71,8 +71,8 @@ class MessageParserImpl implements MessageParser { @Override public MessageMetadata parseMetadata(BdfDictionary meta) throws FormatException { - MessageType type = MessageType.fromValue( - meta.getLong(MSG_KEY_MESSAGE_TYPE).intValue()); + MessageType type = + MessageType.fromValue(meta.getInt(MSG_KEY_MESSAGE_TYPE)); GroupId privateGroupId = new GroupId(meta.getRaw(MSG_KEY_PRIVATE_GROUP_ID)); long timestamp = meta.getLong(MSG_KEY_TIMESTAMP); diff --git a/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/SessionParser.java b/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/SessionParser.java index 976c5e3df..f59153888 100644 --- a/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/SessionParser.java +++ b/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/SessionParser.java @@ -15,7 +15,7 @@ interface SessionParser { Role getRole(BdfDictionary d) throws FormatException; - boolean isSession(BdfDictionary d); + boolean isSession(BdfDictionary d) throws FormatException; Session parseSession(GroupId contactGroupId, BdfDictionary d) throws FormatException; diff --git a/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/SessionParserImpl.java b/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/SessionParserImpl.java index a21c80273..4d316ee2e 100644 --- a/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/SessionParserImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/SessionParserImpl.java @@ -45,11 +45,11 @@ class SessionParserImpl implements SessionParser { @Override public Role getRole(BdfDictionary d) throws FormatException { - return Role.fromValue(d.getLong(SESSION_KEY_ROLE).intValue()); + return Role.fromValue(d.getInt(SESSION_KEY_ROLE)); } @Override - public boolean isSession(BdfDictionary d) { + public boolean isSession(BdfDictionary d) throws FormatException { return d.getBoolean(SESSION_KEY_IS_SESSION, false); } @@ -101,7 +101,7 @@ class SessionParserImpl implements SessionParser { } private int getState(BdfDictionary d) throws FormatException { - return d.getLong(SESSION_KEY_STATE).intValue(); + return d.getInt(SESSION_KEY_STATE); } private GroupId getPrivateGroupId(BdfDictionary d) throws FormatException { diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/MessageParserImpl.java b/briar-core/src/main/java/org/briarproject/briar/sharing/MessageParserImpl.java index dd8768bcc..124aa4d84 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/MessageParserImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/MessageParserImpl.java @@ -64,8 +64,8 @@ abstract class MessageParserImpl @Override public MessageMetadata parseMetadata(BdfDictionary meta) throws FormatException { - MessageType type = MessageType - .fromValue(meta.getLong(MSG_KEY_MESSAGE_TYPE).intValue()); + MessageType type = + MessageType.fromValue(meta.getInt(MSG_KEY_MESSAGE_TYPE)); GroupId shareableId = new GroupId(meta.getRaw(MSG_KEY_SHAREABLE_ID)); long timestamp = meta.getLong(MSG_KEY_TIMESTAMP); boolean local = meta.getBoolean(MSG_KEY_LOCAL); diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/SessionParser.java b/briar-core/src/main/java/org/briarproject/briar/sharing/SessionParser.java index 7eb84706b..3235a73dc 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/SessionParser.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/SessionParser.java @@ -13,7 +13,7 @@ interface SessionParser { BdfDictionary getAllSessionsQuery(); - boolean isSession(BdfDictionary d); + boolean isSession(BdfDictionary d) throws FormatException; Session parseSession(GroupId contactGroupId, BdfDictionary d) throws FormatException; diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/SessionParserImpl.java b/briar-core/src/main/java/org/briarproject/briar/sharing/SessionParserImpl.java index a29b25e0c..027b65850 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/SessionParserImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/SessionParserImpl.java @@ -40,7 +40,7 @@ class SessionParserImpl implements SessionParser { } @Override - public boolean isSession(BdfDictionary d) { + public boolean isSession(BdfDictionary d) throws FormatException { return d.getBoolean(SESSION_KEY_IS_SESSION, false); } @@ -54,7 +54,7 @@ class SessionParserImpl implements SessionParser { } private int getState(BdfDictionary d) throws FormatException { - return d.getLong(SESSION_KEY_STATE).intValue(); + return d.getInt(SESSION_KEY_STATE); } private GroupId getShareableId(BdfDictionary d) throws FormatException { diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/SharingManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/sharing/SharingManagerImpl.java index b34b9965e..9b74a2b08 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/SharingManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/SharingManagerImpl.java @@ -604,9 +604,9 @@ abstract class SharingManagerImpl // get all sessions and their states Map sessions = new HashMap<>(); for (BdfDictionary d : metadata.values()) { - if (!sessionParser.isSession(d)) continue; Session session; try { + if (!sessionParser.isSession(d)) continue; session = sessionParser.parseSession(contactGroup, d); } catch (FormatException e) { throw new DbException(e); @@ -668,13 +668,12 @@ abstract class SharingManagerImpl // assign protocol messages to their sessions for (Entry entry : metadata.entrySet()) { - // skip all sessions, we are only interested in messages - BdfDictionary d = entry.getValue(); - if (sessionParser.isSession(d)) continue; - // parse message metadata and skip messages not visible in UI MessageMetadata m; try { + // skip all sessions, we are only interested in messages + BdfDictionary d = entry.getValue(); + if (sessionParser.isSession(d)) continue; m = messageParser.parseMetadata(d); } catch (FormatException e) { throw new DbException(e); diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/SharingValidator.java b/briar-core/src/main/java/org/briarproject/briar/sharing/SharingValidator.java index e03af82d7..cf68fe62d 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/SharingValidator.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/SharingValidator.java @@ -40,7 +40,7 @@ abstract class SharingValidator extends BdfMessageValidator { @Override protected BdfMessageContext validateMessage(Message m, Group g, BdfList body) throws FormatException { - MessageType type = MessageType.fromValue(body.getLong(0).intValue()); + MessageType type = MessageType.fromValue(body.getInt(0)); switch (type) { case INVITE: return validateInviteMessage(m, body); diff --git a/briar-core/src/test/java/org/briarproject/briar/privategroup/GroupMessageValidatorTest.java b/briar-core/src/test/java/org/briarproject/briar/privategroup/GroupMessageValidatorTest.java index b8ed89b16..3932d1c99 100644 --- a/briar-core/src/test/java/org/briarproject/briar/privategroup/GroupMessageValidatorTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/privategroup/GroupMessageValidatorTest.java @@ -651,7 +651,7 @@ public class GroupMessageValidatorTest extends ValidatorTestCase { MessageType type, BdfList member, Collection dependencies) throws FormatException { BdfDictionary d = c.getDictionary(); - assertEquals(type.getInt(), d.getLong(KEY_TYPE).intValue()); + assertEquals(type.getInt(), d.getInt(KEY_TYPE).intValue()); assertEquals(message.getTimestamp(), d.getLong(KEY_TIMESTAMP).longValue()); assertFalse(d.getBoolean(KEY_READ));