Skip to content

Commit ceacec7

Browse files
sunmy2019miss-islington
authored andcommitted
gh-146615: Fix crash in __get__() for METH_METHOD descriptors with invalid type argument (GH-146634)
(cherry picked from commit 72d29ea) Co-authored-by: sunmy2019 <59365878+sunmy2019@users.noreply.github.com>
1 parent 99f333d commit ceacec7

File tree

3 files changed

+26
-1
lines changed

3 files changed

+26
-1
lines changed

Lib/test/test_descr.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1712,6 +1712,28 @@ class SubSpam(spam.spamlist): pass
17121712
spam_cm.__get__(None, list)
17131713
self.assertEqual(str(cm.exception), expected_errmsg)
17141714

1715+
@support.cpython_only
1716+
def test_method_get_meth_method_invalid_type(self):
1717+
# gh-146615: method_get() for METH_METHOD descriptors used to pass
1718+
# Py_TYPE(type)->tp_name as the %V fallback instead of the separate
1719+
# %s argument, causing a missing argument for %s and a crash.
1720+
# Verify the error message is correct when __get__() is called with a
1721+
# non-type as the second argument.
1722+
#
1723+
# METH_METHOD|METH_FASTCALL|METH_KEYWORDS is the only flag combination
1724+
# that enters the affected branch in method_get().
1725+
import io
1726+
1727+
obj = io.StringIO()
1728+
descr = io.TextIOBase.read
1729+
1730+
with self.assertRaises(TypeError) as cm:
1731+
descr.__get__(obj, "not_a_type")
1732+
self.assertEqual(
1733+
str(cm.exception),
1734+
"descriptor 'read' needs a type, not 'str', as arg 2",
1735+
)
1736+
17151737
def test_staticmethods(self):
17161738
# Testing static methods...
17171739
class C(object):
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix a crash in :meth:`~object.__get__` for :c:expr:`METH_METHOD` descriptors
2+
when an invalid (non-type) object is passed as the second argument.
3+
Patch by Steven Sun.

Objects/descrobject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ method_get(PyObject *self, PyObject *obj, PyObject *type)
150150
} else {
151151
PyErr_Format(PyExc_TypeError,
152152
"descriptor '%V' needs a type, not '%s', as arg 2",
153-
descr_name((PyDescrObject *)descr),
153+
descr_name((PyDescrObject *)descr), "?",
154154
Py_TYPE(type)->tp_name);
155155
return NULL;
156156
}

0 commit comments

Comments
 (0)