in src/main/java/org/apache/xml/security/utils/Base64.java [610:683]
protected static void decode(byte[] base64Data, OutputStream os, int len)
throws Base64DecodingException, IOException {
// remove white spaces
if (len == -1) {
len = removeWhiteSpace(base64Data);
}
if (len % FOURBYTE != 0) {
throw new Base64DecodingException("decoding.divisible.four");
//should be divisible by four
}
int numberQuadruple = len / FOURBYTE;
if (numberQuadruple == 0) {
return;
}
//byte[] decodedData = null;
byte b1 = 0, b2 = 0, b3 = 0, b4 = 0;
int i = 0;
int dataIndex = 0;
//the begin
for (i = numberQuadruple - 1; i > 0; i--) {
b1 = base64Alphabet[base64Data[dataIndex++]];
b2 = base64Alphabet[base64Data[dataIndex++]];
b3 = base64Alphabet[base64Data[dataIndex++]];
b4 = base64Alphabet[base64Data[dataIndex++]];
if (b1 == -1 || b2 == -1 || b3 == -1 || b4 == -1) {
//if found "no data" just return null
throw new Base64DecodingException("decoding.general");
}
os.write((byte)(b1 << 2 | b2 >> 4));
os.write((byte)(((b2 & 0xf) << 4 ) | ((b3 >> 2) & 0xf)));
os.write((byte)(b3 << 6 | b4));
}
b1 = base64Alphabet[base64Data[dataIndex++]];
b2 = base64Alphabet[base64Data[dataIndex++]];
// first last bits.
if (b1 == -1 || b2 == -1) {
//if found "no data" just return null
throw new Base64DecodingException("decoding.general");
}
byte d3, d4;
b3 = base64Alphabet[d3 = base64Data[dataIndex++]];
b4 = base64Alphabet[d4 = base64Data[dataIndex++]];
if (b3 == -1 || b4 == -1) { //Check if they are PAD characters
if (isPad(d3) && isPad(d4)) { //Two PAD e.g. 3c[Pad][Pad]
if ((b2 & 0xf) != 0) { //last 4 bits should be zero
throw new Base64DecodingException("decoding.general");
}
os.write((byte)(b1 << 2 | b2 >> 4));
} else if (!isPad(d3) && isPad(d4)) { //One PAD e.g. 3cQ[Pad]
if ((b3 & 0x3 ) != 0) { //last 2 bits should be zero
throw new Base64DecodingException("decoding.general");
}
os.write((byte)(b1 << 2 | b2 >> 4));
os.write((byte)(((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)));
} else {
//an error like "3c[Pad]r", "3cdX", "3cXd", "3cXX" where X is non data
throw new Base64DecodingException("decoding.general");
}
} else {
//No PAD e.g 3cQl
os.write((byte)(b1 << 2 | b2 >> 4));
os.write( (byte)(((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)));
os.write((byte)(b3 << 6 | b4));
}
}