Repository navigation
PyLong_AsInt32() and friends modify *value when they raise OverflowError #156101
Description
Bug report
PyLong_AsInt32(), PyLong_AsUInt32(), PyLong_AsInt64() and PyLong_AsUInt64() are documented as
Set *value and return
0on success.
Set an exception and return-1on error.
but on overflow they write the truncated value into *value before returning -1.
They are implemented on top of PyLong_AsNativeBytes(), which copies the lowest bytes and reports the required size, and the LONG_TO_INT/LONG_TO_UINT macros in Objects/longobject.c only raise OverflowError afterwards:
Py_ssize_t bytes = PyLong_AsNativeBytes(obj, value, sizeof(*value), flags);
if (bytes < 0) {
return -1;
}
if ((size_t)bytes > sizeof(*value)) {
PyErr_SetString(PyExc_OverflowError,
"Python int too large to convert to " type_name);
return -1;
}This makes the straightforward usage unsafe.
For example, _sqlite3_Cursor_arraysize_set_impl() in Modules/_sqlite/cursor.c passes the target field directly:
import sqlite3
cu = sqlite3.connect(":memory:").cursor()
try:
cu.arraysize = 2**32
except OverflowError:
pass
print(cu.arraysize) # 0, was 1Either the functions should leave *value unchanged on error, or the documentation should say that its value is unspecified after a failure.
Linked PRs
- gh-156101: Fix sqlite3 Cursor.arraysize on a failed assignment #156105
- [3.15] gh-156101: Fix sqlite3 Cursor.arraysize on a failed assignment (GH-156105) #156156
- [3.14] gh-156101: Fix sqlite3 Cursor.arraysize on a failed assignment (GH-156105) #156157
- gh-156101: Don't set the result in error in PyLong_AsInt32() #156727
- [3.15] gh-156101: Don't set the result in error in PyLong_AsInt32() (GH-156727) #156728
- [3.14] gh-156101: Don't set the result in error in PyLong_AsInt32() (GH-156727) #156729
Metadata
Metadata
Assignees
Labels
Projects
- StatusShow more project fieldsDone
Activity
serhiy-storchaka commentedon Aug 20, 2026
cc @vstinner
gh-156101: Fix sqlite3 Cursor.arraysize on a failed assignment (GH-15…
[3.14] gh-156101: Fix sqlite3 Cursor.arraysize on a failed assignment (…
vstinner commentedon Aug 31, 2026
IMO they should leave
*valueunchanged on error. They can use a temporary variable: I wrote PR gh-156727 to do that.gh-156101: Don't set the result in error in PyLong_AsInt32() (#156727)
[3.14] gh-156101: Don't set the result in error in PyLong_AsInt32() (G…
pythongh-156101: Don't set the result in error in PyLong_AsInt32() (p…
[3.15] gh-156101: Don't set the result in error in PyLong_AsInt32() (G…
[3.15] gh-156101: Fix sqlite3 Cursor.arraysize on a failed assignment (…