summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorGeorg Brandl <georg@python.org>2014-03-02 08:18:31 (GMT)
committerGeorg Brandl <georg@python.org>2014-03-02 08:18:31 (GMT)
commit2fc8f773e15863fcde881e7e52a5c64896baa5df (patch)
tree55d24097924fa155960868bfc89531691802a13a /Lib
parent2658bad090f47aec4982af5480f2f8491f87f843 (diff)
downloadcpython-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.py5
-rw-r--r--Lib/test/test_io.py30
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.')