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

Commitd639438

Browse files
authored
gh-97591: InException.__setstate__() acquire strong references before callingtp_hash slot (#97700)
1 parent8baef8a commitd639438

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
@@ -167,8 +167,14 @@ BaseException_setstate(PyObject *self, PyObject *state)
167167
returnNULL;
168168
}
169169
while (PyDict_Next(state,&i,&d_key,&d_value)) {
170-
if (PyObject_SetAttr(self,d_key,d_value)<0)
170+
Py_INCREF(d_key);
171+
Py_INCREF(d_value);
172+
intres=PyObject_SetAttr(self,d_key,d_value);
173+
Py_DECREF(d_value);
174+
Py_DECREF(d_key);
175+
if (res<0) {
171176
returnNULL;
177+
}
172178
}
173179
}
174180
Py_RETURN_NONE;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp