This underflow triggered a SIZE_MAX memset.
Note a huge length beyond the theoretical max size of PTRDIFF_MAX
wraps in my glibc-2.43-9.fc44.x86_64 memset implementations and
only write a couple of hundred bytes or so and may not crash.
But we can still see the issue in valgrind with:

  $ valgrind ls -l --time-style='+%_1z' /dev/null

The above overwrites the stack, while the following
overwrites the heap and was seen to crash:

  $ pr -D'%_1z' /dev/null

This issue was introduced in commit 2bf00710 (Oct 2025).

* lib/strftime.c (do_number_sign_and_padding): Use a signed type
so that the <= 0 comparison is valid).
* tests/test-nstrftime.h: Add test cases.
Reported at https://bugs.gnu.org/82130
---
 lib/strftime.c         | 2 +-
 tests/test-nstrftime.h | 5 +++++
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/lib/strftime.c b/lib/strftime.c
index 6b24ce40ad..25a300dd70 100644
--- a/lib/strftime.c
+++ b/lib/strftime.c
@@ -1928,7 +1928,7 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG 
(size_t maxsize)
             if (digits_base >= 0x100)
               number_digits = number_bytes / 2;
 #endif
-            byte_count_t shortage = width - !!sign_char - number_digits;
+            sbyte_count_t shortage = width - !!sign_char - number_digits;
             byte_count_t padding = (pad == NO_PAD || shortage <= 0
                                     ? 0 : shortage);
 
diff --git a/tests/test-nstrftime.h b/tests/test-nstrftime.h
index 64a007b521..0b7cdb0da0 100644
--- a/tests/test-nstrftime.h
+++ b/tests/test-nstrftime.h
@@ -55,6 +55,11 @@ static struct posixtm_test const T[] =
     { 0,          10,           "%T.%N", "00:00:00.000000010" },
     { 56,         123456789,    "%T.%12N", "00:00:56.123456789000" },
     { 0,          123000000,    "%T.%_6N", "00:00:00.123   " },
+    { 0,          0,            "%+_1z", "+0" },
+    { 0,          0,            "%_1:z", "+0:00" },
+    { 0,          0,            "%_1::z", "+0:00:00" },
+    { 0,          0,            "%_1:::z", "+0" },
+    { 0,          0,            "%_10z", "        +0" },
     { 0,          0,            NULL, NULL }
   };
 
-- 
2.56.0


Reply via email to