Skip to content

Commit 31f63de

Browse files
committed
Avoid undefined behaviour negating PY_SSIZE_T_MIN width in str/bytes formatting
1 parent 1b9fe5c commit 31f63de

3 files changed

Lines changed: 11 additions & 0 deletions

File tree

Lib/test/test_format.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,8 @@ def test_common_format(self):
318318
"format argument 1: too big for width")
319319
test_exc_common('%*r', (-2**1000, 1), OverflowError,
320320
"format argument 1: too big for width")
321+
test_exc_common('%*r', (-maxsize - 1, 1), OverflowError,
322+
"format argument 1: too big for width")
321323
test_exc_common('%.*r', (2**1000, 1), OverflowError,
322324
"format argument 1: too big for precision")
323325
test_exc_common('%.*r', (-2**1000, 1), OverflowError,

Objects/bytesobject.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -803,6 +803,11 @@ _PyBytes_FormatEx(const char *format, Py_ssize_t format_len,
803803
}
804804
if (width < 0) {
805805
flags |= F_LJUST;
806+
if (width < -PY_SSIZE_T_MAX) {
807+
FORMAT_ERROR(PyExc_OverflowError,
808+
"too big for width%s", "");
809+
goto error;
810+
}
806811
width = -width;
807812
}
808813
if (--fmtcnt >= 0)

Objects/unicode_format.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,10 @@ unicode_format_arg_parse(struct unicode_formatter_t *ctx,
560560
}
561561
if (arg->width < 0) {
562562
arg->flags |= F_LJUST;
563+
if (arg->width < -PY_SSIZE_T_MAX) {
564+
FORMAT_ERROR(PyExc_OverflowError, "too big for width%s", "");
565+
return -1;
566+
}
563567
arg->width = -arg->width;
564568
}
565569
if (--ctx->fmtcnt >= 0) {

0 commit comments

Comments
 (0)