diff options
author | robot-contrib <[email protected]> | 2025-05-14 06:53:03 +0300 |
---|---|---|
committer | robot-contrib <[email protected]> | 2025-05-14 07:05:42 +0300 |
commit | 286dbc77293811055ff4f9303cd376eff9e50104 (patch) | |
tree | a50eea3eb2b824c7c68e15b4cc3e127731776d32 /contrib/restricted/aws/aws-c-common/source/encoding.c | |
parent | 0bf9db6399352012396e7791bcfd762e944b33c2 (diff) |
Update contrib/restricted/aws/aws-c-common to 0.12.2
commit_hash:fc6e67f9b12b0b888c90bb97bf2b1cbfcd74a044
Diffstat (limited to 'contrib/restricted/aws/aws-c-common/source/encoding.c')
-rw-r--r-- | contrib/restricted/aws/aws-c-common/source/encoding.c | 57 |
1 files changed, 29 insertions, 28 deletions
diff --git a/contrib/restricted/aws/aws-c-common/source/encoding.c b/contrib/restricted/aws/aws-c-common/source/encoding.c index bc860aa4b99..c9e14ee3b87 100644 --- a/contrib/restricted/aws/aws-c-common/source/encoding.c +++ b/contrib/restricted/aws/aws-c-common/source/encoding.c @@ -23,7 +23,7 @@ static inline size_t aws_common_private_base64_decode_sse41(const unsigned char (void)out; (void)len; AWS_ASSERT(false); - return (size_t)-1; /* unreachable */ + return SIZE_MAX; /* unreachable */ } static inline void aws_common_private_base64_encode_sse41(const unsigned char *in, unsigned char *out, size_t len) { (void)in; @@ -66,7 +66,9 @@ static const uint8_t BASE64_DECODING_TABLE[256] = { int aws_hex_compute_encoded_len(size_t to_encode_len, size_t *encoded_length) { AWS_ASSERT(encoded_length); - size_t temp = (to_encode_len << 1) + 1; + /* For every byte of input, there will be 2 hex chars of encoded output */ + + size_t temp = to_encode_len << 1; if (AWS_UNLIKELY(temp < to_encode_len)) { return aws_raise_error(AWS_ERROR_OVERFLOW_DETECTED); @@ -98,7 +100,7 @@ int aws_hex_encode(const struct aws_byte_cursor *AWS_RESTRICT to_encode, struct output->buffer[written++] = HEX_CHARS[to_encode->ptr[i] & 0x0f]; } - output->buffer[written] = '\0'; + AWS_ASSERT(written == encoded_len); output->len = encoded_len; return AWS_OP_SUCCESS; @@ -153,6 +155,10 @@ static int s_hex_decode_char_to_int(char character, uint8_t *int_val) { int aws_hex_compute_decoded_len(size_t to_decode_len, size_t *decoded_len) { AWS_ASSERT(decoded_len); + /* For every 2 hex chars (rounded up) of encoded input, there will be 1 byte of decoded output. + * Rounding is because if buffer isn't even, we'll pretend there's an extra '0' at start of buffer */ + + /* adding 1 before dividing by 2 is a trick to round up during division */ size_t temp = (to_decode_len + 1); if (AWS_UNLIKELY(temp < to_decode_len)) { @@ -212,6 +218,10 @@ int aws_hex_decode(const struct aws_byte_cursor *AWS_RESTRICT to_decode, struct int aws_base64_compute_encoded_len(size_t to_encode_len, size_t *encoded_len) { AWS_ASSERT(encoded_len); + /* For every 3 bytes (rounded up) of unencoded input, there will be 4 ascii characters of encoded output. + * Rounding is because the output will be padded with '=' chars if necessary to make it divisible by 4. */ + + /* adding 2 before dividing by 3 is a trick to round up during division */ size_t tmp = to_encode_len + 2; if (AWS_UNLIKELY(tmp < to_encode_len)) { @@ -220,7 +230,7 @@ int aws_base64_compute_encoded_len(size_t to_encode_len, size_t *encoded_len) { tmp /= 3; size_t overflow_check = tmp; - tmp = 4 * tmp + 1; /* plus one for the NULL terminator */ + tmp = 4 * tmp; if (AWS_UNLIKELY(tmp < overflow_check)) { return aws_raise_error(AWS_ERROR_OVERFLOW_DETECTED); @@ -243,40 +253,40 @@ int aws_base64_compute_decoded_len(const struct aws_byte_cursor *AWS_RESTRICT to return AWS_OP_SUCCESS; } + /* ensure it's divisible by 4 */ if (AWS_UNLIKELY(len & 0x03)) { return aws_raise_error(AWS_ERROR_INVALID_BASE64_STR); } - size_t tmp = len * 3; - - if (AWS_UNLIKELY(tmp < len)) { - return aws_raise_error(AWS_ERROR_OVERFLOW_DETECTED); - } + /* For every 4 ascii characters of encoded input, there will be 3 bytes of decoded output (deal with padding later) + * decoded_len = 3/4 * len <-- note that result will be smaller then len, so overflow can be avoided + * = (len / 4) * 3 <-- divide before multiply to avoid overflow + */ + size_t decoded_len_tmp = (len / 4) * 3; + /* But last two ascii chars might be padding. */ + AWS_ASSERT(len >= 4); /* we checked earlier len != 0, and was divisible by 4 */ size_t padding = 0; - - if (len >= 2 && input[len - 1] == '=' && input[len - 2] == '=') { /*last two chars are = */ + if (input[len - 1] == '=' && input[len - 2] == '=') { /*last two chars are = */ padding = 2; } else if (input[len - 1] == '=') { /*last char is = */ padding = 1; } - *decoded_len = (tmp / 4 - padding); + *decoded_len = decoded_len_tmp - padding; return AWS_OP_SUCCESS; } int aws_base64_encode(const struct aws_byte_cursor *AWS_RESTRICT to_encode, struct aws_byte_buf *AWS_RESTRICT output) { - AWS_ASSERT(to_encode->ptr); - AWS_ASSERT(output->buffer); + AWS_ASSERT(to_encode->len == 0 || to_encode->ptr != NULL); - size_t terminated_length = 0; size_t encoded_length = 0; - if (AWS_UNLIKELY(aws_base64_compute_encoded_len(to_encode->len, &terminated_length))) { + if (AWS_UNLIKELY(aws_base64_compute_encoded_len(to_encode->len, &encoded_length))) { return AWS_OP_ERR; } size_t needed_capacity = 0; - if (AWS_UNLIKELY(aws_add_size_checked(output->len, terminated_length, &needed_capacity))) { + if (AWS_UNLIKELY(aws_add_size_checked(output->len, encoded_length, &needed_capacity))) { return AWS_OP_ERR; } @@ -284,16 +294,10 @@ int aws_base64_encode(const struct aws_byte_cursor *AWS_RESTRICT to_encode, stru return aws_raise_error(AWS_ERROR_SHORT_BUFFER); } - /* - * For convenience to standard C functions expecting a null-terminated - * string, the output is terminated. As the encoding itself can be used in - * various ways, however, its length should never account for that byte. - */ - encoded_length = (terminated_length - 1); + AWS_ASSERT(needed_capacity == 0 || output->buffer != NULL); if (aws_common_private_has_avx2()) { aws_common_private_base64_encode_sse41(to_encode->ptr, output->buffer + output->len, to_encode->len); - output->buffer[output->len + encoded_length] = 0; output->len += encoded_length; return AWS_OP_SUCCESS; } @@ -329,9 +333,6 @@ int aws_base64_encode(const struct aws_byte_cursor *AWS_RESTRICT to_encode, stru } } - /* it's a string add the null terminator. */ - output->buffer[output->len + encoded_length] = 0; - output->len += encoded_length; return AWS_OP_SUCCESS; @@ -361,7 +362,7 @@ int aws_base64_decode(const struct aws_byte_cursor *AWS_RESTRICT to_decode, stru 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) { + if (result == SIZE_MAX) { return aws_raise_error(AWS_ERROR_INVALID_BASE64_STR); } |