From 31f63dec7291c7963d1e7f51607612c5d431e84f Mon Sep 17 00:00:00 2001 From: AN Long Date: Sun, 21 Jun 2026 17:29:01 +0900 Subject: [PATCH 1/3] Avoid undefined behaviour negating PY_SSIZE_T_MIN width in str/bytes formatting --- Lib/test/test_format.py | 2 ++ Objects/bytesobject.c | 5 +++++ Objects/unicode_format.c | 4 ++++ 3 files changed, 11 insertions(+) diff --git a/Lib/test/test_format.py b/Lib/test/test_format.py index 5d322cb444cfb6..2642000558abab 100644 --- a/Lib/test/test_format.py +++ b/Lib/test/test_format.py @@ -318,6 +318,8 @@ def test_common_format(self): "format argument 1: too big for width") test_exc_common('%*r', (-2**1000, 1), OverflowError, "format argument 1: too big for width") + test_exc_common('%*r', (-maxsize - 1, 1), OverflowError, + "format argument 1: too big for width") test_exc_common('%.*r', (2**1000, 1), OverflowError, "format argument 1: too big for precision") test_exc_common('%.*r', (-2**1000, 1), OverflowError, diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index f63185e14284b1..041d1e612a7d36 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -803,6 +803,11 @@ _PyBytes_FormatEx(const char *format, Py_ssize_t format_len, } if (width < 0) { flags |= F_LJUST; + if (width < -PY_SSIZE_T_MAX) { + FORMAT_ERROR(PyExc_OverflowError, + "too big for width%s", ""); + goto error; + } width = -width; } if (--fmtcnt >= 0) diff --git a/Objects/unicode_format.c b/Objects/unicode_format.c index e2790c8c1d4343..9d70c091daeb67 100644 --- a/Objects/unicode_format.c +++ b/Objects/unicode_format.c @@ -560,6 +560,10 @@ unicode_format_arg_parse(struct unicode_formatter_t *ctx, } if (arg->width < 0) { arg->flags |= F_LJUST; + if (arg->width < -PY_SSIZE_T_MAX) { + FORMAT_ERROR(PyExc_OverflowError, "too big for width%s", ""); + return -1; + } arg->width = -arg->width; } if (--ctx->fmtcnt >= 0) { From cb4df3f2552412e7c52d35d4b5fef8386e87c401 Mon Sep 17 00:00:00 2001 From: AN Long Date: Sun, 21 Jun 2026 23:23:28 +0900 Subject: [PATCH 2/3] Blurb it --- .../2026-06-21-23-23-24.gh-issue-151847.5uNKTL.rst | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-06-21-23-23-24.gh-issue-151847.5uNKTL.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-06-21-23-23-24.gh-issue-151847.5uNKTL.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-06-21-23-23-24.gh-issue-151847.5uNKTL.rst new file mode 100644 index 00000000000000..5f30cbb81c9a17 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-06-21-23-23-24.gh-issue-151847.5uNKTL.rst @@ -0,0 +1,3 @@ +When formatting a ``str`` or ``bytes`` with ``%``, passing ``-sys.maxsize - +1`` as the width previously negated it, this is undefined behaviour in C. it +now raises :exc:`OverflowError`. From 2c03ea9709f511dfc9433257e0a6a361ff72d4a6 Mon Sep 17 00:00:00 2001 From: AN Long Date: Sun, 21 Jun 2026 23:24:27 +0900 Subject: [PATCH 3/3] Fix news entry grammar --- .../2026-06-21-23-23-24.gh-issue-151847.5uNKTL.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-06-21-23-23-24.gh-issue-151847.5uNKTL.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-06-21-23-23-24.gh-issue-151847.5uNKTL.rst index 5f30cbb81c9a17..a815071108a46e 100644 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-06-21-23-23-24.gh-issue-151847.5uNKTL.rst +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-06-21-23-23-24.gh-issue-151847.5uNKTL.rst @@ -1,3 +1,3 @@ When formatting a ``str`` or ``bytes`` with ``%``, passing ``-sys.maxsize - -1`` as the width previously negated it, this is undefined behaviour in C. it +1`` as the width previously negated it, this is undefined behaviour in C. It now raises :exc:`OverflowError`.