8007379: Base64.getMimeDecoder().decode() throws IAE for a non-base64 character after padding
8008925: Base64.getMimeDecoder().decode() does not ignore padding chars Updated implementation and spec for corner cases. Reviewed-by: alanb
This commit is contained in:
parent
bce70c8f7b
commit
3457ff4337
@ -620,7 +620,10 @@ public class Base64 {
|
||||
* required. So if the final unit of the encoded byte data only has
|
||||
* two or three Base64 characters (without the corresponding padding
|
||||
* character(s) padded), they are decoded as if followed by padding
|
||||
* character(s).
|
||||
* character(s). If there is padding character present in the
|
||||
* final unit, the correct number of padding character(s) must be
|
||||
* present, otherwise {@code IllegalArgumentException} is thrown
|
||||
* during decoding.
|
||||
*
|
||||
* <p> Instances of {@link Decoder} class are safe for use by
|
||||
* multiple concurrent threads.
|
||||
@ -1034,23 +1037,26 @@ public class Base64 {
|
||||
throw new IllegalArgumentException(
|
||||
"Input byte[] should at least have 2 bytes for base64 bytes");
|
||||
}
|
||||
if (src[sl - 1] == '=') {
|
||||
paddings++;
|
||||
if (src[sl - 2] == '=')
|
||||
paddings++;
|
||||
}
|
||||
if (isMIME) {
|
||||
// scan all bytes to fill out all non-alphabet. a performance
|
||||
// trade-off of pre-scan or Arrays.copyOf
|
||||
int n = 0;
|
||||
while (sp < sl) {
|
||||
int b = src[sp++] & 0xff;
|
||||
if (b == '=')
|
||||
if (b == '=') {
|
||||
len -= (sl - sp + 1);
|
||||
break;
|
||||
}
|
||||
if ((b = base64[b]) == -1)
|
||||
n++;
|
||||
}
|
||||
len -= n;
|
||||
} else {
|
||||
if (src[sl - 1] == '=') {
|
||||
paddings++;
|
||||
if (src[sl - 2] == '=')
|
||||
paddings++;
|
||||
}
|
||||
}
|
||||
if (paddings == 0 && (len & 0x3) != 0)
|
||||
paddings = 4 - (len & 0x3);
|
||||
|
@ -22,7 +22,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test 4235519 8004212 8005394 8007298 8006295 8006315 8006530
|
||||
* @test 4235519 8004212 8005394 8007298 8006295 8006315 8006530 8007379 8008925
|
||||
* @summary tests java.util.Base64
|
||||
*/
|
||||
|
||||
@ -107,6 +107,9 @@ public class TestBase64 {
|
||||
checkIAE(new Runnable() { public void run() {
|
||||
Base64.getDecoder().decode(ByteBuffer.wrap(decoded), ByteBuffer.allocateDirect(1024)); }});
|
||||
|
||||
// illegal ending unit
|
||||
checkIAE(new Runnable() { public void run() { Base64.getMimeDecoder().decode("$=#"); }});
|
||||
|
||||
// test return value from decode(ByteBuffer, ByteBuffer)
|
||||
testDecBufRet();
|
||||
|
||||
@ -115,7 +118,6 @@ public class TestBase64 {
|
||||
|
||||
// test decoding of unpadded data
|
||||
testDecodeUnpadded();
|
||||
|
||||
// test mime decoding with ignored character after padding
|
||||
testDecodeIgnoredAfterPadding();
|
||||
}
|
||||
@ -384,6 +386,10 @@ public class TestBase64 {
|
||||
encoded = Arrays.copyOf(encoded, encoded.length + 1);
|
||||
encoded[encoded.length - 1] = nonBase64;
|
||||
checkEqual(decM.decode(encoded), src[i], "Non-base64 char is not ignored");
|
||||
byte[] decoded = new byte[src[i].length];
|
||||
decM.decode(encoded, decoded);
|
||||
checkEqual(decoded, src[i], "Non-base64 char is not ignored");
|
||||
|
||||
try {
|
||||
dec.decode(encoded);
|
||||
throw new RuntimeException("No IAE for non-base64 char");
|
||||
|
Loading…
x
Reference in New Issue
Block a user