From a401798e5e8f3142b49858c958bfcb9d4a764ddb Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Tue, 04 Sep 2012 16:29:01 +0000
Subject: [PATCH] Fix OPENDJ-369: Consider exposing base 64 encode/decode APIs

---
 opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPCompare.java |    4 
 opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ByteSequence.java          |    8 +
 /dev/null                                                                                  |  196 --------------------------------
 opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldif/AbstractLDIFReader.java    |    7 
 opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ByteString.java            |   26 ++++
 opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ByteStringBuilder.java     |   17 ++
 opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/Base64.java                |   16 +-
 opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/ByteStringTestCase.java    |   76 ++++++++++++
 opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/ByteSequenceTestCase.java  |    7 +
 opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldif/AbstractLDIFWriter.java    |    3 
 10 files changed, 147 insertions(+), 213 deletions(-)

diff --git a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/Base64.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/Base64.java
similarity index 96%
rename from opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/Base64.java
rename to opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/Base64.java
index c2f7ec3..5686d5b 100755
--- a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/Base64.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/Base64.java
@@ -24,7 +24,7 @@
  *      Copyright 2006-2009 Sun Microsystems, Inc.
  *      Portions copyright 2012 ForgeRock AS.
  */
-package com.forgerock.opendj.util;
+package org.forgerock.opendj.ldap;
 
 import static com.forgerock.opendj.util.Validator.ensureNotNull;
 import static org.forgerock.opendj.ldap.CoreMessages.ERR_BASE64_DECODE_INVALID_CHARACTER;
@@ -32,17 +32,19 @@
 
 import org.forgerock.i18n.LocalizableMessage;
 import org.forgerock.i18n.LocalizedIllegalArgumentException;
-import org.forgerock.opendj.ldap.ByteSequence;
-import org.forgerock.opendj.ldap.ByteString;
-import org.forgerock.opendj.ldap.ByteStringBuilder;
 
 /**
  * This class provides methods for performing base64 encoding and decoding.
  * Base64 is a mechanism for encoding binary data in ASCII form by converting
  * sets of three bytes with eight significant bits each to sets of four bytes
  * with six significant bits each.
+ * <p>
+ * <b>NOTE:</b> the JDK class {@link javax.xml.bind.DatatypeConverter} provides
+ * similar functionality, however the methods are better suited to the LDAP SDK.
+ * For example, the JDK encoder does not handle array/offset/len parameters, and
+ * the decoder ignores invalid Base64 data.
  */
-public final class Base64 {
+final class Base64 {
     /**
      * The set of characters that may be used in base64-encoded values.
      */
@@ -61,7 +63,7 @@
      * @throws NullPointerException
      *             If {@code base64} was {@code null}.
      */
-    public static ByteString decode(final String base64) {
+    static ByteString decode(final String base64) {
         ensureNotNull(base64);
 
         // The encoded value must have length that is a multiple of four
@@ -315,7 +317,7 @@
      * @throws NullPointerException
      *             If {@code bytes} was {@code null}.
      */
-    public static String encode(final ByteSequence bytes) {
+    static String encode(final ByteSequence bytes) {
         ensureNotNull(bytes);
 
         final StringBuilder buffer = new StringBuilder(4 * bytes.length() / 3);
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ByteSequence.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ByteSequence.java
index 975b840..63d8453 100755
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ByteSequence.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ByteSequence.java
@@ -260,6 +260,14 @@
     ByteSequence subSequence(int start, int end);
 
     /**
+     * Returns the Base64 encoded string representation of this byte string.
+     *
+     * @return The Base64 encoded string representation of this byte string.
+     * @see ByteString#valueOfBase64(String)
+     */
+    String toBase64String();
+
+    /**
      * Returns a byte array containing the bytes in this sequence in the same
      * order as this sequence. The length of the byte array will be the length
      * of this sequence.
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ByteString.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ByteString.java
index 2b92904..ae874c8 100755
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ByteString.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ByteString.java
@@ -34,6 +34,8 @@
 import java.util.Arrays;
 import java.util.logging.Level;
 
+import org.forgerock.i18n.LocalizedIllegalArgumentException;
+
 import com.forgerock.opendj.util.StaticUtils;
 
 /**
@@ -140,6 +142,23 @@
     }
 
     /**
+     * Returns a byte string containing the Base64 decoded bytes of the provided
+     * string.
+     *
+     * @param s
+     *            The string to use.
+     * @return The byte string containing the Base64 decoded bytes of the
+     *         provided string.
+     * @throws LocalizedIllegalArgumentException
+     *             If the provided string does not contain valid Base64 encoded
+     *             content.
+     * @see #toBase64String()
+     */
+    public static ByteString valueOfBase64(final String s) {
+        return Base64.decode(s);
+    }
+
+    /**
      * Returns a byte string containing the contents of the provided byte array.
      * <p>
      * This method differs from {@link #wrap(byte[])} in that it defensively
@@ -531,6 +550,13 @@
     /**
      * {@inheritDoc}
      */
+    public String toBase64String() {
+        return Base64.encode(this);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
     public byte[] toByteArray() {
         return copyTo(new byte[length]);
     }
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ByteStringBuilder.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ByteStringBuilder.java
index 6ecfd05..7e6d643 100755
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ByteStringBuilder.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/ByteStringBuilder.java
@@ -200,6 +200,15 @@
             return new SubSequence(subOffset + start, end - start);
         }
 
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public String toBase64String() {
+            return Base64.encode(this);
+        }
+
         /**
          * {@inheritDoc}
          */
@@ -899,6 +908,14 @@
     /**
      * {@inheritDoc}
      */
+    @Override
+    public String toBase64String() {
+        return Base64.encode(this);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
     public byte[] toByteArray() {
         return copyTo(new byte[length]);
     }
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldif/AbstractLDIFReader.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldif/AbstractLDIFReader.java
index 27c4178..0b6caf2 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldif/AbstractLDIFReader.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldif/AbstractLDIFReader.java
@@ -55,7 +55,6 @@
 import org.forgerock.opendj.ldap.schema.Syntax;
 import org.forgerock.opendj.ldap.schema.UnknownSchemaElementException;
 
-import com.forgerock.opendj.util.Base64;
 import com.forgerock.opendj.util.Validator;
 
 /**
@@ -258,7 +257,7 @@
                 }
 
                 try {
-                    value = Base64.decode(ldifLine.substring(pos));
+                    value = ByteString.valueOfBase64(ldifLine.substring(pos));
                 } catch (final LocalizedIllegalArgumentException e) {
                     // The value did not have a valid base64-encoding.
                     final LocalizableMessage message =
@@ -608,7 +607,7 @@
 
             final String base64DN = ldifLine.substring(pos);
             try {
-                dnString = Base64.decode(base64DN).toString();
+                dnString = ByteString.valueOfBase64(base64DN).toString();
             } catch (final LocalizedIllegalArgumentException e) {
                 // The value did not have a valid base64-encoding.
                 final LocalizableMessage message =
@@ -663,7 +662,7 @@
             }
 
             try {
-                pair.value = Base64.decode(ldifLine.substring(pos)).toString();
+                pair.value = ByteString.valueOfBase64(ldifLine.substring(pos)).toString();
             } catch (final LocalizedIllegalArgumentException e) {
                 pair.key = null;
                 return ldifLine;
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldif/AbstractLDIFWriter.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldif/AbstractLDIFWriter.java
index be8d3a9..d4b03da 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldif/AbstractLDIFWriter.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldif/AbstractLDIFWriter.java
@@ -39,7 +39,6 @@
 import org.forgerock.opendj.ldap.controls.Control;
 import org.forgerock.opendj.ldap.schema.Schema;
 
-import com.forgerock.opendj.util.Base64;
 import com.forgerock.opendj.util.Validator;
 
 /**
@@ -335,7 +334,7 @@
             builder.setLength(0);
             builder.append(key);
             builder.append(":: ");
-            builder.append(Base64.encode(value));
+            builder.append(value.toBase64String());
         } else {
             builder.append(key);
             builder.append(": ");
diff --git a/opendj3/opendj-ldap-sdk/src/test/java/com/forgerock/opendj/util/Base64TestCase.java b/opendj3/opendj-ldap-sdk/src/test/java/com/forgerock/opendj/util/Base64TestCase.java
deleted file mode 100644
index 9b13da3..0000000
--- a/opendj3/opendj-ldap-sdk/src/test/java/com/forgerock/opendj/util/Base64TestCase.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
- * or http://forgerock.org/license/CDDLv1.0.html.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at legal-notices/CDDLv1_0.txt.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information:
- *      Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- *
- *
- *      Copyright 2010 Sun Microsystems, Inc.
- */
-
-package com.forgerock.opendj.util;
-
-import java.util.Arrays;
-
-import org.forgerock.i18n.LocalizedIllegalArgumentException;
-import org.forgerock.opendj.ldap.ByteString;
-import org.testng.Assert;
-import org.testng.annotations.DataProvider;
-import org.testng.annotations.Test;
-
-/**
- * This class defines a set of tests for the {@link Base64} class.
- */
-public final class Base64TestCase extends UtilTestCase {
-    // Look up table for converting hex chars to byte values.
-    private static final byte[] HEX_TO_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, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1,
-        -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -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, 10, 11, 12, 13, 14, 15, -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 };
-
-    /**
-     * Base 64 invalid test data provider.
-     *
-     * @return Returns an array of invalid encoded base64 data.
-     */
-    @DataProvider(name = "invalidData")
-    public Object[][] createInvalidData() {
-        // FIXME: fix cases ==== and ==x=
-
-        return new Object[][] { { "=" }, { "==" }, { "===" }, { "A" }, { "AA" }, { "AAA" },
-            { "AA`=" }, { "AA~=" }, { "AA!=" }, { "AA@=" }, { "AA#=" }, { "AA$=" }, { "AA%=" },
-            { "AA^=" }, { "AA*=" }, { "AA(=" }, { "AA)=" }, { "AA_=" }, { "AA-=" }, { "AA{=" },
-            { "AA}=" }, { "AA|=" }, { "AA[=" }, { "AA]=" }, { "AA\\=" }, { "AA;=" }, { "AA'=" },
-            { "AA\"=" }, { "AA:=" }, { "AA,=" }, { "AA.=" }, { "AA<=" }, { "AA>=" }, { "AA?=" },
-            { "AA;=" } };
-    }
-
-    /**
-     * Base 64 valid test data provider.
-     *
-     * @return Returns an array of decoded and valid encoded base64 data.
-     */
-    @DataProvider(name = "validData")
-    public Object[][] createValidData() {
-        return new Object[][] {
-            { "", "" },
-            { "00", "AA==" },
-            { "01", "AQ==" },
-            { "02", "Ag==" },
-            { "03", "Aw==" },
-            { "04", "BA==" },
-            { "05", "BQ==" },
-            { "06", "Bg==" },
-            { "07", "Bw==" },
-            { "0000", "AAA=" },
-            { "000000", "AAAA" },
-            { "00000000", "AAAAAA==" },
-            {
-                "000102030405060708090a0b0c0d0e0f" + "101112131415161718191a1b1c1d1e1f"
-                        + "202122232425262728292a2b2c2d2e2f" + "303132333435363738393a3b3c3d3e3f"
-                        + "404142434445464748494a4b4c4d4e4f" + "505152535455565758595a5b5c5d5e5f"
-                        + "606162636465666768696a6b6c6d6e6f" + "707172737475767778797a7b7c7d7e7f"
-                        + "808182838485868788898a8b8c8d8e8f" + "909192939495969798999a9b9c9d9e9f"
-                        + "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf" + "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
-                        + "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf" + "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf"
-                        + "e0e1e2e3e4e5e6e7e8e9eaebecedeeef" + "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
-                "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4v"
-                        + "MDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5f"
-                        + "YGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6P"
-                        + "kJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/"
-                        + "wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v"
-                        + "8PHy8/T19vf4+fr7/P3+/w==" }, };
-    }
-
-    /**
-     * Tests the decode method against invalid data.
-     *
-     * @param encodedData
-     *            The invalid encoded data.
-     * @throws Exception
-     *             If the test failed unexpectedly.
-     */
-    @Test(dataProvider = "invalidData",
-            expectedExceptions = { LocalizedIllegalArgumentException.class })
-    public void testDecodeInvalidData(final String encodedData) throws Exception {
-        Assert.fail("Expected exception but got result: "
-                + Arrays.toString(new ByteString[] { Base64.decode(encodedData) }));
-    }
-
-    /**
-     * Tests the decode method against valid data.
-     *
-     * @param hexData
-     *            The decoded hex data.
-     * @param encodedData
-     *            The encoded data.
-     * @throws Exception
-     *             If the test failed unexpectedly.
-     */
-    @Test(dataProvider = "validData")
-    public void testDecodeValidData(final String hexData, final String encodedData)
-            throws Exception {
-        final byte[] data = getBytes(hexData);
-        final byte[] decodedData = Base64.decode(encodedData).toByteArray();
-        Assert.assertEquals(decodedData, data);
-    }
-
-    /**
-     * Tests the encode method.
-     *
-     * @param hexData
-     *            The decoded hex data.
-     * @param encodedData
-     *            The encoded data.
-     * @throws Exception
-     *             If the test failed unexpectedly.
-     */
-    @Test(dataProvider = "validData")
-    public void testEncode(final String hexData, final String encodedData) throws Exception {
-        final byte[] data = getBytes(hexData);
-        final String base64 = Base64.encode(ByteString.wrap(data));
-        Assert.assertEquals(base64, encodedData);
-    }
-
-    /**
-     * Decode a hex string to a byte-array.
-     *
-     * @param hexData
-     *            The string of hex.
-     * @return Returns the decoded byte array.
-     */
-    private byte[] getBytes(final String hexData) {
-        final int sz = hexData.length();
-
-        if ((sz % 2) != 0) {
-            throw new IllegalArgumentException(
-                    "Hex string does not contain an even number of hex digits");
-        }
-
-        final byte[] bytes = new byte[sz / 2];
-
-        for (int i = 0, j = 0; i < sz; i += 2, j++) {
-            int c = hexData.codePointAt(i);
-            if ((c & 0x7f) != c) {
-                throw new IllegalArgumentException("Hex string contains non-hex digits");
-            }
-
-            final byte b1 = HEX_TO_BYTE[c];
-            if (b1 < 0) {
-                throw new IllegalArgumentException("Hex string contains non-hex digits");
-            }
-
-            c = hexData.codePointAt(i + 1);
-            if ((c & 0x7f) != c) {
-                throw new IllegalArgumentException("Hex string contains non-hex digits");
-            }
-
-            final byte b2 = HEX_TO_BYTE[c];
-            if (b2 < 0) {
-                throw new IllegalArgumentException("Hex string contains non-hex digits");
-            }
-
-            bytes[j] = (byte) ((b1 << 4) | b2);
-        }
-
-        return bytes;
-    }
-}
diff --git a/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/ByteSequenceTestCase.java b/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/ByteSequenceTestCase.java
index 125c05c..c04d578 100644
--- a/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/ByteSequenceTestCase.java
+++ b/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/ByteSequenceTestCase.java
@@ -30,6 +30,8 @@
 import java.io.UnsupportedEncodingException;
 import java.util.Arrays;
 
+import javax.xml.bind.DatatypeConverter;
+
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
@@ -167,4 +169,9 @@
         Assert.assertTrue(bs.toString().equals(str));
     }
 
+    @Test(dataProvider = "byteSequenceProvider")
+    public void testToBase64String(final ByteSequence bs, final byte[] ba) throws Exception {
+        final String base64 = bs.toBase64String();
+        Assert.assertEquals(base64, DatatypeConverter.printBase64Binary(ba));
+    }
 }
diff --git a/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/ByteStringTestCase.java b/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/ByteStringTestCase.java
index 2eb9091..cdea5c3 100644
--- a/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/ByteStringTestCase.java
+++ b/opendj3/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/ByteStringTestCase.java
@@ -22,13 +22,16 @@
  *
  *
  *      Copyright 2010 Sun Microsystems, Inc.
- *      Portions copyright 2011 ForgeRock AS
+ *      Portions copyright 2011-2012 ForgeRock AS
  */
 
 package org.forgerock.opendj.ldap;
 
 import java.util.Arrays;
 
+import javax.xml.bind.DatatypeConverter;
+
+import org.forgerock.i18n.LocalizedIllegalArgumentException;
 import org.testng.Assert;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
@@ -51,6 +54,9 @@
 
         return new Object[][] {
             { ByteString.empty(), new byte[0] },
+            { ByteString.valueOfBase64("AAA="), new byte[] { 0x00, 0x00 }},
+            { ByteString.valueOfBase64("AAAA"), new byte[] { 0x00, 0x00, 0x00 }},
+            { ByteString.valueOfBase64("AAAAAA=="), new byte[] { 0x00, 0x00, 0x00, 0x00 }},
             { ByteString.valueOf(1),
                 new byte[] { (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01 } },
             { ByteString.valueOf(Integer.MAX_VALUE),
@@ -165,4 +171,72 @@
     public void testUndersizedToLong() {
         ByteString.wrap(new byte[] { (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x03 }).toLong();
     }
+
+    /**
+     * Base 64 invalid test data provider.
+     *
+     * @return Returns an array of invalid encoded base64 data.
+     */
+    @DataProvider(name = "invalidBase64Data")
+    public Object[][] createInvalidBase64Data() {
+        // FIXME: fix cases ==== and ==x=
+
+        return new Object[][] { { "=" }, { "==" }, { "===" }, { "A" }, { "AA" }, { "AAA" },
+            { "AA`=" }, { "AA~=" }, { "AA!=" }, { "AA@=" }, { "AA#=" }, { "AA$=" }, { "AA%=" },
+            { "AA^=" }, { "AA*=" }, { "AA(=" }, { "AA)=" }, { "AA_=" }, { "AA-=" }, { "AA{=" },
+            { "AA}=" }, { "AA|=" }, { "AA[=" }, { "AA]=" }, { "AA\\=" }, { "AA;=" }, { "AA'=" },
+            { "AA\"=" }, { "AA:=" }, { "AA,=" }, { "AA.=" }, { "AA<=" }, { "AA>=" }, { "AA?=" },
+            { "AA;=" } };
+    }
+
+    /**
+     * Base 64 valid test data provider.
+     *
+     * @return Returns an array of decoded and valid encoded base64 data.
+     */
+    @DataProvider(name = "validBase64Data")
+    public Object[][] createValidBase64Data() {
+        return new Object[][] {
+            { "", "" },
+            { "00", "AA==" },
+            { "01", "AQ==" },
+            { "02", "Ag==" },
+            { "03", "Aw==" },
+            { "04", "BA==" },
+            { "05", "BQ==" },
+            { "06", "Bg==" },
+            { "07", "Bw==" },
+            { "0000", "AAA=" },
+            { "000000", "AAAA" },
+            { "00000000", "AAAAAA==" },
+            {
+                "000102030405060708090a0b0c0d0e0f" + "101112131415161718191a1b1c1d1e1f"
+                        + "202122232425262728292a2b2c2d2e2f" + "303132333435363738393a3b3c3d3e3f"
+                        + "404142434445464748494a4b4c4d4e4f" + "505152535455565758595a5b5c5d5e5f"
+                        + "606162636465666768696a6b6c6d6e6f" + "707172737475767778797a7b7c7d7e7f"
+                        + "808182838485868788898a8b8c8d8e8f" + "909192939495969798999a9b9c9d9e9f"
+                        + "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf" + "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
+                        + "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf" + "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf"
+                        + "e0e1e2e3e4e5e6e7e8e9eaebecedeeef" + "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
+                "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4v"
+                        + "MDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5f"
+                        + "YGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6P"
+                        + "kJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/"
+                        + "wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v"
+                        + "8PHy8/T19vf4+fr7/P3+/w==" }, };
+    }
+
+    @Test(dataProvider = "invalidBase64Data",
+            expectedExceptions = { LocalizedIllegalArgumentException.class })
+    public void testValueOfBase64ThrowsLIAE(final String invalidBase64) throws Exception {
+        Assert.fail("Expected exception but got result: "
+                + Arrays.toString(new ByteString[] { ByteString.valueOfBase64(invalidBase64) }));
+    }
+
+    @Test(dataProvider = "validBase64Data")
+    public void testValueOfBase64(final String hexData, final String encodedData) throws Exception {
+        final byte[] data = DatatypeConverter.parseHexBinary(hexData);
+        final byte[] decodedData = ByteString.valueOfBase64(encodedData).toByteArray();
+        Assert.assertEquals(decodedData, data);
+    }
 }
diff --git a/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPCompare.java b/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPCompare.java
index c4eb763..910d652 100644
--- a/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPCompare.java
+++ b/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPCompare.java
@@ -54,8 +54,6 @@
 import org.forgerock.opendj.ldap.requests.Requests;
 import org.forgerock.opendj.ldap.responses.Result;
 
-import com.forgerock.opendj.util.Base64;
-
 /**
  * A tool that can be used to issue Compare requests to the Directory Server.
  */
@@ -299,7 +297,7 @@
             if (nextChar == ':') {
                 final String base64 = remainder.substring(1, remainder.length());
                 try {
-                    attributeVal = Base64.decode(base64);
+                    attributeVal = ByteString.valueOfBase64(base64);
                 } catch (final LocalizedIllegalArgumentException e) {
                     println(INFO_COMPARE_CANNOT_BASE64_DECODE_ASSERTION_VALUE.get());
                     return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue();

--
Gitblit v1.10.0