gh-132629: Deprecate accepting out-of-range values for unsigned integers in PyArg_Parse (GH-132630)

For unsigned integer formats in the PyArg_Parse* functions,
accepting Python integers with value that is larger than
the maximal value the corresponding C type or less than
the minimal value for the corresponding signed integer type
is now deprecated.
This commit is contained in:
Serhiy Storchaka 2025-07-13 12:44:54 +03:00 committed by GitHub
parent 3dbe02ccd3
commit e18829a8ad
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 674 additions and 211 deletions

View file

@ -241,9 +241,11 @@ the Python object to the required type.
For signed integer formats, :exc:`OverflowError` is raised if the value
is out of range for the C type.
For unsigned integer formats, no range checking is done --- the
For unsigned integer formats, the
most significant bits are silently truncated when the receiving field is too
small to receive the value.
small to receive the value, and :exc:`DeprecationWarning` is emitted when
the value is larger than the maximal value for the C type or less than
the minimal value for the corresponding signed integer type of the same size.
``b`` (:class:`int`) [unsigned char]
Convert a nonnegative Python integer to an unsigned tiny integer, stored in a C
@ -252,27 +254,25 @@ small to receive the value.
``B`` (:class:`int`) [unsigned char]
Convert a Python integer to a tiny integer without overflow checking, stored in a C
:c:expr:`unsigned char`.
Convert a Python integer to a C :c:expr:`unsigned char`.
``h`` (:class:`int`) [short int]
Convert a Python integer to a C :c:expr:`short int`.
``H`` (:class:`int`) [unsigned short int]
Convert a Python integer to a C :c:expr:`unsigned short int`, without overflow
checking.
Convert a Python integer to a C :c:expr:`unsigned short int`.
``i`` (:class:`int`) [int]
Convert a Python integer to a plain C :c:expr:`int`.
``I`` (:class:`int`) [unsigned int]
Convert a Python integer to a C :c:expr:`unsigned int`, without overflow
checking.
Convert a Python integer to a C :c:expr:`unsigned int`.
``l`` (:class:`int`) [long int]
Convert a Python integer to a C :c:expr:`long int`.
``k`` (:class:`int`) [unsigned long]
Convert a Python integer to a C :c:expr:`unsigned long` without
overflow checking.
Convert a Python integer to a C :c:expr:`unsigned long`.
.. versionchanged:: 3.14
Use :meth:`~object.__index__` if available.
@ -281,8 +281,7 @@ small to receive the value.
Convert a Python integer to a C :c:expr:`long long`.
``K`` (:class:`int`) [unsigned long long]
Convert a Python integer to a C :c:expr:`unsigned long long`
without overflow checking.
Convert a Python integer to a C :c:expr:`unsigned long long`.
.. versionchanged:: 3.14
Use :meth:`~object.__index__` if available.
@ -310,6 +309,14 @@ small to receive the value.
``D`` (:class:`complex`) [Py_complex]
Convert a Python complex number to a C :c:type:`Py_complex` structure.
.. deprecated:: next
For unsigned integer formats ``B``, ``H``, ``I``, ``k`` and ``K``,
:exc:`DeprecationWarning` is emitted when the value is larger than
the maximal value for the C type or less than the minimal value for
the corresponding signed integer type of the same size.
Other objects
-------------

View file

@ -462,7 +462,11 @@ Porting to Python 3.15
Deprecated C APIs
-----------------
* TODO
* For unsigned integer formats in :c:func:`PyArg_ParseTuple`,
accepting Python integers with value that is larger than the maximal value
for the C type or less than the minimal value for the corresponding
signed integer type of the same size is now deprecated.
(Contributed by Serhiy Storchaka in :gh:`132629`.)
.. Add C API deprecations above alphabetically, not here at the end.

View file

@ -1020,12 +1020,19 @@ test_unsigned_char_converter(PyObject *module, PyObject *const *args, Py_ssize_t
goto skip_optional;
}
{
unsigned long ival = PyLong_AsUnsignedLongMask(args[2]);
if (ival == (unsigned long)-1 && PyErr_Occurred()) {
Py_ssize_t _bytes = PyLong_AsNativeBytes(args[2], &c, sizeof(unsigned char),
Py_ASNATIVEBYTES_NATIVE_ENDIAN |
Py_ASNATIVEBYTES_ALLOW_INDEX |
Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
if (_bytes < 0) {
goto exit;
}
else {
c = (unsigned char) ival;
if ((size_t)_bytes > sizeof(unsigned char)) {
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"integer value out of range", 1) < 0)
{
goto exit;
}
}
}
skip_optional:
@ -1038,7 +1045,7 @@ exit:
static PyObject *
test_unsigned_char_converter_impl(PyObject *module, unsigned char a,
unsigned char b, unsigned char c)
/*[clinic end generated code: output=45920dbedc22eb55 input=021414060993e289]*/
/*[clinic end generated code: output=49eda9faaf53372a input=021414060993e289]*/
/*[clinic input]
@ -1151,9 +1158,21 @@ test_unsigned_short_converter(PyObject *module, PyObject *const *args, Py_ssize_
if (nargs < 3) {
goto skip_optional;
}
c = (unsigned short)PyLong_AsUnsignedLongMask(args[2]);
if (c == (unsigned short)-1 && PyErr_Occurred()) {
goto exit;
{
Py_ssize_t _bytes = PyLong_AsNativeBytes(args[2], &c, sizeof(unsigned short),
Py_ASNATIVEBYTES_NATIVE_ENDIAN |
Py_ASNATIVEBYTES_ALLOW_INDEX |
Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
if (_bytes < 0) {
goto exit;
}
if ((size_t)_bytes > sizeof(unsigned short)) {
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"integer value out of range", 1) < 0)
{
goto exit;
}
}
}
skip_optional:
return_value = test_unsigned_short_converter_impl(module, a, b, c);
@ -1165,7 +1184,7 @@ exit:
static PyObject *
test_unsigned_short_converter_impl(PyObject *module, unsigned short a,
unsigned short b, unsigned short c)
/*[clinic end generated code: output=e6e990df729114fc input=cdfd8eff3d9176b4]*/
/*[clinic end generated code: output=f591c7797e150f49 input=cdfd8eff3d9176b4]*/
/*[clinic input]
@ -1298,9 +1317,21 @@ test_unsigned_int_converter(PyObject *module, PyObject *const *args, Py_ssize_t
if (nargs < 3) {
goto skip_optional;
}
c = (unsigned int)PyLong_AsUnsignedLongMask(args[2]);
if (c == (unsigned int)-1 && PyErr_Occurred()) {
goto exit;
{
Py_ssize_t _bytes = PyLong_AsNativeBytes(args[2], &c, sizeof(unsigned int),
Py_ASNATIVEBYTES_NATIVE_ENDIAN |
Py_ASNATIVEBYTES_ALLOW_INDEX |
Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
if (_bytes < 0) {
goto exit;
}
if ((size_t)_bytes > sizeof(unsigned int)) {
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"integer value out of range", 1) < 0)
{
goto exit;
}
}
}
skip_optional:
return_value = test_unsigned_int_converter_impl(module, a, b, c);
@ -1312,7 +1343,7 @@ exit:
static PyObject *
test_unsigned_int_converter_impl(PyObject *module, unsigned int a,
unsigned int b, unsigned int c)
/*[clinic end generated code: output=f9cdbe410ccc98a3 input=5533534828b62fc0]*/
/*[clinic end generated code: output=50a413f1cc82dc11 input=5533534828b62fc0]*/
/*[clinic input]
@ -1414,7 +1445,22 @@ test_unsigned_long_converter(PyObject *module, PyObject *const *args, Py_ssize_t
_PyArg_BadArgument("test_unsigned_long_converter", "argument 3", "int", args[2]);
goto exit;
}
c = PyLong_AsUnsignedLongMask(args[2]);
{
Py_ssize_t _bytes = PyLong_AsNativeBytes(args[2], &c, sizeof(unsigned long),
Py_ASNATIVEBYTES_NATIVE_ENDIAN |
Py_ASNATIVEBYTES_ALLOW_INDEX |
Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
if (_bytes < 0) {
goto exit;
}
if ((size_t)_bytes > sizeof(unsigned long)) {
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"integer value out of range", 1) < 0)
{
goto exit;
}
}
}
skip_optional:
return_value = test_unsigned_long_converter_impl(module, a, b, c);
@ -1425,7 +1471,7 @@ exit:
static PyObject *
test_unsigned_long_converter_impl(PyObject *module, unsigned long a,
unsigned long b, unsigned long c)
/*[clinic end generated code: output=d74eed227d77a31b input=f450d94cae1ef73b]*/
/*[clinic end generated code: output=1bbf5620093cc914 input=f450d94cae1ef73b]*/
/*[clinic input]
@ -1529,7 +1575,22 @@ test_unsigned_long_long_converter(PyObject *module, PyObject *const *args, Py_ss
_PyArg_BadArgument("test_unsigned_long_long_converter", "argument 3", "int", args[2]);
goto exit;
}
c = PyLong_AsUnsignedLongLongMask(args[2]);
{
Py_ssize_t _bytes = PyLong_AsNativeBytes(args[2], &c, sizeof(unsigned long long),
Py_ASNATIVEBYTES_NATIVE_ENDIAN |
Py_ASNATIVEBYTES_ALLOW_INDEX |
Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
if (_bytes < 0) {
goto exit;
}
if ((size_t)_bytes > sizeof(unsigned long long)) {
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"integer value out of range", 1) < 0)
{
goto exit;
}
}
}
skip_optional:
return_value = test_unsigned_long_long_converter_impl(module, a, b, c);
@ -1542,7 +1603,7 @@ test_unsigned_long_long_converter_impl(PyObject *module,
unsigned long long a,
unsigned long long b,
unsigned long long c)
/*[clinic end generated code: output=5ca4e4dfb3db644b input=a15115dc41866ff4]*/
/*[clinic end generated code: output=582a6623dc845824 input=a15115dc41866ff4]*/
/*[clinic input]

View file

@ -48,8 +48,8 @@ except ImportError:
LARGE = 0x7FFFFFFF
VERY_LARGE = 0xFF0000121212121212121242
from _testcapi import UCHAR_MAX, USHRT_MAX, UINT_MAX, ULONG_MAX, INT_MAX, \
INT_MIN, LONG_MIN, LONG_MAX, PY_SSIZE_T_MIN, PY_SSIZE_T_MAX, \
from _testcapi import UCHAR_MAX, USHRT_MAX, UINT_MAX, ULONG_MAX, ULLONG_MAX, INT_MAX, \
INT_MIN, LONG_MIN, LONG_MAX, LLONG_MIN, LLONG_MAX, PY_SSIZE_T_MIN, PY_SSIZE_T_MAX, \
SHRT_MIN, SHRT_MAX, FLT_MIN, FLT_MAX, DBL_MIN, DBL_MAX
DBL_MAX_EXP = sys.float_info.max_exp
@ -57,9 +57,8 @@ INF = float('inf')
NAN = float('nan')
# fake, they are not defined in Python's header files
LLONG_MAX = 2**63-1
LLONG_MIN = -2**63
ULLONG_MAX = 2**64-1
SCHAR_MAX = UCHAR_MAX // 2
SCHAR_MIN = SCHAR_MAX - UCHAR_MAX
NULL = None
@ -209,10 +208,23 @@ class Unsigned_TestCase(unittest.TestCase):
self.assertEqual(UCHAR_MAX, getargs_B(-1))
self.assertEqual(0, getargs_B(0))
self.assertEqual(UCHAR_MAX, getargs_B(UCHAR_MAX))
self.assertEqual(0, getargs_B(UCHAR_MAX+1))
with self.assertWarns(DeprecationWarning):
self.assertEqual(0, getargs_B(UCHAR_MAX+1))
with self.assertWarns(DeprecationWarning):
self.assertEqual(1, getargs_B(-UCHAR_MAX))
self.assertEqual(SCHAR_MAX+1, getargs_B(SCHAR_MIN))
with self.assertWarns(DeprecationWarning):
self.assertEqual(SCHAR_MAX, getargs_B(SCHAR_MIN-1))
self.assertEqual(128, getargs_B(-2**7))
with self.assertWarns(DeprecationWarning):
self.assertEqual(127, getargs_B(-2**7-1))
self.assertEqual(42, getargs_B(42))
self.assertEqual(UCHAR_MAX & VERY_LARGE, getargs_B(VERY_LARGE))
with self.assertWarns(DeprecationWarning):
self.assertEqual(UCHAR_MAX & VERY_LARGE, getargs_B(VERY_LARGE))
with self.assertWarns(DeprecationWarning):
self.assertEqual(UCHAR_MAX & -VERY_LARGE, getargs_B(-VERY_LARGE))
def test_H(self):
from _testcapi import getargs_H
@ -233,11 +245,18 @@ class Unsigned_TestCase(unittest.TestCase):
self.assertEqual(USHRT_MAX, getargs_H(-1))
self.assertEqual(0, getargs_H(0))
self.assertEqual(USHRT_MAX, getargs_H(USHRT_MAX))
self.assertEqual(0, getargs_H(USHRT_MAX+1))
with self.assertWarns(DeprecationWarning):
self.assertEqual(0, getargs_H(USHRT_MAX+1))
self.assertEqual(SHRT_MAX+1, getargs_H(SHRT_MIN))
with self.assertWarns(DeprecationWarning):
self.assertEqual(SHRT_MAX, getargs_H(SHRT_MIN-1))
self.assertEqual(42, getargs_H(42))
self.assertEqual(VERY_LARGE & USHRT_MAX, getargs_H(VERY_LARGE))
with self.assertWarns(DeprecationWarning):
self.assertEqual(USHRT_MAX & VERY_LARGE, getargs_H(VERY_LARGE))
with self.assertWarns(DeprecationWarning):
self.assertEqual(USHRT_MAX & -VERY_LARGE, getargs_H(-VERY_LARGE))
def test_I(self):
from _testcapi import getargs_I
@ -258,11 +277,18 @@ class Unsigned_TestCase(unittest.TestCase):
self.assertEqual(UINT_MAX, getargs_I(-1))
self.assertEqual(0, getargs_I(0))
self.assertEqual(UINT_MAX, getargs_I(UINT_MAX))
self.assertEqual(0, getargs_I(UINT_MAX+1))
with self.assertWarns(DeprecationWarning):
self.assertEqual(0, getargs_I(UINT_MAX+1))
self.assertEqual(INT_MAX+1, getargs_I(INT_MIN))
with self.assertWarns(DeprecationWarning):
self.assertEqual(INT_MAX, getargs_I(INT_MIN-1))
self.assertEqual(42, getargs_I(42))
self.assertEqual(VERY_LARGE & UINT_MAX, getargs_I(VERY_LARGE))
with self.assertWarns(DeprecationWarning):
self.assertEqual(UINT_MAX & VERY_LARGE, getargs_I(VERY_LARGE))
with self.assertWarns(DeprecationWarning):
self.assertEqual(UINT_MAX & -VERY_LARGE, getargs_I(-VERY_LARGE))
def test_k(self):
from _testcapi import getargs_k
@ -283,11 +309,18 @@ class Unsigned_TestCase(unittest.TestCase):
self.assertEqual(ULONG_MAX, getargs_k(-1))
self.assertEqual(0, getargs_k(0))
self.assertEqual(ULONG_MAX, getargs_k(ULONG_MAX))
self.assertEqual(0, getargs_k(ULONG_MAX+1))
with self.assertWarns(DeprecationWarning):
self.assertEqual(0, getargs_k(ULONG_MAX+1))
self.assertEqual(LONG_MAX+1, getargs_k(LONG_MIN))
with self.assertWarns(DeprecationWarning):
self.assertEqual(LONG_MAX, getargs_k(LONG_MIN-1))
self.assertEqual(42, getargs_k(42))
self.assertEqual(VERY_LARGE & ULONG_MAX, getargs_k(VERY_LARGE))
with self.assertWarns(DeprecationWarning):
self.assertEqual(ULONG_MAX & VERY_LARGE, getargs_k(VERY_LARGE))
with self.assertWarns(DeprecationWarning):
self.assertEqual(ULONG_MAX & -VERY_LARGE, getargs_k(-VERY_LARGE))
class Signed_TestCase(unittest.TestCase):
def test_h(self):
@ -434,11 +467,18 @@ class LongLong_TestCase(unittest.TestCase):
self.assertEqual(ULLONG_MAX, getargs_K(ULLONG_MAX))
self.assertEqual(0, getargs_K(0))
self.assertEqual(ULLONG_MAX, getargs_K(ULLONG_MAX))
self.assertEqual(0, getargs_K(ULLONG_MAX+1))
with self.assertWarns(DeprecationWarning):
self.assertEqual(0, getargs_K(ULLONG_MAX+1))
self.assertEqual(LLONG_MAX+1, getargs_K(LLONG_MIN))
with self.assertWarns(DeprecationWarning):
self.assertEqual(LLONG_MAX, getargs_K(LLONG_MIN-1))
self.assertEqual(42, getargs_K(42))
self.assertEqual(VERY_LARGE & ULLONG_MAX, getargs_K(VERY_LARGE))
with self.assertWarns(DeprecationWarning):
self.assertEqual(ULLONG_MAX & VERY_LARGE, getargs_K(VERY_LARGE))
with self.assertWarns(DeprecationWarning):
self.assertEqual(ULLONG_MAX & -VERY_LARGE, getargs_K(-VERY_LARGE))
class Float_TestCase(unittest.TestCase, FloatsAreIdenticalMixin):

View file

@ -3048,6 +3048,8 @@ class ClinicFunctionalTest(unittest.TestCase):
def test_unsigned_char_converter(self):
from _testcapi import UCHAR_MAX
SCHAR_MAX = UCHAR_MAX // 2
SCHAR_MIN = SCHAR_MAX - UCHAR_MAX
with self.assertRaises(OverflowError):
ac_tester.unsigned_char_converter(-1)
with self.assertRaises(OverflowError):
@ -3057,8 +3059,13 @@ class ClinicFunctionalTest(unittest.TestCase):
with self.assertRaises(TypeError):
ac_tester.unsigned_char_converter([])
self.assertEqual(ac_tester.unsigned_char_converter(), (12, 34, 56))
self.assertEqual(ac_tester.unsigned_char_converter(0, 0, UCHAR_MAX + 1), (0, 0, 0))
self.assertEqual(ac_tester.unsigned_char_converter(0, 0, (UCHAR_MAX + 1) * 3 + 123), (0, 0, 123))
with self.assertWarns(DeprecationWarning):
self.assertEqual(ac_tester.unsigned_char_converter(0, 0, UCHAR_MAX + 1), (0, 0, 0))
self.assertEqual(ac_tester.unsigned_char_converter(0, 0, SCHAR_MIN), (0, 0, SCHAR_MAX + 1))
with self.assertWarns(DeprecationWarning):
self.assertEqual(ac_tester.unsigned_char_converter(0, 0, SCHAR_MIN - 1), (0, 0, SCHAR_MAX))
with self.assertWarns(DeprecationWarning):
self.assertEqual(ac_tester.unsigned_char_converter(0, 0, (UCHAR_MAX + 1) * 3 + 123), (0, 0, 123))
def test_short_converter(self):
from _testcapi import SHRT_MIN, SHRT_MAX
@ -3072,7 +3079,7 @@ class ClinicFunctionalTest(unittest.TestCase):
self.assertEqual(ac_tester.short_converter(4321), (4321,))
def test_unsigned_short_converter(self):
from _testcapi import USHRT_MAX
from _testcapi import SHRT_MIN, SHRT_MAX, USHRT_MAX
with self.assertRaises(ValueError):
ac_tester.unsigned_short_converter(-1)
with self.assertRaises(OverflowError):
@ -3082,8 +3089,13 @@ class ClinicFunctionalTest(unittest.TestCase):
with self.assertRaises(TypeError):
ac_tester.unsigned_short_converter([])
self.assertEqual(ac_tester.unsigned_short_converter(), (12, 34, 56))
self.assertEqual(ac_tester.unsigned_short_converter(0, 0, USHRT_MAX + 1), (0, 0, 0))
self.assertEqual(ac_tester.unsigned_short_converter(0, 0, (USHRT_MAX + 1) * 3 + 123), (0, 0, 123))
with self.assertWarns(DeprecationWarning):
self.assertEqual(ac_tester.unsigned_short_converter(0, 0, USHRT_MAX + 1), (0, 0, 0))
self.assertEqual(ac_tester.unsigned_short_converter(0, 0, SHRT_MIN), (0, 0, SHRT_MAX + 1))
with self.assertWarns(DeprecationWarning):
self.assertEqual(ac_tester.unsigned_short_converter(0, 0, SHRT_MIN - 1), (0, 0, SHRT_MAX))
with self.assertWarns(DeprecationWarning):
self.assertEqual(ac_tester.unsigned_short_converter(0, 0, (USHRT_MAX + 1) * 3 + 123), (0, 0, 123))
def test_int_converter(self):
from _testcapi import INT_MIN, INT_MAX
@ -3099,7 +3111,7 @@ class ClinicFunctionalTest(unittest.TestCase):
self.assertEqual(ac_tester.int_converter(1, 2, '3'), (1, 2, ord('3')))
def test_unsigned_int_converter(self):
from _testcapi import UINT_MAX
from _testcapi import INT_MIN, INT_MAX, UINT_MAX
with self.assertRaises(ValueError):
ac_tester.unsigned_int_converter(-1)
with self.assertRaises(OverflowError):
@ -3109,8 +3121,13 @@ class ClinicFunctionalTest(unittest.TestCase):
with self.assertRaises(TypeError):
ac_tester.unsigned_int_converter([])
self.assertEqual(ac_tester.unsigned_int_converter(), (12, 34, 56))
self.assertEqual(ac_tester.unsigned_int_converter(0, 0, UINT_MAX + 1), (0, 0, 0))
self.assertEqual(ac_tester.unsigned_int_converter(0, 0, (UINT_MAX + 1) * 3 + 123), (0, 0, 123))
with self.assertWarns(DeprecationWarning):
self.assertEqual(ac_tester.unsigned_int_converter(0, 0, UINT_MAX + 1), (0, 0, 0))
self.assertEqual(ac_tester.unsigned_int_converter(0, 0, INT_MIN), (0, 0, INT_MAX + 1))
with self.assertWarns(DeprecationWarning):
self.assertEqual(ac_tester.unsigned_int_converter(0, 0, INT_MIN - 1), (0, 0, INT_MAX))
with self.assertWarns(DeprecationWarning):
self.assertEqual(ac_tester.unsigned_int_converter(0, 0, (UINT_MAX + 1) * 3 + 123), (0, 0, 123))
def test_long_converter(self):
from _testcapi import LONG_MIN, LONG_MAX
@ -3124,7 +3141,7 @@ class ClinicFunctionalTest(unittest.TestCase):
self.assertEqual(ac_tester.long_converter(-1234), (-1234,))
def test_unsigned_long_converter(self):
from _testcapi import ULONG_MAX
from _testcapi import LONG_MIN, LONG_MAX, ULONG_MAX
with self.assertRaises(ValueError):
ac_tester.unsigned_long_converter(-1)
with self.assertRaises(OverflowError):
@ -3134,8 +3151,13 @@ class ClinicFunctionalTest(unittest.TestCase):
with self.assertRaises(TypeError):
ac_tester.unsigned_long_converter([])
self.assertEqual(ac_tester.unsigned_long_converter(), (12, 34, 56))
self.assertEqual(ac_tester.unsigned_long_converter(0, 0, ULONG_MAX + 1), (0, 0, 0))
self.assertEqual(ac_tester.unsigned_long_converter(0, 0, (ULONG_MAX + 1) * 3 + 123), (0, 0, 123))
with self.assertWarns(DeprecationWarning):
self.assertEqual(ac_tester.unsigned_long_converter(0, 0, ULONG_MAX + 1), (0, 0, 0))
self.assertEqual(ac_tester.unsigned_long_converter(0, 0, LONG_MIN), (0, 0, LONG_MAX + 1))
with self.assertWarns(DeprecationWarning):
self.assertEqual(ac_tester.unsigned_long_converter(0, 0, LONG_MIN - 1), (0, 0, LONG_MAX))
with self.assertWarns(DeprecationWarning):
self.assertEqual(ac_tester.unsigned_long_converter(0, 0, (ULONG_MAX + 1) * 3 + 123), (0, 0, 123))
def test_long_long_converter(self):
from _testcapi import LLONG_MIN, LLONG_MAX
@ -3149,7 +3171,7 @@ class ClinicFunctionalTest(unittest.TestCase):
self.assertEqual(ac_tester.long_long_converter(-1234), (-1234,))
def test_unsigned_long_long_converter(self):
from _testcapi import ULLONG_MAX
from _testcapi import LLONG_MIN, LLONG_MAX, ULLONG_MAX
with self.assertRaises(ValueError):
ac_tester.unsigned_long_long_converter(-1)
with self.assertRaises(OverflowError):
@ -3159,8 +3181,13 @@ class ClinicFunctionalTest(unittest.TestCase):
with self.assertRaises(TypeError):
ac_tester.unsigned_long_long_converter([])
self.assertEqual(ac_tester.unsigned_long_long_converter(), (12, 34, 56))
self.assertEqual(ac_tester.unsigned_long_long_converter(0, 0, ULLONG_MAX + 1), (0, 0, 0))
self.assertEqual(ac_tester.unsigned_long_long_converter(0, 0, (ULLONG_MAX + 1) * 3 + 123), (0, 0, 123))
with self.assertWarns(DeprecationWarning):
self.assertEqual(ac_tester.unsigned_long_long_converter(0, 0, ULLONG_MAX + 1), (0, 0, 0))
self.assertEqual(ac_tester.unsigned_long_long_converter(0, 0, LLONG_MIN), (0, 0, LLONG_MAX + 1))
with self.assertWarns(DeprecationWarning):
self.assertEqual(ac_tester.unsigned_long_long_converter(0, 0, LLONG_MIN - 1), (0, 0, LLONG_MAX))
with self.assertWarns(DeprecationWarning):
self.assertEqual(ac_tester.unsigned_long_long_converter(0, 0, (ULLONG_MAX + 1) * 3 + 123), (0, 0, 123))
def test_py_ssize_t_converter(self):
from _testcapi import PY_SSIZE_T_MIN, PY_SSIZE_T_MAX

View file

@ -0,0 +1,4 @@
For unsigned integer formats in :c:func:`PyArg_ParseTuple`, accepting Python
integers with value that is larger than the maximal value for the C type or
less than the minimal value for the corresponding signed integer type
of the same size is now deprecated.

View file

@ -2372,7 +2372,22 @@ _curses_ungetmouse(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
_PyArg_BadArgument("ungetmouse", "argument 5", "int", args[4]);
goto exit;
}
bstate = PyLong_AsUnsignedLongMask(args[4]);
{
Py_ssize_t _bytes = PyLong_AsNativeBytes(args[4], &bstate, sizeof(unsigned long),
Py_ASNATIVEBYTES_NATIVE_ENDIAN |
Py_ASNATIVEBYTES_ALLOW_INDEX |
Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
if (_bytes < 0) {
goto exit;
}
if ((size_t)_bytes > sizeof(unsigned long)) {
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"integer value out of range", 1) < 0)
{
goto exit;
}
}
}
return_value = _curses_ungetmouse_impl(module, id, x, y, z, bstate);
exit:
@ -3138,7 +3153,22 @@ _curses_mousemask(PyObject *module, PyObject *arg)
_PyArg_BadArgument("mousemask", "argument", "int", arg);
goto exit;
}
newmask = PyLong_AsUnsignedLongMask(arg);
{
Py_ssize_t _bytes = PyLong_AsNativeBytes(arg, &newmask, sizeof(unsigned long),
Py_ASNATIVEBYTES_NATIVE_ENDIAN |
Py_ASNATIVEBYTES_ALLOW_INDEX |
Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
if (_bytes < 0) {
goto exit;
}
if ((size_t)_bytes > sizeof(unsigned long)) {
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"integer value out of range", 1) < 0)
{
goto exit;
}
}
}
return_value = _curses_mousemask_impl(module, newmask);
exit:
@ -4420,4 +4450,4 @@ _curses_has_extended_color_support(PyObject *module, PyObject *Py_UNUSED(ignored
#ifndef _CURSES_ASSUME_DEFAULT_COLORS_METHODDEF
#define _CURSES_ASSUME_DEFAULT_COLORS_METHODDEF
#endif /* !defined(_CURSES_ASSUME_DEFAULT_COLORS_METHODDEF) */
/*[clinic end generated code: output=a083473003179b30 input=a9049054013a1b77]*/
/*[clinic end generated code: output=79ddaae4da3b80df input=a9049054013a1b77]*/

View file

@ -746,12 +746,19 @@ unsigned_char_converter(PyObject *module, PyObject *const *args, Py_ssize_t narg
goto skip_optional;
}
{
unsigned long ival = PyLong_AsUnsignedLongMask(args[2]);
if (ival == (unsigned long)-1 && PyErr_Occurred()) {
Py_ssize_t _bytes = PyLong_AsNativeBytes(args[2], &c, sizeof(unsigned char),
Py_ASNATIVEBYTES_NATIVE_ENDIAN |
Py_ASNATIVEBYTES_ALLOW_INDEX |
Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
if (_bytes < 0) {
goto exit;
}
else {
c = (unsigned char) ival;
if ((size_t)_bytes > sizeof(unsigned char)) {
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"integer value out of range", 1) < 0)
{
goto exit;
}
}
}
skip_optional:
@ -848,9 +855,21 @@ unsigned_short_converter(PyObject *module, PyObject *const *args, Py_ssize_t nar
if (nargs < 3) {
goto skip_optional;
}
c = (unsigned short)PyLong_AsUnsignedLongMask(args[2]);
if (c == (unsigned short)-1 && PyErr_Occurred()) {
goto exit;
{
Py_ssize_t _bytes = PyLong_AsNativeBytes(args[2], &c, sizeof(unsigned short),
Py_ASNATIVEBYTES_NATIVE_ENDIAN |
Py_ASNATIVEBYTES_ALLOW_INDEX |
Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
if (_bytes < 0) {
goto exit;
}
if ((size_t)_bytes > sizeof(unsigned short)) {
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"integer value out of range", 1) < 0)
{
goto exit;
}
}
}
skip_optional:
return_value = unsigned_short_converter_impl(module, a, b, c);
@ -955,9 +974,21 @@ unsigned_int_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs
if (nargs < 3) {
goto skip_optional;
}
c = (unsigned int)PyLong_AsUnsignedLongMask(args[2]);
if (c == (unsigned int)-1 && PyErr_Occurred()) {
goto exit;
{
Py_ssize_t _bytes = PyLong_AsNativeBytes(args[2], &c, sizeof(unsigned int),
Py_ASNATIVEBYTES_NATIVE_ENDIAN |
Py_ASNATIVEBYTES_ALLOW_INDEX |
Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
if (_bytes < 0) {
goto exit;
}
if ((size_t)_bytes > sizeof(unsigned int)) {
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"integer value out of range", 1) < 0)
{
goto exit;
}
}
}
skip_optional:
return_value = unsigned_int_converter_impl(module, a, b, c);
@ -1042,7 +1073,22 @@ unsigned_long_converter(PyObject *module, PyObject *const *args, Py_ssize_t narg
_PyArg_BadArgument("unsigned_long_converter", "argument 3", "int", args[2]);
goto exit;
}
c = PyLong_AsUnsignedLongMask(args[2]);
{
Py_ssize_t _bytes = PyLong_AsNativeBytes(args[2], &c, sizeof(unsigned long),
Py_ASNATIVEBYTES_NATIVE_ENDIAN |
Py_ASNATIVEBYTES_ALLOW_INDEX |
Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
if (_bytes < 0) {
goto exit;
}
if ((size_t)_bytes > sizeof(unsigned long)) {
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"integer value out of range", 1) < 0)
{
goto exit;
}
}
}
skip_optional:
return_value = unsigned_long_converter_impl(module, a, b, c);
@ -1126,7 +1172,22 @@ unsigned_long_long_converter(PyObject *module, PyObject *const *args, Py_ssize_t
_PyArg_BadArgument("unsigned_long_long_converter", "argument 3", "int", args[2]);
goto exit;
}
c = PyLong_AsUnsignedLongLongMask(args[2]);
{
Py_ssize_t _bytes = PyLong_AsNativeBytes(args[2], &c, sizeof(unsigned long long),
Py_ASNATIVEBYTES_NATIVE_ENDIAN |
Py_ASNATIVEBYTES_ALLOW_INDEX |
Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
if (_bytes < 0) {
goto exit;
}
if ((size_t)_bytes > sizeof(unsigned long long)) {
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"integer value out of range", 1) < 0)
{
goto exit;
}
}
}
skip_optional:
return_value = unsigned_long_long_converter_impl(module, a, b, c);
@ -4481,4 +4542,4 @@ _testclinic_TestClass_posonly_poskw_varpos_array_no_fastcall(PyObject *type, PyO
exit:
return return_value;
}
/*[clinic end generated code: output=84ffc31f27215baa input=a9049054013a1b77]*/
/*[clinic end generated code: output=6b04671afdafbecf input=a9049054013a1b77]*/

View file

@ -434,12 +434,19 @@ zoneinfo_ZoneInfo__unpickle(PyObject *type, PyTypeObject *cls, PyObject *const *
}
key = args[0];
{
unsigned long ival = PyLong_AsUnsignedLongMask(args[1]);
if (ival == (unsigned long)-1 && PyErr_Occurred()) {
Py_ssize_t _bytes = PyLong_AsNativeBytes(args[1], &from_cache, sizeof(unsigned char),
Py_ASNATIVEBYTES_NATIVE_ENDIAN |
Py_ASNATIVEBYTES_ALLOW_INDEX |
Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
if (_bytes < 0) {
goto exit;
}
else {
from_cache = (unsigned char) ival;
if ((size_t)_bytes > sizeof(unsigned char)) {
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"integer value out of range", 1) < 0)
{
goto exit;
}
}
}
return_value = zoneinfo_ZoneInfo__unpickle_impl((PyTypeObject *)type, cls, key, from_cache);
@ -447,4 +454,4 @@ zoneinfo_ZoneInfo__unpickle(PyObject *type, PyTypeObject *cls, PyObject *const *
exit:
return return_value;
}
/*[clinic end generated code: output=8e9e204f390261b9 input=a9049054013a1b77]*/
/*[clinic end generated code: output=c6df04d7b400bd7f input=a9049054013a1b77]*/

View file

@ -292,9 +292,21 @@ binascii_crc_hqx(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) {
goto exit;
}
crc = (unsigned int)PyLong_AsUnsignedLongMask(args[1]);
if (crc == (unsigned int)-1 && PyErr_Occurred()) {
goto exit;
{
Py_ssize_t _bytes = PyLong_AsNativeBytes(args[1], &crc, sizeof(unsigned int),
Py_ASNATIVEBYTES_NATIVE_ENDIAN |
Py_ASNATIVEBYTES_ALLOW_INDEX |
Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
if (_bytes < 0) {
goto exit;
}
if ((size_t)_bytes > sizeof(unsigned int)) {
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"integer value out of range", 1) < 0)
{
goto exit;
}
}
}
return_value = binascii_crc_hqx_impl(module, &data, crc);
@ -336,9 +348,21 @@ binascii_crc32(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
if (nargs < 2) {
goto skip_optional;
}
crc = (unsigned int)PyLong_AsUnsignedLongMask(args[1]);
if (crc == (unsigned int)-1 && PyErr_Occurred()) {
goto exit;
{
Py_ssize_t _bytes = PyLong_AsNativeBytes(args[1], &crc, sizeof(unsigned int),
Py_ASNATIVEBYTES_NATIVE_ENDIAN |
Py_ASNATIVEBYTES_ALLOW_INDEX |
Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
if (_bytes < 0) {
goto exit;
}
if ((size_t)_bytes > sizeof(unsigned int)) {
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"integer value out of range", 1) < 0)
{
goto exit;
}
}
}
skip_optional:
_return_value = binascii_crc32_impl(module, &data, crc);
@ -788,4 +812,4 @@ exit:
return return_value;
}
/*[clinic end generated code: output=adb855a2797c3cad input=a9049054013a1b77]*/
/*[clinic end generated code: output=fba6a71e0d7d092f input=a9049054013a1b77]*/

View file

@ -124,7 +124,22 @@ fcntl_ioctl(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
PyErr_Format(PyExc_TypeError, "ioctl() argument 2 must be int, not %T", args[1]);
goto exit;
}
code = PyLong_AsUnsignedLongMask(args[1]);
{
Py_ssize_t _bytes = PyLong_AsNativeBytes(args[1], &code, sizeof(unsigned long),
Py_ASNATIVEBYTES_NATIVE_ENDIAN |
Py_ASNATIVEBYTES_ALLOW_INDEX |
Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
if (_bytes < 0) {
goto exit;
}
if ((size_t)_bytes > sizeof(unsigned long)) {
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"integer value out of range", 1) < 0)
{
goto exit;
}
}
}
if (nargs < 3) {
goto skip_optional;
}
@ -264,4 +279,4 @@ skip_optional:
exit:
return return_value;
}
/*[clinic end generated code: output=65a16bc64c7b4de4 input=a9049054013a1b77]*/
/*[clinic end generated code: output=bf84289b741e7cf6 input=a9049054013a1b77]*/

View file

@ -844,7 +844,22 @@ os_chflags(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *
_PyArg_BadArgument("chflags", "argument 'flags'", "int", args[1]);
goto exit;
}
flags = PyLong_AsUnsignedLongMask(args[1]);
{
Py_ssize_t _bytes = PyLong_AsNativeBytes(args[1], &flags, sizeof(unsigned long),
Py_ASNATIVEBYTES_NATIVE_ENDIAN |
Py_ASNATIVEBYTES_ALLOW_INDEX |
Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
if (_bytes < 0) {
goto exit;
}
if ((size_t)_bytes > sizeof(unsigned long)) {
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"integer value out of range", 1) < 0)
{
goto exit;
}
}
}
if (!noptargs) {
goto skip_optional_pos;
}
@ -928,7 +943,22 @@ os_lchflags(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject
_PyArg_BadArgument("lchflags", "argument 'flags'", "int", args[1]);
goto exit;
}
flags = PyLong_AsUnsignedLongMask(args[1]);
{
Py_ssize_t _bytes = PyLong_AsNativeBytes(args[1], &flags, sizeof(unsigned long),
Py_ASNATIVEBYTES_NATIVE_ENDIAN |
Py_ASNATIVEBYTES_ALLOW_INDEX |
Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
if (_bytes < 0) {
goto exit;
}
if ((size_t)_bytes > sizeof(unsigned long)) {
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"integer value out of range", 1) < 0)
{
goto exit;
}
}
}
return_value = os_lchflags_impl(module, &path, flags);
exit:
@ -11373,9 +11403,21 @@ os_memfd_create(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj
if (!noptargs) {
goto skip_optional_pos;
}
flags = (unsigned int)PyLong_AsUnsignedLongMask(args[1]);
if (flags == (unsigned int)-1 && PyErr_Occurred()) {
goto exit;
{
Py_ssize_t _bytes = PyLong_AsNativeBytes(args[1], &flags, sizeof(unsigned int),
Py_ASNATIVEBYTES_NATIVE_ENDIAN |
Py_ASNATIVEBYTES_ALLOW_INDEX |
Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
if (_bytes < 0) {
goto exit;
}
if ((size_t)_bytes > sizeof(unsigned int)) {
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"integer value out of range", 1) < 0)
{
goto exit;
}
}
}
skip_optional_pos:
return_value = os_memfd_create_impl(module, name, flags);
@ -13398,4 +13440,4 @@ os__emscripten_debugger(PyObject *module, PyObject *Py_UNUSED(ignored))
#ifndef OS__EMSCRIPTEN_DEBUGGER_METHODDEF
#define OS__EMSCRIPTEN_DEBUGGER_METHODDEF
#endif /* !defined(OS__EMSCRIPTEN_DEBUGGER_METHODDEF) */
/*[clinic end generated code: output=ae64df0389746258 input=a9049054013a1b77]*/
/*[clinic end generated code: output=5341daae6581a62b input=a9049054013a1b77]*/

View file

@ -783,9 +783,21 @@ select_epoll_register(PyObject *self, PyObject *const *args, Py_ssize_t nargs, P
if (!noptargs) {
goto skip_optional_pos;
}
eventmask = (unsigned int)PyLong_AsUnsignedLongMask(args[1]);
if (eventmask == (unsigned int)-1 && PyErr_Occurred()) {
goto exit;
{
Py_ssize_t _bytes = PyLong_AsNativeBytes(args[1], &eventmask, sizeof(unsigned int),
Py_ASNATIVEBYTES_NATIVE_ENDIAN |
Py_ASNATIVEBYTES_ALLOW_INDEX |
Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
if (_bytes < 0) {
goto exit;
}
if ((size_t)_bytes > sizeof(unsigned int)) {
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"integer value out of range", 1) < 0)
{
goto exit;
}
}
}
skip_optional_pos:
return_value = select_epoll_register_impl((pyEpoll_Object *)self, fd, eventmask);
@ -860,9 +872,21 @@ select_epoll_modify(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyO
if (fd < 0) {
goto exit;
}
eventmask = (unsigned int)PyLong_AsUnsignedLongMask(args[1]);
if (eventmask == (unsigned int)-1 && PyErr_Occurred()) {
goto exit;
{
Py_ssize_t _bytes = PyLong_AsNativeBytes(args[1], &eventmask, sizeof(unsigned int),
Py_ASNATIVEBYTES_NATIVE_ENDIAN |
Py_ASNATIVEBYTES_ALLOW_INDEX |
Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
if (_bytes < 0) {
goto exit;
}
if ((size_t)_bytes > sizeof(unsigned int)) {
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"integer value out of range", 1) < 0)
{
goto exit;
}
}
}
return_value = select_epoll_modify_impl((pyEpoll_Object *)self, fd, eventmask);
@ -1375,4 +1399,4 @@ exit:
#ifndef SELECT_KQUEUE_CONTROL_METHODDEF
#define SELECT_KQUEUE_CONTROL_METHODDEF
#endif /* !defined(SELECT_KQUEUE_CONTROL_METHODDEF) */
/*[clinic end generated code: output=6fc20d78802511d1 input=a9049054013a1b77]*/
/*[clinic end generated code: output=2a66dd831f22c696 input=a9049054013a1b77]*/

View file

@ -660,7 +660,22 @@ signal_pthread_kill(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
_PyArg_BadArgument("pthread_kill", "argument 1", "int", args[0]);
goto exit;
}
thread_id = PyLong_AsUnsignedLongMask(args[0]);
{
Py_ssize_t _bytes = PyLong_AsNativeBytes(args[0], &thread_id, sizeof(unsigned long),
Py_ASNATIVEBYTES_NATIVE_ENDIAN |
Py_ASNATIVEBYTES_ALLOW_INDEX |
Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
if (_bytes < 0) {
goto exit;
}
if ((size_t)_bytes > sizeof(unsigned long)) {
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"integer value out of range", 1) < 0)
{
goto exit;
}
}
}
signalnum = PyLong_AsInt(args[1]);
if (signalnum == -1 && PyErr_Occurred()) {
goto exit;
@ -779,4 +794,4 @@ exit:
#ifndef SIGNAL_PIDFD_SEND_SIGNAL_METHODDEF
#define SIGNAL_PIDFD_SEND_SIGNAL_METHODDEF
#endif /* !defined(SIGNAL_PIDFD_SEND_SIGNAL_METHODDEF) */
/*[clinic end generated code: output=48bfaffeb25df5d2 input=a9049054013a1b77]*/
/*[clinic end generated code: output=37ae8ebeae4178fa input=a9049054013a1b77]*/

View file

@ -1028,9 +1028,21 @@ zlib_adler32(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
if (nargs < 2) {
goto skip_optional;
}
value = (unsigned int)PyLong_AsUnsignedLongMask(args[1]);
if (value == (unsigned int)-1 && PyErr_Occurred()) {
goto exit;
{
Py_ssize_t _bytes = PyLong_AsNativeBytes(args[1], &value, sizeof(unsigned int),
Py_ASNATIVEBYTES_NATIVE_ENDIAN |
Py_ASNATIVEBYTES_ALLOW_INDEX |
Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
if (_bytes < 0) {
goto exit;
}
if ((size_t)_bytes > sizeof(unsigned int)) {
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"integer value out of range", 1) < 0)
{
goto exit;
}
}
}
skip_optional:
return_value = zlib_adler32_impl(module, &data, value);
@ -1080,13 +1092,37 @@ zlib_adler32_combine(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
if (!_PyArg_CheckPositional("adler32_combine", nargs, 3, 3)) {
goto exit;
}
adler1 = (unsigned int)PyLong_AsUnsignedLongMask(args[0]);
if (adler1 == (unsigned int)-1 && PyErr_Occurred()) {
goto exit;
{
Py_ssize_t _bytes = PyLong_AsNativeBytes(args[0], &adler1, sizeof(unsigned int),
Py_ASNATIVEBYTES_NATIVE_ENDIAN |
Py_ASNATIVEBYTES_ALLOW_INDEX |
Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
if (_bytes < 0) {
goto exit;
}
if ((size_t)_bytes > sizeof(unsigned int)) {
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"integer value out of range", 1) < 0)
{
goto exit;
}
}
}
adler2 = (unsigned int)PyLong_AsUnsignedLongMask(args[1]);
if (adler2 == (unsigned int)-1 && PyErr_Occurred()) {
goto exit;
{
Py_ssize_t _bytes = PyLong_AsNativeBytes(args[1], &adler2, sizeof(unsigned int),
Py_ASNATIVEBYTES_NATIVE_ENDIAN |
Py_ASNATIVEBYTES_ALLOW_INDEX |
Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
if (_bytes < 0) {
goto exit;
}
if ((size_t)_bytes > sizeof(unsigned int)) {
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"integer value out of range", 1) < 0)
{
goto exit;
}
}
}
if (!PyLong_Check(args[2])) {
_PyArg_BadArgument("adler32_combine", "argument 3", "int", args[2]);
@ -1137,9 +1173,21 @@ zlib_crc32(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
if (nargs < 2) {
goto skip_optional;
}
value = (unsigned int)PyLong_AsUnsignedLongMask(args[1]);
if (value == (unsigned int)-1 && PyErr_Occurred()) {
goto exit;
{
Py_ssize_t _bytes = PyLong_AsNativeBytes(args[1], &value, sizeof(unsigned int),
Py_ASNATIVEBYTES_NATIVE_ENDIAN |
Py_ASNATIVEBYTES_ALLOW_INDEX |
Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
if (_bytes < 0) {
goto exit;
}
if ((size_t)_bytes > sizeof(unsigned int)) {
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"integer value out of range", 1) < 0)
{
goto exit;
}
}
}
skip_optional:
_return_value = zlib_crc32_impl(module, &data, value);
@ -1193,13 +1241,37 @@ zlib_crc32_combine(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
if (!_PyArg_CheckPositional("crc32_combine", nargs, 3, 3)) {
goto exit;
}
crc1 = (unsigned int)PyLong_AsUnsignedLongMask(args[0]);
if (crc1 == (unsigned int)-1 && PyErr_Occurred()) {
goto exit;
{
Py_ssize_t _bytes = PyLong_AsNativeBytes(args[0], &crc1, sizeof(unsigned int),
Py_ASNATIVEBYTES_NATIVE_ENDIAN |
Py_ASNATIVEBYTES_ALLOW_INDEX |
Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
if (_bytes < 0) {
goto exit;
}
if ((size_t)_bytes > sizeof(unsigned int)) {
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"integer value out of range", 1) < 0)
{
goto exit;
}
}
}
crc2 = (unsigned int)PyLong_AsUnsignedLongMask(args[1]);
if (crc2 == (unsigned int)-1 && PyErr_Occurred()) {
goto exit;
{
Py_ssize_t _bytes = PyLong_AsNativeBytes(args[1], &crc2, sizeof(unsigned int),
Py_ASNATIVEBYTES_NATIVE_ENDIAN |
Py_ASNATIVEBYTES_ALLOW_INDEX |
Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
if (_bytes < 0) {
goto exit;
}
if ((size_t)_bytes > sizeof(unsigned int)) {
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"integer value out of range", 1) < 0)
{
goto exit;
}
}
}
if (!PyLong_Check(args[2])) {
_PyArg_BadArgument("crc32_combine", "argument 3", "int", args[2]);
@ -1239,4 +1311,4 @@ exit:
#ifndef ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF
#define ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF
#endif /* !defined(ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF) */
/*[clinic end generated code: output=3f7692eb3b5d5a0c input=a9049054013a1b77]*/
/*[clinic end generated code: output=3054c8894aa44568 input=a9049054013a1b77]*/

View file

@ -1,9 +1,9 @@
/* fcntl module */
// Need limited C API version 3.13 for PyLong_AsInt()
// Need limited C API version 3.14 for PyLong_AsNativeBytes() in AC code
#include "pyconfig.h" // Py_GIL_DISABLED
#ifndef Py_GIL_DISABLED
# define Py_LIMITED_API 0x030d0000
# define Py_LIMITED_API 0x030e0000
#endif
#include "Python.h"

View file

@ -690,9 +690,21 @@ msvcrt_SetErrorMode(PyObject *module, PyObject *arg)
PyObject *return_value = NULL;
unsigned int mode;
mode = (unsigned int)PyLong_AsUnsignedLongMask(arg);
if (mode == (unsigned int)-1 && PyErr_Occurred()) {
goto exit;
{
Py_ssize_t _bytes = PyLong_AsNativeBytes(arg, &mode, sizeof(unsigned int),
Py_ASNATIVEBYTES_NATIVE_ENDIAN |
Py_ASNATIVEBYTES_ALLOW_INDEX |
Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
if (_bytes < 0) {
goto exit;
}
if ((size_t)_bytes > sizeof(unsigned int)) {
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"integer value out of range", 1) < 0)
{
goto exit;
}
}
}
return_value = msvcrt_SetErrorMode_impl(module, mode);
@ -731,4 +743,4 @@ exit:
#ifndef MSVCRT_GETERRORMODE_METHODDEF
#define MSVCRT_GETERRORMODE_METHODDEF
#endif /* !defined(MSVCRT_GETERRORMODE_METHODDEF) */
/*[clinic end generated code: output=692c6f52bb9193ce input=a9049054013a1b77]*/
/*[clinic end generated code: output=f67eaf745685429d input=a9049054013a1b77]*/

View file

@ -734,11 +734,20 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
values allowed */
unsigned char *p = va_arg(*p_va, unsigned char *);
HANDLE_NULLABLE;
unsigned long ival = PyLong_AsUnsignedLongMask(arg);
if (ival == (unsigned long)-1 && PyErr_Occurred())
Py_ssize_t bytes = PyLong_AsNativeBytes(arg, p, sizeof(unsigned char),
Py_ASNATIVEBYTES_NATIVE_ENDIAN |
Py_ASNATIVEBYTES_ALLOW_INDEX |
Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
if (bytes < 0) {
RETURN_ERR_OCCURRED;
else
*p = (unsigned char) ival;
}
if ((size_t)bytes > sizeof(unsigned char)) {
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"integer value out of range", 1) < 0)
{
RETURN_ERR_OCCURRED;
}
}
break;
}
@ -767,11 +776,20 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
unsigned allowed */
unsigned short *p = va_arg(*p_va, unsigned short *);
HANDLE_NULLABLE;
unsigned long ival = PyLong_AsUnsignedLongMask(arg);
if (ival == (unsigned long)-1 && PyErr_Occurred())
Py_ssize_t bytes = PyLong_AsNativeBytes(arg, p, sizeof(unsigned short),
Py_ASNATIVEBYTES_NATIVE_ENDIAN |
Py_ASNATIVEBYTES_ALLOW_INDEX |
Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
if (bytes < 0) {
RETURN_ERR_OCCURRED;
else
*p = (unsigned short) ival;
}
if ((size_t)bytes > sizeof(unsigned short)) {
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"integer value out of range", 1) < 0)
{
RETURN_ERR_OCCURRED;
}
}
break;
}
@ -800,11 +818,20 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
unsigned allowed */
unsigned int *p = va_arg(*p_va, unsigned int *);
HANDLE_NULLABLE;
unsigned long ival = PyLong_AsUnsignedLongMask(arg);
if (ival == (unsigned long)-1 && PyErr_Occurred())
Py_ssize_t bytes = PyLong_AsNativeBytes(arg, p, sizeof(unsigned int),
Py_ASNATIVEBYTES_NATIVE_ENDIAN |
Py_ASNATIVEBYTES_ALLOW_INDEX |
Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
if (bytes < 0) {
RETURN_ERR_OCCURRED;
else
*p = (unsigned int) ival;
}
if ((size_t)bytes > sizeof(unsigned int)) {
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"integer value out of range", 1) < 0)
{
RETURN_ERR_OCCURRED;
}
}
break;
}
@ -838,15 +865,23 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
case 'k': { /* long sized bitfield */
unsigned long *p = va_arg(*p_va, unsigned long *);
HANDLE_NULLABLE;
unsigned long ival;
if (!PyIndex_Check(arg)) {
return converterr(nullable, "int", arg, msgbuf, bufsize);
}
ival = PyLong_AsUnsignedLongMask(arg);
if (ival == (unsigned long)(long)-1 && PyErr_Occurred()) {
Py_ssize_t bytes = PyLong_AsNativeBytes(arg, p, sizeof(unsigned long),
Py_ASNATIVEBYTES_NATIVE_ENDIAN |
Py_ASNATIVEBYTES_ALLOW_INDEX |
Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
if (bytes < 0) {
RETURN_ERR_OCCURRED;
}
*p = ival;
if ((size_t)bytes > sizeof(unsigned long)) {
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"integer value out of range", 1) < 0)
{
RETURN_ERR_OCCURRED;
}
}
break;
}
@ -864,15 +899,23 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
case 'K': { /* long long sized bitfield */
unsigned long long *p = va_arg(*p_va, unsigned long long *);
HANDLE_NULLABLE;
unsigned long long ival;
if (!PyIndex_Check(arg)) {
return converterr(nullable, "int", arg, msgbuf, bufsize);
}
ival = PyLong_AsUnsignedLongLongMask(arg);
if (ival == (unsigned long long)(long long)-1 && PyErr_Occurred()) {
Py_ssize_t bytes = PyLong_AsNativeBytes(arg, p, sizeof(unsigned long long),
Py_ASNATIVEBYTES_NATIVE_ENDIAN |
Py_ASNATIVEBYTES_ALLOW_INDEX |
Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
if (bytes < 0) {
RETURN_ERR_OCCURRED;
}
*p = ival;
if ((size_t)bytes > sizeof(unsigned long long)) {
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"integer value out of range", 1) < 0)
{
RETURN_ERR_OCCURRED;
}
}
break;
}

View file

@ -18,6 +18,7 @@ TypeSet = set[bltns.type[object]]
class BaseUnsignedIntConverter(CConverter):
bitwise = False
def use_converter(self) -> None:
if self.converter:
@ -25,6 +26,38 @@ class BaseUnsignedIntConverter(CConverter):
f'{self.converter}()')
def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None:
if self.bitwise:
result = self.format_code("""
{{{{
Py_ssize_t _bytes = PyLong_AsNativeBytes({argname}, &{paramname}, sizeof({type}),
Py_ASNATIVEBYTES_NATIVE_ENDIAN |
Py_ASNATIVEBYTES_ALLOW_INDEX |
Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
if (_bytes < 0) {{{{
goto exit;
}}}}
if ((size_t)_bytes > sizeof({type})) {{{{
if (PyErr_WarnEx(PyExc_DeprecationWarning,
"integer value out of range", 1) < 0)
{{{{
goto exit;
}}}}
}}}}
}}}}
""",
argname=argname,
type=self.type,
bad_argument=self.bad_argument(displayname, 'int', limited_capi=limited_capi))
if self.format_unit in ('k', 'K'):
result = self.format_code("""
if (!PyIndex_Check({argname})) {{{{
{bad_argument}
goto exit;
}}}}""",
argname=argname,
bad_argument=self.bad_argument(displayname, 'int', limited_capi=limited_capi)) + result
return result
if not limited_capi:
return super().parse_arg(argname, displayname, limited_capi=limited_capi)
return self.format_code("""
@ -172,13 +205,14 @@ class char_converter(CConverter):
@add_legacy_c_converter('B', bitwise=True)
class unsigned_char_converter(CConverter):
class unsigned_char_converter(BaseUnsignedIntConverter):
type = 'unsigned char'
default_type = int
format_unit = 'b'
c_ignored_default = "'\0'"
def converter_init(self, *, bitwise: bool = False) -> None:
self.bitwise = bitwise
if bitwise:
self.format_unit = 'B'
@ -206,19 +240,6 @@ class unsigned_char_converter(CConverter):
}}}}
""",
argname=argname)
elif self.format_unit == 'B':
return self.format_code("""
{{{{
unsigned long ival = PyLong_AsUnsignedLongMask({argname});
if (ival == (unsigned long)-1 && PyErr_Occurred()) {{{{
goto exit;
}}}}
else {{{{
{paramname} = (unsigned char) ival;
}}}}
}}}}
""",
argname=argname)
return super().parse_arg(argname, displayname, limited_capi=limited_capi)
@ -265,22 +286,12 @@ class unsigned_short_converter(BaseUnsignedIntConverter):
c_ignored_default = "0"
def converter_init(self, *, bitwise: bool = False) -> None:
self.bitwise = bitwise
if bitwise:
self.format_unit = 'H'
else:
self.converter = '_PyLong_UnsignedShort_Converter'
def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None:
if self.format_unit == 'H':
return self.format_code("""
{paramname} = (unsigned short)PyLong_AsUnsignedLongMask({argname});
if ({paramname} == (unsigned short)-1 && PyErr_Occurred()) {{{{
goto exit;
}}}}
""",
argname=argname)
return super().parse_arg(argname, displayname, limited_capi=limited_capi)
@add_legacy_c_converter('C', accept={str})
class int_converter(CConverter):
@ -336,22 +347,12 @@ class unsigned_int_converter(BaseUnsignedIntConverter):
c_ignored_default = "0"
def converter_init(self, *, bitwise: bool = False) -> None:
self.bitwise = bitwise
if bitwise:
self.format_unit = 'I'
else:
self.converter = '_PyLong_UnsignedInt_Converter'
def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None:
if self.format_unit == 'I':
return self.format_code("""
{paramname} = (unsigned int)PyLong_AsUnsignedLongMask({argname});
if ({paramname} == (unsigned int)-1 && PyErr_Occurred()) {{{{
goto exit;
}}}}
""",
argname=argname)
return super().parse_arg(argname, displayname, limited_capi=limited_capi)
class long_converter(CConverter):
type = 'long'
@ -377,25 +378,12 @@ class unsigned_long_converter(BaseUnsignedIntConverter):
c_ignored_default = "0"
def converter_init(self, *, bitwise: bool = False) -> None:
self.bitwise = bitwise
if bitwise:
self.format_unit = 'k'
else:
self.converter = '_PyLong_UnsignedLong_Converter'
def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None:
if self.format_unit == 'k':
return self.format_code("""
if (!PyIndex_Check({argname})) {{{{
{bad_argument}
goto exit;
}}}}
{paramname} = PyLong_AsUnsignedLongMask({argname});
""",
argname=argname,
bad_argument=self.bad_argument(displayname, 'int', limited_capi=limited_capi),
)
return super().parse_arg(argname, displayname, limited_capi=limited_capi)
class long_long_converter(CConverter):
type = 'long long'
@ -421,25 +409,12 @@ class unsigned_long_long_converter(BaseUnsignedIntConverter):
c_ignored_default = "0"
def converter_init(self, *, bitwise: bool = False) -> None:
self.bitwise = bitwise
if bitwise:
self.format_unit = 'K'
else:
self.converter = '_PyLong_UnsignedLongLong_Converter'
def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None:
if self.format_unit == 'K':
return self.format_code("""
if (!PyIndex_Check({argname})) {{{{
{bad_argument}
goto exit;
}}}}
{paramname} = PyLong_AsUnsignedLongLongMask({argname});
""",
argname=argname,
bad_argument=self.bad_argument(displayname, 'int', limited_capi=limited_capi),
)
return super().parse_arg(argname, displayname, limited_capi=limited_capi)
class Py_ssize_t_converter(CConverter):
type = 'Py_ssize_t'