]> granicus.if.org Git - python/commitdiff
[3.6] bpo-8256: Fixed possible failing or crashing input() (#641)
authorSerhiy Storchaka <storchaka@gmail.com>
Sun, 12 Mar 2017 19:52:17 +0000 (21:52 +0200)
committerGitHub <noreply@github.com>
Sun, 12 Mar 2017 19:52:17 +0000 (21:52 +0200)
if attributes "encoding" or "errors" of sys.stdin or sys.stdout are not set or are not strings.

Misc/NEWS
Python/bltinmodule.c

index 640c783ed7f4beb7ed3fecc4376627730f077229..eef4dfa335228655f65ea1887eaa1278211a62da 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -24,6 +24,9 @@ Core and Builtins
 Library
 -------
 
+- bpo-8256: Fixed possible failing or crashing input() if attributes "encoding"
+  or "errors" of sys.stdin or sys.stdout are not set or are not strings.
+
 - bpo-28298: Fix a bug that prevented array 'Q', 'L' and 'I' from accepting big
   intables (objects that have __int__) as elements.  Patch by Oren Milman.
 
index ef5a34cae900b648dd68655b045a4066ac06f690..597e26ec69a95a9af32b8e9ff50a393564d83bf7 100644 (file)
@@ -1927,12 +1927,15 @@ builtin_input_impl(PyObject *module, PyObject *prompt)
         PyObject *result;
         size_t len;
 
+        /* stdin is a text stream, so it must have an encoding. */
         stdin_encoding = _PyObject_GetAttrId(fin, &PyId_encoding);
         stdin_errors = _PyObject_GetAttrId(fin, &PyId_errors);
-        if (!stdin_encoding || !stdin_errors)
-            /* stdin is a text stream, so it must have an
-               encoding. */
+        if (!stdin_encoding || !stdin_errors ||
+                !PyUnicode_Check(stdin_encoding) ||
+                !PyUnicode_Check(stdin_errors)) {
+            tty = 0;
             goto _readline_errors;
+        }
         stdin_encoding_str = PyUnicode_AsUTF8(stdin_encoding);
         stdin_errors_str = PyUnicode_AsUTF8(stdin_errors);
         if (!stdin_encoding_str || !stdin_errors_str)
@@ -1948,8 +1951,12 @@ builtin_input_impl(PyObject *module, PyObject *prompt)
             PyObject *stringpo;
             stdout_encoding = _PyObject_GetAttrId(fout, &PyId_encoding);
             stdout_errors = _PyObject_GetAttrId(fout, &PyId_errors);
-            if (!stdout_encoding || !stdout_errors)
+            if (!stdout_encoding || !stdout_errors ||
+                    !PyUnicode_Check(stdout_encoding) ||
+                    !PyUnicode_Check(stdout_errors)) {
+                tty = 0;
                 goto _readline_errors;
+            }
             stdout_encoding_str = PyUnicode_AsUTF8(stdout_encoding);
             stdout_errors_str = PyUnicode_AsUTF8(stdout_errors);
             if (!stdout_encoding_str || !stdout_errors_str)
@@ -2003,13 +2010,17 @@ builtin_input_impl(PyObject *module, PyObject *prompt)
         Py_XDECREF(po);
         PyMem_FREE(s);
         return result;
+
     _readline_errors:
         Py_XDECREF(stdin_encoding);
         Py_XDECREF(stdout_encoding);
         Py_XDECREF(stdin_errors);
         Py_XDECREF(stdout_errors);
         Py_XDECREF(po);
-        return NULL;
+        if (tty)
+            return NULL;
+
+        PyErr_Clear();
     }
 
     /* Fallback if we're not interactive */