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); } } }
