[
https://issues.apache.org/jira/browse/CODEC-263?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17028010#comment-17028010
]
Alex Herbert commented on CODEC-263:
------------------------------------
Hi [~larry_west],
Adding this method makes sense in the context of the functionality to add
strict/lenient decoding (CODEC-280).
It should be straightforward to add this method. You cannot just use the length
of the input array due to whitespace padding so you would need to do the same
as {{isBase64}} which scans the entire input bytes and checks the byte is
either a valid padding character or a valid base64 character. However in this
case for the latter you increment a count of base64 characters.
At the end you use the count to compute the modulus of the number of trailing
characters left over from a decode block (i.e. 4 for base 64 and 8 for base 32)
and then pass the modulus and final character to a validation method. This can
be composed of the same logic as the processing switch statement for the final
bytes in the decode method. The current validation method can be rearranged to
not throw but return true/false for your check. To reduce duplication the
validation in decode can be removed and it can call this new trailing character
check:
{code:java}
public boolean isDecodable(byte[] data) {
// scan data:
// if an invalid char then return false
// count valid chars; ignore padding
// validation
int modulus = count % BLOCK_SIZE;
int finalByte = ...; // Scan backwards and find first valid char, or track
this in the first scan
return isValidTrailingBits(modulus, finalByte);
}
// Inside decode:
// These should be available in the decode Context data structure:
int modulus = ...; // Count of trailing bytes (x): 0<=x<4 for Base64; 0<=x<8
for Base32
int finalByte = ...; // The final byte. Unused bits from this should be zero
if (isStrictDecoding() && !isValidTrailingBits(modulus, finalByte)) {
throw new IllegalArgumentException("...");
}
// Then decode what is left
{code}
In the default case of lenient decoding this validation will be ignored and the
codec will just decode what is left as best it can.
Hope that is clear. Have a look and see if you can make it work.
> Base64.decodeBase64 throw exception
> -----------------------------------
>
> Key: CODEC-263
> URL: https://issues.apache.org/jira/browse/CODEC-263
> Project: Commons Codec
> Issue Type: Bug
> Affects Versions: 1.13
> Environment: JDK 7/JDK 8
> commons-codec 1.13
> Reporter: xie tao
> Priority: Critical
> Attachments: image-jpg-01-big.base64.txt
>
>
> Codec upgrade to 1.13, code throw exception as follows:
> {code:java}
> @Test
> public void test(){
> Base64.decodeBase64("publishMessage");
> }
> {code}
> exception like:
> {code:java}
> java.lang.IllegalArgumentException: Last encoded character (before the
> paddings if any) is a valid base 64 alphabet but not a possible value
> at
> org.apache.commons.codec.binary.Base64.validateCharacter(Base64.java:798)
> at org.apache.commons.codec.binary.Base64.decode(Base64.java:472)
> at
> org.apache.commons.codec.binary.BaseNCodec.decode(BaseNCodec.java:412)
> at
> org.apache.commons.codec.binary.BaseNCodec.decode(BaseNCodec.java:395)
> at org.apache.commons.codec.binary.Base64.decodeBase64(Base64.java:694)
> {code}
--
This message was sent by Atlassian Jira
(v8.3.4#803005)