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

Commit0ef4ffe

Browse files
gh-130163: Fix crashes related to PySys_GetObject() (GH-130503)
The use of PySys_GetObject() and _PySys_GetAttr(), which return a borrowedreference, has been replaced by using one of the following functions, whichreturn a strong reference and distinguish a missing attribute from an error:_PySys_GetOptionalAttr(), _PySys_GetOptionalAttrString(),_PySys_GetRequiredAttr(), and _PySys_GetRequiredAttrString().
1 parent2dad1e0 commit0ef4ffe

23 files changed

+509
-209
lines changed

‎Include/internal/pycore_sysmodule.h‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@ extern "C" {
88
# error "this header requires Py_BUILD_CORE define"
99
#endif
1010

11-
// Export for '_pickle' shared extension
12-
PyAPI_FUNC(PyObject*)_PySys_GetAttr(PyThreadState*tstate,PyObject*name);
11+
PyAPI_FUNC(int)_PySys_GetOptionalAttr(PyObject*,PyObject**);
12+
PyAPI_FUNC(int)_PySys_GetOptionalAttrString(constchar*,PyObject**);
13+
PyAPI_FUNC(PyObject*)_PySys_GetRequiredAttr(PyObject*);
14+
PyAPI_FUNC(PyObject*)_PySys_GetRequiredAttrString(constchar*);
1315

1416
// Export for '_pickle' shared extension
1517
PyAPI_FUNC(size_t)_PySys_GetSizeOf(PyObject*);

‎Lib/test/test_builtin.py‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1710,6 +1710,29 @@ def test_input(self):
17101710
sys.stdout=savestdout
17111711
fp.close()
17121712

1713+
deftest_input_gh130163(self):
1714+
classX(io.StringIO):
1715+
def__getattribute__(self,name):
1716+
nonlocalpatch
1717+
ifpatch:
1718+
patch=False
1719+
sys.stdout=X()
1720+
sys.stderr=X()
1721+
sys.stdin=X('input\n')
1722+
support.gc_collect()
1723+
returnio.StringIO.__getattribute__(self,name)
1724+
1725+
with (support.swap_attr(sys,'stdout',None),
1726+
support.swap_attr(sys,'stderr',None),
1727+
support.swap_attr(sys,'stdin',None)):
1728+
patch=False
1729+
# the only references:
1730+
sys.stdout=X()
1731+
sys.stderr=X()
1732+
sys.stdin=X('input\n')
1733+
patch=True
1734+
input()# should not crash
1735+
17131736
# test_int(): see test_int.py for tests of built-in function int().
17141737

17151738
deftest_repr(self):

‎Lib/test/test_print.py‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,17 @@ def flush(self):
129129
raiseRuntimeError
130130
self.assertRaises(RuntimeError,print,1,file=noflush(),flush=True)
131131

132+
deftest_gh130163(self):
133+
classX:
134+
def__str__(self):
135+
sys.stdout=StringIO()
136+
support.gc_collect()
137+
return'foo'
138+
139+
withsupport.swap_attr(sys,'stdout',None):
140+
sys.stdout=StringIO()# the only reference
141+
print(X())# should not crash
142+
132143

133144
classTestPy2MigrationHint(unittest.TestCase):
134145
"""Test that correct hint is produced analogous to Python3 syntax,

‎Lib/test/test_sys.py‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
importcodecs
33
import_datetime
44
importgc
5+
importio
56
importlocale
67
importoperator
78
importos
@@ -80,6 +81,18 @@ def baddisplayhook(obj):
8081
code=compile("42","<string>","single")
8182
self.assertRaises(ValueError,eval,code)
8283

84+
deftest_gh130163(self):
85+
classX:
86+
def__repr__(self):
87+
sys.stdout=io.StringIO()
88+
support.gc_collect()
89+
return'foo'
90+
91+
withsupport.swap_attr(sys,'stdout',None):
92+
sys.stdout=io.StringIO()# the only reference
93+
sys.displayhook(X())# should not crash
94+
95+
8396
classActiveExceptionTests(unittest.TestCase):
8497
deftest_exc_info_no_exception(self):
8598
self.assertEqual(sys.exc_info(), (None,None,None))
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix possible crashes related to concurrent
2+
change and use of the:mod:`sys` module attributes.

‎Modules/_cursesmodule.c‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ static const char PyCursesVersion[] = "2.2";
108108
#include"pycore_capsule.h"// _PyCapsule_SetTraverse()
109109
#include"pycore_long.h"// _PyLong_GetZero()
110110
#include"pycore_structseq.h"// _PyStructSequence_NewType()
111+
#include"pycore_sysmodule.h"// _PySys_GetOptionalAttrString()
111112

112113
#ifdef__hpux
113114
#defineSTRICT_SYSV_CURSES
@@ -3542,16 +3543,19 @@ _curses_setupterm_impl(PyObject *module, const char *term, int fd)
35423543
if (fd==-1) {
35433544
PyObject*sys_stdout;
35443545

3545-
sys_stdout=PySys_GetObject("stdout");
3546+
if (_PySys_GetOptionalAttrString("stdout",&sys_stdout)<0) {
3547+
returnNULL;
3548+
}
35463549

35473550
if (sys_stdout==NULL||sys_stdout==Py_None) {
35483551
cursesmodule_state*state=get_cursesmodule_state(module);
35493552
PyErr_SetString(state->error,"lost sys.stdout");
3553+
Py_XDECREF(sys_stdout);
35503554
returnNULL;
35513555
}
35523556

35533557
fd=PyObject_AsFileDescriptor(sys_stdout);
3554-
3558+
Py_DECREF(sys_stdout);
35553559
if (fd==-1) {
35563560
returnNULL;
35573561
}

‎Modules/_pickle.c‎

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
#include"pycore_pystate.h"// _PyThreadState_GET()
2020
#include"pycore_runtime.h"// _Py_ID()
2121
#include"pycore_setobject.h"// _PySet_NextEntry()
22-
#include"pycore_sysmodule.h"//_PySys_GetAttr()
22+
#include"pycore_sysmodule.h"//_PySys_GetSizeOf()
2323

2424
#include<stdlib.h>// strtol()
2525

@@ -1910,10 +1910,8 @@ whichmodule(PickleState *st, PyObject *global, PyObject *global_name, PyObject *
19101910
__module__ can be None. If it is so, then search sys.modules for
19111911
the module of global. */
19121912
Py_CLEAR(module_name);
1913-
PyThreadState*tstate=_PyThreadState_GET();
1914-
modules=_PySys_GetAttr(tstate,&_Py_ID(modules));
1913+
modules=_PySys_GetRequiredAttr(&_Py_ID(modules));
19151914
if (modules==NULL) {
1916-
PyErr_SetString(PyExc_RuntimeError,"unable to get sys.modules");
19171915
returnNULL;
19181916
}
19191917
if (PyDict_CheckExact(modules)) {
@@ -1923,41 +1921,48 @@ whichmodule(PickleState *st, PyObject *global, PyObject *global_name, PyObject *
19231921
Py_INCREF(module);
19241922
if (_checkmodule(module_name,module,global,dotted_path)==0) {
19251923
Py_DECREF(module);
1924+
Py_DECREF(modules);
19261925
returnmodule_name;
19271926
}
19281927
Py_DECREF(module);
19291928
Py_DECREF(module_name);
19301929
if (PyErr_Occurred()) {
1930+
Py_DECREF(modules);
19311931
returnNULL;
19321932
}
19331933
}
19341934
}
19351935
else {
19361936
PyObject*iterator=PyObject_GetIter(modules);
19371937
if (iterator==NULL) {
1938+
Py_DECREF(modules);
19381939
returnNULL;
19391940
}
19401941
while ((module_name=PyIter_Next(iterator))) {
19411942
module=PyObject_GetItem(modules,module_name);
19421943
if (module==NULL) {
19431944
Py_DECREF(module_name);
19441945
Py_DECREF(iterator);
1946+
Py_DECREF(modules);
19451947
returnNULL;
19461948
}
19471949
if (_checkmodule(module_name,module,global,dotted_path)==0) {
19481950
Py_DECREF(module);
19491951
Py_DECREF(iterator);
1952+
Py_DECREF(modules);
19501953
returnmodule_name;
19511954
}
19521955
Py_DECREF(module);
19531956
Py_DECREF(module_name);
19541957
if (PyErr_Occurred()) {
19551958
Py_DECREF(iterator);
1959+
Py_DECREF(modules);
19561960
returnNULL;
19571961
}
19581962
}
19591963
Py_DECREF(iterator);
19601964
}
1965+
Py_DECREF(modules);
19611966
if (PyErr_Occurred()) {
19621967
returnNULL;
19631968
}

‎Modules/_threadmodule.c‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
#include"pycore_modsupport.h"// _PyArg_NoKeywords()
99
#include"pycore_pylifecycle.h"
1010
#include"pycore_pystate.h"// _PyThreadState_SetCurrent()
11-
#include"pycore_sysmodule.h"//_PySys_GetAttr()
11+
#include"pycore_sysmodule.h"//_PySys_GetOptionalAttr()
1212
#include"pycore_time.h"// _PyTime_FromSeconds()
1313
#include"pycore_weakref.h"// _PyWeakref_GET_REF()
1414

@@ -2249,9 +2249,12 @@ thread_excepthook(PyObject *module, PyObject *args)
22492249
PyObject*exc_tb=PyStructSequence_GET_ITEM(args,2);
22502250
PyObject*thread=PyStructSequence_GET_ITEM(args,3);
22512251

2252-
PyThreadState*tstate=_PyThreadState_GET();
2253-
PyObject*file=_PySys_GetAttr(tstate,&_Py_ID(stderr));
2252+
PyObject*file;
2253+
if (_PySys_GetOptionalAttr(&_Py_ID(stderr),&file)<0) {
2254+
returnNULL;
2255+
}
22542256
if (file==NULL||file==Py_None) {
2257+
Py_XDECREF(file);
22552258
if (thread==Py_None) {
22562259
/* do nothing if sys.stderr is None and thread is None */
22572260
Py_RETURN_NONE;
@@ -2268,9 +2271,6 @@ thread_excepthook(PyObject *module, PyObject *args)
22682271
Py_RETURN_NONE;
22692272
}
22702273
}
2271-
else {
2272-
Py_INCREF(file);
2273-
}
22742274

22752275
intres=thread_excepthook_file(file,exc_type,exc_value,exc_tb,
22762276
thread);

‎Modules/_tkinter.c‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ Copyright (C) 1994 Steen Lumholt.
3131
#endif
3232

3333
#include"pycore_long.h"// _PyLong_IsNegative()
34+
#include"pycore_sysmodule.h"// _PySys_GetOptionalAttrString()
3435

3536
#ifdefMS_WINDOWS
3637
# include<windows.h>
@@ -142,18 +143,21 @@ _get_tcl_lib_path(void)
142143
if (already_checked==0) {
143144
structstatstat_buf;
144145
intstat_return_value;
146+
PyObject*prefix;
145147

146-
PyObject*prefix=PySys_GetObject("base_prefix");// borrowed reference
148+
(void)_PySys_GetOptionalAttrString("base_prefix",&prefix);
147149
if (prefix==NULL) {
148150
returnNULL;
149151
}
150152

151153
/* Check expected location for an installed Python first */
152154
tcl_library_path=PyUnicode_FromString("\\tcl\\tcl"TCL_VERSION);
153155
if (tcl_library_path==NULL) {
156+
Py_DECREF(prefix);
154157
returnNULL;
155158
}
156159
tcl_library_path=PyUnicode_Concat(prefix,tcl_library_path);
160+
Py_DECREF(prefix);
157161
if (tcl_library_path==NULL) {
158162
returnNULL;
159163
}
@@ -3516,9 +3520,10 @@ PyInit__tkinter(void)
35163520

35173521
/* This helps the dynamic loader; in Unicode aware Tcl versions
35183522
it also helps Tcl find its encodings. */
3519-
uexe=PySys_GetObject("executable");// borrowed reference
3523+
(void)_PySys_GetOptionalAttrString("executable",&uexe);
35203524
if (uexe&&PyUnicode_Check(uexe)) {// sys.executable can be None
35213525
cexe=PyUnicode_EncodeFSDefault(uexe);
3526+
Py_DECREF(uexe);
35223527
if (cexe) {
35233528
#ifdefMS_WINDOWS
35243529
intset_var=0;
@@ -3531,12 +3536,14 @@ PyInit__tkinter(void)
35313536
if (!ret&&GetLastError()==ERROR_ENVVAR_NOT_FOUND) {
35323537
str_path=_get_tcl_lib_path();
35333538
if (str_path==NULL&&PyErr_Occurred()) {
3539+
Py_DECREF(cexe);
35343540
Py_DECREF(m);
35353541
returnNULL;
35363542
}
35373543
if (str_path!=NULL) {
35383544
wcs_path=PyUnicode_AsWideCharString(str_path,NULL);
35393545
if (wcs_path==NULL) {
3546+
Py_DECREF(cexe);
35403547
Py_DECREF(m);
35413548
returnNULL;
35423549
}
@@ -3557,6 +3564,9 @@ PyInit__tkinter(void)
35573564
}
35583565
Py_XDECREF(cexe);
35593566
}
3567+
else {
3568+
Py_XDECREF(uexe);
3569+
}
35603570

35613571
if (PyErr_Occurred()) {
35623572
Py_DECREF(m);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp