On Sun, May 17, 2020 at 3:46 PM Alex Herbert <alex.d.herb...@gmail.com> wrote:
> +1 to the changes. > > One minor nit is the javadoc on line 307 of BaseNCodec.getCodecPolicy which > states that decoding will raise an exception. This should be qualified by > stating it will raise an exception when in strict decoding mode. I think > the sentence about the default mode should be first. Then the sentence > about strict decoding, i.e. the alternative, raising an exception. > I updated org.apache.commons.codec.binary.BaseNCodec.getCodecPolicy() > > A second nit is line 295 of BaseNCodec.isStrictDecoding that states the > default is for lenient *encoding*. This should be *decoding*. > I updated org.apache.commons.codec.binary.BaseNCodec.isStrictDecoding() > > One issue is whether decoding should raise a DecoderException and not an > IllegalArgumentException. > Will ponder... Gary > > WDYT? > > Alex > > > On Sun, 17 May 2020, 16:51 , <ggreg...@apache.org> wrote: > > > 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 > > > > > > The following commit(s) were added to refs/heads/master by this push: > > new 9f1b740 Reimplement the new-in-1.15 BaseNCodec's and friends' > > strict vs. lenient decoding as final instance variables and with an enum > > instead of a boolean. Introduce the last amount of new constructors. > > 9f1b740 is described below > > > > commit 9f1b740a17f0d54366edfb45df0636b8e302666a > > Author: Gary Gregory <garydgreg...@gmail.com> > > AuthorDate: Sun May 17 11:51:25 2020 -0400 > > > > Reimplement the new-in-1.15 BaseNCodec's and friends' strict vs. > > lenient > > decoding as final instance variables and with an enum instead of a > > boolean. Introduce the last amount of new constructors. > > --- > > .../java/org/apache/commons/codec/CodecPolicy.java | 36 +++++++ > > .../org/apache/commons/codec/binary/Base32.java | 60 +++++++---- > > .../commons/codec/binary/Base32InputStream.java | 43 +++++++- > > .../commons/codec/binary/Base32OutputStream.java | 42 +++++++- > > .../org/apache/commons/codec/binary/Base64.java | 56 +++++++--- > > .../commons/codec/binary/Base64InputStream.java | 42 +++++++- > > .../commons/codec/binary/Base64OutputStream.java | 42 +++++++- > > .../apache/commons/codec/binary/BaseNCodec.java | 119 > > +++++++++++++++------ > > .../codec/binary/BaseNCodecInputStream.java | 20 ---- > > .../codec/binary/BaseNCodecOutputStream.java | 20 ---- > > .../java/org/apache/commons/codec/net/BCodec.java | 52 ++++----- > > .../codec/binary/Base32InputStreamTest.java | 4 +- > > .../codec/binary/Base32OutputStreamTest.java | 14 +-- > > .../apache/commons/codec/binary/Base32Test.java | 17 +-- > > .../codec/binary/Base64InputStreamTest.java | 4 +- > > .../codec/binary/Base64OutputStreamTest.java | 18 ++-- > > .../apache/commons/codec/binary/Base64Test.java | 7 +- > > .../org/apache/commons/codec/net/BCodecTest.java | 22 +++- > > 18 files changed, 451 insertions(+), 167 deletions(-) > > > > diff --git a/src/main/java/org/apache/commons/codec/CodecPolicy.java > > b/src/main/java/org/apache/commons/codec/CodecPolicy.java > > new file mode 100644 > > index 0000000..9cf5e12 > > --- /dev/null > > +++ b/src/main/java/org/apache/commons/codec/CodecPolicy.java > > @@ -0,0 +1,36 @@ > > +/* > > + * Licensed to the Apache Software Foundation (ASF) under one or more > > + * contributor license agreements. See the NOTICE file distributed with > > + * this work for additional information regarding copyright ownership. > > + * The ASF licenses this file to You under the Apache License, Version > 2.0 > > + * (the "License"); you may not use this file except in compliance with > > + * the License. You may obtain a copy of the License at > > + * > > + * http://www.apache.org/licenses/LICENSE-2.0 > > + * > > + * Unless required by applicable law or agreed to in writing, software > > + * distributed under the License is distributed on an "AS IS" BASIS, > > + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or > > implied. > > + * See the License for the specific language governing permissions and > > + * limitations under the License. > > + */ > > + > > +package org.apache.commons.codec; > > + > > +/** > > + * Defines encoding and decoding policies. > > + * > > + * @since 1.15 > > + */ > > +public enum CodecPolicy { > > + > > + /** > > + * The strict policy. Data that causes a codec to fail should throw > > an exception. > > + */ > > + STRICT, > > + > > + /** > > + * The strict policy. Data that causes a codec to fail should not > > throw an exception. > > + */ > > + LENIENT > > +} > > 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 aa5d3e4..8d57861 100644 > > --- a/src/main/java/org/apache/commons/codec/binary/Base32.java > > +++ b/src/main/java/org/apache/commons/codec/binary/Base32.java > > @@ -17,6 +17,8 @@ > > > > package org.apache.commons.codec.binary; > > > > +import org.apache.commons.codec.CodecPolicy; > > + > > /** > > * Provides Base32 encoding and decoding as defined by <a href=" > > http://www.ietf.org/rfc/rfc4648.txt">RFC 4648</a>. > > * > > @@ -52,13 +54,6 @@ public class Base32 extends BaseNCodec { > > private static final int BYTES_PER_UNENCODED_BLOCK = 5; > > > > /** > > - * Chunk separator per RFC 2045 section 2.1. > > - * > > - * @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045 > > section 2.1</a> > > - */ > > - private static final byte[] CHUNK_SEPARATOR = {'\r', '\n'}; > > - > > - /** > > * This array is a lookup table that translates Unicode characters > > drawn from the "Base32 Alphabet" (as specified > > * in Table 3 of RFC 4648) into their 5-bit positive integer > > equivalents. Characters that are not in the Base32 > > * alphabet but fall within the bounds of the array are translated > to > > -1. > > @@ -200,10 +195,10 @@ public class Base32 extends BaseNCodec { > > * When encoding the line length is 0 (no chunking). > > * </p> > > * @param useHex if {@code true} then use Base32 Hex alphabet > > - * @param pad byte used as padding byte. > > + * @param padding byte used as padding byte. > > */ > > - public Base32(final boolean useHex, final byte pad) { > > - this(0, null, useHex, pad); > > + public Base32(final boolean useHex, final byte padding) { > > + this(0, null, useHex, padding); > > } > > > > /** > > @@ -237,7 +232,7 @@ public class Base32 extends BaseNCodec { > > * @param lineSeparator > > * Each line of encoded data will end with this sequence > > of bytes. > > * @throws IllegalArgumentException > > - * The provided lineSeparator included some Base32 > > characters. That's not going to work! > > + * Thrown when the {@code lineSeparator} contains Base32 > > characters. > > */ > > public Base32(final int lineLength, final byte[] lineSeparator) { > > this(lineLength, lineSeparator, false, PAD_DEFAULT); > > @@ -261,7 +256,7 @@ public class Base32 extends BaseNCodec { > > * @param useHex > > * if {@code true}, then use Base32 Hex alphabet, > > otherwise use Base32 alphabet > > * @throws IllegalArgumentException > > - * The provided lineSeparator included some Base32 > > characters. That's not going to work! Or the > > + * Thrown when the {@code lineSeparator} contains Base32 > > characters. Or the > > * lineLength > 0 and lineSeparator is null. > > */ > > public Base32(final int lineLength, final byte[] lineSeparator, > final > > boolean useHex) { > > @@ -285,14 +280,41 @@ public class Base32 extends BaseNCodec { > > * Each line of encoded data will end with this sequence > > of bytes. > > * @param useHex > > * if {@code true}, then use Base32 Hex alphabet, > > otherwise use Base32 alphabet > > - * @param pad byte used as padding byte. > > + * @param padding byte used as padding byte. > > + * @throws IllegalArgumentException > > + * Thrown when the {@code lineSeparator} contains Base32 > > characters. Or the > > + * lineLength > 0 and lineSeparator is null. > > + */ > > + public Base32(final int lineLength, final byte[] lineSeparator, > final > > boolean useHex, final byte padding) { > > + this(lineLength, lineSeparator, useHex, padding, > > DECODING_POLICY_DEFAULT); > > + } > > + > > + /** > > + * Creates a Base32 / Base32 Hex codec used for decoding and > encoding. > > + * <p> > > + * When encoding the line length and line separator are given in the > > constructor. > > + * </p> > > + * <p> > > + * Line lengths that aren't multiples of 8 will still essentially > end > > up being multiples of 8 in the encoded data. > > + * </p> > > + * > > + * @param lineLength > > + * Each line of encoded data will be at most of the given > > length (rounded down to nearest multiple of > > + * 8). If lineLength <= 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. > > + * @param useHex > > + * if {@code true}, then use Base32 Hex alphabet, > > otherwise use Base32 alphabet > > + * @param padding byte used as padding byte. > > + * @param decodingPolicy The decoding policy. > > * @throws IllegalArgumentException > > - * The provided lineSeparator included some Base32 > > characters. That's not going to work! Or the > > + * Thrown when the {@code lineSeparator} contains Base32 > > characters. Or the > > * lineLength > 0 and lineSeparator is null. > > */ > > - public Base32(final int lineLength, final byte[] lineSeparator, > final > > boolean useHex, final byte pad) { > > + public Base32(final int lineLength, final byte[] lineSeparator, > final > > boolean useHex, final byte padding, CodecPolicy decodingPolicy) { > > super(BYTES_PER_UNENCODED_BLOCK, BYTES_PER_ENCODED_BLOCK, > > lineLength, > > - lineSeparator == null ? 0 : lineSeparator.length, pad); > > + lineSeparator == null ? 0 : lineSeparator.length, > > padding, decodingPolicy); > > if (useHex) { > > this.encodeTable = HEX_ENCODE_TABLE; > > this.decodeTable = HEX_DECODE_TABLE; > > @@ -318,7 +340,7 @@ public class Base32 extends BaseNCodec { > > } > > this.decodeSize = this.encodeSize - 1; > > > > - if (isInAlphabet(pad) || isWhiteSpace(pad)) { > > + if (isInAlphabet(padding) || isWhiteSpace(padding)) { > > throw new IllegalArgumentException("pad must not be in > > alphabet or whitespace"); > > } > > } > > @@ -436,7 +458,7 @@ public class Base32 extends BaseNCodec { > > break; > > default: > > // modulus can be 0-7, and we excluded 0,1 already > > - throw new IllegalStateException("Impossible modulus > > "+context.modulus); > > + throw new IllegalStateException("Impossible modulus > " > > + context.modulus); > > } > > } > > } > > @@ -516,7 +538,7 @@ public class Base32 extends BaseNCodec { > > buffer[context.pos++] = pad; > > break; > > default: > > - throw new IllegalStateException("Impossible modulus > > "+context.modulus); > > + throw new IllegalStateException("Impossible modulus > " > > + context.modulus); > > } > > context.currentLinePos += context.pos - savedPos; // keep > > track of current line position > > // if currentPos == 0 we are at the start of a line, so > don't > > add CRLF > > diff --git > > a/src/main/java/org/apache/commons/codec/binary/Base32InputStream.java > > b/src/main/java/org/apache/commons/codec/binary/Base32InputStream.java > > index 0be8860..92a6a74 100644 > > --- > a/src/main/java/org/apache/commons/codec/binary/Base32InputStream.java > > +++ > b/src/main/java/org/apache/commons/codec/binary/Base32InputStream.java > > @@ -19,6 +19,8 @@ package org.apache.commons.codec.binary; > > > > import java.io.InputStream; > > > > +import org.apache.commons.codec.CodecPolicy; > > + > > /** > > * Provides Base32 encoding and decoding in a streaming fashion > > (unlimited size). When encoding the default lineLength > > * is 76 characters and the default lineEnding is CRLF, but these can be > > overridden by using the appropriate > > @@ -31,7 +33,22 @@ import java.io.InputStream; > > * Since this class operates directly on byte streams, and not character > > streams, it is hard-coded to only encode/decode > > * character encodings which are compatible with the lower 127 ASCII > > chart (ISO-8859-1, Windows-1252, UTF-8, etc). > > * </p> > > - * > > + * <p> > > + * You can set the decoding behavior when the input bytes contain > > leftover trailing bits that cannot be created by a valid > > + * encoding. These can be bits that are unused from the final character > > or entire characters. The default mode is > > + * lenient decoding. > > + * </p> > > + * <ul> > > + * <li>Lenient: Any trailing bits are composed into 8-bit bytes where > > possible. The remainder are discarded. > > + * <li>Strict: The decoding will raise an {@link > > IllegalArgumentException} if trailing bits are not part of a valid > > + * encoding. Any unused bits from the final character must be zero. > > Impossible counts of entire final characters are not > > + * allowed. > > + * </ul> > > + * <p> > > + * When strict decoding is enabled it is expected that the decoded bytes > > will be re-encoded to a byte array that matches > > + * the original, i.e. no changes occur on the final character. This > > requires that the input bytes use the same padding > > + * and alphabet as the encoder. > > + * </p> > > * @see <a href="http://www.ietf.org/rfc/rfc4648.txt">RFC 4648</a> > > * @since 1.5 > > */ > > @@ -81,4 +98,28 @@ public class Base32InputStream extends > > BaseNCodecInputStream { > > super(input, new Base32(lineLength, lineSeparator), doEncode); > > } > > > > + /** > > + * Creates a Base32InputStream such that all data read is either > > Base32-encoded or Base32-decoded from the original > > + * provided InputStream. > > + * > > + * @param input > > + * InputStream to wrap. > > + * @param doEncode > > + * true if we should encode all data read from us, false > > if we should decode. > > + * @param lineLength > > + * If doEncode is true, each line of encoded data will > > contain lineLength characters (rounded down to > > + * nearest multiple of 4). If lineLength <= 0, the > > encoded data is not divided into lines. If doEncode > > + * is false, lineLength is ignored. > > + * @param lineSeparator > > + * If doEncode is true, each line of encoded data will be > > terminated with this byte sequence (e.g. \r\n). > > + * If lineLength <= 0, the lineSeparator is not used. > > If doEncode is false lineSeparator is ignored. > > + * @param decodingPolicy > > + * The decoding policy. > > + * @since 1.15 > > + */ > > + public Base32InputStream(final InputStream input, final boolean > > doEncode, > > + final int lineLength, final byte[] > > lineSeparator, final CodecPolicy decodingPolicy) { > > + super(input, new Base32(lineLength, lineSeparator, false, > > BaseNCodec.PAD_DEFAULT, decodingPolicy), doEncode); > > + } > > + > > } > > diff --git > > a/src/main/java/org/apache/commons/codec/binary/Base32OutputStream.java > > b/src/main/java/org/apache/commons/codec/binary/Base32OutputStream.java > > index be0a7a4..a553a7d 100644 > > --- > a/src/main/java/org/apache/commons/codec/binary/Base32OutputStream.java > > +++ > b/src/main/java/org/apache/commons/codec/binary/Base32OutputStream.java > > @@ -19,6 +19,8 @@ package org.apache.commons.codec.binary; > > > > import java.io.OutputStream; > > > > +import org.apache.commons.codec.CodecPolicy; > > + > > /** > > * Provides Base32 encoding and decoding in a streaming fashion > > (unlimited size). When encoding the default lineLength > > * is 76 characters and the default lineEnding is CRLF, but these can be > > overridden by using the appropriate > > @@ -35,7 +37,22 @@ import java.io.OutputStream; > > * <b>Note:</b> It is mandatory to close the stream after the last byte > > has been written to it, otherwise the > > * final padding will be omitted and the resulting data will be > > incomplete/inconsistent. > > * </p> > > - * > > + * <p> > > + * You can set the decoding behavior when the input bytes contain > > leftover trailing bits that cannot be created by a valid > > + * encoding. These can be bits that are unused from the final character > > or entire characters. The default mode is > > + * lenient decoding. > > + * </p> > > + * <ul> > > + * <li>Lenient: Any trailing bits are composed into 8-bit bytes where > > possible. The remainder are discarded. > > + * <li>Strict: The decoding will raise an {@link > > IllegalArgumentException} if trailing bits are not part of a valid > > + * encoding. Any unused bits from the final character must be zero. > > Impossible counts of entire final characters are not > > + * allowed. > > + * </ul> > > + * <p> > > + * When strict decoding is enabled it is expected that the decoded bytes > > will be re-encoded to a byte array that matches > > + * the original, i.e. no changes occur on the final character. This > > requires that the input bytes use the same padding > > + * and alphabet as the encoder. > > + * </p> > > * @see <a href="http://www.ietf.org/rfc/rfc4648.txt">RFC 4648</a> > > * @since 1.5 > > */ > > @@ -85,4 +102,27 @@ public class Base32OutputStream extends > > BaseNCodecOutputStream { > > super(ouput, new Base32(lineLength, lineSeparator), doEncode); > > } > > > > + /** > > + * Creates a Base32OutputStream such that all data written is either > > Base32-encoded or Base32-decoded to the > > + * original provided OutputStream. > > + * > > + * @param ouput > > + * OutputStream to wrap. > > + * @param doEncode > > + * true if we should encode all data written to us, false > > if we should decode. > > + * @param lineLength > > + * If doEncode is true, each line of encoded data will > > contain lineLength characters (rounded down to > > + * nearest multiple of 4). If lineLength <= 0, the > > encoded data is not divided into lines. If doEncode > > + * is false, lineLength is ignored. > > + * @param lineSeparator > > + * If doEncode is true, each line of encoded data will be > > terminated with this byte sequence (e.g. \r\n). > > + * If lineLength <= 0, the lineSeparator is not used. > > If doEncode is false lineSeparator is ignored. > > + * @param decodingPolicy The decoding policy. > > + * @since 1.15 > > + */ > > + public Base32OutputStream(final OutputStream ouput, final boolean > > doEncode, > > + final int lineLength, final byte[] > > lineSeparator, final CodecPolicy decodingPolicy) { > > + super(ouput, new Base32(lineLength, lineSeparator, false, > > BaseNCodec.PAD_DEFAULT, decodingPolicy), doEncode); > > + } > > + > > } > > 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 5311207..178633d 100644 > > --- a/src/main/java/org/apache/commons/codec/binary/Base64.java > > +++ b/src/main/java/org/apache/commons/codec/binary/Base64.java > > @@ -20,6 +20,8 @@ package org.apache.commons.codec.binary; > > import java.math.BigInteger; > > import java.util.Objects; > > > > +import org.apache.commons.codec.CodecPolicy; > > + > > /** > > * Provides Base64 encoding and decoding as defined by <a href=" > > http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>. > > * > > @@ -63,17 +65,6 @@ public class Base64 extends BaseNCodec { > > private static final int BYTES_PER_ENCODED_BLOCK = 4; > > > > /** > > - * Chunk separator per RFC 2045 section 2.1. > > - * > > - * <p> > > - * N.B. The next major release may break compatibility and make this > > field private. > > - * </p> > > - * > > - * @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045 > > section 2.1</a> > > - */ > > - static final byte[] CHUNK_SEPARATOR = {'\r', '\n'}; > > - > > - /** > > * This array is a lookup table that translates 6-bit positive > > integer index values into their "Base64 Alphabet" > > * equivalents as specified in Table 1 of RFC 2045. > > * > > @@ -272,13 +263,47 @@ public class Base64 extends BaseNCodec { > > * operations. Decoding seamlessly handles both modes. > > * <b>Note: no padding is added when using the URL-safe > > alphabet.</b> > > * @throws IllegalArgumentException > > - * The provided lineSeparator included some base64 > > characters. That's not going to work! > > + * Thrown when the {@code lineSeparator} contains Base64 > > characters. > > * @since 1.4 > > */ > > public Base64(final int lineLength, final byte[] lineSeparator, > final > > boolean urlSafe) { > > + this(lineLength, lineSeparator, urlSafe, > DECODING_POLICY_DEFAULT); > > + } > > + > > + /** > > + * Creates 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 nearest multiple of > > + * 4). If lineLength <= 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. > > + * @param urlSafe > > + * Instead of emitting '+' and '/' we emit '-' and '_' > > respectively. urlSafe is only applied to encode > > + * operations. Decoding seamlessly handles both modes. > > + * <b>Note: no padding is added when using the URL-safe > > alphabet.</b> > > + * @param decodingPolicy The decoding policy. > > + * @throws IllegalArgumentException > > + * Thrown when the {@code lineSeparator} contains Base64 > > characters. > > + * @since 1.15 > > + */ > > + public Base64(final int lineLength, final byte[] lineSeparator, > final > > boolean urlSafe, final CodecPolicy decodingPolicy) { > > super(BYTES_PER_UNENCODED_BLOCK, BYTES_PER_ENCODED_BLOCK, > > lineLength, > > - lineSeparator == null ? 0 : lineSeparator.length); > > + lineSeparator == null ? 0 : lineSeparator.length, > > + PAD_DEFAULT, > > + decodingPolicy); > > // 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) { > > @@ -372,7 +397,7 @@ public class Base64 extends BaseNCodec { > > } > > break; > > default: > > - throw new IllegalStateException("Impossible modulus > > "+context.modulus); > > + throw new IllegalStateException("Impossible modulus > " > > + context.modulus); > > } > > context.currentLinePos += context.pos - savedPos; // keep > > track of current line position > > // if currentPos == 0 we are at the start of a line, so > don't > > add CRLF > > @@ -485,7 +510,7 @@ public class Base64 extends BaseNCodec { > > buffer[context.pos++] = (byte) > > ((context.ibitWorkArea) & MASK_8BITS); > > break; > > default: > > - throw new IllegalStateException("Impossible modulus > > "+context.modulus); > > + throw new IllegalStateException("Impossible modulus > " > > + context.modulus); > > } > > } > > } > > @@ -819,4 +844,5 @@ public class Base64 extends BaseNCodec { > > "Expected the discarded bits from the character to be > > zero."); > > } > > } > > + > > } > > diff --git > > a/src/main/java/org/apache/commons/codec/binary/Base64InputStream.java > > b/src/main/java/org/apache/commons/codec/binary/Base64InputStream.java > > index 0a09bd8..7755ce1 100644 > > --- > a/src/main/java/org/apache/commons/codec/binary/Base64InputStream.java > > +++ > b/src/main/java/org/apache/commons/codec/binary/Base64InputStream.java > > @@ -19,6 +19,8 @@ package org.apache.commons.codec.binary; > > > > import java.io.InputStream; > > > > +import org.apache.commons.codec.CodecPolicy; > > + > > /** > > * Provides Base64 encoding and decoding in a streaming fashion > > (unlimited size). When encoding the default lineLength > > * is 76 characters and the default lineEnding is CRLF, but these can be > > overridden by using the appropriate > > @@ -35,7 +37,22 @@ import java.io.InputStream; > > * Since this class operates directly on byte streams, and not character > > streams, it is hard-coded to only encode/decode > > * character encodings which are compatible with the lower 127 ASCII > > chart (ISO-8859-1, Windows-1252, UTF-8, etc). > > * </p> > > - * > > + * <p> > > + * You can set the decoding behavior when the input bytes contain > > leftover trailing bits that cannot be created by a valid > > + * encoding. These can be bits that are unused from the final character > > or entire characters. The default mode is > > + * lenient decoding. > > + * </p> > > + * <ul> > > + * <li>Lenient: Any trailing bits are composed into 8-bit bytes where > > possible. The remainder are discarded. > > + * <li>Strict: The decoding will raise an {@link > > IllegalArgumentException} if trailing bits are not part of a valid > > + * encoding. Any unused bits from the final character must be zero. > > Impossible counts of entire final characters are not > > + * allowed. > > + * </ul> > > + * <p> > > + * When strict decoding is enabled it is expected that the decoded bytes > > will be re-encoded to a byte array that matches > > + * the original, i.e. no changes occur on the final character. This > > requires that the input bytes use the same padding > > + * and alphabet as the encoder. > > + * </p> > > * @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a> > > * @since 1.4 > > */ > > @@ -84,4 +101,27 @@ public class Base64InputStream extends > > BaseNCodecInputStream { > > final int lineLength, final byte[] > > lineSeparator) { > > super(in, new Base64(lineLength, lineSeparator), doEncode); > > } > > + > > + /** > > + * Creates a Base64InputStream such that all data read is either > > Base64-encoded or Base64-decoded from the original > > + * provided InputStream. > > + * > > + * @param in > > + * InputStream to wrap. > > + * @param doEncode > > + * true if we should encode all data read from us, false > > if we should decode. > > + * @param lineLength > > + * If doEncode is true, each line of encoded data will > > contain lineLength characters (rounded down to > > + * nearest multiple of 4). If lineLength <= 0, the > > encoded data is not divided into lines. If doEncode > > + * is false, lineLength is ignored. > > + * @param lineSeparator > > + * If doEncode is true, each line of encoded data will be > > terminated with this byte sequence (e.g. \r\n). > > + * If lineLength <= 0, the lineSeparator is not used. > > If doEncode is false lineSeparator is ignored. > > + * @param decodingPolicy The decoding policy. > > + * @since 1.15 > > + */ > > + public Base64InputStream(final InputStream in, final boolean > doEncode, > > + final int lineLength, final byte[] > > lineSeparator, final CodecPolicy decodingPolicy) { > > + super(in, new Base64(lineLength, lineSeparator, false, > > decodingPolicy), doEncode); > > + } > > } > > diff --git > > a/src/main/java/org/apache/commons/codec/binary/Base64OutputStream.java > > b/src/main/java/org/apache/commons/codec/binary/Base64OutputStream.java > > index 07d6b5c..aa9be55 100644 > > --- > a/src/main/java/org/apache/commons/codec/binary/Base64OutputStream.java > > +++ > b/src/main/java/org/apache/commons/codec/binary/Base64OutputStream.java > > @@ -19,6 +19,8 @@ package org.apache.commons.codec.binary; > > > > import java.io.OutputStream; > > > > +import org.apache.commons.codec.CodecPolicy; > > + > > /** > > * Provides Base64 encoding and decoding in a streaming fashion > > (unlimited size). When encoding the default lineLength > > * is 76 characters and the default lineEnding is CRLF, but these can be > > overridden by using the appropriate > > @@ -39,7 +41,22 @@ import java.io.OutputStream; > > * <b>Note:</b> It is mandatory to close the stream after the last byte > > has been written to it, otherwise the > > * final padding will be omitted and the resulting data will be > > incomplete/inconsistent. > > * </p> > > - * > > + * <p> > > + * You can set the decoding behavior when the input bytes contain > > leftover trailing bits that cannot be created by a valid > > + * encoding. These can be bits that are unused from the final character > > or entire characters. The default mode is > > + * lenient decoding. > > + * </p> > > + * <ul> > > + * <li>Lenient: Any trailing bits are composed into 8-bit bytes where > > possible. The remainder are discarded. > > + * <li>Strict: The decoding will raise an {@link > > IllegalArgumentException} if trailing bits are not part of a valid > > + * encoding. Any unused bits from the final character must be zero. > > Impossible counts of entire final characters are not > > + * allowed. > > + * </ul> > > + * <p> > > + * When strict decoding is enabled it is expected that the decoded bytes > > will be re-encoded to a byte array that matches > > + * the original, i.e. no changes occur on the final character. This > > requires that the input bytes use the same padding > > + * and alphabet as the encoder. > > + * </p> > > * @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a> > > * @since 1.4 > > */ > > @@ -88,4 +105,27 @@ public class Base64OutputStream extends > > BaseNCodecOutputStream { > > final int lineLength, final byte[] > > lineSeparator) { > > super(out, new Base64(lineLength, lineSeparator), doEncode); > > } > > + > > + /** > > + * Creates a Base64OutputStream such that all data written is either > > Base64-encoded or Base64-decoded to the > > + * original provided OutputStream. > > + * > > + * @param out > > + * OutputStream to wrap. > > + * @param doEncode > > + * true if we should encode all data written to us, false > > if we should decode. > > + * @param lineLength > > + * If doEncode is true, each line of encoded data will > > contain lineLength characters (rounded down to > > + * nearest multiple of 4). If lineLength <= 0, the > > encoded data is not divided into lines. If doEncode > > + * is false, lineLength is ignored. > > + * @param lineSeparator > > + * If doEncode is true, each line of encoded data will be > > terminated with this byte sequence (e.g. \r\n). > > + * If lineLength <= 0, the lineSeparator is not used. > > If doEncode is false lineSeparator is ignored. > > + * @param decodingPolicy The decoding policy. > > + * @since 1.15 > > + */ > > + public Base64OutputStream(final OutputStream out, final boolean > > doEncode, > > + final int lineLength, final byte[] > > lineSeparator, final CodecPolicy decodingPolicy) { > > + super(out, new Base64(lineLength, lineSeparator, false, > > decodingPolicy), doEncode); > > + } > > } > > 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 4c983c6..b45437d 100644 > > --- a/src/main/java/org/apache/commons/codec/binary/BaseNCodec.java > > +++ b/src/main/java/org/apache/commons/codec/binary/BaseNCodec.java > > @@ -18,9 +18,11 @@ > > package org.apache.commons.codec.binary; > > > > import java.util.Arrays; > > +import java.util.Objects; > > > > import org.apache.commons.codec.BinaryDecoder; > > import org.apache.commons.codec.BinaryEncoder; > > +import org.apache.commons.codec.CodecPolicy; > > import org.apache.commons.codec.DecoderException; > > import org.apache.commons.codec.EncoderException; > > > > @@ -31,6 +33,20 @@ import org.apache.commons.codec.EncoderException; > > * This class is thread-safe. > > * </p> > > * > > + * You can set the decoding behavior when the input bytes contain > > leftover trailing bits that cannot be created by a valid > > + * encoding. These can be bits that are unused from the final character > > or entire characters. The default mode is > > + * lenient decoding. > > + * <ul> > > + * <li>Lenient: Any trailing bits are composed into 8-bit bytes where > > possible. The remainder are discarded. > > + * <li>Strict: The decoding will raise an {@link > > IllegalArgumentException} if trailing bits are not part of a valid > > + * encoding. Any unused bits from the final character must be zero. > > Impossible counts of entire final characters are not > > + * allowed. > > + * </ul> > > + * <p> > > + * When strict decoding is enabled it is expected that the decoded bytes > > will be re-encoded to a byte array that matches > > + * the original, i.e. no changes occur on the final character. This > > requires that the input bytes use the same padding > > + * and alphabet as the encoder. > > + * </p> > > */ > > public abstract class BaseNCodec implements BinaryEncoder, > BinaryDecoder { > > > > @@ -165,6 +181,18 @@ public abstract class BaseNCodec implements > > BinaryEncoder, BinaryDecoder { > > protected static final byte PAD_DEFAULT = '='; // Allow static > access > > to default > > > > /** > > + * The default decoding policy. > > + */ > > + protected static final CodecPolicy DECODING_POLICY_DEFAULT = > > CodecPolicy.LENIENT; > > + > > + /** > > + * Chunk separator per RFC 2045 section 2.1. > > + * > > + * @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045 > > section 2.1</a> > > + */ > > + static final byte[] CHUNK_SEPARATOR = {'\r', '\n'}; > > + > > + /** > > * @deprecated Use {@link #pad}. Will be removed in 2.0. > > */ > > @Deprecated > > @@ -191,10 +219,24 @@ public abstract class BaseNCodec implements > > BinaryEncoder, BinaryDecoder { > > private final int chunkSeparatorLength; > > > > /** > > - * If true then decoding should throw an exception for impossible > > combinations of bits at the > > - * end of the byte input. The default is to decode as much of them > as > > possible. > > + * Defines the decoding behavior when the input bytes contain > > leftover trailing bits that > > + * cannot be created by a valid encoding. These can be bits that are > > unused from the final > > + * character or entire characters. The default mode is lenient > > decoding. Set this to > > + * {@code true} to enable strict decoding. > > + * <ul> > > + * <li>Lenient: Any trailing bits are composed into 8-bit bytes > where > > possible. > > + * The remainder are discarded. > > + * <li>Strict: The decoding will raise an {@link > > IllegalArgumentException} if trailing bits > > + * are not part of a valid encoding. Any unused bits from the > > final character must > > + * be zero. Impossible counts of entire final characters are not > > allowed. > > + * </ul> > > + * > > + * <p>When strict decoding is enabled it is expected that the > decoded > > bytes will be re-encoded > > + * to a byte array that matches the original, i.e. no changes occur > > on the final > > + * character. This requires that the input bytes use the same > padding > > and alphabet > > + * as the encoder. > > */ > > - private boolean strictDecoding; > > + private final CodecPolicy decodingPolicy; > > > > /** > > * Note {@code lineLength} is rounded down to the nearest multiple > of > > the encoded block size. > > @@ -220,54 +262,60 @@ public abstract class BaseNCodec implements > > BinaryEncoder, BinaryDecoder { > > */ > > protected BaseNCodec(final int unencodedBlockSize, final int > > encodedBlockSize, > > final int lineLength, final int > > chunkSeparatorLength, final byte pad) { > > + this(unencodedBlockSize, encodedBlockSize, lineLength, > > chunkSeparatorLength, pad, DECODING_POLICY_DEFAULT); > > + } > > + > > + /** > > + * Note {@code lineLength} is rounded down to the nearest multiple > of > > the encoded block size. > > + * If {@code chunkSeparatorLength} is zero, then chunking is > disabled. > > + * @param unencodedBlockSize the size of an unencoded block (e.g. > > Base64 = 3) > > + * @param encodedBlockSize the size of an encoded block (e.g. Base64 > > = 4) > > + * @param lineLength if > 0, use chunking with a length {@code > > lineLength} > > + * @param chunkSeparatorLength the chunk separator length, if > relevant > > + * @param pad byte used as padding byte. > > + * @param decodingPolicy Decoding policy. > > + * @since 1.15 > > + */ > > + protected BaseNCodec(final int unencodedBlockSize, final int > > encodedBlockSize, > > + final int lineLength, final int > > chunkSeparatorLength, final byte pad, final CodecPolicy decodingPolicy) { > > this.unencodedBlockSize = unencodedBlockSize; > > this.encodedBlockSize = encodedBlockSize; > > final boolean useChunking = lineLength > 0 && > > chunkSeparatorLength > 0; > > this.lineLength = useChunking ? (lineLength / encodedBlockSize) > * > > encodedBlockSize : 0; > > this.chunkSeparatorLength = chunkSeparatorLength; > > - > > this.pad = pad; > > + this.decodingPolicy = Objects.requireNonNull(decodingPolicy, > > "codecPolicy"); > > } > > > > /** > > - * Sets the decoding behavior when the input bytes contain leftover > > trailing bits that > > - * cannot be created by a valid encoding. These can be bits that are > > unused from the final > > - * character or entire characters. The default mode is lenient > > decoding. Set this to > > - * {@code true} to enable strict decoding. > > - * <ul> > > - * <li>Lenient: Any trailing bits are composed into 8-bit bytes > where > > possible. > > - * The remainder are discarded. > > - * <li>Strict: The decoding will raise an {@link > > IllegalArgumentException} if trailing bits > > - * are not part of a valid encoding. Any unused bits from the > > final character must > > - * be zero. Impossible counts of entire final characters are not > > allowed. > > - * </ul> > > + * Returns true if decoding behavior is strict. Decoding will raise > > an {@link IllegalArgumentException} if trailing > > + * bits are not part of a valid encoding. > > * > > - * <p>When strict decoding is enabled it is expected that the > decoded > > bytes will be re-encoded > > - * to a byte array that matches the original, i.e. no changes occur > > on the final > > - * character. This requires that the input bytes use the same > padding > > and alphabet > > - * as the encoder. > > + * <p> > > + * The default is false for lenient encoding. Decoding will compose > > trailing bits into 8-bit bytes and discard the > > + * remainder. > > + * </p> > > * > > - * @param strictDecoding Set to true to enable strict decoding; > > otherwise use lenient decoding. > > - * @see #encode(byte[]) > > + * @return true if using strict decoding > > * @since 1.15 > > */ > > - public void setStrictDecoding(boolean strictDecoding) { > > - this.strictDecoding = strictDecoding; > > + public boolean isStrictDecoding() { > > + return decodingPolicy == CodecPolicy.STRICT; > > } > > > > /** > > - * Returns true if decoding behavior is strict. Decoding will raise > an > > - * {@link IllegalArgumentException} if trailing bits are not part of > > a valid encoding. > > + * Returns the decoding behavior policy. Decoding will raise an > > {@link IllegalArgumentException} if trailing bits > > + * are not part of a valid encoding. > > * > > - * <p>The default is false for lenient encoding. Decoding will > > compose trailing bits > > - * into 8-bit bytes and discard the remainder. > > + * <p> > > + * The default is lenient. Decoding will compose trailing bits into > > 8-bit bytes and discard the remainder. > > + * </p> > > * > > * @return true if using strict decoding > > - * @see #setStrictDecoding(boolean) > > * @since 1.15 > > */ > > - public boolean isStrictDecoding() { > > - return strictDecoding; > > + public CodecPolicy getCodecPolicy() { > > + return decodingPolicy; > > } > > > > /** > > @@ -418,6 +466,17 @@ public abstract class BaseNCodec implements > > BinaryEncoder, BinaryDecoder { > > } > > > > /** > > + * Gets a copy of the chunk separator per RFC 2045 section 2.1. > > + * > > + * @return the chunk separator > > + * @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045 > > section 2.1</a> > > + * @since 1.15 > > + */ > > + public static byte[] getChunkSeparator() { > > + return CHUNK_SEPARATOR.clone(); > > + } > > + > > + /** > > * Checks if a byte value is whitespace or not. > > * Whitespace is taken to mean: space, tab, CR, LF > > * @param byteToCheck > > 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 c183c43..90792f1 100644 > > --- > > > a/src/main/java/org/apache/commons/codec/binary/BaseNCodecInputStream.java > > +++ > > > b/src/main/java/org/apache/commons/codec/binary/BaseNCodecInputStream.java > > @@ -48,25 +48,6 @@ public class BaseNCodecInputStream extends > > FilterInputStream { > > } > > > > /** > > - * Sets the decoding behavior when the input bytes contain leftover > > trailing bits that > > - * cannot be created by a valid encoding. This setting is > transferred > > to the instance > > - * of {@link BaseNCodec} used to perform decoding. > > - * > > - * <p>The default is false for lenient encoding. Decoding will > > compose trailing bits > > - * into 8-bit bytes and discard the remainder. > > - * > > - * <p>Set to true to enable strict decoding. Decoding will raise an > > - * {@link IllegalArgumentException} if trailing bits are not part of > > a valid encoding. > > - * > > - * @param strictDecoding Set to true to enable strict decoding; > > otherwise use lenient decoding. > > - * @see BaseNCodec#setStrictDecoding(boolean) > > - * @since 1.15 > > - */ > > - public void setStrictDecoding(boolean strictDecoding) { > > - baseNCodec.setStrictDecoding(strictDecoding); > > - } > > - > > - /** > > * Returns true if decoding behavior is strict. Decoding will raise > an > > * {@link IllegalArgumentException} if trailing bits are not part of > > a valid encoding. > > * > > @@ -74,7 +55,6 @@ public class BaseNCodecInputStream extends > > FilterInputStream { > > * into 8-bit bytes and discard the remainder. > > * > > * @return true if using strict decoding > > - * @see #setStrictDecoding(boolean) > > * @since 1.15 > > */ > > public boolean isStrictDecoding() { > > 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 71b2a13..bc27e07 100644 > > --- > > > a/src/main/java/org/apache/commons/codec/binary/BaseNCodecOutputStream.java > > +++ > > > b/src/main/java/org/apache/commons/codec/binary/BaseNCodecOutputStream.java > > @@ -61,25 +61,6 @@ public class BaseNCodecOutputStream extends > > FilterOutputStream { > > } > > > > /** > > - * Sets the decoding behavior when the input bytes contain leftover > > trailing bits that > > - * cannot be created by a valid encoding. This setting is > transferred > > to the instance > > - * of {@link BaseNCodec} used to perform decoding. > > - * > > - * <p>The default is false for lenient encoding. Decoding will > > compose trailing bits > > - * into 8-bit bytes and discard the remainder. > > - * > > - * <p>Set to true to enable strict decoding. Decoding will raise an > > - * {@link IllegalArgumentException} if trailing bits are not part of > > a valid encoding. > > - * > > - * @param strictDecoding Set to true to enable strict decoding; > > otherwise use lenient decoding. > > - * @see BaseNCodec#setStrictDecoding(boolean) > > - * @since 1.15 > > - */ > > - public void setStrictDecoding(boolean strictDecoding) { > > - baseNCodec.setStrictDecoding(strictDecoding); > > - } > > - > > - /** > > * Returns true if decoding behavior is strict. Decoding will raise > an > > * {@link IllegalArgumentException} if trailing bits are not part of > > a valid encoding. > > * > > @@ -87,7 +68,6 @@ public class BaseNCodecOutputStream extends > > FilterOutputStream { > > * into 8-bit bytes and discard the remainder. > > * > > * @return true if using strict decoding > > - * @see #setStrictDecoding(boolean) > > * @since 1.15 > > */ > > public boolean isStrictDecoding() { > > diff --git a/src/main/java/org/apache/commons/codec/net/BCodec.java > > b/src/main/java/org/apache/commons/codec/net/BCodec.java > > index b054e3b..e9f9ecc 100644 > > --- a/src/main/java/org/apache/commons/codec/net/BCodec.java > > +++ b/src/main/java/org/apache/commons/codec/net/BCodec.java > > @@ -21,11 +21,13 @@ import java.io.UnsupportedEncodingException; > > import java.nio.charset.Charset; > > import java.nio.charset.StandardCharsets; > > > > +import org.apache.commons.codec.CodecPolicy; > > import org.apache.commons.codec.DecoderException; > > import org.apache.commons.codec.EncoderException; > > import org.apache.commons.codec.StringDecoder; > > import org.apache.commons.codec.StringEncoder; > > import org.apache.commons.codec.binary.Base64; > > +import org.apache.commons.codec.binary.BaseNCodec; > > > > /** > > * Identical to the Base64 encoding defined by <a href=" > > http://www.ietf.org/rfc/rfc1521.txt">RFC 1521</a> > > @@ -43,6 +45,12 @@ import org.apache.commons.codec.binary.Base64; > > * @since 1.3 > > */ > > public class BCodec extends RFC1522Codec implements StringEncoder, > > StringDecoder { > > + > > + /** > > + * The default decoding policy. > > + */ > > + private static final CodecPolicy DECODING_POLICY_DEFAULT = > > CodecPolicy.LENIENT; > > + > > /** > > * The default Charset used for string decoding and encoding. > > */ > > @@ -52,7 +60,7 @@ public class BCodec extends RFC1522Codec implements > > StringEncoder, StringDecoder > > * If true then decoding should throw an exception for impossible > > combinations of bits at the > > * end of the byte input. The default is to decode as much of them > as > > possible. > > */ > > - private boolean strictDecoding; > > + private final CodecPolicy decodingPolicy; > > > > /** > > * Default constructor. > > @@ -72,6 +80,22 @@ public class BCodec extends RFC1522Codec implements > > StringEncoder, StringDecoder > > */ > > public BCodec(final Charset charset) { > > this.charset = charset; > > + this.decodingPolicy = DECODING_POLICY_DEFAULT; > > + } > > + > > + /** > > + * Constructor which allows for the selection of a default Charset. > > + * > > + * @param charset > > + * the default string Charset to use. > > + * @param decodingPolicy The decoding policy. > > + * > > + * @see <a href=" > > > http://download.oracle.com/javase/7/docs/api/java/nio/charset/Charset.html > ">Standard > > charsets</a> > > + * @since 1.15 > > + */ > > + public BCodec(final Charset charset, final CodecPolicy > > decodingPolicy) { > > + this.charset = charset; > > + this.decodingPolicy = decodingPolicy; > > } > > > > /** > > @@ -89,25 +113,6 @@ public class BCodec extends RFC1522Codec implements > > StringEncoder, StringDecoder > > } > > > > /** > > - * Sets the decoding behavior when the input bytes contain leftover > > trailing bits that > > - * cannot be created by a valid Base64 encoding. This setting is > > transferred to the instance > > - * of {@link Base64} used to perform decoding. > > - * > > - * <p>The default is false for lenient encoding. Decoding will > > compose trailing bits > > - * into 8-bit bytes and discard the remainder. > > - * > > - * <p>Set to true to enable strict decoding. Decoding will raise a > > - * {@link DecoderException} if trailing bits are not part of a valid > > Base64 encoding. > > - * > > - * @param strictDecoding Set to true to enable strict decoding; > > otherwise use lenient decoding. > > - * @see > > org.apache.commons.codec.binary.BaseNCodec#setStrictDecoding(boolean) > > BaseNCodec.setStrictDecoding(boolean) > > - * @since 1.15 > > - */ > > - public void setStrictDecoding(boolean strictDecoding) { > > - this.strictDecoding = strictDecoding; > > - } > > - > > - /** > > * Returns true if decoding behavior is strict. Decoding will raise > a > > * {@link DecoderException} if trailing bits are not part of a valid > > Base64 encoding. > > * > > @@ -115,11 +120,10 @@ public class BCodec extends RFC1522Codec implements > > StringEncoder, StringDecoder > > * into 8-bit bytes and discard the remainder. > > * > > * @return true if using strict decoding > > - * @see #setStrictDecoding(boolean) > > * @since 1.15 > > */ > > public boolean isStrictDecoding() { > > - return strictDecoding; > > + return decodingPolicy == CodecPolicy.STRICT; > > } > > > > @Override > > @@ -140,9 +144,7 @@ public class BCodec extends RFC1522Codec implements > > StringEncoder, StringDecoder > > if (bytes == null) { > > return null; > > } > > - final Base64 codec = new Base64(); > > - codec.setStrictDecoding(strictDecoding); > > - return codec.decode(bytes); > > + return new Base64(0, BaseNCodec.getChunkSeparator(), false, > > decodingPolicy).decode(bytes); > > } > > > > /** > > 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 85bcbb3..fe77eee 100644 > > --- > > > a/src/test/java/org/apache/commons/codec/binary/Base32InputStreamTest.java > > +++ > > > b/src/test/java/org/apache/commons/codec/binary/Base32InputStreamTest.java > > @@ -29,6 +29,7 @@ import java.io.IOException; > > import java.io.InputStream; > > import java.util.Arrays; > > > > +import org.apache.commons.codec.CodecPolicy; > > import org.junit.Test; > > > > public class Base32InputStreamTest { > > @@ -574,8 +575,7 @@ public class Base32InputStreamTest { > > Base32TestData.streamToBytes(in); > > > > // Strict decoding should throw > > - in = new Base32InputStream(new > ByteArrayInputStream(encoded), > > false); > > - in.setStrictDecoding(true); > > + in = new Base32InputStream(new > ByteArrayInputStream(encoded), > > false, 0, null, CodecPolicy.STRICT); > > assertTrue(in.isStrictDecoding()); > > try { > > Base32TestData.streamToBytes(in); > > 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 2cb09e0..a276f8e 100644 > > --- > > > a/src/test/java/org/apache/commons/codec/binary/Base32OutputStreamTest.java > > +++ > > > b/src/test/java/org/apache/commons/codec/binary/Base32OutputStreamTest.java > > @@ -25,11 +25,12 @@ import java.io.ByteArrayOutputStream; > > import java.io.OutputStream; > > import java.util.Arrays; > > > > +import org.apache.commons.codec.CodecPolicy; > > import org.junit.Test; > > > > public class Base32OutputStreamTest { > > > > - private final static byte[] CRLF = {(byte) '\r', (byte) '\n'}; > > + private final static byte[] CR_LF = {(byte) '\r', (byte) '\n'}; > > > > private final static byte[] LF = {(byte) '\n'}; > > > > @@ -84,8 +85,8 @@ public class Base32OutputStreamTest { > > private void testBase32EmptyOutputStream(final int chunkSize) throws > > Exception { > > final byte[] emptyEncoded = new byte[0]; > > final byte[] emptyDecoded = new byte[0]; > > - testByteByByte(emptyEncoded, emptyDecoded, chunkSize, CRLF); > > - testByChunk(emptyEncoded, emptyDecoded, chunkSize, CRLF); > > + testByteByByte(emptyEncoded, emptyDecoded, chunkSize, CR_LF); > > + testByChunk(emptyEncoded, emptyDecoded, chunkSize, CR_LF); > > } > > > > /** > > @@ -99,7 +100,7 @@ public class Base32OutputStreamTest { > > // Hello World test. > > byte[] encoded = > > StringUtils.getBytesUtf8(Base32TestData.BASE32_FIXTURE); > > byte[] decoded = > > StringUtils.getBytesUtf8(Base32TestData.STRING_FIXTURE); > > - testByChunk(encoded, decoded, BaseNCodec.MIME_CHUNK_SIZE, CRLF); > > + testByChunk(encoded, decoded, BaseNCodec.MIME_CHUNK_SIZE, > CR_LF); > > > > // // Single Byte test. > > // encoded = StringUtils.getBytesUtf8("AA==\r\n"); > > @@ -134,7 +135,7 @@ public class Base32OutputStreamTest { > > // Hello World test. > > byte[] encoded = > > StringUtils.getBytesUtf8(Base32TestData.BASE32_FIXTURE); > > byte[] decoded = > > StringUtils.getBytesUtf8(Base32TestData.STRING_FIXTURE); > > - testByteByByte(encoded, decoded, 76, CRLF); > > + testByteByByte(encoded, decoded, 76, CR_LF); > > > > // // Single Byte test. > > // encoded = StringUtils.getBytesUtf8("AA==\r\n"); > > @@ -354,8 +355,7 @@ public class Base32OutputStreamTest { > > > > // Strict decoding should throw > > bout = new ByteArrayOutputStream(); > > - out = new Base32OutputStream(bout, false); > > - out.setStrictDecoding(true); > > + out = new Base32OutputStream(bout, false, 0, null, > > CodecPolicy.STRICT); > > assertTrue(out.isStrictDecoding()); > > try { > > out.write(encoded); > > 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 7033e91..65c828e 100644 > > --- a/src/test/java/org/apache/commons/codec/binary/Base32Test.java > > +++ b/src/test/java/org/apache/commons/codec/binary/Base32Test.java > > @@ -18,9 +18,9 @@ > > > > package org.apache.commons.codec.binary; > > > > +import static org.junit.Assert.assertArrayEquals; > > import static org.junit.Assert.assertEquals; > > import static org.junit.Assert.assertFalse; > > -import static org.junit.Assert.assertArrayEquals; > > import static org.junit.Assert.assertNotNull; > > import static org.junit.Assert.assertTrue; > > import static org.junit.Assert.fail; > > @@ -29,6 +29,7 @@ import java.nio.charset.Charset; > > import java.nio.charset.StandardCharsets; > > import java.util.Arrays; > > > > +import org.apache.commons.codec.CodecPolicy; > > import org.apache.commons.codec.DecoderException; > > import org.apache.commons.lang3.ArrayUtils; > > import org.junit.Test; > > @@ -291,21 +292,24 @@ public class Base32Test { > > > > @Test > > public void testBase32ImpossibleSamples() { > > - testImpossibleCases(new Base32(), BASE32_IMPOSSIBLE_CASES); > > + testImpossibleCases(new Base32(0, null, false, > > BaseNCodec.PAD_DEFAULT, CodecPolicy.STRICT), > > + BASE32_IMPOSSIBLE_CASES); > > } > > > > @Test > > public void testBase32ImpossibleChunked() { > > - testImpossibleCases(new Base32(20), > > BASE32_IMPOSSIBLE_CASES_CHUNKED); > > + testImpossibleCases( > > + new Base32(20, BaseNCodec.CHUNK_SEPARATOR, false, > > BaseNCodec.PAD_DEFAULT, CodecPolicy.STRICT), > > + BASE32_IMPOSSIBLE_CASES_CHUNKED); > > } > > > > @Test > > public void testBase32HexImpossibleSamples() { > > - testImpossibleCases(new Base32(true), > BASE32HEX_IMPOSSIBLE_CASES); > > + testImpossibleCases(new Base32(0, null, true, > > BaseNCodec.PAD_DEFAULT, CodecPolicy.STRICT), > > + BASE32HEX_IMPOSSIBLE_CASES); > > } > > > > private void testImpossibleCases(final Base32 codec, final String[] > > impossible_cases) { > > - codec.setStrictDecoding(true); > > for (final String impossible : impossible_cases) { > > try { > > codec.decode(impossible); > > @@ -360,9 +364,8 @@ public class Base32Test { > > * @param nbits the number of trailing bits (must be a factor of 5 > > and {@code <40}) > > */ > > private static void assertBase32DecodingOfTrailingBits(final int > > nbits) { > > - final Base32 codec = new Base32(); > > // Requires strict decoding > > - codec.setStrictDecoding(true); > > + final Base32 codec = new Base32(0, null, false, > > BaseNCodec.PAD_DEFAULT, CodecPolicy.STRICT); > > assertTrue(codec.isStrictDecoding()); > > // A lenient decoder should not re-encode to the same bytes > > final Base32 defaultCodec = new Base32(); > > 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 2b1f5cf..83a0285 100644 > > --- > > > a/src/test/java/org/apache/commons/codec/binary/Base64InputStreamTest.java > > +++ > > > b/src/test/java/org/apache/commons/codec/binary/Base64InputStreamTest.java > > @@ -32,6 +32,7 @@ import java.io.InputStream; > > import java.io.InputStreamReader; > > import java.util.Arrays; > > > > +import org.apache.commons.codec.CodecPolicy; > > import org.junit.Test; > > > > /** > > @@ -587,8 +588,7 @@ public class Base64InputStreamTest { > > Base64TestData.streamToBytes(in); > > > > // Strict decoding should throw > > - in = new Base64InputStream(new > ByteArrayInputStream(encoded), > > false); > > - in.setStrictDecoding(true); > > + in = new Base64InputStream(new > ByteArrayInputStream(encoded), > > false, 0, null, CodecPolicy.STRICT); > > assertTrue(in.isStrictDecoding()); > > try { > > Base64TestData.streamToBytes(in); > > 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 b644363..a2e3157 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 java.io.ByteArrayOutputStream; > > import java.io.OutputStream; > > import java.util.Arrays; > > > > +import org.apache.commons.codec.CodecPolicy; > > import org.junit.Test; > > > > /** > > @@ -33,7 +34,7 @@ import org.junit.Test; > > */ > > public class Base64OutputStreamTest { > > > > - private final static byte[] CRLF = {(byte) '\r', (byte) '\n'}; > > + private final static byte[] CR_LF = {(byte) '\r', (byte) '\n'}; > > > > private final static byte[] LF = {(byte) '\n'}; > > > > @@ -86,8 +87,8 @@ public class Base64OutputStreamTest { > > private void testBase64EmptyOutputStream(final int chunkSize) throws > > Exception { > > final byte[] emptyEncoded = new byte[0]; > > final byte[] emptyDecoded = new byte[0]; > > - testByteByByte(emptyEncoded, emptyDecoded, chunkSize, CRLF); > > - testByChunk(emptyEncoded, emptyDecoded, chunkSize, CRLF); > > + testByteByByte(emptyEncoded, emptyDecoded, chunkSize, CR_LF); > > + testByChunk(emptyEncoded, emptyDecoded, chunkSize, CR_LF); > > } > > > > /** > > @@ -101,12 +102,12 @@ public class Base64OutputStreamTest { > > // Hello World test. > > byte[] encoded = > StringUtils.getBytesUtf8("SGVsbG8gV29ybGQ=\r\n"); > > byte[] decoded = StringUtils.getBytesUtf8(STRING_FIXTURE); > > - testByChunk(encoded, decoded, BaseNCodec.MIME_CHUNK_SIZE, CRLF); > > + testByChunk(encoded, decoded, BaseNCodec.MIME_CHUNK_SIZE, > CR_LF); > > > > // Single Byte test. > > encoded = StringUtils.getBytesUtf8("AA==\r\n"); > > decoded = new byte[]{(byte) 0}; > > - testByChunk(encoded, decoded, BaseNCodec.MIME_CHUNK_SIZE, CRLF); > > + testByChunk(encoded, decoded, BaseNCodec.MIME_CHUNK_SIZE, > CR_LF); > > > > // OpenSSL interop test. > > encoded = > > StringUtils.getBytesUtf8(Base64TestData.ENCODED_64_CHARS_PER_LINE); > > @@ -139,12 +140,12 @@ public class Base64OutputStreamTest { > > // Hello World test. > > byte[] encoded = > StringUtils.getBytesUtf8("SGVsbG8gV29ybGQ=\r\n"); > > byte[] decoded = StringUtils.getBytesUtf8(STRING_FIXTURE); > > - testByteByByte(encoded, decoded, 76, CRLF); > > + testByteByByte(encoded, decoded, 76, CR_LF); > > > > // Single Byte test. > > encoded = StringUtils.getBytesUtf8("AA==\r\n"); > > decoded = new byte[]{(byte) 0}; > > - testByteByByte(encoded, decoded, 76, CRLF); > > + testByteByByte(encoded, decoded, 76, CR_LF); > > > > // OpenSSL interop test. > > encoded = > > StringUtils.getBytesUtf8(Base64TestData.ENCODED_64_CHARS_PER_LINE); > > @@ -362,8 +363,7 @@ public class Base64OutputStreamTest { > > > > // Strict decoding should throw > > bout = new ByteArrayOutputStream(); > > - out = new Base64OutputStream(bout, false); > > - out.setStrictDecoding(true); > > + out = new Base64OutputStream(bout, false, 0, null, > > CodecPolicy.STRICT); > > assertTrue(out.isStrictDecoding()); > > try { > > out.write(encoded); > > 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 8d79f59..884b4a2 100644 > > --- a/src/test/java/org/apache/commons/codec/binary/Base64Test.java > > +++ b/src/test/java/org/apache/commons/codec/binary/Base64Test.java > > @@ -30,6 +30,7 @@ import java.nio.charset.StandardCharsets; > > import java.util.Arrays; > > import java.util.Random; > > > > +import org.apache.commons.codec.CodecPolicy; > > import org.apache.commons.codec.DecoderException; > > import org.apache.commons.codec.EncoderException; > > import org.apache.commons.lang3.ArrayUtils; > > @@ -1323,8 +1324,7 @@ public class Base64Test { > > > > @Test > > public void testBase64ImpossibleSamples() { > > - final Base64 codec = new Base64(); > > - codec.setStrictDecoding(true); > > + final Base64 codec = new Base64(0, null, false, > > CodecPolicy.STRICT); > > for (final String s : BASE64_IMPOSSIBLE_CASES) { > > try { > > codec.decode(s); > > @@ -1359,9 +1359,8 @@ public class Base64Test { > > * @param nbits the number of trailing bits (must be a factor of 6 > > and {@code <24}) > > */ > > private static void assertBase64DecodingOfTrailingBits(final int > > nbits) { > > - final Base64 codec = new Base64(); > > + final Base64 codec = new Base64(0, null, false, > > CodecPolicy.STRICT); > > // Requires strict decoding > > - codec.setStrictDecoding(true); > > assertTrue(codec.isStrictDecoding()); > > // A lenient decoder should not re-encode to the same bytes > > final Base64 defaultCodec = new Base64(); > > diff --git a/src/test/java/org/apache/commons/codec/net/BCodecTest.java > > b/src/test/java/org/apache/commons/codec/net/BCodecTest.java > > index 4569e41..45392a3 100644 > > --- a/src/test/java/org/apache/commons/codec/net/BCodecTest.java > > +++ b/src/test/java/org/apache/commons/codec/net/BCodecTest.java > > @@ -21,9 +21,11 @@ import static org.junit.Assert.assertEquals; > > import static org.junit.Assert.assertNull; > > import static org.junit.Assert.fail; > > > > +import java.nio.charset.StandardCharsets; > > import java.nio.charset.UnsupportedCharsetException; > > > > import org.apache.commons.codec.CharEncoding; > > +import org.apache.commons.codec.CodecPolicy; > > import org.apache.commons.codec.DecoderException; > > import org.apache.commons.codec.EncoderException; > > import org.junit.Assert; > > @@ -158,15 +160,28 @@ public class BCodecTest { > > } > > > > @Test > > - public void testBase64ImpossibleSamples() throws DecoderException { > > + public void testBase64ImpossibleSamplesDefault() throws > > DecoderException { > > final BCodec codec = new BCodec(); > > // Default encoding is lenient > > Assert.assertFalse(codec.isStrictDecoding()); > > for (final String s : BASE64_IMPOSSIBLE_CASES) { > > codec.decode(s); > > } > > - // Use strict mode to prevent impossible cases > > - codec.setStrictDecoding(true); > > + } > > + > > + @Test > > + public void testBase64ImpossibleSamplesLenient() throws > > DecoderException { > > + final BCodec codec = new BCodec(StandardCharsets.UTF_8, > > CodecPolicy.LENIENT); > > + // Default encoding is lenient > > + Assert.assertFalse(codec.isStrictDecoding()); > > + for (final String s : BASE64_IMPOSSIBLE_CASES) { > > + codec.decode(s); > > + } > > + } > > + > > + @Test > > + public void testBase64ImpossibleSamplesStrict() throws > > DecoderException { > > + final BCodec codec = new BCodec(StandardCharsets.UTF_8, > > CodecPolicy.STRICT); > > Assert.assertTrue(codec.isStrictDecoding()); > > for (final String s : BASE64_IMPOSSIBLE_CASES) { > > try { > > @@ -177,4 +192,5 @@ public class BCodecTest { > > } > > } > > } > > + > > } > > > > >