From 2a96a7b7e02f2ffb8d679af8b9b8bba3efea10bd Mon Sep 17 00:00:00 2001 From: sobolevn Date: Sun, 5 Sep 2021 20:35:23 +0300 Subject: [PATCH 1/6] bpo-45034: Fixes how upper limit is formatted for `struct.pack("H", ...)` --- Lib/test/test_struct.py | 9 +++++++++ .../Library/2021-09-05-20-33-25.bpo-45034.62NLD5.rst | 2 ++ Modules/_struct.c | 6 +++--- 3 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2021-09-05-20-33-25.bpo-45034.62NLD5.rst diff --git a/Lib/test/test_struct.py b/Lib/test/test_struct.py index b3f21ea7db49ef..3280c7ababca72 100644 --- a/Lib/test/test_struct.py +++ b/Lib/test/test_struct.py @@ -678,6 +678,15 @@ def test_issue35714(self): 'embedded null character'): struct.calcsize(s) + @support.cpython_only + def test_issue45034(self): + from _testcapi import USHRT_MAX + error_msg = f'ushort format requires 0 <= number <= {USHRT_MAX}' + with self.assertRaisesRegex(struct.error, error_msg): + struct.pack('H', 70000) # too large + with self.assertRaisesRegex(struct.error, error_msg): + struct.pack('H', -1) # too small + class UnpackIteratorTest(unittest.TestCase): """ diff --git a/Misc/NEWS.d/next/Library/2021-09-05-20-33-25.bpo-45034.62NLD5.rst b/Misc/NEWS.d/next/Library/2021-09-05-20-33-25.bpo-45034.62NLD5.rst new file mode 100644 index 00000000000000..afc5bb9d0f97b9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-09-05-20-33-25.bpo-45034.62NLD5.rst @@ -0,0 +1,2 @@ +Changes how max value is formatted for ``struct.pack`` with ``'H'`` mode and +too large / small numbers. diff --git a/Modules/_struct.c b/Modules/_struct.c index 30ad9f2b79d8f3..24b8c60a15c188 100644 --- a/Modules/_struct.c +++ b/Modules/_struct.c @@ -607,9 +607,9 @@ np_ushort(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) if (get_long(state, v, &x) < 0) return -1; if (x < 0 || x > USHRT_MAX) { - PyErr_SetString(state->StructError, - "ushort format requires 0 <= number <= " - Py_STRINGIFY(USHRT_MAX)); + PyErr_Format(state->StructError, + "ushort format requires 0 <= number <= %zu", + USHRT_MAX); return -1; } y = (unsigned short)x; From fba681ced5fb5397318f9d42aac9ca7dd859ce01 Mon Sep 17 00:00:00 2001 From: Nikita Sobolev Date: Mon, 6 Sep 2021 11:21:43 +0300 Subject: [PATCH 2/6] Update Modules/_struct.c Co-authored-by: Mark Dickinson --- Modules/_struct.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/_struct.c b/Modules/_struct.c index 24b8c60a15c188..5dc8413562c153 100644 --- a/Modules/_struct.c +++ b/Modules/_struct.c @@ -608,7 +608,7 @@ np_ushort(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) return -1; if (x < 0 || x > USHRT_MAX) { PyErr_Format(state->StructError, - "ushort format requires 0 <= number <= %zu", + "ushort format requires 0 <= number <= %u", USHRT_MAX); return -1; } From 9f285bb4f235b60974548109f9b83919697ea8c4 Mon Sep 17 00:00:00 2001 From: Nikita Sobolev Date: Mon, 6 Sep 2021 11:22:00 +0300 Subject: [PATCH 3/6] Update Modules/_struct.c Co-authored-by: Mark Dickinson --- Modules/_struct.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/_struct.c b/Modules/_struct.c index 5dc8413562c153..9088b7761ce56b 100644 --- a/Modules/_struct.c +++ b/Modules/_struct.c @@ -609,7 +609,7 @@ np_ushort(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) if (x < 0 || x > USHRT_MAX) { PyErr_Format(state->StructError, "ushort format requires 0 <= number <= %u", - USHRT_MAX); + (unsigned int)(USHRT_MAX)); return -1; } y = (unsigned short)x; From 3df665231dc0474908276129fa9a7824b0398433 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Mon, 6 Sep 2021 16:24:12 +0300 Subject: [PATCH 4/6] Fixes `np_short` error message --- Lib/test/test_struct.py | 11 ++++++++++- .../Library/2021-09-05-20-33-25.bpo-45034.62NLD5.rst | 4 ++-- Modules/_struct.c | 9 +++++---- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/Lib/test/test_struct.py b/Lib/test/test_struct.py index 3280c7ababca72..49decacb132f87 100644 --- a/Lib/test/test_struct.py +++ b/Lib/test/test_struct.py @@ -679,7 +679,7 @@ def test_issue35714(self): struct.calcsize(s) @support.cpython_only - def test_issue45034(self): + def test_issue45034_unsigned(self): from _testcapi import USHRT_MAX error_msg = f'ushort format requires 0 <= number <= {USHRT_MAX}' with self.assertRaisesRegex(struct.error, error_msg): @@ -687,6 +687,15 @@ def test_issue45034(self): with self.assertRaisesRegex(struct.error, error_msg): struct.pack('H', -1) # too small + @support.cpython_only + def test_issue45034_signed(self): + from _testcapi import SHRT_MIN, SHRT_MAX + error_msg = f'short format requires {SHRT_MIN} <= number <= {SHRT_MAX}' + with self.assertRaisesRegex(struct.error, error_msg): + struct.pack('h', 70000) # too large + with self.assertRaisesRegex(struct.error, error_msg): + struct.pack('h', -70000) # too small + class UnpackIteratorTest(unittest.TestCase): """ diff --git a/Misc/NEWS.d/next/Library/2021-09-05-20-33-25.bpo-45034.62NLD5.rst b/Misc/NEWS.d/next/Library/2021-09-05-20-33-25.bpo-45034.62NLD5.rst index afc5bb9d0f97b9..8d94821470a2ad 100644 --- a/Misc/NEWS.d/next/Library/2021-09-05-20-33-25.bpo-45034.62NLD5.rst +++ b/Misc/NEWS.d/next/Library/2021-09-05-20-33-25.bpo-45034.62NLD5.rst @@ -1,2 +1,2 @@ -Changes how max value is formatted for ``struct.pack`` with ``'H'`` mode and -too large / small numbers. +Changes how error is formatted for ``struct.pack`` with ``'H'`` and ``'h'`` modes and +too large / small numbers. Now it shows the actual numeric limits, while previously it was showing arithmetic expressions. diff --git a/Modules/_struct.c b/Modules/_struct.c index 9088b7761ce56b..e5696e02d64ffd 100644 --- a/Modules/_struct.c +++ b/Modules/_struct.c @@ -589,9 +589,10 @@ np_short(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) if (get_long(state, v, &x) < 0) return -1; if (x < SHRT_MIN || x > SHRT_MAX) { - PyErr_SetString(state->StructError, - "short format requires " Py_STRINGIFY(SHRT_MIN) - " <= number <= " Py_STRINGIFY(SHRT_MAX)); + PyErr_Format(state->StructError, + "short format requires %d <= number <= %d", + SHRT_MIN, + SHRT_MAX); return -1; } y = (short)x; @@ -609,7 +610,7 @@ np_ushort(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) if (x < 0 || x > USHRT_MAX) { PyErr_Format(state->StructError, "ushort format requires 0 <= number <= %u", - (unsigned int)(USHRT_MAX)); + (unsigned int)USHRT_MAX); return -1; } y = (unsigned short)x; From 3f8cf5048f4af44afe6901ecbcf90d257380d422 Mon Sep 17 00:00:00 2001 From: Nikita Sobolev Date: Tue, 7 Sep 2021 11:46:04 +0300 Subject: [PATCH 5/6] Adds "Nikita Sobolev" to `Misc/ACKS` --- Misc/ACKS | 1 + 1 file changed, 1 insertion(+) diff --git a/Misc/ACKS b/Misc/ACKS index df0b92c72df862..481e46d4c17320 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1663,6 +1663,7 @@ Ryan Smith-Roberts Rafal Smotrzyk Josh Snider Eric Snow +Nikita Sobolev Dirk Soede Nir Soffer Paul Sokolovsky From c57e30c167f82f52f20807c778623f64878e175c Mon Sep 17 00:00:00 2001 From: Nikita Sobolev Date: Tue, 7 Sep 2021 14:13:02 +0300 Subject: [PATCH 6/6] Update Modules/_struct.c Co-authored-by: Serhiy Storchaka --- Modules/_struct.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Modules/_struct.c b/Modules/_struct.c index e5696e02d64ffd..872c30d659d824 100644 --- a/Modules/_struct.c +++ b/Modules/_struct.c @@ -591,8 +591,7 @@ np_short(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) if (x < SHRT_MIN || x > SHRT_MAX) { PyErr_Format(state->StructError, "short format requires %d <= number <= %d", - SHRT_MIN, - SHRT_MAX); + (int)SHRT_MIN, (int)SHRT_MAX); return -1; } y = (short)x;