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

(cherry picked from commit c2cf12857187aa147c268651f10acd6da2c9cb74)

Misc/NEWS
Python/bltinmodule.c

index df0975a4d5ea2216badce3a4b2c647fdd12ac2a2..98b47bdab4a8f111e825c1d9d25dd93a97becc49 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -41,6 +41,9 @@ Extension Modules
 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 33d2cc2dc8e2cfcb99e130d09b42249578920d24..17c074a1b3b26b9e33c21c8b170a01f031e01afc 100644 (file)
@@ -1892,12 +1892,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_AsString(stdin_encoding);
         stdin_errors_str = _PyUnicode_AsString(stdin_errors);
         if (!stdin_encoding_str || !stdin_errors_str)
@@ -1913,8 +1916,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_AsString(stdout_encoding);
             stdout_errors_str = _PyUnicode_AsString(stdout_errors);
             if (!stdout_encoding_str || !stdout_errors_str)
@@ -1969,13 +1976,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 */