]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-91051: fix segfault when using all 8 type watchers (#107853)
authorCarl Meyer <carl@oddbird.net>
Fri, 11 Aug 2023 18:42:26 +0000 (12:42 -0600)
committerGitHub <noreply@github.com>
Fri, 11 Aug 2023 18:42:26 +0000 (12:42 -0600)
Doc/c-api/typeobj.rst
Doc/includes/typestruct.h
Include/cpython/object.h
Lib/test/test_capi/test_watchers.py
Misc/NEWS.d/next/Core and Builtins/2023-08-10-17-36-27.gh-issue-91051.LfaeNW.rst [new file with mode: 0644]

index 221a05b1922404c5373c0a8a175a7aa375034094..faa183e27fcfa23e9b3f0aaf144ca5b09210cbbe 100644 (file)
@@ -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.
 
index f0ad1e47cb0d86cf93fdcd363db857606c916b62..ec939c28831c33cd001d152f05399544490e88f2 100644 (file)
@@ -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;
index fd45fa57e6282bef5f0dcbdf0a180297c944be3a..5f8b1f7c195501da145fc4cd853c2cdb6588f7a1 100644 (file)
@@ -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
index 93f6ef752d0663ce09cdd6ae4c936a89e156f506..10b76e163bfb216deaf3aee52aa69a3c85438eb6 100644 (file)
@@ -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 (file)
index 0000000..b4b90ad
--- /dev/null
@@ -0,0 +1,2 @@
+Fix abort / segfault when using all eight type watcher slots, on platforms
+where ``char`` is signed by default.