8014217: Base64.getXDecoder().wrap(...).read() doesn't throw exception for an incorrect number of padding chars in the final unit
authorsherman
Tue, 14 May 2013 14:20:18 -0700
changeset 17471 c2adb7330c84
parent 17470 b65cf2b5983b
child 17472 4ce9bd9f56ac
8014217: Base64.getXDecoder().wrap(...).read() doesn't throw exception for an incorrect number of padding chars in the final unit Summary: to throw IOE for malformed final unit in base64 stream Reviewed-by: chegar, alanb
jdk/src/share/classes/java/util/Base64.java
jdk/test/java/util/Base64/TestBase64.java
--- a/jdk/src/share/classes/java/util/Base64.java	Tue May 14 14:09:18 2013 -0700
+++ b/jdk/src/share/classes/java/util/Base64.java	Tue May 14 14:20:18 2013 -0700
@@ -625,7 +625,8 @@
      * character(s) padded), they are decoded as if followed by padding
      * 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
+     * present, otherwise {@code IllegalArgumentException} (
+     * {@code IOException} when reading from a Base64 stream) is thrown
      * during decoding.
      *
      * <p> Instances of {@link Decoder} class are safe for use by
@@ -1306,7 +1307,12 @@
                         return off - oldOff;
                 }
                 if (v == '=') {                  // padding byte(s)
-                    if (nextin != 6 && nextin != 0) {
+                    // =     shiftto==18 unnecessary padding
+                    // x=    shiftto==12 invalid unit
+                    // xx=   shiftto==6 && missing last '='
+                    // xx=y                or last is not '='
+                    if (nextin == 18 || nextin == 12 ||
+                        nextin == 6 && is.read() != '=') {
                         throw new IOException("Illegal base64 ending sequence:" + nextin);
                     }
                     b[off++] = (byte)(bits >> (16));
--- a/jdk/test/java/util/Base64/TestBase64.java	Tue May 14 14:09:18 2013 -0700
+++ b/jdk/test/java/util/Base64/TestBase64.java	Tue May 14 14:20:18 2013 -0700
@@ -23,6 +23,7 @@
 
 /**
  * @test 4235519 8004212 8005394 8007298 8006295 8006315 8006530 8007379 8008925
+ *       8014217
  * @summary tests java.util.Base64
  */
 
@@ -110,6 +111,14 @@
         // illegal ending unit
         checkIAE(new Runnable() { public void run() { Base64.getMimeDecoder().decode("$=#"); }});
 
+        checkIOE(new Testable() { public void test() throws IOException {
+                                     byte[] bytes = "AA=".getBytes("ASCII");
+                                     try (InputStream stream =
+                                              Base64.getDecoder().wrap(new ByteArrayInputStream(bytes))) {
+                                         while (stream.read() != -1);
+                                     }
+        }});
+
         // test return value from decode(ByteBuffer, ByteBuffer)
         testDecBufRet();