That can be triggered with:
ls -l --time-style='+%_10000z' /dev/null
* lib/strftime.c (do_number_sign_and_padding): Check buffer limits
before writing padding, which was inadvertently removed in
commit 1c740444 (Dec 2019).
* tests/test-nstrftime.h: Add a test case.
---
lib/strftime.c | 6 +++---
tests/test-nstrftime.h | 9 +++++++++
2 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/lib/strftime.c b/lib/strftime.c
index 25a300dd70..5915acad38 100644
--- a/lib/strftime.c
+++ b/lib/strftime.c
@@ -1936,13 +1936,13 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG
(size_t maxsize)
{
if (pad == SPACE_PAD)
{
- if (p)
- memset_space (p, padding);
- if (ckd_add (&i, i, padding) && FPRINTFTIME)
+ if (incr_overflow (padding))
{
errno = ERANGE;
return FAILURE;
}
+ if (p)
+ memset_space (p, padding);
width -= padding;
}
width_add1 (0, sign_char);
diff --git a/tests/test-nstrftime.h b/tests/test-nstrftime.h
index 0b7cdb0da0..73096af17a 100644
--- a/tests/test-nstrftime.h
+++ b/tests/test-nstrftime.h
@@ -92,6 +92,15 @@ posixtm_test (void)
T[i].fmt, buf, T[i].exp);
fflush (stdout);
}
+
+ /* A one-byte buffer must fail without writing beyond its limit.
+ In particular, it is too small for the padding in %_10z. */
+ memset (buf, '~', sizeof buf - 1);
+ buf[sizeof buf - 1] = '\0';
+ errno = 0;
+ ASSERT (FUNC (buf, 1, T[i].fmt, tm, NULL, T[i].in_ns) == -1);
+ ASSERT (errno == ERANGE);
+ ASSERT (strspn (buf + 1, "~") == sizeof buf - 2);
}
return fail;
--
2.56.0