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 2026-08-05 19:07:41
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/aws-c-common (Old)
 and      /work/SRC/openSUSE:Factory/.aws-c-common.new.16738 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "aws-c-common"

Wed Aug  5 19:07:41 2026 rev:34 rq:1369462 version:0.14.4

Changes:
--------
--- /work/SRC/openSUSE:Factory/aws-c-common/aws-c-common.changes        
2026-07-21 22:59:49.016518765 +0200
+++ /work/SRC/openSUSE:Factory/.aws-c-common.new.16738/aws-c-common.changes     
2026-08-05 19:07:43.911783432 +0200
@@ -1,0 +2,9 @@
+Tue Aug  4 08:55:27 UTC 2026 - John Paul Adrian Glaubitz 
<[email protected]>
+
+- Update to 0.14.4
+  * aws_file_get_last_modified_epoch by @TingDaoK in (#1258)
+- from version 0.14.3
+  * Add HWASan suppression support by @antonio2368 in (#1256)
+  * Fix windows nonascii env by @kai-ion in (#1260)
+
+-------------------------------------------------------------------

Old:
----
  v0.14.2.tar.gz

New:
----
  v0.14.4.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ aws-c-common.spec ++++++
--- /var/tmp/diff_new_pack.PSWVsp/_old  2026-08-05 19:07:44.551805550 +0200
+++ /var/tmp/diff_new_pack.PSWVsp/_new  2026-08-05 19:07:44.555805688 +0200
@@ -19,7 +19,7 @@
 %define library_version 1.0.0
 %define library_soversion 1
 Name:           aws-c-common
-Version:        0.14.2
+Version:        0.14.4
 Release:        0
 Summary:        Core C99 package for AWS SDK for C
 License:        Apache-2.0

++++++ v0.14.2.tar.gz -> v0.14.4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aws-c-common-0.14.2/include/aws/common/file.h 
new/aws-c-common-0.14.4/include/aws/common/file.h
--- old/aws-c-common-0.14.2/include/aws/common/file.h   2026-07-09 
18:53:07.000000000 +0200
+++ new/aws-c-common-0.14.4/include/aws/common/file.h   2026-07-21 
19:03:28.000000000 +0200
@@ -308,6 +308,32 @@
 AWS_COMMON_API
 bool aws_file_direct_io_is_supported(void);
 
+/*
+ * Gets the last modification time of an open file as nanoseconds since unix 
epoch.
+ *
+ * Unix flavors use fstat with nanosecond-precision fields (st_mtim on 
Linux/FreeBSD,
+ * st_mtimespec on Apple). Windows uses GetFileTime on the HANDLE queried from 
the
+ * libc FILE pointer (100-nanosecond FILETIME precision).
+ *
+ * Platform timestamp-visibility guarantees differ:
+ * - POSIX: st_mtime/st_mtim is updated by write(2) itself (see inode(7):
+ *   https://man7.org/linux/man-pages/man7/inode.7.html). Callers using 
buffered stdio
+ *   writes must fflush() or fclose() first so write(2) actually happens; once 
it has,
+ *   a subsequent stat()/fstat() sees the new timestamp immediately, no fsync 
needed
+ *   (fsync(2) confirms fdatasync() skips flushing st_mtime for this reason:
+ *   https://man7.org/linux/man-pages/man2/fsync.2.html).
+ * - Windows: the last write time is only guaranteed correct once all write 
handles are
+ *   closed; FlushFileBuffers() does not help. See "File Times":
+ *   https://learn.microsoft.com/en-us/windows/win32/sysinfo/file-times
+ *
+ * As a result, if a file was written to and you need to observe that write in 
its
+ * updated timestamp, close the write handle first, then open a new handle and 
call
+ * this function on that new handle. Calling this function on the (now-closed) 
write
+ * handle is not valid on any platform, since a closed FILE* cannot be used at 
all.
+ */
+AWS_COMMON_API
+int aws_file_get_last_modified_epoch(FILE *file, uint64_t *last_modified_ns);
+
 AWS_EXTERN_C_END AWS_POP_SANE_WARNING_LEVEL
 
 #endif /* AWS_COMMON_FILE_H */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aws-c-common-0.14.2/include/aws/common/macros.h 
new/aws-c-common-0.14.4/include/aws/common/macros.h
--- old/aws-c-common-0.14.2/include/aws/common/macros.h 2026-07-09 
18:53:07.000000000 +0200
+++ new/aws-c-common-0.14.4/include/aws/common/macros.h 2026-07-21 
19:03:28.000000000 +0200
@@ -114,6 +114,20 @@
 #endif
 
 #if defined(__has_feature)
+#    if __has_feature(hwaddress_sanitizer)
+#        define AWS_SUPPRESS_HWASAN __attribute__((no_sanitize("hwaddress")))
+#    endif
+#elif defined(__SANITIZE_HWADDRESS__)
+#    if defined(__GNUC__)
+#        define AWS_SUPPRESS_HWASAN __attribute__((no_sanitize("hwaddress")))
+#    endif
+#endif
+
+#if !defined(AWS_SUPPRESS_HWASAN)
+#    define AWS_SUPPRESS_HWASAN
+#endif
+
+#if defined(__has_feature)
 #    if __has_feature(thread_sanitizer)
 #        define AWS_SUPPRESS_TSAN __attribute__((no_sanitize("thread")))
 #    endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/aws-c-common-0.14.2/include/aws/common/private/lookup3.inl 
new/aws-c-common-0.14.4/include/aws/common/private/lookup3.inl
--- old/aws-c-common-0.14.2/include/aws/common/private/lookup3.inl      
2026-07-09 18:53:07.000000000 +0200
+++ new/aws-c-common-0.14.4/include/aws/common/private/lookup3.inl      
2026-07-21 19:03:28.000000000 +0200
@@ -496,8 +496,8 @@
  * the key.  *pc is better mixed than *pb, so use *pc first.  If you want
  * a 64-bit value do something like "*pc + (((uint64_t)*pb)<<32)".
  */
-/* AddressSanitizer hates this implementation, even though it's innocuous */
-AWS_SUPPRESS_ASAN static void hashlittle2(
+/* AddressSanitizer and HWAddressSanitizer hate this implementation, even 
though it's innocuous */
+AWS_SUPPRESS_ASAN AWS_SUPPRESS_HWASAN static void hashlittle2(
   const void *key,       /* the key to hash */
   size_t      length,    /* length of the key */
   uint32_t   *pc,        /* IN: primary initval, OUT: primary hash */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aws-c-common-0.14.2/source/allocator_sba.c 
new/aws-c-common-0.14.4/source/allocator_sba.c
--- old/aws-c-common-0.14.2/source/allocator_sba.c      2026-07-09 
18:53:07.000000000 +0200
+++ new/aws-c-common-0.14.4/source/allocator_sba.c      2026-07-21 
19:03:28.000000000 +0200
@@ -406,7 +406,9 @@
     return aws_mem_acquire(sba->allocator, size);
 }
 
-AWS_SUPPRESS_ASAN AWS_SUPPRESS_TSAN static void s_sba_free(struct 
small_block_allocator *sba, void *addr) {
+AWS_SUPPRESS_ASAN AWS_SUPPRESS_HWASAN AWS_SUPPRESS_TSAN static void s_sba_free(
+    struct small_block_allocator *sba,
+    void *addr) {
     if (!addr) {
         return;
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aws-c-common-0.14.2/source/posix/file.c 
new/aws-c-common-0.14.4/source/posix/file.c
--- old/aws-c-common-0.14.2/source/posix/file.c 2026-07-09 18:53:07.000000000 
+0200
+++ new/aws-c-common-0.14.4/source/posix/file.c 2026-07-21 19:03:28.000000000 
+0200
@@ -2,6 +2,9 @@
  * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
  * SPDX-License-Identifier: Apache-2.0.
  */
+
+#define _GNU_SOURCE /* NOLINT(bugprone-reserved-identifier) */
+
 #include <aws/common/environment.h>
 #include <aws/common/file.h>
 #include <aws/common/logging.h>
@@ -308,3 +311,30 @@
 
     return AWS_OP_SUCCESS;
 }
+
+int aws_file_get_last_modified_epoch(FILE *file, uint64_t *last_modified_ns) {
+
+    struct stat file_stats;
+
+    int fd = fileno(file);
+    if (fd == -1) {
+        return aws_raise_error(AWS_ERROR_INVALID_FILE_HANDLE);
+    }
+
+    if (fstat(fd, &file_stats)) {
+        int errno_value = errno; /* Always cache errno before potential 
side-effect */
+        return aws_translate_and_raise_io_error(errno_value);
+    }
+
+#if defined(AWS_OS_APPLE)
+    uint64_t secs = (uint64_t)file_stats.st_mtimespec.tv_sec;
+    uint64_t nsecs = (uint64_t)file_stats.st_mtimespec.tv_nsec;
+#else
+    uint64_t secs = (uint64_t)file_stats.st_mtim.tv_sec;
+    uint64_t nsecs = (uint64_t)file_stats.st_mtim.tv_nsec;
+#endif
+
+    *last_modified_ns = secs * (uint64_t)1000000000 + nsecs;
+
+    return AWS_OP_SUCCESS;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aws-c-common-0.14.2/source/windows/environment.c 
new/aws-c-common-0.14.4/source/windows/environment.c
--- old/aws-c-common-0.14.2/source/windows/environment.c        2026-07-09 
18:53:07.000000000 +0200
+++ new/aws-c-common-0.14.4/source/windows/environment.c        2026-07-21 
19:03:28.000000000 +0200
@@ -10,36 +10,61 @@
 
 struct aws_string *aws_get_env(struct aws_allocator *allocator, const char 
*name) {
 #ifdef _MSC_VER
-#    pragma warning(push)
-#    pragma warning(disable : 4996)
-#endif
+    /*
+     * On Windows, environment variables are natively stored as wide (UTF-16)
+     * strings. The narrow getenv()/_dupenv_s() APIs return values in the 
active
+     * ANSI code page, which is a lossy compatibility layer. Downstream code
+     * (aws_fopen_safe) assumes all strings are UTF-8, so reading through the
+     * narrow API produces encoding mismatches for non-ASCII values.
+     *
+     * We use _wdupenv_s to read the authoritative wide value, then convert to
+     * UTF-8 for consistent handling throughout the SDK.
+     */
+
+    /* Convert variable name to wide (env var names are ASCII, which is valid 
UTF-8) */
+    struct aws_byte_cursor name_cursor = aws_byte_cursor_from_c_str(name);
+    struct aws_wstring *w_name = 
aws_string_convert_to_wchar_from_byte_cursor(allocator, &name_cursor);
+    if (!w_name) {
+        return NULL;
+    }
+
+    /* Read value as wide characters using _wdupenv_s */
+    wchar_t *w_value = NULL;
+    size_t w_value_len = 0;
+    errno_t err = _wdupenv_s(&w_value, &w_value_len, 
aws_wstring_c_str(w_name));
+    aws_wstring_destroy(w_name);
+
+    if (err != 0 || w_value == NULL || w_value_len == 0) {
+        free(w_value);
+        return NULL;
+    }
+
+    /* Convert wide value to UTF-8 */
+    struct aws_string *result = aws_string_convert_from_wchar_c_str(allocator, 
w_value);
+    free(w_value);
+
+    return result;
+#else
     const char *value = getenv(name);
-#ifdef _MSC_VER
-#    pragma warning(pop)
-#endif
 
     if (value == NULL) {
         return NULL;
     }
 
     return aws_string_new_from_c_str(allocator, value);
+#endif
 }
 
 struct aws_string *aws_get_env_nonempty(struct aws_allocator *allocator, const 
char *name) {
-#ifdef _MSC_VER
-#    pragma warning(push)
-#    pragma warning(disable : 4996)
-#endif
-    const char *value = getenv(name);
-#ifdef _MSC_VER
-#    pragma warning(pop)
-#endif
-
-    if (value == NULL || value[0] == '\0') {
+    struct aws_string *value = aws_get_env(allocator, name);
+    if (value == NULL) {
         return NULL;
     }
-
-    return aws_string_new_from_c_str(allocator, value);
+    if (value->len == 0) {
+        aws_string_destroy(value);
+        return NULL;
+    }
+    return value;
 }
 
 int aws_get_environment_value(
@@ -47,26 +72,7 @@
     const struct aws_string *variable_name,
     struct aws_string **value_out) {
 
-#ifdef _MSC_VER
-#    pragma warning(push)
-#    pragma warning(disable : 4996)
-#endif
-
-    const char *value = getenv(aws_string_c_str(variable_name));
-
-#ifdef _MSC_VER
-#    pragma warning(pop)
-#endif
-
-    if (value == NULL) {
-        *value_out = NULL;
-        return AWS_OP_SUCCESS;
-    }
-
-    *value_out = aws_string_new_from_c_str(allocator, value);
-    if (*value_out == NULL) {
-        return aws_raise_error(AWS_ERROR_ENVIRONMENT_GET);
-    }
+    *value_out = aws_get_env(allocator, aws_string_c_str(variable_name));
 
     return AWS_OP_SUCCESS;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aws-c-common-0.14.2/source/windows/file.c 
new/aws-c-common-0.14.4/source/windows/file.c
--- old/aws-c-common-0.14.2/source/windows/file.c       2026-07-09 
18:53:07.000000000 +0200
+++ new/aws-c-common-0.14.4/source/windows/file.c       2026-07-21 
19:03:28.000000000 +0200
@@ -544,3 +544,43 @@
 
     return AWS_OP_SUCCESS;
 }
+
+int aws_file_get_last_modified_epoch(FILE *file, uint64_t *last_modified_ns) {
+    if (file == NULL) {
+        return aws_raise_error(AWS_ERROR_INVALID_FILE_HANDLE);
+    }
+
+    int fd = _fileno(file);
+    if (fd == -1) {
+        return aws_raise_error(AWS_ERROR_INVALID_FILE_HANDLE);
+    }
+
+    HANDLE os_file = (HANDLE)_get_osfhandle(fd);
+    if (os_file == INVALID_HANDLE_VALUE) {
+        int errno_value = errno; /* Always cache errno before potential 
side-effect */
+        return aws_translate_and_raise_io_error(errno_value);
+    }
+
+    FILETIME last_write_time;
+    if (!GetFileTime(os_file, NULL /*creation*/, NULL /*access*/, 
&last_write_time)) {
+        return aws_raise_error(AWS_ERROR_SYS_CALL_FAILURE);
+    }
+
+    /*
+     * FILETIME is 100-nanosecond intervals since January 1, 1601 UTC.
+     * Convert to nanoseconds since unix epoch (January 1, 1970 UTC).
+     * The difference is 11644473600 seconds = 116444736000000000 
hundred-nanos.
+     * See aws_sys_clock_get_ticks() in clock.c for the same conversion.
+     */
+    ULARGE_INTEGER int_conv;
+    int_conv.LowPart = last_write_time.dwLowDateTime;
+    int_conv.HighPart = last_write_time.dwHighDateTime;
+
+    static const uint64_t WINDOWS_TICK = 10000000;
+    static const uint64_t EC_TO_UNIX_EPOCH = 11644473600LL;
+    static const uint64_t FILE_TIME_TO_NS = 100;
+
+    *last_modified_ns = (int_conv.QuadPart - (WINDOWS_TICK * 
EC_TO_UNIX_EPOCH)) * FILE_TIME_TO_NS;
+
+    return AWS_OP_SUCCESS;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aws-c-common-0.14.2/tests/CMakeLists.txt 
new/aws-c-common-0.14.4/tests/CMakeLists.txt
--- old/aws-c-common-0.14.2/tests/CMakeLists.txt        2026-07-09 
18:53:07.000000000 +0200
+++ new/aws-c-common-0.14.4/tests/CMakeLists.txt        2026-07-21 
19:03:28.000000000 +0200
@@ -415,6 +415,7 @@
 
 add_test_case(test_environment_functions)
 add_test_case(test_env_functions)
+add_test_case(test_env_non_ascii_path)
 
 add_test_case(short_argument_parse)
 add_test_case(long_argument_parse)
@@ -534,6 +535,7 @@
 add_test_case(test_file_path_read_from_offset)
 add_test_case(test_file_path_read_from_offset_direct_io_chunking)
 add_test_case(test_file_path_write_to_offset_direct_io)
+add_test_case(test_file_get_last_modified_epoch)
 
 add_test_case(test_json_parse_from_string)
 add_test_case(test_json_parse_to_string)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aws-c-common-0.14.2/tests/environment_test.c 
new/aws-c-common-0.14.4/tests/environment_test.c
--- old/aws-c-common-0.14.2/tests/environment_test.c    2026-07-09 
18:53:07.000000000 +0200
+++ new/aws-c-common-0.14.4/tests/environment_test.c    2026-07-21 
19:03:28.000000000 +0200
@@ -82,3 +82,33 @@
 }
 
 AWS_TEST_CASE(test_env_functions, s_test_env_functions_fn)
+
+static int s_test_env_non_ascii_path_fn(struct aws_allocator *allocator, void 
*ctx) {
+    (void)ctx;
+#ifdef AWS_OS_WINDOWS
+    /* Set a non-ASCII environment variable. The value 0xE9 is 'é' in the
+     * ANSI code page (CP-1252), simulating a Windows user whose USERPROFILE
+     * contains accented characters. */
+    AWS_STATIC_STRING_FROM_LITERAL(s_var_name, "AWS_TEST_NONASCII_VAR");
+    struct aws_string *ansi_value = aws_string_new_from_c_str(allocator, 
"C:\\Users\\hom\xE9");
+    aws_set_environment_value(s_var_name, ansi_value);
+    aws_string_destroy(ansi_value);
+
+    /* Read it back through aws_get_env */
+    struct aws_string *value = aws_get_env(allocator, "AWS_TEST_NONASCII_VAR");
+    ASSERT_NOT_NULL(value);
+
+    /* The value should be valid UTF-8. U+00E9 in UTF-8 is the two bytes 0xC3 
0xA9. */
+    const char *expected_utf8 = "C:\\Users\\hom\xC3\xA9";
+    ASSERT_TRUE(strcmp(aws_string_c_str(value), expected_utf8) == 0);
+    aws_string_destroy(value);
+
+    /* Clean up */
+    aws_unset_environment_value(s_var_name);
+#else
+    (void)allocator;
+#endif
+    return AWS_OP_SUCCESS;
+}
+
+AWS_TEST_CASE(test_env_non_ascii_path, s_test_env_non_ascii_path_fn)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aws-c-common-0.14.2/tests/file_test.c 
new/aws-c-common-0.14.4/tests/file_test.c
--- old/aws-c-common-0.14.2/tests/file_test.c   2026-07-09 18:53:07.000000000 
+0200
+++ new/aws-c-common-0.14.4/tests/file_test.c   2026-07-21 19:03:28.000000000 
+0200
@@ -4,10 +4,12 @@
  */
 
 #include <aws/common/allocator.h>
+#include <aws/common/clock.h>
 #include <aws/common/device_random.h>
 #include <aws/common/file.h>
 #include <aws/common/string.h>
 #include <aws/common/system_info.h>
+#include <aws/common/thread.h>
 
 #include <aws/testing/aws_test_harness.h>
 
@@ -1038,3 +1040,61 @@
 }
 
 AWS_TEST_CASE(test_file_path_write_to_offset_direct_io, 
s_test_file_path_write_to_offset_direct_io)
+
+static int s_test_file_get_last_modified_epoch_fn(struct aws_allocator 
*allocator, void *ctx) {
+    (void)ctx;
+
+    const char *file_path_cstr = "last_modified_test.txt";
+    struct aws_string *file_path = aws_string_new_from_c_str(allocator, 
file_path_cstr);
+
+    /* Create a file and write something */
+    FILE *file = aws_fopen(file_path_cstr, "w");
+    ASSERT_NOT_NULL(file);
+    fprintf(file, "hello");
+    fclose(file); /* must close the write handle: on Windows the last write 
time is only
+                     guaranteed correct once all writing handles are closed 
(see doc comment
+                     on aws_file_get_last_modified_epoch) */
+
+    /* Get last modified time on a fresh handle */
+    file = aws_fopen(file_path_cstr, "r");
+    ASSERT_NOT_NULL(file);
+
+    uint64_t first_modified_ns = 0;
+    ASSERT_SUCCESS(aws_file_get_last_modified_epoch(file, &first_modified_ns));
+    fclose(file);
+
+    /* Verify it's less than current time */
+    uint64_t now_ns = 0;
+    ASSERT_SUCCESS(aws_sys_clock_get_ticks(&now_ns));
+    ASSERT_TRUE(first_modified_ns <= now_ns);
+    ASSERT_TRUE(first_modified_ns > 0);
+
+    /* Sleep to ensure filesystem timestamp advances */
+    aws_thread_current_sleep((uint64_t)1000000000); /* 1 second */
+
+    /* Modify the file */
+    file = aws_fopen(file_path_cstr, "w");
+    ASSERT_NOT_NULL(file);
+    fprintf(file, "world");
+    fclose(file); /* close write handle before re-querying, same reason as 
above */
+
+    /* Get last modified time again on a fresh handle */
+    file = aws_fopen(file_path_cstr, "r");
+    ASSERT_NOT_NULL(file);
+
+    uint64_t second_modified_ns = 0;
+    ASSERT_SUCCESS(aws_file_get_last_modified_epoch(file, 
&second_modified_ns));
+    fclose(file);
+
+    /* Second modification time must be strictly later than first */
+    ASSERT_TRUE(second_modified_ns > first_modified_ns);
+    ASSERT_TRUE(second_modified_ns > now_ns);
+
+    /* Cleanup */
+    remove(file_path_cstr);
+    aws_string_destroy(file_path);
+
+    return AWS_OP_SUCCESS;
+}
+
+AWS_TEST_CASE(test_file_get_last_modified_epoch, 
s_test_file_get_last_modified_epoch_fn)

Reply via email to