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

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

commit 5369282d2d254477c71f9c2aba98a7724a4fdcae
Author: Gary Gregory <[email protected]>
AuthorDate: Sat Aug 8 16:57:52 2026 -0400

    Throw IOException instead of IllegalArgumentException in
    BaseNCodecOutputStream and BaseNCodecOutputStream IO methods
---
 src/changes/changes.xml                                |  1 +
 .../org/apache/commons/codec/binary/BaseNCodec.java    | 14 ++++++++++++++
 .../commons/codec/binary/BaseNCodecInputStream.java    |  8 ++------
 .../commons/codec/binary/BaseNCodecOutputStream.java   | 18 +++++-------------
 .../commons/codec/binary/Base32InputStreamTest.java    |  6 ++++--
 .../commons/codec/binary/Base32OutputStreamTest.java   | 10 +++++++---
 .../commons/codec/binary/Base64InputStreamTest.java    |  6 ++++--
 .../commons/codec/binary/Base64OutputStreamTest.java   | 11 ++++++++---
 8 files changed, 45 insertions(+), 29 deletions(-)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index d4c9db0c..18a255c6 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -50,6 +50,7 @@ The <action> type attribute can be add,update,fix,remove.
       <action type="fix" dev="ggregory" due-to="Yu Bao, Gary Gregory">Optimize 
Base58.convertFromBase58(byte[], Context) for speed and temporary object 
allocation.</action>
       <action type="fix" dev="ggregory" due-to="Yu Bao, Gary Gregory">Allocate 
a single MessageDigest and use it in Sha2Crypt.sha2Crypt(byte[], String, 
String, int, String).</action>
       <action type="fix" dev="ggregory" due-to="Gary Gregory">Javadoc 
improvements.</action>
+      <action type="fix" dev="ggregory" due-to="Gary Gregory">Throw 
IOException instead of IllegalArgumentException in BaseNCodecOutputStream and 
BaseNCodecOutputStream IO methods.</action>
       <!-- ADD -->
       <action type="add" dev="ggregory" due-to="Gary Gregory">Add and use 
PhoneticEngine.Builder and deprecate old constructors.</action>
       <action type="add" dev="ggregory" due-to="Gary Gregory">Add 
BeiderMorseEncoder.Builder and deprecate old constructor.</action>
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 7a6e39d6..47f6b8a9 100644
--- a/src/main/java/org/apache/commons/codec/binary/BaseNCodec.java
+++ b/src/main/java/org/apache/commons/codec/binary/BaseNCodec.java
@@ -17,6 +17,7 @@
 
 package org.apache.commons.codec.binary;
 
+import java.io.IOException;
 import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -382,6 +383,19 @@ public abstract class BaseNCodec implements BinaryEncoder, 
BinaryDecoder {
      */
     static final byte[] EMPTY_BYTE_ARRAY = {};
 
+    static void code(final boolean doEncode, final BaseNCodec baseNCodec, 
final byte[] buf, final int offset, final int len, final Context context)
+            throws IOException {
+        try {
+            if (doEncode) {
+                baseNCodec.encode(buf, offset, len, context);
+            } else {
+                baseNCodec.decode(buf, offset, len, context);
+            }
+        } catch (final IllegalArgumentException e) {
+            throw new IOException(e.getMessage(), e);
+        }
+    }
+
     /**
      * 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 can be allocated.
diff --git 
a/src/main/java/org/apache/commons/codec/binary/BaseNCodecInputStream.java 
b/src/main/java/org/apache/commons/codec/binary/BaseNCodecInputStream.java
index 5071bad1..e5a8766d 100644
--- a/src/main/java/org/apache/commons/codec/binary/BaseNCodecInputStream.java
+++ b/src/main/java/org/apache/commons/codec/binary/BaseNCodecInputStream.java
@@ -35,6 +35,7 @@ import org.apache.commons.codec.binary.BaseNCodec.Context;
  * @param <B> A subclass.
  * @see Base16InputStream
  * @see Base32InputStream
+ * @see Base58InputStream
  * @see Base64InputStream
  * @since 1.5
  */
@@ -235,12 +236,7 @@ public class BaseNCodecInputStream<C extends BaseNCodec, T 
extends BaseNCodecInp
             if (!baseNCodec.hasData(context)) {
                 // Obtain more data.
                 // buf is reused across calls to read to avoid repeated 
allocations
-                final int c = in.read(buf);
-                if (doEncode) {
-                    baseNCodec.encode(buf, 0, c, context);
-                } else {
-                    baseNCodec.decode(buf, 0, c, context);
-                }
+                BaseNCodec.code(doEncode, baseNCodec, buf, 0, in.read(buf), 
context);
             }
             final int read = baseNCodec.readResults(array, offset + readLen, 
len - readLen, context);
             if (read < 0) {
diff --git 
a/src/main/java/org/apache/commons/codec/binary/BaseNCodecOutputStream.java 
b/src/main/java/org/apache/commons/codec/binary/BaseNCodecOutputStream.java
index 73031947..586cb110 100644
--- a/src/main/java/org/apache/commons/codec/binary/BaseNCodecOutputStream.java
+++ b/src/main/java/org/apache/commons/codec/binary/BaseNCodecOutputStream.java
@@ -138,17 +138,13 @@ public class BaseNCodecOutputStream<C extends BaseNCodec, 
T extends BaseNCodecOu
     }
 
     /**
-     * Writes EOF.
+     * Notifies the decoder or encoder of EOF (-1).
      *
+     * @throws IOException Thrown when a problem is detected processing data.
      * @since 1.11
      */
-    public void eof() {
-        // Notify encoder of EOF (-1).
-        if (doEncode) {
-            baseNCodec.encode(singleByte, 0, EOF, context);
-        } else {
-            baseNCodec.decode(singleByte, 0, EOF, context);
-        }
+    public void eof() throws IOException {
+        BaseNCodec.code(doEncode, baseNCodec, singleByte, 0, EOF, context);
     }
 
     /**
@@ -213,11 +209,7 @@ public class BaseNCodecOutputStream<C extends BaseNCodec, 
T extends BaseNCodecOu
             throw new IndexOutOfBoundsException();
         }
         if (len > 0) {
-            if (doEncode) {
-                baseNCodec.encode(array, offset, len, context);
-            } else {
-                baseNCodec.decode(array, offset, len, context);
-            }
+            BaseNCodec.code(doEncode, baseNCodec, array, offset, len, context);
             flush(false);
         }
     }
diff --git 
a/src/test/java/org/apache/commons/codec/binary/Base32InputStreamTest.java 
b/src/test/java/org/apache/commons/codec/binary/Base32InputStreamTest.java
index 7a50ff7d..009344c5 100644
--- a/src/test/java/org/apache/commons/codec/binary/Base32InputStreamTest.java
+++ b/src/test/java/org/apache/commons/codec/binary/Base32InputStreamTest.java
@@ -554,7 +554,8 @@ class Base32InputStreamTest {
             // Strict decoding should throw
             final Base32InputStream in2 = new Base32InputStream(new 
ByteArrayInputStream(encoded), false, 0, null, CodecPolicy.STRICT);
             assertTrue(in2.isStrictDecoding());
-            assertThrows(IllegalArgumentException.class, () -> 
IOUtils.toByteArray(in2));
+            IOException ioe = assertThrows(IOException.class, () -> 
IOUtils.toByteArray(in2));
+            assertTrue(ioe.getCause() instanceof IllegalArgumentException);
             // Same with a builder
             try (Base32InputStream in3 = Base32InputStream.builder()
                     .setByteArray(encoded)
@@ -562,7 +563,8 @@ class Base32InputStreamTest {
                     
.setBaseNCodec(Base32.builder().setLineLength(0).setLineSeparator(null).setDecodingPolicy(CodecPolicy.STRICT).get())
                     .get()) {
                 assertTrue(in3.isStrictDecoding());
-                assertThrows(IllegalArgumentException.class, () -> 
IOUtils.toByteArray(in3));
+                ioe = assertThrows(IOException.class, () -> 
IOUtils.toByteArray(in3));
+                assertTrue(ioe.getCause() instanceof IllegalArgumentException);
             }
         }
     }
diff --git 
a/src/test/java/org/apache/commons/codec/binary/Base32OutputStreamTest.java 
b/src/test/java/org/apache/commons/codec/binary/Base32OutputStreamTest.java
index 705a4a1b..8d12ef54 100644
--- a/src/test/java/org/apache/commons/codec/binary/Base32OutputStreamTest.java
+++ b/src/test/java/org/apache/commons/codec/binary/Base32OutputStreamTest.java
@@ -24,6 +24,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.io.ByteArrayOutputStream;
+import java.io.IOException;
 import java.io.OutputStream;
 
 import org.apache.commons.codec.CodecPolicy;
@@ -307,21 +308,24 @@ class Base32OutputStreamTest extends 
AbstractBaseNOutputStreamTest {
                 bout = new ByteArrayOutputStream();
                 try (Base32OutputStream out2 = new Base32OutputStream(bout, 
false, 0, null, CodecPolicy.STRICT)) {
                     assertTrue(out2.isStrictDecoding());
-                    assertThrows(IllegalArgumentException.class, () -> 
out2.write(encoded));
+                    final IOException ioe = assertThrows(IOException.class, () 
-> out2.write(encoded));
+                    assertTrue(ioe.getCause() instanceof 
IllegalArgumentException);
                 }
                 try (Base32OutputStream out2 = Base32OutputStream.builder()
                         .setOutputStream(bout).setEncode(false)
                         
.setBaseNCodec(Base32.builder().setLineLength(0).setLineSeparator(null).setDecodingPolicy(CodecPolicy.STRICT).get())
                         .get()) {
                     assertTrue(out2.isStrictDecoding());
-                    assertThrows(IllegalArgumentException.class, () -> 
out2.write(encoded));
+                    final IOException ioe = assertThrows(IOException.class, () 
-> out2.write(encoded));
+                    assertTrue(ioe.getCause() instanceof 
IllegalArgumentException);
                 }
                 try (Base32OutputStream out2 = Base32OutputStream.builder()
                         .setOutputStream(bout).setEncode(false)
                         
.setBaseNCodec(Base32.builder().setDecodingPolicy(CodecPolicy.STRICT).get())
                         .get()) {
                     assertTrue(out2.isStrictDecoding());
-                    assertThrows(IllegalArgumentException.class, () -> 
out2.write(encoded));
+                    final IOException ioe = assertThrows(IOException.class, () 
-> out2.write(encoded));
+                    assertTrue(ioe.getCause() instanceof 
IllegalArgumentException);
                 }
             }
         }
diff --git 
a/src/test/java/org/apache/commons/codec/binary/Base64InputStreamTest.java 
b/src/test/java/org/apache/commons/codec/binary/Base64InputStreamTest.java
index 0c5031ce..1e39eec2 100644
--- a/src/test/java/org/apache/commons/codec/binary/Base64InputStreamTest.java
+++ b/src/test/java/org/apache/commons/codec/binary/Base64InputStreamTest.java
@@ -587,7 +587,8 @@ class Base64InputStreamTest {
             // Strict decoding should throw
             final Base64InputStream in2 = new Base64InputStream(new 
ByteArrayInputStream(encoded), false, 0, null, CodecPolicy.STRICT);
             assertTrue(in2.isStrictDecoding());
-            assertThrows(IllegalArgumentException.class, () -> 
IOUtils.toByteArray(in2));
+            IOException ioe = assertThrows(IOException.class, () -> 
IOUtils.toByteArray(in2));
+            assertTrue(ioe.getCause() instanceof IllegalArgumentException);
             // Same with a builder
             try (Base64InputStream in3 = Base64InputStream.builder()
                     .setByteArray(encoded)
@@ -595,7 +596,8 @@ class Base64InputStreamTest {
                     
.setBaseNCodec(Base64.builder().setLineLength(0).setLineSeparator(null).setDecodingPolicy(CodecPolicy.STRICT).get())
                     .get()) {
                 assertTrue(in3.isStrictDecoding());
-                assertThrows(IllegalArgumentException.class, () -> 
IOUtils.toByteArray(in3));
+                ioe = assertThrows(IOException.class, () -> 
IOUtils.toByteArray(in3));
+                assertTrue(ioe.getCause() instanceof IllegalArgumentException);
             }
         }
     }
diff --git 
a/src/test/java/org/apache/commons/codec/binary/Base64OutputStreamTest.java 
b/src/test/java/org/apache/commons/codec/binary/Base64OutputStreamTest.java
index 6e4df673..ffda5a4f 100644
--- a/src/test/java/org/apache/commons/codec/binary/Base64OutputStreamTest.java
+++ b/src/test/java/org/apache/commons/codec/binary/Base64OutputStreamTest.java
@@ -26,6 +26,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.io.ByteArrayOutputStream;
 import java.io.FileOutputStream;
+import java.io.IOException;
 import java.io.OutputStream;
 import java.nio.file.Files;
 import java.nio.file.Path;
@@ -348,20 +349,23 @@ class Base64OutputStreamTest extends 
AbstractBaseNOutputStreamTest {
             try (Base64OutputStream out = new Base64OutputStream(bout, false, 
0, null, CodecPolicy.STRICT)) {
                 // May throw on write or on close depending on the position of 
the
                 // impossible last character in the output block size
-                assertThrows(IllegalArgumentException.class, () -> {
+                final IOException ioe = assertThrows(IOException.class, () -> {
                     out.write(impossibleEncoded);
                     out.close();
                 });
+                assertTrue(ioe.getCause() instanceof IllegalArgumentException);
+
             }
             try (Base64OutputStream out = Base64OutputStream.builder()
                     .setOutputStream(bout).setEncode(false)
                     
.setBaseNCodec(Base64.builder().setLineLength(0).setLineSeparator(null).setDecodingPolicy(CodecPolicy.STRICT).get())
                     .get()) {
                 assertTrue(out.isStrictDecoding());
-                assertThrows(IllegalArgumentException.class, () -> {
+                final IOException ioe = assertThrows(IOException.class, () -> {
                     out.write(impossibleEncoded);
                     out.close();
                 });
+                assertTrue(ioe.getCause() instanceof IllegalArgumentException);
             }
             try (Base64OutputStream out = Base64OutputStream.builder()
                     .setOutputStream(bout).setEncode(false)
@@ -369,10 +373,11 @@ class Base64OutputStreamTest extends 
AbstractBaseNOutputStreamTest {
                     .get()) {
                 // May throw on write or on close depending on the position of 
the
                 // impossible last character in the output block size
-                assertThrows(IllegalArgumentException.class, () -> {
+                final IOException ioe = assertThrows(IOException.class, () -> {
                     out.write(impossibleEncoded);
                     out.close();
                 });
+                assertTrue(ioe.getCause() instanceof IllegalArgumentException);
             }
         }
     }

Reply via email to