Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 871dfc4

Browse files
committed
Issue #13204: Calling sys.flags.__new__ would crash the interpreter, now it raises a TypeError.
1 parent 94ba146 commit 871dfc4

3 files changed

Lines changed: 33 additions & 3 deletions

File tree

Lib/test/test_sys.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,26 @@ def test_sys_flags(self):
519519
self.assertTrue(repr(sys.flags))
520520
self.assertEqual(len(sys.flags), len(attrs))
521521

522+
def assert_raise_on_new_sys_type(self, sys_attr):
523+
# Users are intentionally prevented from creating new instances of
524+
# sys.flags, sys.version_info, and sys.getwindowsversion.
525+
attr_type = type(sys_attr)
526+
with self.assertRaises(TypeError):
527+
attr_type()
528+
with self.assertRaises(TypeError):
529+
attr_type.__new__(attr_type)
530+
531+
def test_sys_flags_no_instantiation(self):
532+
self.assert_raise_on_new_sys_type(sys.flags)
533+
534+
def test_sys_version_info_no_instantiation(self):
535+
self.assert_raise_on_new_sys_type(sys.version_info)
536+
537+
def test_sys_getwindowsversion_no_instantiation(self):
538+
# Skip if not being run on Windows.
539+
test.support.get_attribute(sys, "getwindowsversion")
540+
self.assert_raise_on_new_sys_type(sys.getwindowsversion())
541+
522542
def test_clear_type_cache(self):
523543
sys._clear_type_cache()
524544

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ Core and Builtins
3939
Library
4040
-------
4141

42+
- Issue #13204: Calling sys.flags.__new__ would crash the interpreter,
43+
now it raises a TypeError.
44+
4245
- Issue #19385: Make operations on a closed dbm.dumb database always raise the
4346
same exception.
4447

Python/sysmodule.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1622,14 +1622,14 @@ PyObject *
16221622
_PySys_Init(void)
16231623
{
16241624
PyObject *m, *sysdict, *version_info;
1625+
int res;
16251626

16261627
m = PyModule_Create(&sysmodule);
16271628
if (m == NULL)
16281629
return NULL;
16291630
sysdict = PyModule_GetDict(m);
16301631
#define SET_SYS_FROM_STRING_BORROW(key, value) \
16311632
do { \
1632-
int res; \
16331633
PyObject *v = (value); \
16341634
if (v == NULL) \
16351635
return NULL; \
@@ -1640,7 +1640,6 @@ _PySys_Init(void)
16401640
} while (0)
16411641
#define SET_SYS_FROM_STRING(key, value) \
16421642
do { \
1643-
int res; \
16441643
PyObject *v = (value); \
16451644
if (v == NULL) \
16461645
return NULL; \
@@ -1759,6 +1758,9 @@ _PySys_Init(void)
17591758
/* prevent user from creating new instances */
17601759
VersionInfoType.tp_init = NULL;
17611760
VersionInfoType.tp_new = NULL;
1761+
res = PyDict_DelItemString(VersionInfoType.tp_dict, "__new__");
1762+
if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError))
1763+
PyErr_Clear();
17621764

17631765
/* implementation */
17641766
SET_SYS_FROM_STRING("implementation", make_impl_info(version_info));
@@ -1772,7 +1774,9 @@ _PySys_Init(void)
17721774
/* prevent user from creating new instances */
17731775
FlagsType.tp_init = NULL;
17741776
FlagsType.tp_new = NULL;
1775-
1777+
res = PyDict_DelItemString(FlagsType.tp_dict, "__new__");
1778+
if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError))
1779+
PyErr_Clear();
17761780

17771781
#if defined(MS_WINDOWS)
17781782
/* getwindowsversion */
@@ -1783,6 +1787,9 @@ _PySys_Init(void)
17831787
/* prevent user from creating new instances */
17841788
WindowsVersionType.tp_init = NULL;
17851789
WindowsVersionType.tp_new = NULL;
1790+
res = PyDict_DelItemString(WindowsVersionType.tp_dict, "__new__");
1791+
if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError))
1792+
PyErr_Clear();
17861793
#endif
17871794

17881795
/* float repr style: 0.03 (short) vs 0.029999999999999999 (legacy) */

0 commit comments

Comments
 (0)