Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package aws-c-common for openSUSE:Factory checked in at 2025-11-21 16:56:16 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/aws-c-common (Old) and /work/SRC/openSUSE:Factory/.aws-c-common.new.2061 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "aws-c-common" Fri Nov 21 16:56:16 2025 rev:29 rq:1318938 version:0.12.6 Changes: -------- --- /work/SRC/openSUSE:Factory/aws-c-common/aws-c-common.changes 2025-09-22 17:06:40.925525531 +0200 +++ /work/SRC/openSUSE:Factory/.aws-c-common.new.2061/aws-c-common.changes 2025-11-21 16:57:09.451571824 +0100 @@ -1,0 +2,11 @@ +Thu Nov 20 08:30:37 UTC 2025 - John Paul Adrian Glaubitz <[email protected]> + +- Update to 0.12.6 + * Remove apple-specific pthread_getname compile definition + by @azkrishpy in (#1224) + * Extend Platform Helper Functions by @xiazhvera in (#1225) + * Remove no-op from CMakeLists.txt by @sbSteveK in (#1226) + * Add va_end call by @azkrishpy in (#1228) + * Base64url support by @DmitriyMusatkin in (#1229) + +------------------------------------------------------------------- Old: ---- v0.12.5.tar.gz New: ---- v0.12.6.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ aws-c-common.spec ++++++ --- /var/tmp/diff_new_pack.4Zov7P/_old 2025-11-21 16:57:11.191645149 +0100 +++ /var/tmp/diff_new_pack.4Zov7P/_new 2025-11-21 16:57:11.199645486 +0100 @@ -19,7 +19,7 @@ %define library_version 1.0.0 %define library_soversion 1 Name: aws-c-common -Version: 0.12.5 +Version: 0.12.6 Release: 0 Summary: Core C99 package for AWS SDK for C License: Apache-2.0 ++++++ v0.12.5.tar.gz -> v0.12.6.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-common-0.12.5/CMakeLists.txt new/aws-c-common-0.12.6/CMakeLists.txt --- old/aws-c-common-0.12.5/CMakeLists.txt 2025-09-18 18:39:54.000000000 +0200 +++ new/aws-c-common-0.12.6/CMakeLists.txt 2025-11-14 02:45:38.000000000 +0100 @@ -61,10 +61,6 @@ if (WIN32) set(WINDOWS_KERNEL_LIB "kernel32" CACHE STRING "The name of the kernel library to link against (default: kernel32)") - file(GLOB AWS_COMMON_OS_HEADERS - "include/aws/common/windows/*" - ) - file(GLOB AWS_COMMON_OS_SRC "source/windows/*.c" "source/platform_fallback_stubs/system_info.c" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-common-0.12.5/cmake/AwsThreadName.cmake new/aws-c-common-0.12.6/cmake/AwsThreadName.cmake --- old/aws-c-common-0.12.5/cmake/AwsThreadName.cmake 2025-09-18 18:39:54.000000000 +0200 +++ new/aws-c-common-0.12.6/cmake/AwsThreadName.cmake 2025-11-14 02:45:38.000000000 +0100 @@ -52,13 +52,6 @@ endfunction() function(aws_set_thread_name_getter_method target) - if (APPLE) - # All Apple platforms we support have the same function, so no need for - # compile-time check. - target_compile_definitions(${target} PRIVATE -DAWS_PTHREAD_GETNAME_TAKES_3ARGS) - return() - endif() - # Some platforms have 2 arg version check_c_source_compiles(" ${c_source_start} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-common-0.12.5/include/aws/common/encoding.h new/aws-c-common-0.12.6/include/aws/common/encoding.h --- old/aws-c-common-0.12.5/include/aws/common/encoding.h 2025-09-18 18:39:54.000000000 +0200 +++ new/aws-c-common-0.12.6/include/aws/common/encoding.h 2025-11-14 02:45:38.000000000 +0100 @@ -64,13 +64,30 @@ int aws_base64_compute_encoded_len(size_t to_encode_len, size_t *encoded_len); /* + * Computes the length necessary to store the output of aws_base64_url_encode call. + * returns -1 on failure, and 0 on success. encoded_length will be set on + * success. + */ +AWS_COMMON_API +int aws_base64_url_compute_encoded_len(size_t to_encode_len, size_t *encoded_len); + +/* * Base 64 encodes the contents of to_encode and stores the result in output. */ AWS_COMMON_API int aws_base64_encode(const struct aws_byte_cursor *AWS_RESTRICT to_encode, struct aws_byte_buf *AWS_RESTRICT output); /* + * Base 64 URL encodes the contents of to_encode and stores the result in output. + */ +AWS_COMMON_API +int aws_base64_url_encode( + const struct aws_byte_cursor *AWS_RESTRICT to_encode, + struct aws_byte_buf *AWS_RESTRICT output); + +/* * Computes the length necessary to store the output of aws_base64_decode call. + * Note: works on both regular and url base64. * returns -1 on failure, and 0 on success. decoded_len will be set on success. */ AWS_COMMON_API @@ -78,6 +95,7 @@ /* * Base 64 decodes the contents of to_decode and stores the result in output. + * Note: works on both regular and url base64. */ AWS_COMMON_API int aws_base64_decode(const struct aws_byte_cursor *AWS_RESTRICT to_decode, struct aws_byte_buf *AWS_RESTRICT output); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-common-0.12.5/include/aws/common/platform.h new/aws-c-common-0.12.6/include/aws/common/platform.h --- old/aws-c-common-0.12.5/include/aws/common/platform.h 2025-09-18 18:39:54.000000000 +0200 +++ new/aws-c-common-0.12.6/include/aws/common/platform.h 2025-11-14 02:45:38.000000000 +0100 @@ -31,6 +31,10 @@ # define AWS_OS_LINUX #endif +#if defined(__ANDROID__) +# define AWS_OS_ANDROID +#endif + #if defined(_POSIX_VERSION) # define AWS_OS_POSIX #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-common-0.12.5/include/aws/common/system_info.h new/aws-c-common-0.12.6/include/aws/common/system_info.h --- old/aws-c-common-0.12.5/include/aws/common/system_info.h 2025-09-18 18:39:54.000000000 +0200 +++ new/aws-c-common-0.12.6/include/aws/common/system_info.h 2025-11-14 02:45:38.000000000 +0100 @@ -11,9 +11,22 @@ AWS_PUSH_SANE_WARNING_LEVEL +/** + * Platform OS enumeration and their corresponding string representations. + * + * String mappings: + * - AWS_PLATFORM_OS_WINDOWS → "Windows" (Microsoft Windows family) + * - AWS_PLATFORM_OS_MAC → "macOS" (Apple desktop/laptop) + * - AWS_PLATFORM_OS_IOS → "iOS" (Apple mobile platforms, covers iOS, watchOS, tvOS, + * and other non-macOS Apple platforms) + * - AWS_PLATFORM_OS_ANDROID → "Android" (Google Android) + * - AWS_PLATFORM_OS_UNIX → "Unix" (Linux, BSD, other Unix-like) + */ enum aws_platform_os { AWS_PLATFORM_OS_WINDOWS, AWS_PLATFORM_OS_MAC, + AWS_PLATFORM_OS_IOS, + AWS_PLATFORM_OS_ANDROID, AWS_PLATFORM_OS_UNIX, }; @@ -74,6 +87,10 @@ AWS_COMMON_API enum aws_platform_os aws_get_platform_build_os(void); +/* Returns the OS this was built under as a string */ +AWS_COMMON_API +struct aws_byte_cursor aws_get_platform_build_os_string(void); + /* Returns the number of online processors available for usage. */ AWS_COMMON_API size_t aws_system_info_processor_count(void); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-common-0.12.5/source/arch/intel/encoding_avx2.c new/aws-c-common-0.12.6/source/arch/intel/encoding_avx2.c --- old/aws-c-common-0.12.5/source/arch/intel/encoding_avx2.c 2025-09-18 18:39:54.000000000 +0200 +++ new/aws-c-common-0.12.6/source/arch/intel/encoding_avx2.c 2025-11-14 02:45:38.000000000 +0100 @@ -52,19 +52,28 @@ * on decode failure, returns false, else returns true on success. */ static inline bool decode_vec(__m256i *in) { - __m256i tmp1, tmp2, tmp3; + __m256i tmp1, tmp2, tmp3, tmp4, tmp5; /* * Base64 decoding table, see RFC4648 * * Note that we use multiple vector registers to try to allow the CPU to - * paralellize the merging ORs + * parallelize the merging ORs */ tmp1 = translate_range(*in, 'A', 'Z', 0 + 1); tmp2 = translate_range(*in, 'a', 'z', 26 + 1); tmp3 = translate_range(*in, '0', '9', 52 + 1); - tmp1 = _mm256_or_si256(tmp1, translate_exact(*in, '+', 62 + 1)); - tmp2 = _mm256_or_si256(tmp2, translate_exact(*in, '/', 63 + 1)); + // Handle both '+' and '-' for value 62 + tmp4 = translate_exact(*in, '+', 62 + 1); + tmp4 = _mm256_or_si256(tmp4, translate_exact(*in, '-', 62 + 1)); + + // Handle both '/' and '_' for value 63 + tmp5 = translate_exact(*in, '/', 63 + 1); + tmp5 = _mm256_or_si256(tmp5, translate_exact(*in, '_', 63 + 1)); + + // Combine all results + tmp1 = _mm256_or_si256(tmp1, tmp4); + tmp2 = _mm256_or_si256(tmp2, tmp5); tmp3 = _mm256_or_si256(tmp3, _mm256_or_si256(tmp1, tmp2)); /* diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-common-0.12.5/source/byte_buf.c new/aws-c-common-0.12.6/source/byte_buf.c --- old/aws-c-common-0.12.5/source/byte_buf.c 2025-09-18 18:39:54.000000000 +0200 +++ new/aws-c-common-0.12.6/source/byte_buf.c 2025-11-14 02:45:38.000000000 +0100 @@ -174,6 +174,7 @@ while ((cursor_i = va_arg(args, struct aws_byte_cursor *)) != NULL) { AWS_ASSERT(aws_byte_cursor_is_valid(cursor_i)); if (aws_add_size_checked(total_len, cursor_i->len, &total_len)) { + va_end(args); return AWS_OP_ERR; } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-common-0.12.5/source/encoding.c new/aws-c-common-0.12.6/source/encoding.c --- old/aws-c-common-0.12.5/source/encoding.c 2025-09-18 18:39:54.000000000 +0200 +++ new/aws-c-common-0.12.6/source/encoding.c 2025-11-14 02:45:38.000000000 +0100 @@ -5,12 +5,17 @@ #include <aws/common/encoding.h> +#include <aws/common/logging.h> #include <ctype.h> #include <stdlib.h> #ifdef USE_SIMD_ENCODING size_t aws_common_private_base64_decode_sse41(const unsigned char *in, unsigned char *out, size_t len); -void aws_common_private_base64_encode_sse41(const unsigned char *in, unsigned char *out, size_t len); +void aws_common_private_base64_encode_sse41( + const unsigned char *in, + unsigned char *out, + size_t len, + bool url_safe_encoding); bool aws_common_private_has_avx2(void); #else /* @@ -25,10 +30,15 @@ AWS_ASSERT(false); return SIZE_MAX; /* unreachable */ } -static inline void aws_common_private_base64_encode_sse41(const unsigned char *in, unsigned char *out, size_t len) { +static inline void aws_common_private_base64_encode_sse41( + const unsigned char *in, + unsigned char *out, + size_t len, + bool url_safe_encoding) { (void)in; (void)out; (void)len; + (void)url_safe_encoding; AWS_ASSERT(false); } static inline bool aws_common_private_has_avx2(void) { @@ -40,6 +50,7 @@ static const uint8_t BASE64_SENTINEL_VALUE = 0xff; static const uint8_t BASE64_ENCODING_TABLE[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +static const uint8_t BASE64_URL_ENCODING_TABLE[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; /* in this table, 0xDD is an invalid decoded value, if you have to do byte counting for any reason, there's 16 bytes * per row. Reformatting is turned off to make sure this stays as 16 bytes per line. */ @@ -47,10 +58,10 @@ static const uint8_t BASE64_DECODING_TABLE[256] = { 64, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, - 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 62, 0xDD, 0xDD, 0xDD, 63, + 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 62, 0xDD, 62, 0xDD, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0xDD, 0xDD, 0xDD, 255, 0xDD, 0xDD, 0xDD, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0xDD, 0xDD, 0xDD, 0xDD, 63, 0xDD, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, @@ -216,73 +227,102 @@ } int aws_base64_compute_encoded_len(size_t to_encode_len, size_t *encoded_len) { - AWS_ASSERT(encoded_len); + AWS_ERROR_PRECONDITION(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; + size_t tmp = 0; - if (AWS_UNLIKELY(tmp < to_encode_len)) { - return aws_raise_error(AWS_ERROR_OVERFLOW_DETECTED); + if (AWS_UNLIKELY(aws_add_size_checked(to_encode_len, 2, &tmp))) { + return AWS_OP_ERR; } tmp /= 3; - size_t overflow_check = tmp; - tmp = 4 * tmp; + if (AWS_UNLIKELY(aws_mul_size_checked(tmp, 4, &tmp))) { + return AWS_OP_ERR; + } - if (AWS_UNLIKELY(tmp < overflow_check)) { - return aws_raise_error(AWS_ERROR_OVERFLOW_DETECTED); + *encoded_len = tmp; + + return AWS_OP_SUCCESS; +} + +int aws_base64_url_compute_encoded_len(size_t to_encode_len, size_t *encoded_len) { + AWS_ERROR_PRECONDITION(encoded_len); + + /* Just do direct math for each each 6 bits map to char. +5 is same trick to as before to round up. */ + + size_t tmp = 0; + + if (AWS_UNLIKELY(aws_mul_size_checked(to_encode_len, 8, &tmp))) { + return AWS_OP_ERR; + } + + if (AWS_UNLIKELY(aws_add_size_checked(tmp, 5, &tmp))) { + return AWS_OP_ERR; } + tmp /= 6; + *encoded_len = tmp; return AWS_OP_SUCCESS; } +bool s_ispadding(uint8_t ch) { + return ch == '='; +} + int aws_base64_compute_decoded_len(const struct aws_byte_cursor *AWS_RESTRICT to_decode, size_t *decoded_len) { AWS_ASSERT(to_decode); AWS_ASSERT(decoded_len); - const size_t len = to_decode->len; - const uint8_t *input = to_decode->ptr; + /* strip padding */ + struct aws_byte_cursor trimmed = aws_byte_cursor_right_trim_pred(to_decode, s_ispadding); + + const size_t len = trimmed.len; if (len == 0) { *decoded_len = 0; return AWS_OP_SUCCESS; } - /* ensure it's divisible by 4 */ - if (AWS_UNLIKELY(len & 0x03)) { + /* impossible len */ + if (AWS_UNLIKELY(len % 4 == 1)) { return aws_raise_error(AWS_ERROR_INVALID_BASE64_STR); } - /* 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; + /* For every 4 ascii characters of encoded input, there will be 3 bytes of decoded output. */ + size_t decoded_len_tmp = 0; - /* 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 (input[len - 1] == '=' && input[len - 2] == '=') { /*last two chars are = */ - padding = 2; - } else if (input[len - 1] == '=') { /*last char is = */ - padding = 1; + if (aws_mul_size_checked(len, 3, &decoded_len_tmp)) { + return AWS_OP_ERR; } - *decoded_len = decoded_len_tmp - padding; + decoded_len_tmp >>= 2; + + /* But last two ascii chars might be padding. */ + + *decoded_len = decoded_len_tmp; 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->len == 0 || to_encode->ptr != NULL); +static int s_base64_encode( + const struct aws_byte_cursor *AWS_RESTRICT to_encode, + struct aws_byte_buf *AWS_RESTRICT output, + bool do_url_safe_encoding) { size_t encoded_length = 0; - if (AWS_UNLIKELY(aws_base64_compute_encoded_len(to_encode->len, &encoded_length))) { - return AWS_OP_ERR; + if (do_url_safe_encoding) { + if (AWS_UNLIKELY(aws_base64_url_compute_encoded_len(to_encode->len, &encoded_length))) { + return AWS_OP_ERR; + } + } else { + if (AWS_UNLIKELY(aws_base64_compute_encoded_len(to_encode->len, &encoded_length))) { + return AWS_OP_ERR; + } } size_t needed_capacity = 0; @@ -296,8 +336,14 @@ 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); + /* + * Note: avx2 impl currently does not support url base64 (no padding -> output not divisible by 4 -> it writes out + * of bounds). Just use software version for now (since need for base64 url is small) instead of hacking together + * half hearted avx2 impl. + */ + if (!do_url_safe_encoding && aws_common_private_has_avx2()) { + aws_common_private_base64_encode_sse41( + to_encode->ptr, output->buffer + output->len, to_encode->len, do_url_safe_encoding); output->len += encoded_length; return AWS_OP_SUCCESS; } @@ -307,7 +353,9 @@ size_t remainder_count = (buffer_length % 3); size_t str_index = output->len; - for (size_t i = 0; i < to_encode->len; i += 3) { + const uint8_t *encoding_table = do_url_safe_encoding ? BASE64_URL_ENCODING_TABLE : BASE64_ENCODING_TABLE; + + for (size_t i = 0; i < buffer_length; i += 3) { uint32_t block = to_encode->ptr[i]; block <<= 8; @@ -316,17 +364,21 @@ } block <<= 8; - if (AWS_LIKELY(i + 2 < to_encode->len)) { + if (AWS_LIKELY(i + 2 < buffer_length)) { block = block | to_encode->ptr[i + 2]; } - output->buffer[str_index++] = BASE64_ENCODING_TABLE[(block >> 18) & 0x3F]; - output->buffer[str_index++] = BASE64_ENCODING_TABLE[(block >> 12) & 0x3F]; - output->buffer[str_index++] = BASE64_ENCODING_TABLE[(block >> 6) & 0x3F]; - output->buffer[str_index++] = BASE64_ENCODING_TABLE[block & 0x3F]; + output->buffer[str_index++] = encoding_table[(block >> 18) & 0x3F]; + output->buffer[str_index++] = encoding_table[(block >> 12) & 0x3F]; + if (AWS_LIKELY(i + 1 < buffer_length)) { + output->buffer[str_index++] = encoding_table[(block >> 6) & 0x3F]; + if (AWS_LIKELY(i + 2 < buffer_length)) { + output->buffer[str_index++] = encoding_table[block & 0x3F]; + } + } } - if (remainder_count > 0) { + if (!do_url_safe_encoding && remainder_count > 0) { output->buffer[output->len + block_count * 4 - 1] = '='; if (remainder_count == 1) { output->buffer[output->len + block_count * 4 - 2] = '='; @@ -338,6 +390,16 @@ return AWS_OP_SUCCESS; } +int aws_base64_encode(const struct aws_byte_cursor *AWS_RESTRICT to_encode, struct aws_byte_buf *AWS_RESTRICT output) { + return s_base64_encode(to_encode, output, false); +} + +int aws_base64_url_encode( + const struct aws_byte_cursor *AWS_RESTRICT to_encode, + struct aws_byte_buf *AWS_RESTRICT output) { + return s_base64_encode(to_encode, output, true); +} + static inline int s_base64_get_decoded_value(unsigned char to_decode, uint8_t *value, int8_t allow_sentinel) { uint8_t decode_value = BASE64_DECODING_TABLE[(size_t)to_decode]; @@ -360,7 +422,14 @@ return aws_raise_error(AWS_ERROR_SHORT_BUFFER); } - if (aws_common_private_has_avx2()) { + /* + * Note: avx2 version relies on input being padded to 4 byte boundary. + * Regular base64 is always padded to 4, but for url variant padding is skipped. + * Fall back to software version for inputs that are not divisible by 4 cleanly (aka base64 url), + * as those are a corner case and we dont need them as often. + * Reconsider, writing intrinsic version is usage becomes more widespread. + */ + if ((to_decode->len % 4 == 0) && aws_common_private_has_avx2()) { size_t result = aws_common_private_base64_decode_sse41(to_decode->ptr, output->buffer, to_decode->len); if (result == SIZE_MAX) { return aws_raise_error(AWS_ERROR_INVALID_BASE64_STR); @@ -370,7 +439,8 @@ return AWS_OP_SUCCESS; } - int64_t block_count = (int64_t)to_decode->len / 4; + int64_t block_count = (int64_t)(to_decode->len + 3) / 4; + size_t remainder = to_decode->len % 4; size_t string_index = 0; uint8_t value1 = 0, value2 = 0, value3 = 0, value4 = 0; int64_t buffer_index = 0; @@ -394,9 +464,19 @@ 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)) { + s_base64_get_decoded_value(to_decode->ptr[string_index++], &value2, 0)) { + return aws_raise_error(AWS_ERROR_INVALID_BASE64_STR); + } + + value3 = BASE64_SENTINEL_VALUE; + value4 = BASE64_SENTINEL_VALUE; + + if ((remainder == 3 || remainder == 0) && + s_base64_get_decoded_value(to_decode->ptr[string_index++], &value3, 1)) { + return aws_raise_error(AWS_ERROR_INVALID_BASE64_STR); + } + + if (remainder == 0 && s_base64_get_decoded_value(to_decode->ptr[string_index++], &value4, 1)) { return aws_raise_error(AWS_ERROR_INVALID_BASE64_STR); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-common-0.12.5/source/posix/system_info.c new/aws-c-common-0.12.6/source/posix/system_info.c --- old/aws-c-common-0.12.5/source/posix/system_info.c 2025-09-18 18:39:54.000000000 +0200 +++ new/aws-c-common-0.12.6/source/posix/system_info.c 2025-11-14 02:45:38.000000000 +0100 @@ -465,12 +465,15 @@ } #endif /* AWS_HAVE_EXECINFO */ -#if defined(AWS_OS_APPLE) enum aws_platform_os aws_get_platform_build_os(void) { +#if defined(AWS_OS_MACOS) return AWS_PLATFORM_OS_MAC; -} +// Other Apple platforms will be reported as iOS +#elif defined(AWS_OS_APPLE) + return AWS_PLATFORM_OS_IOS; +#elif defined(AWS_OS_ANDROID) + return AWS_PLATFORM_OS_ANDROID; #else -enum aws_platform_os aws_get_platform_build_os(void) { return AWS_PLATFORM_OS_UNIX; +#endif } -#endif /* AWS_OS_APPLE */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-common-0.12.5/source/system_info.c new/aws-c-common-0.12.6/source/system_info.c --- old/aws-c-common-0.12.5/source/system_info.c 2025-09-18 18:39:54.000000000 +0200 +++ new/aws-c-common-0.12.6/source/system_info.c 2025-11-14 02:45:38.000000000 +0100 @@ -78,3 +78,39 @@ size_t aws_system_environment_get_cpu_group_count(const struct aws_system_environment *env) { return env->cpu_group_count; } + +/* + * Platform OS string constants - these are the string representations for each supported platform. String choices + * follow common industry conventions: + * - "Windows" - Microsoft Windows family + * - "macOS" - Apple macOS + * - "iOS" - Apple iOS (or other unknown Apple platform) + * - "Android" - Google Android mobile OS + * - "Unix" - Unix-like systems (Linux, BSD, etc.) + * - "Unknown" - Fallback for unrecognized platforms + */ +AWS_STATIC_STRING_FROM_LITERAL(s_windows_str, "Windows"); +AWS_STATIC_STRING_FROM_LITERAL(s_macos_str, "macOS"); +AWS_STATIC_STRING_FROM_LITERAL(s_ios_str, "iOS"); +AWS_STATIC_STRING_FROM_LITERAL(s_android_str, "Android"); +AWS_STATIC_STRING_FROM_LITERAL(s_unix_str, "Unix"); +AWS_STATIC_STRING_FROM_LITERAL(s_unknown_str, "Unknown"); + +struct aws_byte_cursor aws_get_platform_build_os_string(void) { + enum aws_platform_os os = aws_get_platform_build_os(); + switch (os) { + case AWS_PLATFORM_OS_WINDOWS: + return aws_byte_cursor_from_string(s_windows_str); + case AWS_PLATFORM_OS_MAC: + return aws_byte_cursor_from_string(s_macos_str); + case AWS_PLATFORM_OS_IOS: + return aws_byte_cursor_from_string(s_ios_str); + case AWS_PLATFORM_OS_ANDROID: + return aws_byte_cursor_from_string(s_android_str); + case AWS_PLATFORM_OS_UNIX: + return aws_byte_cursor_from_string(s_unix_str); + } + /* Handle invalid enum values */ + AWS_LOGF_WARN(AWS_LS_COMMON_GENERAL, "Unknown platform OS enum value: %d", (int)os); + return aws_byte_cursor_from_string(s_unknown_str); +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-common-0.12.5/tests/CMakeLists.txt new/aws-c-common-0.12.6/tests/CMakeLists.txt --- old/aws-c-common-0.12.5/tests/CMakeLists.txt 2025-09-18 18:39:54.000000000 +0200 +++ new/aws-c-common-0.12.6/tests/CMakeLists.txt 2025-11-14 02:45:38.000000000 +0100 @@ -129,6 +129,14 @@ add_test_case(base64_encoding_test_case_fooba_test) add_test_case(base64_encoding_test_case_foobar_test) add_test_case(base64_encoding_test_case_32bytes_test) +add_test_case(base64_url_encoding_test_case_empty_test) +add_test_case(base64_url_encoding_test_case_f_test) +add_test_case(base64_url_encoding_test_case_fo_test) +add_test_case(base64_url_encoding_test_case_foo_test) +add_test_case(base64_url_encoding_test_case_foob_test) +add_test_case(base64_url_encoding_test_case_fooba_test) +add_test_case(base64_url_encoding_test_case_foobar_test) +add_test_case(base64_url_encoding_test_case_32bytes_test) add_test_case(base64_encoding_buffer_size_too_small_test) add_test_case(base64_encoding_buffer_size_overflow_test) add_test_case(base64_encoding_buffer_size_invalid_test) @@ -138,6 +146,7 @@ add_test_case(base64_encoding_test_zeros) add_test_case(base64_encoding_test_roundtrip) add_test_case(base64_encoding_test_all_values) +add_test_case(base64_url_encoding_test_all_values) add_test_case(uint64_buffer_test) add_test_case(uint64_buffer_non_aligned_test) add_test_case(uint32_buffer_test) @@ -309,6 +318,7 @@ add_test_case(test_page_size_at_least_works_superficially) add_test_case(test_stack_trace_decoding) add_test_case(test_platform_build_os) +add_test_case(test_platform_build_os_string) add_test_case(test_sanity_check_numa_discovery) add_test_case(test_sanity_check_environment_loader) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-common-0.12.5/tests/encoding_test.c new/aws-c-common-0.12.6/tests/encoding_test.c --- old/aws-c-common-0.12.5/tests/encoding_test.c 2025-09-18 18:39:54.000000000 +0200 +++ new/aws-c-common-0.12.6/tests/encoding_test.c 2025-11-14 02:45:38.000000000 +0100 @@ -265,19 +265,21 @@ AWS_STATIC_STRING_FROM_LITERAL(s_base64_encode_prefix, "Prefix"); -/*base64 encoding test cases */ +/* base64 encoding test cases */ static int s_run_base64_encoding_test_case( struct aws_allocator *allocator, const char *test_str, size_t test_str_len, const char *expected, - size_t expected_len) { + size_t expected_len, + bool url_safe) { size_t output_len = 0; /* Part 1: encoding */ ASSERT_SUCCESS( - aws_base64_compute_encoded_len(test_str_len, &output_len), + url_safe ? aws_base64_url_compute_encoded_len(test_str_len, &output_len) + : aws_base64_compute_encoded_len(test_str_len, &output_len), "Compute base64 encoded length failed with %d", aws_last_error()); ASSERT_INT_EQUALS(expected_len, output_len, "Output len on string should be %d", expected_len); @@ -292,10 +294,18 @@ struct aws_byte_buf output = aws_byte_buf_from_empty_array(allocation.buffer + 1, output_len); - ASSERT_SUCCESS(aws_base64_encode(&to_encode, &output), "encode call should have succeeded"); + ASSERT_SUCCESS( + url_safe ? aws_base64_url_encode(&to_encode, &output) : aws_base64_encode(&to_encode, &output), + "encode call should have succeeded"); ASSERT_BIN_ARRAYS_EQUALS( - expected, expected_len, output.buffer, output.len, "Encode output should have been {%s}", expected); + expected, + expected_len, + output.buffer, + output.len, + "Encode output should have been {%s}, but got " PRInSTR, + expected, + AWS_BYTE_BUF_PRI(output)); ASSERT_INT_EQUALS( (unsigned char)*(allocation.buffer), (unsigned char)0xdd, @@ -312,7 +322,9 @@ struct aws_byte_cursor prefix_cursor = aws_byte_cursor_from_string(s_base64_encode_prefix); ASSERT_SUCCESS(aws_byte_buf_append(&allocation, &prefix_cursor)); - ASSERT_SUCCESS(aws_base64_encode(&to_encode, &allocation), "encode call should have succeeded"); + ASSERT_SUCCESS( + url_safe ? aws_base64_url_encode(&to_encode, &allocation) : aws_base64_encode(&to_encode, &allocation), + "encode call should have succeeded"); ASSERT_BIN_ARRAYS_EQUALS( expected, @@ -378,77 +390,140 @@ char test_data[] = ""; char expected[] = ""; - return s_run_base64_encoding_test_case(allocator, test_data, strlen(test_data), expected, strlen(expected)); + return s_run_base64_encoding_test_case(allocator, test_data, strlen(test_data), expected, strlen(expected), false); } - AWS_TEST_CASE(base64_encoding_test_case_empty_test, s_base64_encoding_test_case_empty) +static int s_base64_url_encoding_test_case_empty(struct aws_allocator *allocator, void *ctx) { + (void)ctx; + + char test_data[] = ""; + char expected[] = ""; + + return s_run_base64_encoding_test_case(allocator, test_data, strlen(test_data), expected, strlen(expected), true); +} +AWS_TEST_CASE(base64_url_encoding_test_case_empty_test, s_base64_url_encoding_test_case_empty) + static int s_base64_encoding_test_case_f(struct aws_allocator *allocator, void *ctx) { (void)ctx; char test_data[] = "f"; char expected[] = "Zg=="; - return s_run_base64_encoding_test_case(allocator, test_data, strlen(test_data), expected, strlen(expected)); + return s_run_base64_encoding_test_case(allocator, test_data, strlen(test_data), expected, strlen(expected), false); } - AWS_TEST_CASE(base64_encoding_test_case_f_test, s_base64_encoding_test_case_f) +static int s_base64_url_encoding_test_case_f(struct aws_allocator *allocator, void *ctx) { + (void)ctx; + + char test_data[] = "f"; + char expected[] = "Zg"; + + return s_run_base64_encoding_test_case(allocator, test_data, strlen(test_data), expected, strlen(expected), true); +} +AWS_TEST_CASE(base64_url_encoding_test_case_f_test, s_base64_url_encoding_test_case_f) + static int s_base64_encoding_test_case_fo(struct aws_allocator *allocator, void *ctx) { (void)ctx; char test_data[] = "fo"; char expected[] = "Zm8="; - return s_run_base64_encoding_test_case(allocator, test_data, strlen(test_data), expected, strlen(expected)); + return s_run_base64_encoding_test_case(allocator, test_data, strlen(test_data), expected, strlen(expected), false); } - AWS_TEST_CASE(base64_encoding_test_case_fo_test, s_base64_encoding_test_case_fo) +static int s_base64_url_encoding_test_case_fo(struct aws_allocator *allocator, void *ctx) { + (void)ctx; + + char test_data[] = "fo"; + char expected[] = "Zm8"; + + return s_run_base64_encoding_test_case(allocator, test_data, strlen(test_data), expected, strlen(expected), true); +} +AWS_TEST_CASE(base64_url_encoding_test_case_fo_test, s_base64_url_encoding_test_case_fo) + static int s_base64_encoding_test_case_foo(struct aws_allocator *allocator, void *ctx) { (void)ctx; char test_data[] = "foo"; char expected[] = "Zm9v"; - return s_run_base64_encoding_test_case(allocator, test_data, strlen(test_data), expected, strlen(expected)); + return s_run_base64_encoding_test_case(allocator, test_data, strlen(test_data), expected, strlen(expected), false); } - AWS_TEST_CASE(base64_encoding_test_case_foo_test, s_base64_encoding_test_case_foo) +static int s_base64_url_encoding_test_case_foo(struct aws_allocator *allocator, void *ctx) { + (void)ctx; + + char test_data[] = "foo"; + char expected[] = "Zm9v"; + + return s_run_base64_encoding_test_case(allocator, test_data, strlen(test_data), expected, strlen(expected), true); +} +AWS_TEST_CASE(base64_url_encoding_test_case_foo_test, s_base64_url_encoding_test_case_foo) + static int s_base64_encoding_test_case_foob(struct aws_allocator *allocator, void *ctx) { (void)ctx; char test_data[] = "foob"; char expected[] = "Zm9vYg=="; - return s_run_base64_encoding_test_case(allocator, test_data, strlen(test_data), expected, strlen(expected)); + return s_run_base64_encoding_test_case(allocator, test_data, strlen(test_data), expected, strlen(expected), false); } - AWS_TEST_CASE(base64_encoding_test_case_foob_test, s_base64_encoding_test_case_foob) +static int s_base64_url_encoding_test_case_foob(struct aws_allocator *allocator, void *ctx) { + (void)ctx; + + char test_data[] = "foob"; + char expected[] = "Zm9vYg"; + + return s_run_base64_encoding_test_case(allocator, test_data, strlen(test_data), expected, strlen(expected), true); +} +AWS_TEST_CASE(base64_url_encoding_test_case_foob_test, s_base64_url_encoding_test_case_foob) + static int s_base64_encoding_test_case_fooba(struct aws_allocator *allocator, void *ctx) { (void)ctx; char test_data[] = "fooba"; char expected[] = "Zm9vYmE="; - return s_run_base64_encoding_test_case(allocator, test_data, strlen(test_data), expected, strlen(expected)); + return s_run_base64_encoding_test_case(allocator, test_data, strlen(test_data), expected, strlen(expected), false); } - AWS_TEST_CASE(base64_encoding_test_case_fooba_test, s_base64_encoding_test_case_fooba) +static int s_base64_url_encoding_test_case_fooba(struct aws_allocator *allocator, void *ctx) { + (void)ctx; + + char test_data[] = "fooba"; + char expected[] = "Zm9vYmE"; + + return s_run_base64_encoding_test_case(allocator, test_data, strlen(test_data), expected, strlen(expected), true); +} +AWS_TEST_CASE(base64_url_encoding_test_case_fooba_test, s_base64_url_encoding_test_case_fooba) + static int s_base64_encoding_test_case_foobar(struct aws_allocator *allocator, void *ctx) { (void)ctx; char test_data[] = "foobar"; char expected[] = "Zm9vYmFy"; - return s_run_base64_encoding_test_case(allocator, test_data, strlen(test_data), expected, strlen(expected)); + return s_run_base64_encoding_test_case(allocator, test_data, strlen(test_data), expected, strlen(expected), false); } - AWS_TEST_CASE(base64_encoding_test_case_foobar_test, s_base64_encoding_test_case_foobar) +static int s_base64_url_encoding_test_case_foobar(struct aws_allocator *allocator, void *ctx) { + (void)ctx; + + char test_data[] = "foobar"; + char expected[] = "Zm9vYmFy"; + + return s_run_base64_encoding_test_case(allocator, test_data, strlen(test_data), expected, strlen(expected), true); +} +AWS_TEST_CASE(base64_url_encoding_test_case_foobar_test, s_base64_url_encoding_test_case_foobar) + static int s_base64_encoding_test_case_32bytes(struct aws_allocator *allocator, void *ctx) { (void)ctx; @@ -456,22 +531,43 @@ char test_data[] = "this is a 32 byte long string!!!"; char expected[] = "dGhpcyBpcyBhIDMyIGJ5dGUgbG9uZyBzdHJpbmchISE="; - return s_run_base64_encoding_test_case(allocator, test_data, strlen(test_data), expected, strlen(expected)); + return s_run_base64_encoding_test_case(allocator, test_data, strlen(test_data), expected, strlen(expected), false); } - AWS_TEST_CASE(base64_encoding_test_case_32bytes_test, s_base64_encoding_test_case_32bytes) +static int s_base64_url_encoding_test_case_32bytes(struct aws_allocator *allocator, void *ctx) { + (void)ctx; + + /* 01234567890123456789012345678901 */ + char test_data[] = "this is a 32 byte long string!!!"; + char expected[] = "dGhpcyBpcyBhIDMyIGJ5dGUgbG9uZyBzdHJpbmchISE"; + + return s_run_base64_encoding_test_case(allocator, test_data, strlen(test_data), expected, strlen(expected), true); +} +AWS_TEST_CASE(base64_url_encoding_test_case_32bytes_test, s_base64_url_encoding_test_case_32bytes) + static int s_base64_encoding_test_zeros_fn(struct aws_allocator *allocator, void *ctx) { (void)ctx; uint8_t test_data[6] = {0}; char expected[] = "AAAAAAAA"; - return s_run_base64_encoding_test_case(allocator, (char *)test_data, sizeof(test_data), expected, strlen(expected)); + return s_run_base64_encoding_test_case( + allocator, (char *)test_data, sizeof(test_data), expected, strlen(expected), false); } - AWS_TEST_CASE(base64_encoding_test_zeros, s_base64_encoding_test_zeros_fn) +static int s_base64_url_encoding_test_zeros_fn(struct aws_allocator *allocator, void *ctx) { + (void)ctx; + + uint8_t test_data[6] = {0}; + char expected[] = "AAAAAAAA"; + + return s_run_base64_encoding_test_case( + allocator, (char *)test_data, sizeof(test_data), expected, strlen(expected), true); +} +AWS_TEST_CASE(base64_url_encoding_test_zeros, s_base64_url_encoding_test_zeros_fn) + static int s_base64_encoding_test_roundtrip(struct aws_allocator *allocator, void *ctx) { (void)ctx; (void)allocator; @@ -530,10 +626,10 @@ } AWS_TEST_CASE(base64_encoding_test_roundtrip, s_base64_encoding_test_roundtrip) -/* this test is here because I manually touched the decoding table with sentinal +/* this test is here because I manually touched the decoding table with sentinel * values for efficiency reasons and I want to make sure it matches the encoded * string. This checks that none of those values that were previously 0 which I - * moved to a sentinal value of 0xDD, were actually supposed to be a 0 other + * moved to a sentinel value of 0xDD, were actually supposed to be a 0 other * than character value of 65 -> "A" -> 0. */ static int s_base64_encoding_test_all_values_fn(struct aws_allocator *allocator, void *ctx) { @@ -550,11 +646,30 @@ "jY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0t" "PU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+"; - return s_run_base64_encoding_test_case(allocator, (char *)test_data, sizeof(test_data), expected, strlen(expected)); + return s_run_base64_encoding_test_case( + allocator, (char *)test_data, sizeof(test_data), expected, strlen(expected), false); } - AWS_TEST_CASE(base64_encoding_test_all_values, s_base64_encoding_test_all_values_fn) +static int s_base64_url_encoding_test_all_values_fn(struct aws_allocator *allocator, void *ctx) { + (void)ctx; + + uint8_t test_data[255] = {0}; + + for (uint8_t i = 0; i < (uint8_t)sizeof(test_data); ++i) { + test_data[i] = i; + } + + char expected[] = "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0-P0BBQkNERU" + "ZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn-AgYKDhIWGh4iJiouM" + "jY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq-wsbKztLW2t7i5uru8vb6_wMHCw8TFxsfIycrLzM3Oz9DR0t" + "PU1dbX2Nna29zd3t_g4eLj5OXm5-jp6uvs7e7v8PHy8_T19vf4-fr7_P3-"; + + return s_run_base64_encoding_test_case( + allocator, (char *)test_data, sizeof(test_data), expected, strlen(expected), true); +} +AWS_TEST_CASE(base64_url_encoding_test_all_values, s_base64_url_encoding_test_all_values_fn) + static int s_base64_encoding_buffer_size_too_small_test_fn(struct aws_allocator *allocator, void *ctx) { (void)allocator; (void)ctx; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-common-0.12.5/tests/system_info_tests.c new/aws-c-common-0.12.6/tests/system_info_tests.c --- old/aws-c-common-0.12.5/tests/system_info_tests.c 2025-09-18 18:39:54.000000000 +0200 +++ new/aws-c-common-0.12.6/tests/system_info_tests.c 2025-11-14 02:45:38.000000000 +0100 @@ -116,8 +116,12 @@ enum aws_platform_os build_os = aws_get_platform_build_os(); -#if defined(AWS_OS_APPLE) +#if defined(AWS_OS_MACOS) ASSERT_INT_EQUALS(build_os, AWS_PLATFORM_OS_MAC); +#elif defined(AWS_OS_APPLE) + ASSERT_INT_EQUALS(build_os, AWS_PLATFORM_OS_IOS); +#elif defined(AWS_OS_ANDROID) + ASSERT_INT_EQUALS(build_os, AWS_PLATFORM_OS_ANDROID); #elif defined(_WIN32) ASSERT_INT_EQUALS(build_os, AWS_PLATFORM_OS_WINDOWS); #else @@ -129,6 +133,31 @@ AWS_TEST_CASE(test_platform_build_os, s_test_platform_build_os_fn) +static int s_test_platform_build_os_string_fn(struct aws_allocator *allocator, void *ctx) { + (void)allocator; + (void)ctx; + + struct aws_byte_cursor os_string = aws_get_platform_build_os_string(); + ASSERT_TRUE(aws_byte_cursor_is_valid(&os_string)); + ASSERT_TRUE(os_string.len > 0); + +#if defined(AWS_OS_MACOS) + ASSERT_TRUE(aws_byte_cursor_eq_c_str(&os_string, "macOS")); +#elif defined(AWS_OS_APPLE) + ASSERT_TRUE(aws_byte_cursor_eq_c_str(&os_string, "iOS")); +#elif defined(AWS_OS_ANDROID) + ASSERT_TRUE(aws_byte_cursor_eq_c_str(&os_string, "Android")); +#elif defined(_WIN32) + ASSERT_TRUE(aws_byte_cursor_eq_c_str(&os_string, "Windows")); +#else + ASSERT_TRUE(aws_byte_cursor_eq_c_str(&os_string, "Unix")); +#endif + + return 0; +} + +AWS_TEST_CASE(test_platform_build_os_string, s_test_platform_build_os_string_fn) + static int s_test_sanity_check_numa_discovery(struct aws_allocator *allocator, void *ctx) { (void)ctx;
