diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e97c6ee --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +target/ +*.class diff --git a/pom.xml b/pom.xml index de6b1ce..140c50b 100644 --- a/pom.xml +++ b/pom.xml @@ -20,19 +20,19 @@ com.google.guava guava - 32.1.1-android + 33.6.0-android com.google.crypto.tink tink-android - 1.10.0 + 1.23.0 org.bouncycastle - bcprov-jdk15on - 1.69 + bcprov-jdk18on + 1.84 jar @@ -42,10 +42,8 @@ %regex[.*.class] - 1.1.2 - 3.12.0 - 3.1.0 - 3.2.1 + 3.12.0 + 3.4.0 UTF-8 @@ -126,6 +124,29 @@ --> 8 8 + true + + -J--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED + -J--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED + -J--add-exports=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED + -J--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED + -J--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED + -J--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED + -J--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED + -J--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED + -J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED + -J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED + -J--add-opens=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED + -J--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED + -J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED + -J--add-opens=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED + -J--add-opens=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED + -J--add-opens=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED + -J--add-opens=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED + -J--add-opens=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED + -J--add-opens=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED + -J--add-opens=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED + @@ -133,7 +154,7 @@ maven-compiler-plugin - 3.8.1 + 3.15.0 1.8 1.8 @@ -145,14 +166,14 @@ com.google.errorprone error_prone_core - 2.14.0 + 2.49.0 maven-jar-plugin - 3.2.0 + 3.5.0 maven-source-plugin @@ -192,15 +213,15 @@ maven-dependency-plugin - 3.1.1 + 3.11.0 maven-antrun-plugin - 1.6 + 3.2.0 maven-surefire-plugin - 2.22.2 + 3.5.6 ${test.include} @@ -216,7 +237,7 @@ org.apache.maven.plugins maven-enforcer-plugin - 3.0.0-M3 + 3.6.3 diff --git a/src/com/google/cose/utils/CborUtils.java b/src/com/google/cose/utils/CborUtils.java index 67739cc..bdee45c 100644 --- a/src/com/google/cose/utils/CborUtils.java +++ b/src/com/google/cose/utils/CborUtils.java @@ -46,8 +46,18 @@ public class CborUtils { * @return DataItem cbor object */ public static DataItem decode(final byte[] data) throws CborException { + if (data == null) { + throw new CborException("data cannot be null"); + } final ByteArrayInputStream bais = new ByteArrayInputStream(data); - final List dataItems = new CborDecoder(bais).decode(); + final CborDecoder decoder = new CborDecoder(bais); + decoder.setMaxPreallocationSize(data.length); + final List dataItems; + try { + dataItems = new CborDecoder(bais).decode(); + } catch (OutOfMemoryError e) { + throw new CborException("CBOR declared size exceeds input length", e); + } if (dataItems.size() != 1) { throw new CborException("Byte stream cannot be decoded properly. Expected 1 item, found " + dataItems.size()); @@ -61,6 +71,9 @@ public static DataItem decode(final byte[] data) throws CborException { * @return encoded bytes */ public static byte[] encode(final DataItem dataItem) throws CborException { + if (dataItem == null) { + throw new CborException("dataItem cannot be null"); + } final ByteArrayOutputStream baos = new ByteArrayOutputStream(); CborEncoder encoder = new CborEncoder(baos); encoder.encode(dataItem); @@ -73,6 +86,9 @@ public static byte[] encode(final DataItem dataItem) throws CborException { * @return Map object */ public static Map asMap(final DataItem dataItem) throws CborException { + if (dataItem == null) { + throw new CborException("dataItem cannot be null"); + } if (dataItem.getMajorType() != MajorType.MAP) { throw new CborException( String.format("Expected a map, got %s", dataItem.getMajorType().name())); @@ -86,6 +102,9 @@ public static Map asMap(final DataItem dataItem) throws CborException { * @return Array object */ public static Array asArray(final DataItem dataItem) throws CborException { + if (dataItem == null) { + throw new CborException("dataItem cannot be null"); + } if (dataItem.getMajorType() != MajorType.ARRAY) { throw new CborException( String.format("Expected an array, got %s", dataItem.getMajorType().name())); @@ -95,6 +114,9 @@ public static Array asArray(final DataItem dataItem) throws CborException { public static Array asArray(final DataItem dataItem, final int length, final String semanticName) throws CborException { + if (semanticName == null) { + throw new CborException("semanticName cannot be null"); + } Array item = asArray(dataItem); if (item.getDataItems().size() != length) { throw new CborException(String.format("Expected %s to be of size %d, recieved %d", @@ -118,6 +140,9 @@ public static List getDataItems(final DataItem dataItem) throws CborEx * @return ByteString object */ public static ByteString asByteString(final DataItem dataItem) throws CborException { + if (dataItem == null) { + throw new CborException("dataItem cannot be null"); + } if (dataItem.getMajorType() != MajorType.BYTE_STRING) { throw new CborException( String.format("Expected a byte string, got %s", dataItem.getMajorType().name())); @@ -140,6 +165,9 @@ public static byte[] getBytes(final DataItem dataItem) throws CborException { * @return UnicodeString object */ public static UnicodeString asUnicodeString(final DataItem dataItem) throws CborException { + if (dataItem == null) { + throw new CborException("dataItem cannot be null"); + } if (dataItem.getMajorType() != MajorType.UNICODE_STRING) { throw new CborException( String.format("Expected a unicode string, got %s", dataItem.getMajorType().name())); @@ -163,6 +191,9 @@ public static String getString(final DataItem dataItem) throws CborException { * @throws CborException if dataItem is neither UnsignedInteger not NegativeInteger */ public static int asInteger(final DataItem dataItem) throws CborException { + if (dataItem == null) { + throw new CborException("dataItem cannot be null"); + } if (dataItem.getMajorType() == MajorType.UNSIGNED_INTEGER) { return ((UnsignedInteger) dataItem).getValue().intValue(); } @@ -179,6 +210,9 @@ public static int asInteger(final DataItem dataItem) throws CborException { * @return true if the item represents NULL */ public static boolean isNull(final DataItem item) { + if (item == null) { + return false; + } return (item.getMajorType() == MajorType.SPECIAL) && ((Special) item).getSpecialType() == SpecialType.SIMPLE_VALUE && ((SimpleValue) item).getSimpleValueType() == SimpleValueType.NULL; diff --git a/test/com/google/cose/utils/CborUtilsTest.java b/test/com/google/cose/utils/CborUtilsTest.java new file mode 100644 index 0000000..496a345 --- /dev/null +++ b/test/com/google/cose/utils/CborUtilsTest.java @@ -0,0 +1,153 @@ +package com.google.cose.utils; + +import co.nstant.in.cbor.CborException; +import co.nstant.in.cbor.model.Array; +import co.nstant.in.cbor.model.ByteString; +import co.nstant.in.cbor.model.DataItem; +import co.nstant.in.cbor.model.Map; +import co.nstant.in.cbor.model.NegativeInteger; +import co.nstant.in.cbor.model.SimpleValue; +import co.nstant.in.cbor.model.UnicodeString; +import co.nstant.in.cbor.model.UnsignedInteger; +import org.junit.Assert; +import org.junit.Test; + +public class CborUtilsTest { + @Test + public void testDecodeNullThrows() { + Assert.assertThrows(CborException.class, () -> CborUtils.decode(null)); + } + + @Test + public void testEncodeNullThrows() { + Assert.assertThrows(CborException.class, () -> CborUtils.encode(null)); + } + + @Test + public void testAsMapNullThrows() { + Assert.assertThrows(CborException.class, () -> CborUtils.asMap(null)); + } + + @Test + public void testAsArrayNullThrows() { + Assert.assertThrows(CborException.class, () -> CborUtils.asArray(null)); + } + + @Test + public void testAsArrayThreeArgsNullSemanticNameThrows() { + Assert.assertThrows(CborException.class, () -> CborUtils.asArray(new Array(), 0, null)); + } + + @Test + public void testAsArrayThreeArgsNullDataItemThrows() { + Assert.assertThrows(CborException.class, () -> CborUtils.asArray(null, 0, "name")); + } + + @Test + public void testAsByteStringNullThrows() { + Assert.assertThrows(CborException.class, () -> CborUtils.asByteString(null)); + } + + @Test + public void testAsUnicodeStringNullThrows() { + Assert.assertThrows(CborException.class, () -> CborUtils.asUnicodeString(null)); + } + + @Test + public void testAsIntegerNullThrows() { + Assert.assertThrows(CborException.class, () -> CborUtils.asInteger(null)); + } + + @Test + public void testIsNullReturnsFalseForNull() { + Assert.assertFalse(CborUtils.isNull(null)); + } + + @Test + public void testEncodeDecode() throws CborException { + UnicodeString item = new UnicodeString("test"); + byte[] encoded = CborUtils.encode(item); + DataItem decoded = CborUtils.decode(encoded); + Assert.assertEquals(item, decoded); + } + + @Test + public void testAsMapPositive() throws CborException { + Map map = new Map(); + Assert.assertEquals(map, CborUtils.asMap(map)); + } + + @Test + public void testAsMapNegativeWrongType() { + Assert.assertThrows(CborException.class, () -> CborUtils.asMap(new Array())); + } + + @Test + public void testAsArrayPositive() throws CborException { + Array array = new Array(); + Assert.assertEquals(array, CborUtils.asArray(array)); + } + + @Test + public void testAsArrayNegativeWrongType() { + Assert.assertThrows(CborException.class, () -> CborUtils.asArray(new Map())); + } + + @Test + public void testAsArrayThreeArgsPositive() throws CborException { + Array array = new Array(); + array.add(new UnicodeString("item")); + Assert.assertEquals(array, CborUtils.asArray(array, 1, "test-array")); + } + + @Test + public void testAsArrayThreeArgsWrongSizeThrows() { + Array array = new Array(); + Assert.assertThrows(CborException.class, () -> CborUtils.asArray(array, 1, "test-array")); + } + + @Test + public void testAsByteStringPositive() throws CborException { + ByteString bs = new ByteString(new byte[]{1, 2, 3}); + Assert.assertEquals(bs, CborUtils.asByteString(bs)); + Assert.assertArrayEquals(new byte[]{1, 2, 3}, CborUtils.getBytes(bs)); + } + + @Test + public void testAsByteStringNegativeWrongType() { + Assert.assertThrows(CborException.class, () -> CborUtils.asByteString(new UnicodeString("not bytes"))); + } + + @Test + public void testAsUnicodeStringPositive() throws CborException { + UnicodeString us = new UnicodeString("hello"); + Assert.assertEquals(us, CborUtils.asUnicodeString(us)); + Assert.assertEquals("hello", CborUtils.getString(us)); + } + + @Test + public void testAsUnicodeStringNegativeWrongType() { + Assert.assertThrows(CborException.class, () -> CborUtils.asUnicodeString(new ByteString(new byte[]{1}))); + } + + @Test + public void testAsIntegerPositive() throws CborException { + UnsignedInteger ui = new UnsignedInteger(123); + Assert.assertEquals(123, CborUtils.asInteger(ui)); + + NegativeInteger ni = new NegativeInteger(-123); + Assert.assertEquals(-123, CborUtils.asInteger(ni)); + } + + @Test + public void testAsIntegerNegativeWrongType() { + Assert.assertThrows(CborException.class, () -> CborUtils.asInteger(new UnicodeString("not a number"))); + } + + @Test + public void testIsNullPositive() { + Assert.assertTrue(CborUtils.isNull(SimpleValue.NULL)); + Assert.assertFalse(CborUtils.isNull(SimpleValue.TRUE)); + Assert.assertFalse(CborUtils.isNull(new UnicodeString("not null"))); + } +}