[ 
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)

Reply via email to