From: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> Date: Thu, 11 Sep 2025 10:53:27 +0000 (+0200) Subject: [3.13] gh-71810: Fix corner case (length==0) for int.to_bytes() (GH-138739) (#138783) X-Git-Tag: v3.13.8~84 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7195d7f3d4c79f3711ede2e504c19bedc39aa3ad;p=thirdparty%2FPython%2Fcpython.git [3.13] gh-71810: Fix corner case (length==0) for int.to_bytes() (GH-138739) (#138783) gh-71810: Fix corner case (length==0) for int.to_bytes() (GH-138739) ```pycon >>> (0).to_bytes(0, 'big', signed=True) b'' >>> (-1).to_bytes(0, 'big', signed=True) # was b'' Traceback (most recent call last): File "", line 1, in (-1).to_bytes(0, 'big', signed=True) ~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^ OverflowError: int too big to convert ``` (cherry picked from commit 011179a79a0d7b93ce074b25b0819e96b6dd3315) Co-authored-by: Sergey B Kirpichev Co-authored-by: Serhiy Storchaka --- diff --git a/Lib/test/test_long.py b/Lib/test/test_long.py index b247f3322c2b..ad1968f70941 100644 --- a/Lib/test/test_long.py +++ b/Lib/test/test_long.py @@ -1322,17 +1322,22 @@ class LongTest(unittest.TestCase): check(tests4, 'little', signed=False) self.assertRaises(OverflowError, (256).to_bytes, 1, 'big', signed=False) - self.assertRaises(OverflowError, (256).to_bytes, 1, 'big', signed=True) self.assertRaises(OverflowError, (256).to_bytes, 1, 'little', signed=False) - self.assertRaises(OverflowError, (256).to_bytes, 1, 'little', signed=True) + self.assertRaises(OverflowError, (128).to_bytes, 1, 'big', signed=True) + self.assertRaises(OverflowError, (128).to_bytes, 1, 'little', signed=True) + self.assertRaises(OverflowError, (-129).to_bytes, 1, 'big', signed=True) + self.assertRaises(OverflowError, (-129).to_bytes, 1, 'little', signed=True) self.assertRaises(OverflowError, (-1).to_bytes, 2, 'big', signed=False) self.assertRaises(OverflowError, (-1).to_bytes, 2, 'little', signed=False) self.assertEqual((0).to_bytes(0, 'big'), b'') + self.assertEqual((0).to_bytes(0, 'big', signed=True), b'') self.assertEqual((1).to_bytes(5, 'big'), b'\x00\x00\x00\x00\x01') self.assertEqual((0).to_bytes(5, 'big'), b'\x00\x00\x00\x00\x00') self.assertEqual((-1).to_bytes(5, 'big', signed=True), b'\xff\xff\xff\xff\xff') self.assertRaises(OverflowError, (1).to_bytes, 0, 'big') + self.assertRaises(OverflowError, (-1).to_bytes, 0, 'big', signed=True) + self.assertRaises(OverflowError, (-1).to_bytes, 0, 'little', signed=True) # gh-98783 class SubStr(str): diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-09-10-14-53-59.gh-issue-71810.ppf0J-.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-09-10-14-53-59.gh-issue-71810.ppf0J-.rst new file mode 100644 index 000000000000..a87db44225e8 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-09-10-14-53-59.gh-issue-71810.ppf0J-.rst @@ -0,0 +1,2 @@ +Raise :exc:`OverflowError` for ``(-1).to_bytes()`` for signed conversions +when bytes count is zero. Patch by Sergey B Kirpichev. diff --git a/Objects/longobject.c b/Objects/longobject.c index be5cbf0872b4..98bf50d01cc0 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -1041,7 +1041,7 @@ _PyLong_AsByteArray(PyLongObject* v, *p = (unsigned char)(accum & 0xff); p += pincr; } - else if (j == n && n > 0 && is_signed) { + else if (j == n && is_signed) { /* The main loop filled the byte array exactly, so the code just above didn't get to ensure there's a sign bit, and the loop below wouldn't add one either. Make sure a sign bit