bpo-40638: Check for attribute lookup failure in builtin_input_impl
Add tests to cover this case.
This commit is contained in:
parent
62d618c06b
commit
400bef9ca6
|
@ -75,6 +75,23 @@ class BitBucket:
|
|||
def write(self, line):
|
||||
pass
|
||||
|
||||
class MalformedInputStream:
|
||||
def readline(self):
|
||||
return "foobar\n"
|
||||
|
||||
def fileno(self):
|
||||
return 0
|
||||
|
||||
class MalformedOutputStream:
|
||||
def __init__(self):
|
||||
self.value = ""
|
||||
|
||||
def fileno(self):
|
||||
return 1
|
||||
|
||||
def write(self, value):
|
||||
self.value += value
|
||||
|
||||
test_conv_no_sign = [
|
||||
('0', 0),
|
||||
('1', 1),
|
||||
|
@ -1302,6 +1319,13 @@ class BuiltinTest(unittest.TestCase):
|
|||
sys.stdin = io.StringIO()
|
||||
self.assertRaises(EOFError, input)
|
||||
|
||||
# input() in tty mode with a malformed input stream should attempt
|
||||
# to call .readline()
|
||||
sys.stdin = MalformedInputStream()
|
||||
sys.stdout = MalformedOutputStream()
|
||||
self.assertEqual(input("baz"), "foobar") # strips \n
|
||||
self.assertEqual(sys.stdout.value, "baz")
|
||||
|
||||
del sys.stdout
|
||||
self.assertRaises(RuntimeError, input, 'prompt')
|
||||
del sys.stdin
|
||||
|
|
|
@ -2010,17 +2010,21 @@ builtin_input_impl(PyObject *module, PyObject *prompt)
|
|||
|
||||
/* stdin is a text stream, so it must have an encoding. */
|
||||
stdin_encoding = _PyObject_GetAttrId(fin, &PyId_encoding);
|
||||
if (!stdin_encoding || !PyUnicode_Check(stdin_encoding)) {
|
||||
goto _readline_disable_tty_and_fall_back;
|
||||
}
|
||||
stdin_errors = _PyObject_GetAttrId(fin, &PyId_errors);
|
||||
if (!stdin_encoding || !stdin_errors ||
|
||||
!PyUnicode_Check(stdin_encoding) ||
|
||||
!PyUnicode_Check(stdin_errors)) {
|
||||
tty = 0;
|
||||
goto _readline_errors;
|
||||
if (!stdin_errors || !PyUnicode_Check(stdin_errors)) {
|
||||
goto _readline_disable_tty_and_fall_back;
|
||||
}
|
||||
stdin_encoding_str = PyUnicode_AsUTF8(stdin_encoding);
|
||||
stdin_errors_str = PyUnicode_AsUTF8(stdin_errors);
|
||||
if (!stdin_encoding_str || !stdin_errors_str)
|
||||
if (!stdin_encoding_str) {
|
||||
goto _readline_errors;
|
||||
}
|
||||
stdin_errors_str = PyUnicode_AsUTF8(stdin_errors);
|
||||
if (!stdin_errors_str) {
|
||||
goto _readline_errors;
|
||||
}
|
||||
tmp = _PyObject_CallMethodIdNoArgs(fout, &PyId_flush);
|
||||
if (tmp == NULL)
|
||||
PyErr_Clear();
|
||||
|
@ -2099,6 +2103,8 @@ builtin_input_impl(PyObject *module, PyObject *prompt)
|
|||
|
||||
return result;
|
||||
|
||||
_readline_disable_tty_and_fall_back:
|
||||
tty = 0;
|
||||
_readline_errors:
|
||||
Py_XDECREF(stdin_encoding);
|
||||
Py_XDECREF(stdout_encoding);
|
||||
|
|
Loading…
Reference in New Issue