diff options
author | Georg Brandl <georg@python.org> | 2014-03-02 08:18:31 (GMT) |
---|---|---|
committer | Georg Brandl <georg@python.org> | 2014-03-02 08:18:31 (GMT) |
commit | 2fc8f773e15863fcde881e7e52a5c64896baa5df (patch) | |
tree | 55d24097924fa155960868bfc89531691802a13a /Lib | |
parent | 2658bad090f47aec4982af5480f2f8491f87f843 (diff) | |
download | cpython-2fc8f773e15863fcde881e7e52a5c64896baa5df.zip cpython-2fc8f773e15863fcde881e7e52a5c64896baa5df.tar.gz cpython-2fc8f773e15863fcde881e7e52a5c64896baa5df.tar.bz2 |
Issue #20404: reject non-text encodings early in TextIOWrapper.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/_pyio.py | 5 | ||||
-rw-r--r-- | Lib/test/test_io.py | 30 |
2 files changed, 29 insertions, 6 deletions
diff --git a/Lib/_pyio.py b/Lib/_pyio.py index 9a2a1aa..a0c4b25 100644 --- a/Lib/_pyio.py +++ b/Lib/_pyio.py @@ -1495,6 +1495,11 @@ class TextIOWrapper(TextIOBase): if not isinstance(encoding, str): raise ValueError("invalid encoding: %r" % encoding) + if not codecs.lookup(encoding)._is_text_encoding: + msg = ("%r is not a text encoding; " + "use codecs.open() to handle arbitrary codecs") + raise LookupError(msg % encoding) + if errors is None: errors = "strict" else: diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index ac6d478..2a96b7b 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -1955,6 +1955,15 @@ class TextIOWrapperTest(unittest.TestCase): self.assertRaises(TypeError, t.__init__, b, newline=42) self.assertRaises(ValueError, t.__init__, b, newline='xyzzy') + def test_non_text_encoding_codecs_are_rejected(self): + # Ensure the constructor complains if passed a codec that isn't + # marked as a text encoding + # http://bugs.python.org/issue20404 + r = self.BytesIO() + b = self.BufferedWriter(r) + with self.assertRaisesRegex(LookupError, "is not a text encoding"): + self.TextIOWrapper(b, encoding="hex_codec") + def test_detach(self): r = self.BytesIO() b = self.BufferedWriter(r) @@ -2607,15 +2616,22 @@ class TextIOWrapperTest(unittest.TestCase): def test_illegal_decoder(self): # Issue #17106 + # Bypass the early encoding check added in issue 20404 + def _make_illegal_wrapper(): + quopri = codecs.lookup("quopri_codec") + quopri._is_text_encoding = True + try: + t = self.TextIOWrapper(self.BytesIO(b'aaaaaa'), + newline='\n', encoding="quopri_codec") + finally: + quopri._is_text_encoding = False + return t # Crash when decoder returns non-string - t = self.TextIOWrapper(self.BytesIO(b'aaaaaa'), newline='\n', - encoding='quopri_codec') + t = _make_illegal_wrapper() self.assertRaises(TypeError, t.read, 1) - t = self.TextIOWrapper(self.BytesIO(b'aaaaaa'), newline='\n', - encoding='quopri_codec') + t = _make_illegal_wrapper() self.assertRaises(TypeError, t.readline) - t = self.TextIOWrapper(self.BytesIO(b'aaaaaa'), newline='\n', - encoding='quopri_codec') + t = _make_illegal_wrapper() self.assertRaises(TypeError, t.read) @@ -3053,6 +3069,7 @@ class MiscIOTest(unittest.TestCase): class CMiscIOTest(MiscIOTest): io = io + shutdown_error = "RuntimeError: could not find io module state" def test_readinto_buffer_overflow(self): # Issue #18025 @@ -3065,6 +3082,7 @@ class CMiscIOTest(MiscIOTest): class PyMiscIOTest(MiscIOTest): io = pyio + shutdown_error = "LookupError: unknown encoding: ascii" @unittest.skipIf(os.name == 'nt', 'POSIX signals required for this test.') |