From: Sergey B Kirpichev Date: Thu, 11 Sep 2025 10:30:53 +0000 (+0300) Subject: gh-71810: Fix corner case (length==0) for int.to_bytes() (#138739) X-Git-Tag: v3.15.0a1~413 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=011179a79a0d7b93ce074b25b0819e96b6dd3315;p=thirdparty%2FPython%2Fcpython.git gh-71810: Fix corner case (length==0) for int.to_bytes() (#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 ``` Co-authored-by: Serhiy Storchaka --- diff --git a/Lib/test/test_long.py b/Lib/test/test_long.py index d63bc19ed9c9..b48a8812a1a2 100644 --- a/Lib/test/test_long.py +++ b/Lib/test/test_long.py @@ -1374,17 +1374,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 287458ba2da6..63b48572ff20 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -1209,7 +1209,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