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. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 4235519 26 * @author Eric Wang <yiming.wang@oracle.com> 27 * @summary tests java.util.Base64 28 */ 29 30 import java.io.BufferedReader; 31 import java.io.FileReader; 32 import java.nio.ByteBuffer; 33 import java.nio.charset.Charset; 34 import java.nio.charset.StandardCharsets; 35 import java.nio.file.Files; 36 import java.nio.file.Paths; 37 import java.util.Base64; 38 import java.util.Base64.Decoder; 39 import java.util.Base64.Encoder; 40 import java.util.Objects; 41 import java.util.Random; 42 43 import sun.misc.BASE64Decoder; 44 import sun.misc.BASE64Encoder; 45 46 public class TestBase64Golden { 47 48 public static void main(String[] args) throws Exception { 49 test0(Base64Type.BASIC, Base64.getEncoder(), Base64.getDecoder(), 50 "plain.txt", "baseEncode.txt"); 51 52 test0(Base64Type.URLSAFE, Base64.getUrlEncoder(), Base64.getUrlDecoder(), 53 "plain.txt", "urlEncode.txt"); 54 55 test0(Base64Type.MIME, Base64.getMimeEncoder(), Base64.getMimeDecoder(), 56 "plain.txt", "mimeEncode.txt"); 57 test1(); 58 test2(); 59 } 60 61 public static void test0(Base64Type type, Encoder encoder, Decoder decoder, 62 String srcFile, String encodedFile) throws Exception { 63 64 String[] srcLns = Files.readAllLines(Paths.get(SRCDIR, srcFile), DEF_CHARSET) 65 .toArray(new String[0]); 66 String[] encodedLns = Files.readAllLines(Paths.get(SRCDIR, encodedFile), 67 DEF_CHARSET) 68 .toArray(new String[0]); 69 int lns = 0; 70 for (String srcStr : srcLns) { 71 String encodedStr = null; 72 if (type != Base64Type.MIME) { 73 encodedStr = encodedLns[lns++]; 74 } else { 75 while (lns < encodedLns.length) { 76 String s = encodedLns[lns++]; 77 if (s.length() == 0) 78 break; 79 if (encodedStr != null) { 80 encodedStr += DEFAULT_CRLF + s; 81 } else { 82 encodedStr = s; 83 } 84 } 85 if (encodedStr == null && srcStr.length() == 0) { 86 encodedStr = ""; 87 } 88 } 89 System.out.printf("%n src[%d]: %s%n", srcStr.length(), srcStr); 90 System.out.printf("encoded[%d]: %s%n", encodedStr.length(), encodedStr); 91 92 byte[] srcArr = srcStr.getBytes(DEF_CHARSET); 93 byte[] encodedArr = encodedStr.getBytes(DEF_CHARSET); 94 95 ByteBuffer srcBuf = ByteBuffer.wrap(srcArr); 96 ByteBuffer encodedBuf = ByteBuffer.wrap(encodedArr); 97 byte[] resArr = new byte[encodedArr.length]; 98 99 // test int encode(byte[], byte[]) 100 int len = encoder.encode(srcArr, resArr); 101 assertEqual(len, encodedArr.length); 102 assertEqual(resArr, encodedArr); 103 104 // test byte[] encode(byte[]) 105 resArr = encoder.encode(srcArr); 106 assertEqual(resArr, encodedArr); 107 108 // test ByteBuffer encode(ByteBuffer) 109 int limit = srcBuf.limit(); 110 ByteBuffer resBuf = encoder.encode(srcBuf); 111 assertEqual(srcBuf.position(), limit); 112 assertEqual(srcBuf.limit(), limit); 113 assertEqual(resBuf, encodedBuf); 114 srcBuf.rewind(); // reset for next test 115 116 // test encode(ByteBuffer, ByteBuffer, bytesOut) 117 resBuf.clear(); 118 len = encoder.encode(srcBuf, resBuf, 0); 119 assertEqual(len, encodedArr.length); 120 assertEqual(srcBuf.position(), limit); 121 assertEqual(srcBuf.limit(), limit); 122 assertEqual(resBuf.position(), len); 123 resBuf.flip(); 124 assertEqual(resBuf, encodedBuf); 125 srcBuf.rewind(); 126 127 // test encode(ByteBuffer, ByteBuffer, bytesOut)[direct] 128 ByteBuffer resBuf_d = ByteBuffer.allocateDirect(encodedArr.length); 129 len = encoder.encode(srcBuf, resBuf_d, 0); 130 assertEqual(len, encodedArr.length); 131 assertEqual(srcBuf.position(), limit); 132 assertEqual(srcBuf.limit(), limit); 133 assertEqual(resBuf_d.position(), len); 134 resBuf_d.flip(); 135 assertEqual(resBuf_d, encodedBuf); 136 srcBuf.rewind(); 137 138 // test String encodeToString(byte[]) 139 String resEncodeStr = encoder.encodeToString(srcArr); 140 assertEqual(resEncodeStr, encodedStr); 141 142 // test int decode(byte[], byte[]) 143 resArr = new byte[srcArr.length]; 144 len = decoder.decode(encodedArr, resArr); 145 assertEqual(len, srcArr.length); 146 assertEqual(resArr, srcArr); 147 148 // test byte[] decode(byte[]) 149 resArr = decoder.decode(encodedArr); 150 assertEqual(resArr, srcArr); 151 152 // test ByteBuffer decode(ByteBuffer) 153 limit = encodedBuf.limit(); 154 resBuf = decoder.decode(encodedBuf); 155 assertEqual(encodedBuf.position(), limit); 156 assertEqual(encodedBuf.limit(), limit); 157 assertEqual(resBuf, srcBuf); 158 encodedBuf.rewind(); // reset for next test 159 160 // test int decode(ByteBuffer, ByteBuffer) 161 resBuf.clear(); 162 len = decoder.decode(encodedBuf, resBuf); 163 assertEqual(len, srcArr.length); 164 assertEqual(encodedBuf.position(), limit); 165 assertEqual(encodedBuf.limit(), limit); 166 assertEqual(resBuf.position(), len); 167 resBuf.flip(); 168 assertEqual(resBuf, srcBuf); 169 encodedBuf.rewind(); // reset for next test 170 171 // test int decode(ByteBuffer, ByteBuffer)[direct] 172 resBuf_d = ByteBuffer.allocateDirect(srcArr.length); 173 len = decoder.decode(encodedBuf, resBuf_d); 174 assertEqual(len, srcArr.length); 175 assertEqual(encodedBuf.position(), limit); 176 assertEqual(encodedBuf.limit(), limit); 177 assertEqual(resBuf_d.position(), len); 178 resBuf_d.flip(); 179 assertEqual(resBuf_d, srcBuf); 180 encodedBuf.rewind(); // reset for next test 181 182 // test byte[] decode(String) 183 resArr = decoder.decode(encodedStr); 184 assertEqual(resArr, srcArr); 185 186 // test compatible with sun.misc.Base64Encoder 187 if (type == Base64Type.MIME) { 188 sun.misc.BASE64Encoder miscEncoder = new BASE64Encoder(); 189 sun.misc.BASE64Decoder miscDecoder = new BASE64Decoder(); 190 resArr = decoder.decode(miscEncoder.encode(srcArr)); 191 assertEqual(resArr, srcArr); 192 193 resArr = encoder.encode(miscDecoder.decodeBuffer(encodedStr)); 194 assertEqual(new String(resArr, DEF_CHARSET), encodedStr); 195 } 196 } 197 } 198 199 private static void test1() throws Exception { 200 byte[] src = new byte[6]; 201 new Random().nextBytes(src); 202 203 ByteBuffer srcBuf = ByteBuffer.allocate(10); 204 srcBuf.position(2); 205 srcBuf.mark(); 206 srcBuf.limit(8); 207 srcBuf.put(src); 208 srcBuf.reset(); 209 210 ByteBuffer dstBuf = ByteBuffer.allocate((src.length + 2) / 3 * 4); 211 Base64.getEncoder().encode(srcBuf, dstBuf, 0); 212 dstBuf.rewind(); 213 byte[] dst = new byte[dstBuf.limit()]; 214 dstBuf.get(dst); 215 System.out.printf("%n src[%d]: %s%n", src.length, new String(src)); 216 System.out.printf("encoded[%d]: %s%n", dst.length, new String(dst)); 217 assertEqual(src, Base64.getDecoder().decode(dst)); 218 219 dstBuf = ByteBuffer.allocateDirect((src.length + 2) / 3 * 4); 220 srcBuf.reset(); 221 Base64.getEncoder().encode(srcBuf, dstBuf, 0); 222 dstBuf.rewind(); 223 dst = new byte[dstBuf.limit()]; 224 dstBuf.get(dst); 225 assertEqual(src, Base64.getDecoder().decode(dst)); 226 } 227 228 private static void test2() throws Exception { 229 byte[] src = new byte[] { 230 46, -97, -35, -44, 127, -60, -39, -4, -112, 34, -57, 47, -14, 67, 231 40, 18, 90, -59, 68, 112, 23, 121, -91, 94, 35, 49, 104, 17, 30, 232 -80, -104, -3, -53, 27, 38, -72, -47, 113, -52, 18, 5, -126 }; 233 Encoder encoder = Base64.getMimeEncoder(49, new byte[] { 0x7e }); 234 byte[] encoded = encoder.encode(src); 235 Decoder decoder = Base64.getMimeDecoder(); 236 byte[] decoded = decoder.decode(encoded); 237 if (!Objects.deepEquals(src, decoded)) { 238 throw new RuntimeException(); 239 } 240 } 241 242 // helper 243 enum Base64Type { 244 BASIC, URLSAFE, MIME 245 } 246 247 private static final String SRCDIR = System.getProperty("test.src", "."); 248 private static final Charset DEF_CHARSET = StandardCharsets.US_ASCII; 249 private static final String DEF_EXCEPTION_MSG = 250 "Assertion failed! The result is not same as expected"; 251 private static final String DEFAULT_CRLF = "\r\n"; 252 253 private static void assertEqual(Object result, Object expect) { 254 if (!Objects.deepEquals(result, expect)) { 255 String resultStr = result.toString(); 256 String expectStr = expect.toString(); 257 if (result instanceof byte[]) { 258 resultStr = new String((byte[]) result, DEF_CHARSET); 259 } 260 if (expect instanceof byte[]) { 261 expectStr = new String((byte[]) expect, DEF_CHARSET); 262 } 263 throw new RuntimeException(DEF_EXCEPTION_MSG + 264 " result: " + resultStr + " expected: " + expectStr); 265 } 266 } 267 }