]> granicus.if.org Git - python/commitdiff
The _warnings module did not properly handle cases where strings were not being
authorBrett Cannon <bcannon@gmail.com>
Tue, 2 Sep 2008 04:01:42 +0000 (04:01 +0000)
committerBrett Cannon <bcannon@gmail.com>
Tue, 2 Sep 2008 04:01:42 +0000 (04:01 +0000)
passed in as the message to use for a warning. Fixed along with making the code
more robust against other errors where return values were not checked.

Closes issue 3639.
Code review by Benjamin Peterson.

Lib/test/test_warnings.py
Misc/NEWS
Python/_warnings.c

index cd408cf145b4fc8021a143424d900b0eac8e5e26..087bf3d871aa623f84f7d5aa8f474aa676bd0c3b 100644 (file)
@@ -202,6 +202,16 @@ class WarnTests(unittest.TestCase):
                 self.assertEqual(str(w.message), text)
                 self.assert_(w.category is UserWarning)
 
+    # Issue 3639
+    def test_warn_nonstandard_types(self):
+        # warn() should handle non-standard types without issue.
+        for ob in (Warning, None, 42):
+            with support.catch_warning(self.module) as w:
+                self.module.warn(ob)
+                # Don't directly compare objects since
+                # ``Warning() != Warning()``.
+                self.assertEquals(str(w.message), str(UserWarning(ob)))
+
     def test_filename(self):
         with warnings_state(self.module):
             with support.catch_warning(self.module) as w:
@@ -315,7 +325,6 @@ class WarnTests(unittest.TestCase):
                             self.module.warn_explicit,
                             None, Warning, None, 1, registry=42)
 
-
 class CWarnTests(BaseTest, WarnTests):
     module = c_warnings
 
index 5290a83bce8a3abe081a81941dc6ecb4fdfab1b6..366fc54ee95401d11d186602ba91114808232688 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,9 @@ What's New in Python 3.0 release candidate 1
 Core and Builtins
 -----------------
 
+- Issue 3639: The _warnings module could segfault the interpreter when
+  unexpected types were passed in as arguments.
+
 - Issue #3712: The memoryview object had a reference leak and didn't support
   cyclic garbage collection.
 
index a08219e435b5fafede84c11312acdac7f88481ef..84558d1d2763a1c68a7f18d25891ce22e5f1f3d7 100644 (file)
@@ -258,6 +258,8 @@ show_warning(PyObject *filename, int lineno, PyObject *text, PyObject
     /* Print "  source_line\n" */
     if (sourceline) {
         char *source_line_str = _PyUnicode_AsString(sourceline);
+       if (source_line_str == NULL)
+               return;
         while (*source_line_str == ' ' || *source_line_str == '\t' ||
                 *source_line_str == '\014')
             source_line_str++;
@@ -266,8 +268,9 @@ show_warning(PyObject *filename, int lineno, PyObject *text, PyObject
         PyFile_WriteString("\n", f_stderr);
     }
     else
-        _Py_DisplaySourceLine(f_stderr, _PyUnicode_AsString(filename),
-                              lineno, 2);
+        if (_Py_DisplaySourceLine(f_stderr, _PyUnicode_AsString(filename),
+                              lineno, 2) < 0)
+               return;
     PyErr_Clear();
 }
 
@@ -366,8 +369,11 @@ warn_explicit(PyObject *category, PyObject *message,
             PyObject *to_str = PyObject_Str(item);
             const char *err_str = "???";
 
-            if (to_str != NULL)
+            if (to_str != NULL) {
                 err_str = _PyUnicode_AsString(to_str);
+               if (err_str == NULL)
+                       goto cleanup;
+           }
             PyErr_Format(PyExc_RuntimeError,
                         "Unrecognized action (%s) in warnings.filters:\n %s",
                         action, err_str);
@@ -498,7 +504,9 @@ setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno,
     }
     else {
         const char *module_str = _PyUnicode_AsString(*module);
-        if (module_str && strcmp(module_str, "__main__") == 0) {
+       if (module_str == NULL)
+               goto handle_error;
+        if (strcmp(module_str, "__main__") == 0) {
             PyObject *argv = PySys_GetObject("argv");
             if (argv != NULL && PyList_Size(argv) > 0) {
                 int is_true;