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')
--- /dev/null
+Fix potential buffer overflow in :class:`ast.AST` node initialization when
+encountering malformed :attr:`~ast.AST._fields` containing non-:class:`str`.
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) {
// 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) {
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) {
// 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) {