Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc6fcbb4

Browse files
gh-97591: InException.__setstate__() acquire strong references before callingtp_hash slot (GH-97700)
(cherry picked from commitd639438)Co-authored-by: Ofey Chan <ofey206@gmail.com>
1 parenta4fbb94 commitc6fcbb4

File tree

3 files changed

+34
-1
lines changed

3 files changed

+34
-1
lines changed

‎Lib/test/test_baseexception.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,31 @@ def test_interface_no_arg(self):
114114
[repr(exc),exc.__class__.__name__+'()'])
115115
self.interface_test_driver(results)
116116

117+
deftest_setstate_refcount_no_crash(self):
118+
# gh-97591: Acquire strong reference before calling tp_hash slot
119+
# in PyObject_SetAttr.
120+
importgc
121+
d= {}
122+
classHashThisKeyWillClearTheDict(str):
123+
def__hash__(self)->int:
124+
d.clear()
125+
returnsuper().__hash__()
126+
classValue(str):
127+
pass
128+
exc=Exception()
129+
130+
d[HashThisKeyWillClearTheDict()]=Value()# refcount of Value() is 1 now
131+
132+
# Exception.__setstate__ should aquire a strong reference of key and
133+
# value in the dict. Otherwise, Value()'s refcount would go below
134+
# zero in the tp_hash call in PyObject_SetAttr(), and it would cause
135+
# crash in GC.
136+
exc.__setstate__(d)# __hash__() is called again here, clearing the dict.
137+
138+
# This GC would crash if the refcount of Value() goes below zero.
139+
gc.collect()
140+
141+
117142
classUsageTests(unittest.TestCase):
118143

119144
"""Test usage of exceptions"""
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fixed a missing incref/decref pair in `Exception.__setstate__()`.
2+
Patch by Ofey Chan.

‎Objects/exceptions.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,14 @@ BaseException_setstate(PyObject *self, PyObject *state)
156156
returnNULL;
157157
}
158158
while (PyDict_Next(state,&i,&d_key,&d_value)) {
159-
if (PyObject_SetAttr(self,d_key,d_value)<0)
159+
Py_INCREF(d_key);
160+
Py_INCREF(d_value);
161+
intres=PyObject_SetAttr(self,d_key,d_value);
162+
Py_DECREF(d_value);
163+
Py_DECREF(d_key);
164+
if (res<0) {
160165
returnNULL;
166+
}
161167
}
162168
}
163169
Py_RETURN_NONE;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp