in source/encoding.c [351:413]
int aws_base64_decode(const struct aws_byte_cursor *AWS_RESTRICT to_decode, struct aws_byte_buf *AWS_RESTRICT output) {
size_t decoded_length = 0;
if (AWS_UNLIKELY(aws_base64_compute_decoded_len(to_decode, &decoded_length))) {
return AWS_OP_ERR;
}
if (output->capacity < decoded_length) {
return aws_raise_error(AWS_ERROR_SHORT_BUFFER);
}
if (aws_common_private_has_avx2()) {
size_t result = aws_common_private_base64_decode_sse41(to_decode->ptr, output->buffer, to_decode->len);
if (result == -1) {
return aws_raise_error(AWS_ERROR_INVALID_BASE64_STR);
}
output->len = result;
return AWS_OP_SUCCESS;
}
int64_t block_count = (int64_t)to_decode->len / 4;
size_t string_index = 0;
uint8_t value1 = 0, value2 = 0, value3 = 0, value4 = 0;
int64_t buffer_index = 0;
for (int64_t i = 0; i < block_count - 1; ++i) {
if (AWS_UNLIKELY(
s_base64_get_decoded_value(to_decode->ptr[string_index++], &value1, 0) ||
s_base64_get_decoded_value(to_decode->ptr[string_index++], &value2, 0) ||
s_base64_get_decoded_value(to_decode->ptr[string_index++], &value3, 0) ||
s_base64_get_decoded_value(to_decode->ptr[string_index++], &value4, 0))) {
return aws_raise_error(AWS_ERROR_INVALID_BASE64_STR);
}
buffer_index = i * 3;
output->buffer[buffer_index++] = (uint8_t)((value1 << 2) | ((value2 >> 4) & 0x03));
output->buffer[buffer_index++] = (uint8_t)(((value2 << 4) & 0xF0) | ((value3 >> 2) & 0x0F));
output->buffer[buffer_index] = (uint8_t)((value3 & 0x03) << 6 | value4);
}
buffer_index = (block_count - 1) * 3;
if (buffer_index >= 0) {
if (s_base64_get_decoded_value(to_decode->ptr[string_index++], &value1, 0) ||
s_base64_get_decoded_value(to_decode->ptr[string_index++], &value2, 0) ||
s_base64_get_decoded_value(to_decode->ptr[string_index++], &value3, 1) ||
s_base64_get_decoded_value(to_decode->ptr[string_index], &value4, 1)) {
return aws_raise_error(AWS_ERROR_INVALID_BASE64_STR);
}
output->buffer[buffer_index++] = (uint8_t)((value1 << 2) | ((value2 >> 4) & 0x03));
if (value3 != BASE64_SENTIANAL_VALUE) {
output->buffer[buffer_index++] = (uint8_t)(((value2 << 4) & 0xF0) | ((value3 >> 2) & 0x0F));
if (value4 != BASE64_SENTIANAL_VALUE) {
output->buffer[buffer_index] = (uint8_t)((value3 & 0x03) << 6 | value4);
}
}
}
output->len = decoded_length;
return AWS_OP_SUCCESS;
}