gh-140471: Fix buffer overflow in AST node initialization with malformed _fields (#140506)

This commit is contained in:
Stan Ulbrych 2025-10-23 16:35:21 +01:00 committed by GitHub
parent 1a3da2c070
commit 95953b692d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 15 additions and 4 deletions

View file

@ -3308,6 +3308,15 @@ class ASTConstructorTests(unittest.TestCase):
self.assertEqual(obj.a, 1)
self.assertEqual(obj.b, 2)
def test_malformed_fields_with_bytes(self):
class BadFields(ast.AST):
_fields = (b'\xff'*64,)
_field_types = {'a': int}
# This should not crash
with self.assertWarnsRegex(DeprecationWarning, r"Field b'\\xff\\xff.*' .*"):
obj = BadFields()
def test_complete_field_types(self):
class _AllFieldTypes(ast.AST):
_fields = ('a', 'b')

View file

@ -0,0 +1,2 @@
Fix potential buffer overflow in :class:`ast.AST` node initialization when
encountering malformed :attr:`~ast.AST._fields` containing non-:class:`str`.

View file

@ -1009,7 +1009,7 @@ ast_type_init(PyObject *self, PyObject *args, PyObject *kw)
else {
if (PyErr_WarnFormat(
PyExc_DeprecationWarning, 1,
"Field '%U' is missing from %.400s._field_types. "
"Field %R is missing from %.400s._field_types. "
"This will become an error in Python 3.15.",
name, Py_TYPE(self)->tp_name
) < 0) {
@ -1044,7 +1044,7 @@ ast_type_init(PyObject *self, PyObject *args, PyObject *kw)
// simple field (e.g., identifier)
if (PyErr_WarnFormat(
PyExc_DeprecationWarning, 1,
"%.400s.__init__ missing 1 required positional argument: '%U'. "
"%.400s.__init__ missing 1 required positional argument: %R. "
"This will become an error in Python 3.15.",
Py_TYPE(self)->tp_name, name
) < 0) {

4
Python/Python-ast.c generated
View file

@ -5293,7 +5293,7 @@ ast_type_init(PyObject *self, PyObject *args, PyObject *kw)
else {
if (PyErr_WarnFormat(
PyExc_DeprecationWarning, 1,
"Field '%U' is missing from %.400s._field_types. "
"Field %R is missing from %.400s._field_types. "
"This will become an error in Python 3.15.",
name, Py_TYPE(self)->tp_name
) < 0) {
@ -5328,7 +5328,7 @@ ast_type_init(PyObject *self, PyObject *args, PyObject *kw)
// simple field (e.g., identifier)
if (PyErr_WarnFormat(
PyExc_DeprecationWarning, 1,
"%.400s.__init__ missing 1 required positional argument: '%U'. "
"%.400s.__init__ missing 1 required positional argument: %R. "
"This will become an error in Python 3.15.",
Py_TYPE(self)->tp_name, name
) < 0) {