diff --git a/mypyc/lib-rt/int_ops.c b/mypyc/lib-rt/int_ops.c index f5dfa98a595b..b03095d04ba0 100644 --- a/mypyc/lib-rt/int_ops.c +++ b/mypyc/lib-rt/int_ops.c @@ -641,6 +641,7 @@ PyObject *CPyTagged_ToBytes(CPyTagged self, Py_ssize_t length, PyObject *byteord } else if (strcmp(order, "little") == 0) { little_endian = 1; } else { + Py_DECREF(pyint); PyErr_SetString(PyExc_ValueError, "byteorder must be either 'little' or 'big'"); return NULL; } diff --git a/mypyc/test-data/run-integers.test b/mypyc/test-data/run-integers.test index cbcb0d43fc9d..3e4f29345250 100644 --- a/mypyc/test-data/run-integers.test +++ b/mypyc/test-data/run-integers.test @@ -574,6 +574,7 @@ class int: pass [case testIntToBytes] +import sys from testutil import assertRaises def to_bytes(n: int, length: int, byteorder: str, signed: bool = False) -> bytes: return n.to_bytes(length, byteorder, signed=signed) @@ -594,6 +595,19 @@ def test_to_bytes() -> None: with assertRaises(OverflowError): to_bytes(128, 1, "big", True) +def test_invalid_byteorder_refcount() -> None: + n = int("123456789012345678901234567890") + before = sys.getrefcount(n) + for _ in range(10): + with assertRaises(ValueError): + to_bytes(n, 16, "invalid") + assert sys.getrefcount(n) == before + # Keep n alive across both refcount checks. + assert n == int("123456789012345678901234567890") + +[file sys/__init__.pyi] +def getrefcount(n: object) -> int: ... + [case testBitLength] def bit_length(n: int) -> int: return n.bit_length()