1 /*
   2  * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 /**
  27  * @test xxxxxxx
  28  * @summary tests java.util.Base64
  29  */
  30 
  31 import java.io.ByteArrayInputStream;
  32 import java.io.ByteArrayOutputStream;
  33 import java.io.InputStream;
  34 import java.io.IOException;
  35 import java.io.OutputStream;
  36 import java.nio.ByteBuffer;
  37 import java.util.Arrays;
  38 import java.util.Base64;
  39 import java.util.Random;
  40 
  41 public class TestBase64 {
  42 
  43     public static void main(String args[]) throws Throwable {
  44 
  45         int numRuns  = 10;
  46         int numBytes = 200;
  47         if (args.length > 1) {
  48             numRuns  = Integer.parseInt(args[0]);
  49             numBytes = Integer.parseInt(args[1]);
  50         }
  51 
  52         test(Base64.getEncoder(),     Base64.getDecoder(),
  53              numRuns, numBytes);
  54         test(Base64.getUrlEncoder(),  Base64.getUrlDecoder(),
  55              numRuns, numBytes);
  56         test(Base64.getMimeEncoder(), Base64.getMimeDecoder(),
  57              numRuns, numBytes);
  58 
  59         Random rnd = new java.util.Random();
  60         byte[] nl_1 = new byte[] {'\n'};
  61         byte[] nl_2 = new byte[] {'\n', '\r'};
  62         byte[] nl_3 = new byte[] {'\n', '\r', '\n'};
  63         for (int i = 0; i < 10; i++) {
  64             int len = rnd.nextInt(200) + 4;
  65             test(Base64.getEncoder(len, nl_1),
  66                  Base64.getMimeDecoder(),
  67                  numRuns, numBytes);
  68             test(Base64.getEncoder(len, nl_2),
  69                  Base64.getMimeDecoder(),
  70                  numRuns, numBytes);
  71             test(Base64.getEncoder(len, nl_3),
  72                  Base64.getMimeDecoder(),
  73                  numRuns, numBytes);
  74         }
  75     }
  76 
  77     private static void test(Base64.Encoder enc, Base64.Decoder dec,
  78                              int numRuns, int numBytes) throws Throwable {
  79         Random rnd = new java.util.Random();
  80         for (int i=0; i<numRuns; i++) {
  81             for (int j=1; j<numBytes; j++) {
  82                 byte[] orig = new byte[j];
  83                 rnd.nextBytes(orig);
  84 
  85                 // testing encode/decode
  86                 byte[] encoded = enc.encode(orig);
  87                 byte[] decoded = dec.decode(encoded);
  88                 if (!Arrays.equals(orig, decoded))
  89                     System.out.println("Base64 array encoding/decoding failed!");
  90 
  91                 // testing encodetoString()/decode(String)
  92                 String str = enc.encodeToString(orig);
  93                 if (!Arrays.equals(str.getBytes("ASCII"), encoded)) {
  94                     System.out.println("Base64 encodingToString() failed!");
  95                 }
  96                 byte[] buf = dec.decode(new String(encoded, "ASCII"));
  97                 if (!Arrays.equals(buf, orig)) {
  98                     System.out.println("Base64 decoding(String) failed!");
  99                 }
 100 
 101                 // testing encode/decode(Buffer)
 102                 ByteBuffer bin = ByteBuffer.wrap(orig);
 103                 ByteBuffer bout = enc.encode(bin);
 104                 buf = new byte[bout.remaining()];
 105                 bout.get(buf);
 106                 if (bin.remaining() != 0 ||
 107                     buf.length != encoded.length ||
 108                     !Arrays.equals(buf, encoded)) {
 109                     System.out.println("Base64 enc.encode(ByteBuffer) failed!");
 110                 }
 111 
 112                 // testing decode.wrap(input stream)
 113                 ByteArrayInputStream bais = new ByteArrayInputStream(encoded);
 114                 InputStream is = dec.wrap(bais);
 115                 buf = new byte[orig.length + 10];
 116 
 117                 int len = orig.length;
 118                 int off = 0;
 119                 while (true) {
 120                     int n = rnd.nextInt(len);
 121                     if (n == 0)
 122                         n = 1;
 123                     n = is.read(buf, off, n);
 124                     if (n == -1) {
 125                         if (off != orig.length)
 126                             System.out.printf("Base64 stream decoding failed: not enough bytes %d vs %d%n",
 127                                               off, orig.length);
 128                         break;
 129                     }
 130                     off += n;
 131                     len -= n;
 132                     if (len == 0)
 133                         break;
 134                 }
 135                 buf = Arrays.copyOf(buf, off);
 136                 if (!Arrays.equals(buf, orig)) {
 137                     System.out.println("Base64 stream decoding failed!");
 138                 }
 139 
 140                 // testing encode.wrap(output stream)
 141                 ByteArrayOutputStream baos = new ByteArrayOutputStream((orig.length + 2) / 3 * 4 + 10);
 142                 OutputStream os = enc.wrap(baos);
 143                 off = 0;
 144                 len = orig.length;
 145                 for (int k = 0; k < 5; k++) {
 146                     if (len == 0)
 147                         break;
 148                     int n = rnd.nextInt(len);
 149                     if (n == 0)
 150                         n = 1;
 151                     os.write(orig, off, n);
 152                     off += n;
 153                     len -= n;
 154                 }
 155                 if (len != 0)
 156                     os.write(orig, off, len);
 157                 os.close();
 158                 buf = baos.toByteArray();
 159                 if (!Arrays.equals(buf, encoded)) {
 160                     System.out.println("Base64 stream encoding failed!");
 161                 }
 162 
 163                 // testing encode(in, out);
 164                 int dstLen = enc.encode(orig, null);
 165                 buf = new byte[dstLen];
 166                 int ret = enc.encode(orig, buf);
 167                 if (ret != buf.length) {
 168                     throw new RuntimeException(
 169                         "Base64 enc.encode(src, null) returns wrong size!");
 170                 }
 171                 if (!Arrays.equals(buf, encoded)) {
 172                     System.out.println("Base64 enc.encode(src, dst) failed!");
 173                 }
 174                 // testing encode(in, out); -> bigger buf
 175                 buf = new byte[dstLen + rnd.nextInt(100)];
 176                 ret = enc.encode(orig, buf);
 177                 if (ret != dstLen) {
 178                     System.out.println("Base64 enc.encode(src, null) returns wrong size!");
 179                 }
 180                 buf = Arrays.copyOf(buf, dstLen);
 181                 if (!Arrays.equals(buf, encoded)) {
 182                     System.out.println("Base64 enc.encode(src, dst) failed!");
 183                 }
 184 
 185                 // testing decode(in, out);
 186                 dstLen = dec.decode(encoded, null);
 187                 buf = new byte[dstLen];
 188                 ret = dec.decode(encoded, buf);
 189                 if (ret != buf.length) {
 190                     System.out.println("Base64 dec.decode(src, null) returns wrong size!");
 191                 }
 192                 if (!Arrays.equals(buf, orig)) {
 193                     System.out.println("Base64 dec.decode(src, dst) failed!");
 194                 }
 195                 // testing decode(in, out); -> bigger buf
 196                 buf = new byte[dstLen + rnd.nextInt(100)];
 197                 ret = dec.decode(encoded, buf);
 198                 if (ret != dstLen) {
 199                     System.out.println("Base64 enc.encode(src, null) returns wrong size!");
 200                 }
 201                 buf = Arrays.copyOf(buf, dstLen);
 202                 if (!Arrays.equals(buf, orig)) {
 203                     System.out.println("Base64 dec.decode(src, dst) failed!");
 204                 }
 205 
 206             }
 207         }
 208     }
 209 }