diff --git a/org.hl7.fhir.dstu2/src/main/java/org/hl7/fhir/dstu2/model/Base64BinaryType.java b/org.hl7.fhir.dstu2/src/main/java/org/hl7/fhir/dstu2/model/Base64BinaryType.java index fc0b00ca28..76260ef986 100644 --- a/org.hl7.fhir.dstu2/src/main/java/org/hl7/fhir/dstu2/model/Base64BinaryType.java +++ b/org.hl7.fhir.dstu2/src/main/java/org/hl7/fhir/dstu2/model/Base64BinaryType.java @@ -99,7 +99,7 @@ public String fhirType() { * @throws DataFormatException */ public void checkValidBase64(String toCheck) throws DataFormatException { - if (!Base64.isBase64(toCheck.getBytes())) { + if (!org.hl7.fhir.utilities.Base64.isBase64(toCheck.getBytes())) { throw new DataFormatException(""); } } diff --git a/org.hl7.fhir.dstu2016may/src/main/java/org/hl7/fhir/dstu2016may/model/Base64BinaryType.java b/org.hl7.fhir.dstu2016may/src/main/java/org/hl7/fhir/dstu2016may/model/Base64BinaryType.java index 4e5ac9c13c..d4a087dd23 100644 --- a/org.hl7.fhir.dstu2016may/src/main/java/org/hl7/fhir/dstu2016may/model/Base64BinaryType.java +++ b/org.hl7.fhir.dstu2016may/src/main/java/org/hl7/fhir/dstu2016may/model/Base64BinaryType.java @@ -100,7 +100,7 @@ public String fhirType() { * @throws DataFormatException */ public void checkValidBase64(String toCheck) throws DataFormatException { - if (!Base64.isBase64(toCheck.getBytes())) { + if (!org.hl7.fhir.utilities.Base64.isBase64(toCheck.getBytes())) { throw new DataFormatException(""); } } diff --git a/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/model/Base64BinaryType.java b/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/model/Base64BinaryType.java index 99b7f325db..d21204884c 100644 --- a/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/model/Base64BinaryType.java +++ b/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/model/Base64BinaryType.java @@ -152,7 +152,7 @@ public boolean isEmpty() { * @throws DataFormatException */ public void checkValidBase64(String toCheck) throws DataFormatException { - if (!Base64.isBase64(toCheck.getBytes())) { + if (!org.hl7.fhir.utilities.Base64.isBase64(toCheck.getBytes())) { throw new DataFormatException(""); } } diff --git a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/model/Base64BinaryType.java b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/model/Base64BinaryType.java index 7cdceedf78..5b8e67df84 100644 --- a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/model/Base64BinaryType.java +++ b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/model/Base64BinaryType.java @@ -152,7 +152,7 @@ public boolean isEmpty() { * @throws DataFormatException */ public void checkValidBase64(String toCheck) throws DataFormatException { - if (!Base64.isBase64(toCheck.getBytes())) { + if (!org.hl7.fhir.utilities.Base64.isBase64(toCheck.getBytes())) { throw new DataFormatException(""); } } diff --git a/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/model/Base64BinaryType.java b/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/model/Base64BinaryType.java index a1c73f8216..6d6ee67da7 100644 --- a/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/model/Base64BinaryType.java +++ b/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/model/Base64BinaryType.java @@ -156,7 +156,7 @@ public String primitiveValue() { * @throws DataFormatException */ public void checkValidBase64(String toCheck) throws DataFormatException { - if (!Base64.isBase64(toCheck.getBytes())) { + if (!org.hl7.fhir.utilities.Base64.isBase64(toCheck.getBytes())) { throw new DataFormatException(""); } } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/Base64BinaryType.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/Base64BinaryType.java index 4e83d1a8b1..1e1650ee8b 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/Base64BinaryType.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/Base64BinaryType.java @@ -156,7 +156,7 @@ public String primitiveValue() { * @throws DataFormatException */ public void checkValidBase64(String toCheck) throws DataFormatException { - if (!Base64.isBase64(toCheck.getBytes())) { + if (!org.hl7.fhir.utilities.Base64.isBase64(toCheck.getBytes())) { throw new DataFormatException(""); } } diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/Base64.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/Base64.java new file mode 100644 index 0000000000..2d5f10767a --- /dev/null +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/Base64.java @@ -0,0 +1,40 @@ +package org.hl7.fhir.utilities; + +/** + * This is a partial duplication of org.apache.commons.codec.binary.Base64 + * + * It exists because Android compatibility only supports version 1.2 of that + * library, which only has the deprecated isArrayByteBase64. The use of + * isBase64 from this class will allow us to avoid using a deprecated method + * or hacking a solution that involves catching exceptions on decoding. + */ +public class Base64 { + + private static final byte[] DECODE_TABLE = new byte[]{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, 62, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51}; + + public static boolean isBase64(byte octet) { + return octet == 61 || octet >= 0 && octet < DECODE_TABLE.length && DECODE_TABLE[octet] != -1; + } + + public static boolean isBase64(byte[] arrayOctet) { + for(int i = 0; i < arrayOctet.length; ++i) { + if (!isBase64(arrayOctet[i]) && !isWhiteSpace(arrayOctet[i])) { + return false; + } + } + + return true; + } + + protected static boolean isWhiteSpace(byte byteToCheck) { + switch (byteToCheck) { + case 9: + case 10: + case 13: + case 32: + return true; + default: + return false; + } + } +} diff --git a/org.hl7.fhir.utilities/src/test/java/Base64Tests.java b/org.hl7.fhir.utilities/src/test/java/Base64Tests.java new file mode 100644 index 0000000000..dab656b987 --- /dev/null +++ b/org.hl7.fhir.utilities/src/test/java/Base64Tests.java @@ -0,0 +1,27 @@ +import org.junit.jupiter.api.Test; + +import org.hl7.fhir.utilities.Base64; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +public class Base64Tests { + @Test + public void testIsArrayByteBase64() { + assertFalse(Base64.isBase64(new byte[] { Byte.MIN_VALUE })); + assertFalse(Base64.isBase64(new byte[] { -125 })); + assertFalse(Base64.isBase64(new byte[] { -10 })); + assertFalse(Base64.isBase64(new byte[] { 0 })); + assertFalse(Base64.isBase64(new byte[] { 64, Byte.MAX_VALUE })); + assertFalse(Base64.isBase64(new byte[] { Byte.MAX_VALUE })); + + assertTrue(Base64.isBase64(new byte[] { 'A' })); + + assertFalse(Base64.isBase64(new byte[] { 'A', Byte.MIN_VALUE })); + + assertTrue(Base64.isBase64(new byte[] { 'A', 'Z', 'a' })); + assertTrue(Base64.isBase64(new byte[] { '/', '=', '+' })); + + assertFalse(Base64.isBase64(new byte[] { '$' })); + } +}