[Python-checkins] cpython (3.4): Issue #13204: Calling sys.flags.__new__ would crash the interpreter, now it

antoine.pitrou python-checkins at python.org
Mon Apr 28 13:08:36 CEST 2014


http://hg.python.org/cpython/rev/7052fdd90a11
changeset:   90482:7052fdd90a11
branch:      3.4
parent:      90479:c27cb341de7d
user:        Antoine Pitrou <solipsis at pitrou.net>
date:        Mon Apr 28 13:07:06 2014 +0200
summary:
  Issue #13204: Calling sys.flags.__new__ would crash the interpreter, now it raises a TypeError.

files:
  Lib/test/test_sys.py |  20 ++++++++++++++++++++
  Misc/NEWS            |   3 +++
  Python/sysmodule.c   |  13 ++++++++++---
  3 files changed, 33 insertions(+), 3 deletions(-)


diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py
--- a/Lib/test/test_sys.py
+++ b/Lib/test/test_sys.py
@@ -519,6 +519,26 @@
         self.assertTrue(repr(sys.flags))
         self.assertEqual(len(sys.flags), len(attrs))
 
+    def assert_raise_on_new_sys_type(self, sys_attr):
+        # Users are intentionally prevented from creating new instances of
+        # sys.flags, sys.version_info, and sys.getwindowsversion.
+        attr_type = type(sys_attr)
+        with self.assertRaises(TypeError):
+            attr_type()
+        with self.assertRaises(TypeError):
+            attr_type.__new__(attr_type)
+
+    def test_sys_flags_no_instantiation(self):
+        self.assert_raise_on_new_sys_type(sys.flags)
+
+    def test_sys_version_info_no_instantiation(self):
+        self.assert_raise_on_new_sys_type(sys.version_info)
+
+    def test_sys_getwindowsversion_no_instantiation(self):
+        # Skip if not being run on Windows.
+        test.support.get_attribute(sys, "getwindowsversion")
+        self.assert_raise_on_new_sys_type(sys.getwindowsversion())
+
     def test_clear_type_cache(self):
         sys._clear_type_cache()
 
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -39,6 +39,9 @@
 Library
 -------
 
+- Issue #13204: Calling sys.flags.__new__ would crash the interpreter,
+  now it raises a TypeError.
+
 - Issue #19385: Make operations on a closed dbm.dumb database always raise the
   same exception.
 
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -1622,6 +1622,7 @@
 _PySys_Init(void)
 {
     PyObject *m, *sysdict, *version_info;
+    int res;
 
     m = PyModule_Create(&sysmodule);
     if (m == NULL)
@@ -1629,7 +1630,6 @@
     sysdict = PyModule_GetDict(m);
 #define SET_SYS_FROM_STRING_BORROW(key, value)             \
     do {                                                   \
-        int res;                                           \
         PyObject *v = (value);                             \
         if (v == NULL)                                     \
             return NULL;                                   \
@@ -1640,7 +1640,6 @@
     } while (0)
 #define SET_SYS_FROM_STRING(key, value)                    \
     do {                                                   \
-        int res;                                           \
         PyObject *v = (value);                             \
         if (v == NULL)                                     \
             return NULL;                                   \
@@ -1759,6 +1758,9 @@
     /* prevent user from creating new instances */
     VersionInfoType.tp_init = NULL;
     VersionInfoType.tp_new = NULL;
+    res = PyDict_DelItemString(VersionInfoType.tp_dict, "__new__");
+    if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError))
+        PyErr_Clear();
 
     /* implementation */
     SET_SYS_FROM_STRING("implementation", make_impl_info(version_info));
@@ -1772,7 +1774,9 @@
     /* prevent user from creating new instances */
     FlagsType.tp_init = NULL;
     FlagsType.tp_new = NULL;
-
+    res = PyDict_DelItemString(FlagsType.tp_dict, "__new__");
+    if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError))
+        PyErr_Clear();
 
 #if defined(MS_WINDOWS)
     /* getwindowsversion */
@@ -1783,6 +1787,9 @@
     /* prevent user from creating new instances */
     WindowsVersionType.tp_init = NULL;
     WindowsVersionType.tp_new = NULL;
+    res = PyDict_DelItemString(WindowsVersionType.tp_dict, "__new__");
+    if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError))
+        PyErr_Clear();
 #endif
 
     /* float repr style: 0.03 (short) vs 0.029999999999999999 (legacy) */

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list