diff options
author | Carl Meyer <carl@oddbird.net> | 2023-08-11 18:42:26 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-11 18:42:26 (GMT) |
commit | 66e4edd7346b1cd65ddff6da890a0d725e325116 (patch) | |
tree | c26d1da58d8aafa684603980090cba4c74cb329e | |
parent | 04cc01453db2f0af72a06440831637f8bf512daf (diff) | |
download | cpython-66e4edd7346b1cd65ddff6da890a0d725e325116.zip cpython-66e4edd7346b1cd65ddff6da890a0d725e325116.tar.gz cpython-66e4edd7346b1cd65ddff6da890a0d725e325116.tar.bz2 |
gh-91051: fix segfault when using all 8 type watchers (#107853)
-rw-r--r-- | Doc/c-api/typeobj.rst | 4 | ||||
-rw-r--r-- | Doc/includes/typestruct.h | 2 | ||||
-rw-r--r-- | Include/cpython/object.h | 2 | ||||
-rw-r--r-- | Lib/test/test_capi/test_watchers.py | 12 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Core and Builtins/2023-08-10-17-36-27.gh-issue-91051.LfaeNW.rst | 2 |
5 files changed, 18 insertions, 4 deletions
diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index 221a05b..faa183e 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -147,7 +147,7 @@ Quick Reference +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ | :c:member:`~PyTypeObject.tp_vectorcall` | :c:type:`vectorcallfunc` | | | | | | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | [:c:member:`~PyTypeObject.tp_watched`] | char | | | | | | + | [:c:member:`~PyTypeObject.tp_watched`] | unsigned char | | | | | | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ .. [#slots] @@ -2141,7 +2141,7 @@ and :c:data:`PyType_Type` effectively act as defaults.) .. versionadded:: 3.9 (the field exists since 3.8 but it's only used since 3.9) -.. c:member:: char PyTypeObject.tp_watched +.. c:member:: unsigned char PyTypeObject.tp_watched Internal. Do not use. diff --git a/Doc/includes/typestruct.h b/Doc/includes/typestruct.h index f0ad1e4..ec939c2 100644 --- a/Doc/includes/typestruct.h +++ b/Doc/includes/typestruct.h @@ -82,5 +82,5 @@ typedef struct _typeobject { vectorcallfunc tp_vectorcall; /* bitset of which type-watchers care about this type */ - char tp_watched; + unsigned char tp_watched; } PyTypeObject; diff --git a/Include/cpython/object.h b/Include/cpython/object.h index fd45fa5..5f8b1f7 100644 --- a/Include/cpython/object.h +++ b/Include/cpython/object.h @@ -227,7 +227,7 @@ struct _typeobject { vectorcallfunc tp_vectorcall; /* bitset of which type-watchers care about this type */ - char tp_watched; + unsigned char tp_watched; }; /* This struct is used by the specializer diff --git a/Lib/test/test_capi/test_watchers.py b/Lib/test/test_capi/test_watchers.py index 93f6ef7..10b76e1 100644 --- a/Lib/test/test_capi/test_watchers.py +++ b/Lib/test/test_capi/test_watchers.py @@ -294,6 +294,18 @@ class TestTypeWatchers(unittest.TestCase): C2.hmm = "baz" self.assert_events([C1, [C2]]) + def test_all_watchers(self): + class C: pass + with ExitStack() as stack: + last_wid = -1 + # don't make assumptions about how many watchers are already + # registered, just go until we reach the max ID + while last_wid < self.TYPE_MAX_WATCHERS - 1: + last_wid = stack.enter_context(self.watcher()) + self.watch(last_wid, C) + C.foo = "bar" + self.assert_events([C]) + def test_watch_non_type(self): with self.watcher() as wid: with self.assertRaisesRegex(ValueError, r"Cannot watch non-type"): diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-08-10-17-36-27.gh-issue-91051.LfaeNW.rst b/Misc/NEWS.d/next/Core and Builtins/2023-08-10-17-36-27.gh-issue-91051.LfaeNW.rst new file mode 100644 index 0000000..b4b90ad --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-08-10-17-36-27.gh-issue-91051.LfaeNW.rst @@ -0,0 +1,2 @@ +Fix abort / segfault when using all eight type watcher slots, on platforms +where ``char`` is signed by default. |