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
