This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-codec.git

commit 937df546016b229fcea57ca03076c887d3849f7e
Author: Gary D. Gregory <[email protected]>
AuthorDate: Sun Oct 12 15:46:55 2025 -0400

    Internal refactoring
    
    Add missing test
---
 .../org/apache/commons/codec/binary/Base32.java    | 20 +++---
 .../org/apache/commons/codec/binary/Base64.java    | 73 ++++++++--------------
 .../apache/commons/codec/binary/BaseNCodec.java    |  5 ++
 .../apache/commons/codec/binary/Base32Test.java    |  3 +-
 .../apache/commons/codec/binary/Base64Test.java    | 61 ++++++++++--------
 5 files changed, 76 insertions(+), 86 deletions(-)

diff --git a/src/main/java/org/apache/commons/codec/binary/Base32.java 
b/src/main/java/org/apache/commons/codec/binary/Base32.java
index 509a255d..0beac482 100644
--- a/src/main/java/org/apache/commons/codec/binary/Base32.java
+++ b/src/main/java/org/apache/commons/codec/binary/Base32.java
@@ -345,20 +345,16 @@ public class Base32 extends BaseNCodec {
         super(builder);
         Objects.requireNonNull(builder.getEncodeTable(), "encodeTable");
         this.encodeTable = builder.getEncodeTable();
-        this.decodeTable = builder.getEncodeTable() == HEX_ENCODE_TABLE || 
Arrays.equals(builder.getEncodeTable(), HEX_ENCODE_TABLE) ?
-                HEX_DECODE_TABLE : DECODE_TABLE;
+        this.decodeTable = Arrays.equals(builder.getEncodeTable(), 
HEX_ENCODE_TABLE) ? HEX_DECODE_TABLE : DECODE_TABLE;
         if (builder.getLineLength() > 0) {
-            if (builder.getLineSeparator() == null) {
-                throw new IllegalArgumentException("lineLength " + lineLength 
+ " > 0, but lineSeparator is null");
-            }
-            final byte[] lineSeparatorCopy = 
builder.getLineSeparator().clone();
+            final byte[] lineSeparator = builder.getLineSeparator();
             // Must be done after initializing the tables
-            if (containsAlphabetOrPad(lineSeparatorCopy)) {
-                final String sep = 
StringUtils.newStringUtf8(lineSeparatorCopy);
+            if (containsAlphabetOrPad(lineSeparator)) {
+                final String sep = StringUtils.newStringUtf8(lineSeparator);
                 throw new IllegalArgumentException("lineSeparator must not 
contain Base32 characters: [" + sep + "]");
             }
-            this.encodeSize = BYTES_PER_ENCODED_BLOCK + 
lineSeparatorCopy.length;
-            this.lineSeparator = lineSeparatorCopy;
+            this.encodeSize = BYTES_PER_ENCODED_BLOCK + lineSeparator.length;
+            this.lineSeparator = lineSeparator;
         } else {
             this.encodeSize = BYTES_PER_ENCODED_BLOCK;
             this.lineSeparator = null;
@@ -499,8 +495,8 @@ public class Base32 extends BaseNCodec {
      */
     @Deprecated
     public Base32(final int lineLength, final byte[] lineSeparator, final 
boolean useHex, final byte padding, final CodecPolicy decodingPolicy) {
-        
this(builder().setLineLength(lineLength).setLineSeparator(lineSeparator).setEncodeTableRaw(encodeTable(useHex)).setPadding(padding)
-                .setDecodingPolicy(decodingPolicy));
+        
this(builder().setLineLength(lineLength).setLineSeparator(lineSeparator != null 
? lineSeparator : EMPTY_BYTE_ARRAY)
+                
.setEncodeTableRaw(encodeTable(useHex)).setPadding(padding).setDecodingPolicy(decodingPolicy));
     }
 
     /**
diff --git a/src/main/java/org/apache/commons/codec/binary/Base64.java 
b/src/main/java/org/apache/commons/codec/binary/Base64.java
index df0c1a60..9950d04d 100644
--- a/src/main/java/org/apache/commons/codec/binary/Base64.java
+++ b/src/main/java/org/apache/commons/codec/binary/Base64.java
@@ -98,11 +98,13 @@ public class Base64 extends BaseNCodec {
          */
         public Builder() {
             super(STANDARD_ENCODE_TABLE);
+            setEncodedBlockSize(BYTES_PER_ENCODED_BLOCK);
+            setUnencodedBlockSize(BYTES_PER_UNENCODED_BLOCK);
         }
 
         @Override
         public Base64 get() {
-            return new Base64(getLineLength(), getLineSeparator(), 
getPadding(), getEncodeTable(), getDecodingPolicy());
+            return new Base64(this);
         }
 
         /**
@@ -529,6 +531,9 @@ public class Base64 extends BaseNCodec {
 
     private final boolean isUrlSafe;
 
+    private final boolean isStandardEncodeTable;
+
+
     /**
      * Constructs a Base64 codec used for decoding (all modes) and encoding in 
URL-unsafe mode.
      * <p>
@@ -646,7 +651,8 @@ public class Base64 extends BaseNCodec {
      */
     @Deprecated
     public Base64(final int lineLength, final byte[] lineSeparator, final 
boolean urlSafe) {
-        this(lineLength, lineSeparator, PAD_DEFAULT, 
toUrlSafeEncodeTable(urlSafe), DECODING_POLICY_DEFAULT);
+        
this(builder().setLineLength(lineLength).setLineSeparator(lineSeparator != null 
? lineSeparator : EMPTY_BYTE_ARRAY).setPadding(PAD_DEFAULT)
+                
.setEncodeTableRaw(toUrlSafeEncodeTable(urlSafe)).setDecodingPolicy(DECODING_POLICY_DEFAULT));
     }
 
     /**
@@ -680,56 +686,31 @@ public class Base64 extends BaseNCodec {
      */
     @Deprecated
     public Base64(final int lineLength, final byte[] lineSeparator, final 
boolean urlSafe, final CodecPolicy decodingPolicy) {
-        this(lineLength, lineSeparator, PAD_DEFAULT, 
toUrlSafeEncodeTable(urlSafe), decodingPolicy);
+        
this(builder().setLineLength(lineLength).setLineSeparator(lineSeparator).setPadding(PAD_DEFAULT).setEncodeTableRaw(toUrlSafeEncodeTable(urlSafe))
+                .setDecodingPolicy(decodingPolicy));
     }
 
-    /**
-     * Constructs a Base64 codec used for decoding (all modes) and encoding in 
URL-unsafe mode.
-     * <p>
-     * When encoding the line length and line separator are given in the 
constructor, and the encoding table is STANDARD_ENCODE_TABLE.
-     * </p>
-     * <p>
-     * Line lengths that aren't multiples of 4 will still essentially end up 
being multiples of 4 in the encoded data.
-     * </p>
-     * <p>
-     * When decoding all variants are supported.
-     * </p>
-     *
-     * @param lineLength     Each line of encoded data will be at most of the 
given length (rounded down to the nearest multiple of 4). If lineLength &lt;= 0,
-     *                       then the output will not be divided into lines 
(chunks). Ignored when decoding.
-     * @param lineSeparator  Each line of encoded data will end with this 
sequence of bytes; the constructor makes a defensive copy. May be null.
-     * @param padding        padding byte.
-     * @param encodeTable    The manual encodeTable - a byte array of 64 chars.
-     * @param decodingPolicy The decoding policy.
-     * @throws IllegalArgumentException Thrown when the {@code lineSeparator} 
contains Base64 characters.
-     */
-    private Base64(final int lineLength, final byte[] lineSeparator, final 
byte padding, final byte[] encodeTable, final CodecPolicy decodingPolicy) {
-        super(BYTES_PER_UNENCODED_BLOCK, BYTES_PER_ENCODED_BLOCK, lineLength, 
toLength(lineSeparator), padding, decodingPolicy);
-        Objects.requireNonNull(encodeTable, "encodeTable");
-        if (encodeTable.length != STANDARD_ENCODE_TABLE.length) {
+    private Base64(final Builder builder) {
+        super(builder);
+        Objects.requireNonNull(builder.getEncodeTable(), "encodeTable");
+        if (builder.getEncodeTable().length != STANDARD_ENCODE_TABLE.length) {
             throw new IllegalArgumentException("encodeTable must have exactly 
64 entries.");
         }
-        // same array first or equal contents second
-        this.isUrlSafe = encodeTable == URL_SAFE_ENCODE_TABLE || 
Arrays.equals(encodeTable, URL_SAFE_ENCODE_TABLE);
-        if (encodeTable == STANDARD_ENCODE_TABLE || this.isUrlSafe) {
-            decodeTable = DECODE_TABLE;
-            // No need of a defensive copy of an internal table.
-            this.encodeTable = encodeTable;
-        } else {
-            this.encodeTable = encodeTable.clone();
-            this.decodeTable = calculateDecodeTable(this.encodeTable);
-        }
+        this.isStandardEncodeTable = Arrays.equals(builder.getEncodeTable(), 
STANDARD_ENCODE_TABLE);
+        this.isUrlSafe = Arrays.equals(builder.getEncodeTable(), 
URL_SAFE_ENCODE_TABLE);
+        this.encodeTable = builder.getEncodeTable();
+        this.decodeTable = this.isStandardEncodeTable || this.isUrlSafe ? 
DECODE_TABLE : calculateDecodeTable(this.encodeTable);
         // TODO could be simplified if there is no requirement to reject 
invalid line sep when length <=0
         // @see test case Base64Test.testConstructors()
-        if (lineSeparator != null) {
-            final byte[] lineSeparatorCopy = lineSeparator.clone();
-            if (containsAlphabetOrPad(lineSeparatorCopy)) {
-                final String sep = 
StringUtils.newStringUtf8(lineSeparatorCopy);
+        if (builder.getLineSeparator().length > 0) {
+            final byte[] lineSeparatorB = builder.getLineSeparator();
+            if (containsAlphabetOrPad(lineSeparatorB)) {
+                final String sep = StringUtils.newStringUtf8(lineSeparatorB);
                 throw new IllegalArgumentException("lineSeparator must not 
contain base64 characters: [" + sep + "]");
             }
-            if (lineLength > 0) { // null line-sep forces no chunking rather 
than throwing IAE
-                this.encodeSize = BYTES_PER_ENCODED_BLOCK + 
lineSeparatorCopy.length;
-                this.lineSeparator = lineSeparatorCopy;
+            if (builder.getLineLength() > 0) { // null line-sep forces no 
chunking rather than throwing IAE
+                this.encodeSize = BYTES_PER_ENCODED_BLOCK + 
lineSeparatorB.length;
+                this.lineSeparator = lineSeparatorB;
             } else {
                 this.encodeSize = BYTES_PER_ENCODED_BLOCK;
                 this.lineSeparator = null;
@@ -885,7 +866,7 @@ public class Base64 extends BaseNCodec {
                     // remaining 2:
                     buffer[context.pos++] = encodeTable[context.ibitWorkArea 
<< 4 & MASK_6_BITS];
                     // URL-SAFE skips the padding to further reduce size.
-                    if (encodeTable == STANDARD_ENCODE_TABLE) {
+                    if (isStandardEncodeTable) {
                         buffer[context.pos++] = pad;
                         buffer[context.pos++] = pad;
                     }
@@ -896,7 +877,7 @@ public class Base64 extends BaseNCodec {
                     buffer[context.pos++] = encodeTable[context.ibitWorkArea 
>> 4 & MASK_6_BITS];
                     buffer[context.pos++] = encodeTable[context.ibitWorkArea 
<< 2 & MASK_6_BITS];
                     // URL-SAFE skips the padding to further reduce size.
-                    if (encodeTable == STANDARD_ENCODE_TABLE) {
+                    if (isStandardEncodeTable) {
                         buffer[context.pos++] = pad;
                     }
                     break;
diff --git a/src/main/java/org/apache/commons/codec/binary/BaseNCodec.java 
b/src/main/java/org/apache/commons/codec/binary/BaseNCodec.java
index d745f865..59c785c3 100644
--- a/src/main/java/org/apache/commons/codec/binary/BaseNCodec.java
+++ b/src/main/java/org/apache/commons/codec/binary/BaseNCodec.java
@@ -348,6 +348,11 @@ public abstract class BaseNCodec implements BinaryEncoder, 
BinaryDecoder {
      */
     static final byte[] CHUNK_SEPARATOR = {'\r', '\n'};
 
+    /**
+     * The empty byte array.
+     */
+    static final byte[] EMPTY_BYTE_ARRAY = {};
+
     /**
      * Create a positive capacity at least as large the minimum required 
capacity.
      * If the minimum capacity is negative then this throws an 
OutOfMemoryError as no array
diff --git a/src/test/java/org/apache/commons/codec/binary/Base32Test.java 
b/src/test/java/org/apache/commons/codec/binary/Base32Test.java
index 100d9176..43d61cea 100644
--- a/src/test/java/org/apache/commons/codec/binary/Base32Test.java
+++ b/src/test/java/org/apache/commons/codec/binary/Base32Test.java
@@ -427,13 +427,12 @@ class Base32Test {
         // even when line length is negative.
         base32 = new Base32(-1, new byte[] { 'A' });
         base32 = new Base32(32, new byte[] { '$' }); // OK
-        assertArrayEquals(BaseNCodec.CHUNK_SEPARATOR, new Base32(32, 
null).getLineSeparator(), "null line separator use the default");
+        assertArrayEquals(new byte[0], new Base32(32, 
null).getLineSeparator(), "null line separator use an empty array");
         assertThrows(IllegalArgumentException.class, () -> new Base32(32, new 
byte[] { 'A' }), "'A' as a line separator");
         assertThrows(IllegalArgumentException.class, () -> new Base32(32, new 
byte[] { '=' }), "'=' as a line separator");
         assertThrows(IllegalArgumentException.class, () -> new Base32(32, new 
byte[] { 'A', '$' }), "'A$' as a line separator");
         assertThrows(IllegalArgumentException.class, () -> new Base32(32, new 
byte[] { '\n' }, false, (byte) 'A'), "'A' as padding");
         assertThrows(IllegalArgumentException.class, () -> new Base32(32, new 
byte[] { '\n' }, false, (byte) ' '), "' ' as padding");
-
         base32 = new Base32(32, new byte[] { ' ', '$', '\n', '\r', '\t' }); // 
OK
         assertNotNull(base32);
     }
diff --git a/src/test/java/org/apache/commons/codec/binary/Base64Test.java 
b/src/test/java/org/apache/commons/codec/binary/Base64Test.java
index 73ffed61..305ede94 100644
--- a/src/test/java/org/apache/commons/codec/binary/Base64Test.java
+++ b/src/test/java/org/apache/commons/codec/binary/Base64Test.java
@@ -31,6 +31,7 @@ import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
 import java.util.Random;
+import java.util.stream.Stream;
 
 import org.apache.commons.codec.CodecPolicy;
 import org.apache.commons.codec.DecoderException;
@@ -38,6 +39,9 @@ import org.apache.commons.codec.EncoderException;
 import org.apache.commons.lang3.ArrayUtils;
 import org.junit.jupiter.api.Assumptions;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
 
 /**
  * Tests {@link Base64}.
@@ -130,6 +134,24 @@ class Base64Test {
         }
     }
 
+    static Stream<Object> testIsBase64() {
+        // @formatter:off
+        return Stream.of(
+            Arguments.of(new byte[] { 1, 2, 3 }, false),
+            Arguments.of(new byte[] { Byte.MIN_VALUE }, false),
+            Arguments.of(new byte[] { -125 }, false),
+            Arguments.of(new byte[] { -10 }, false),
+            Arguments.of(new byte[] { 0 }, false),
+            Arguments.of(new byte[] { 64, Byte.MAX_VALUE }, false),
+            Arguments.of(new byte[] { Byte.MAX_VALUE }, false),
+            Arguments.of(new byte[] { 'A' }, true),
+            Arguments.of(new byte[] { 'A', Byte.MIN_VALUE }, false),
+            Arguments.of(new byte[] { 'A', 'Z', 'a' }, true),
+            Arguments.of(new byte[] { '/', '=', '+' }, true),
+            Arguments.of(new byte[] { '$' }, false));
+        // @formatter:off
+    }
+
     private final Random random = new Random();
 
     /**
@@ -149,22 +171,16 @@ class Base64Test {
         byte[] encodedBytes = 
Base64.encodeBase64(StringUtils.getBytesUtf8(content));
         encodedContent = StringUtils.newStringUtf8(encodedBytes);
         assertEquals("SGVsbG8gV29ybGQ=", encodedContent, "encoding hello 
world");
-
-        Base64 b64 = new Base64(BaseNCodec.MIME_CHUNK_SIZE, null); // null
-                                                                    // 
lineSeparator
-                                                                    // same as
-                                                                    // saying
-                                                                    // 
no-chunking
+        // null lineSeparator same as saying no-chunking
+        Base64 b64 = new Base64(BaseNCodec.MIME_CHUNK_SIZE, null);
         encodedBytes = b64.encode(StringUtils.getBytesUtf8(content));
         encodedContent = StringUtils.newStringUtf8(encodedBytes);
         assertEquals("SGVsbG8gV29ybGQ=", encodedContent, "encoding hello 
world");
-
-        b64 = new Base64(0, null); // null lineSeparator same as saying
-                                    // no-chunking
+        // null lineSeparator same as saying no-chunking
+        b64 = new Base64(0, null);
         encodedBytes = b64.encode(StringUtils.getBytesUtf8(content));
         encodedContent = StringUtils.newStringUtf8(encodedBytes);
         assertEquals("SGVsbG8gV29ybGQ=", encodedContent, "encoding hello 
world");
-
         // bogus characters to decode (to skip actually) {e-acute*6}
         final byte[] decode = 
b64.decode("SGVsbG{\u00e9\u00e9\u00e9\u00e9\u00e9\u00e9}8gV29ybGQ=");
         final String decodeString = StringUtils.newStringUtf8(decode);
@@ -692,23 +708,16 @@ class Base64Test {
         assertEquals(FOX_TEXT, new 
String(Base64.decodeBase64(FOX_BASE64.getBytes(CHARSET_UTF8))));
     }
 
-    @Test
-    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[] { '/', '=', '+' }));
+    @ParameterizedTest
+    @MethodSource("testIsBase64")
+    void testIsArrayByteBase64(final byte[] arrayOctet, final boolean match) {
+        assertEquals(match, Base64.isArrayByteBase64(arrayOctet));
+    }
 
-        assertFalse(Base64.isBase64(new byte[] { '$' }));
+    @ParameterizedTest
+    @MethodSource
+    void testIsBase64(final byte[] arrayOctet, final boolean match) {
+        assertEquals(match, Base64.isBase64(arrayOctet));
     }
 
     /**

Reply via email to