Commit d5aa487c authored by R David Murray's avatar R David Murray

#21169: fix getpass to use replace error handler on UnicodeEncodeError.

If the input stream encoding couldn't encode one or more of the
non-ascii characters in the prompt, it would fail, throwing a
UnicodeEncodeError.  Now if that happens we re-encoding using the
'replace' error handler.

Patch by Kushal Das.
parent e544f9a2
...@@ -135,6 +135,11 @@ def _raw_input(prompt="", stream=None, input=None): ...@@ -135,6 +135,11 @@ def _raw_input(prompt="", stream=None, input=None):
input = sys.stdin input = sys.stdin
prompt = str(prompt) prompt = str(prompt)
if prompt: if prompt:
try:
stream.write(prompt)
except UnicodeEncodeError:
prompt = prompt.encode(stream.encoding, 'replace')
prompt = prompt.decode(stream.encoding)
stream.write(prompt) stream.write(prompt)
stream.flush() stream.flush()
# NOTE: The Python C API calls flockfile() (and unlock) during readline. # NOTE: The Python C API calls flockfile() (and unlock) during readline.
......
import getpass import getpass
import os import os
import unittest import unittest
from io import BytesIO, StringIO from io import BytesIO, StringIO, TextIOWrapper
from unittest import mock from unittest import mock
from test import support from test import support
...@@ -69,6 +69,14 @@ class GetpassRawinputTest(unittest.TestCase): ...@@ -69,6 +69,14 @@ class GetpassRawinputTest(unittest.TestCase):
getpass._raw_input(stream=StringIO()) getpass._raw_input(stream=StringIO())
mock_input.readline.assert_called_once_with() mock_input.readline.assert_called_once_with()
@mock.patch('sys.stdin')
def test_uses_stdin_as_different_locale(self, mock_input):
stream = TextIOWrapper(BytesIO(), encoding="ascii")
mock_input.readline.return_value = "Hasło: "
getpass._raw_input(prompt="Hasło: ",stream=stream)
mock_input.readline.assert_called_once_with()
def test_raises_on_empty_input(self): def test_raises_on_empty_input(self):
input = StringIO('') input = StringIO('')
self.assertRaises(EOFError, getpass._raw_input, input=input) self.assertRaises(EOFError, getpass._raw_input, input=input)
......
...@@ -27,6 +27,10 @@ Core and Builtins ...@@ -27,6 +27,10 @@ Core and Builtins
Library Library
------- -------
- Issue #21169: getpass now handles non-ascii characters that the
input stream encoding cannot encode by re-encoding using the
replace error handler.
- Issue #21171: Fixed undocumented filter API of the rot13 codec. - Issue #21171: Fixed undocumented filter API of the rot13 codec.
Patch by Berker Peksag. Patch by Berker Peksag.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment