提交 be23fb50 编写于 作者: S sherman

8007379: Base64.getMimeDecoder().decode() throws IAE for a non-base64 character after padding

8008925: Base64.getMimeDecoder().decode() does not ignore padding chars
Summary: updated implementation and spec for corner cases.
Reviewed-by: alanb
上级 843984e9
...@@ -620,7 +620,10 @@ public class Base64 { ...@@ -620,7 +620,10 @@ public class Base64 {
* required. So if the final unit of the encoded byte data only has * required. So if the final unit of the encoded byte data only has
* two or three Base64 characters (without the corresponding padding * two or three Base64 characters (without the corresponding padding
* character(s) padded), they are decoded as if followed by 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 * <p> Instances of {@link Decoder} class are safe for use by
* multiple concurrent threads. * multiple concurrent threads.
...@@ -1034,23 +1037,26 @@ public class Base64 { ...@@ -1034,23 +1037,26 @@ public class Base64 {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Input byte[] should at least have 2 bytes for base64 bytes"); "Input byte[] should at least have 2 bytes for base64 bytes");
} }
if (src[sl - 1] == '=') {
paddings++;
if (src[sl - 2] == '=')
paddings++;
}
if (isMIME) { if (isMIME) {
// scan all bytes to fill out all non-alphabet. a performance // scan all bytes to fill out all non-alphabet. a performance
// trade-off of pre-scan or Arrays.copyOf // trade-off of pre-scan or Arrays.copyOf
int n = 0; int n = 0;
while (sp < sl) { while (sp < sl) {
int b = src[sp++] & 0xff; int b = src[sp++] & 0xff;
if (b == '=') if (b == '=') {
len -= (sl - sp + 1);
break; break;
}
if ((b = base64[b]) == -1) if ((b = base64[b]) == -1)
n++; n++;
} }
len -= n; len -= n;
} else {
if (src[sl - 1] == '=') {
paddings++;
if (src[sl - 2] == '=')
paddings++;
}
} }
if (paddings == 0 && (len & 0x3) != 0) if (paddings == 0 && (len & 0x3) != 0)
paddings = 4 - (len & 0x3); paddings = 4 - (len & 0x3);
......
...@@ -22,7 +22,7 @@ ...@@ -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 * @summary tests java.util.Base64
*/ */
...@@ -107,6 +107,9 @@ public class TestBase64 { ...@@ -107,6 +107,9 @@ public class TestBase64 {
checkIAE(new Runnable() { public void run() { checkIAE(new Runnable() { public void run() {
Base64.getDecoder().decode(ByteBuffer.wrap(decoded), ByteBuffer.allocateDirect(1024)); }}); 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) // test return value from decode(ByteBuffer, ByteBuffer)
testDecBufRet(); testDecBufRet();
...@@ -115,7 +118,6 @@ public class TestBase64 { ...@@ -115,7 +118,6 @@ public class TestBase64 {
// test decoding of unpadded data // test decoding of unpadded data
testDecodeUnpadded(); testDecodeUnpadded();
// test mime decoding with ignored character after padding // test mime decoding with ignored character after padding
testDecodeIgnoredAfterPadding(); testDecodeIgnoredAfterPadding();
} }
...@@ -384,6 +386,10 @@ public class TestBase64 { ...@@ -384,6 +386,10 @@ public class TestBase64 {
encoded = Arrays.copyOf(encoded, encoded.length + 1); encoded = Arrays.copyOf(encoded, encoded.length + 1);
encoded[encoded.length - 1] = nonBase64; encoded[encoded.length - 1] = nonBase64;
checkEqual(decM.decode(encoded), src[i], "Non-base64 char is not ignored"); 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 { try {
dec.decode(encoded); dec.decode(encoded);
throw new RuntimeException("No IAE for non-base64 char"); throw new RuntimeException("No IAE for non-base64 char");
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册