Base64Decoder { public static int decode(byte[] data, OutputStream out) throws IOException { int outLen = 0; byte [] cache = new byte[INPUT_BYTES_PER_CHUNK]; int cachedBytes = 0; for (byte b : data) { final byte d = DECODING_TABLE[MASK_BYTE_UNSIGNED & b]; if (d == INVALID_BYTE) { continue; } cache[cachedBytes++] = d; if (cachedBytes == INPUT_BYTES_PER_CHUNK) { final byte b1 = cache[0]; final byte b2 = cache[1]; final byte b3 = cache[2]; final byte b4 = cache[3]; if (b1 == PAD_BYTE || b2 == PAD_BYTE) { throw new IOException("Invalid Base64 input: incorrect padding, first two bytes cannot be padding"); } out.write((b1 << 2) | (b2 >> 4)); outLen++; if (b3 != PAD_BYTE) { out.write((b2 << 4) | (b3 >> 2)); outLen++; if (b4 != PAD_BYTE) { out.write((b3 << 6) | b4); outLen++; } } else if (b4 != PAD_BYTE) { throw new IOException("Invalid Base64 input: incorrect padding, 4th byte must be padding if 3rd byte is"); } cachedBytes = 0; } } if (cachedBytes != 0) { throw new IOException("Invalid Base64 input: truncated"); } return outLen; } private  Base64Decoder(); static int decode(byte[] data, OutputStream out);  }
@Test(expected = IOException.class) public void truncatedString() throws Exception { final byte[] x = new byte[]{'n'}; Base64Decoder.decode(x, new ByteArrayOutputStream()); }