[Python-checkins] cpython (merge 3.5 -> default): Issue #26754: PyUnicode_FSDecoder() accepted a filename argument encoded as

serhiy.storchaka python-checkins at python.org
Sat Jun 18 06:56:38 EDT 2016


https://hg.python.org/cpython/rev/e18ac7370113
changeset: 102087:e18ac7370113
parent: 102085:79a3aff60e37
parent: 102086:2e48c2c4c733
user: Serhiy Storchaka <storchaka at gmail.com>
date: Sat Jun 18 13:56:16 2016 +0300
summary:
 Issue #26754: PyUnicode_FSDecoder() accepted a filename argument encoded as
an iterable of integers. Now only strings and byte-like objects are accepted.
files:
 Lib/test/test_compile.py | 7 +++++++
 Lib/test/test_parser.py | 16 ++++++++++++++++
 Lib/test/test_symtable.py | 6 ++++++
 Lib/test/test_zipimport.py | 15 +++++++++++++++
 Misc/NEWS | 10 ++++++++++
 Objects/unicodeobject.c | 8 +++++++-
 6 files changed, 61 insertions(+), 1 deletions(-)
diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py
--- a/Lib/test/test_compile.py
+++ b/Lib/test/test_compile.py
@@ -472,6 +472,13 @@
 d = {f(): f(), f(): f()}
 self.assertEqual(d, {1: 2, 3: 4})
 
+ def test_compile_filename(self):
+ for filename in ('file.py', b'file.py',
+ bytearray(b'file.py'), memoryview(b'file.py')):
+ code = compile('pass', filename, 'exec')
+ self.assertEqual(code.co_filename, 'file.py')
+ self.assertRaises(TypeError, compile, 'pass', list(b'file.py'), 'exec')
+
 @support.cpython_only
 def test_same_filename_used(self):
 s = """def f(): pass\ndef g(): pass"""
diff --git a/Lib/test/test_parser.py b/Lib/test/test_parser.py
--- a/Lib/test/test_parser.py
+++ b/Lib/test/test_parser.py
@@ -626,6 +626,22 @@
 code2 = parser.compilest(st)
 self.assertEqual(eval(code2), -3)
 
+ def test_compile_filename(self):
+ st = parser.expr('a + 5')
+ code = parser.compilest(st)
+ self.assertEqual(code.co_filename, '<syntax-tree>')
+ code = st.compile()
+ self.assertEqual(code.co_filename, '<syntax-tree>')
+ for filename in ('file.py', b'file.py',
+ bytearray(b'file.py'), memoryview(b'file.py')):
+ code = parser.compilest(st, filename)
+ self.assertEqual(code.co_filename, 'file.py')
+ code = st.compile(filename)
+ self.assertEqual(code.co_filename, 'file.py')
+ self.assertRaises(TypeError, parser.compilest, st, list(b'file.py'))
+ self.assertRaises(TypeError, st.compile, list(b'file.py'))
+
+
 class ParserStackLimitTestCase(unittest.TestCase):
 """try to push the parser to/over its limits.
 see http://bugs.python.org/issue1881 for a discussion
diff --git a/Lib/test/test_symtable.py b/Lib/test/test_symtable.py
--- a/Lib/test/test_symtable.py
+++ b/Lib/test/test_symtable.py
@@ -157,6 +157,12 @@
 self.fail("no SyntaxError for %r" % (brokencode,))
 checkfilename("def f(x): foo)(") # parse-time
 checkfilename("def f(x): global x") # symtable-build-time
+ symtable.symtable("pass", b"spam", "exec")
+ with self.assertRaises(TypeError):
+ symtable.symtable("pass", bytearray(b"spam"), "exec")
+ symtable.symtable("pass", memoryview(b"spam"), "exec")
+ with self.assertRaises(TypeError):
+ symtable.symtable("pass", list(b"spam"), "exec")
 
 def test_eval(self):
 symbols = symtable.symtable("42", "?", "eval")
diff --git a/Lib/test/test_zipimport.py b/Lib/test/test_zipimport.py
--- a/Lib/test/test_zipimport.py
+++ b/Lib/test/test_zipimport.py
@@ -619,6 +619,19 @@
 finally:
 os.remove(filename)
 
+ def testBytesPath(self):
+ filename = support.TESTFN + ".zip"
+ self.addCleanup(support.unlink, filename)
+ with ZipFile(filename, "w") as z:
+ zinfo = ZipInfo(TESTMOD + ".py", time.localtime(NOW))
+ zinfo.compress_type = self.compression
+ z.writestr(zinfo, test_src)
+
+ zipimport.zipimporter(filename)
+ zipimport.zipimporter(os.fsencode(filename))
+ zipimport.zipimporter(bytearray(os.fsencode(filename)))
+ zipimport.zipimporter(memoryview(os.fsencode(filename)))
+
 
 @support.requires_zlib
 class CompressedZipImportTestCase(UncompressedZipImportTestCase):
@@ -639,6 +652,8 @@
 def testBadArgs(self):
 self.assertRaises(TypeError, zipimport.zipimporter, None)
 self.assertRaises(TypeError, zipimport.zipimporter, TESTMOD, kwd=None)
+ self.assertRaises(TypeError, zipimport.zipimporter,
+ list(os.fsencode(TESTMOD)))
 
 def testFilenameTooLong(self):
 self.assertZipFailure('A' * 33000)
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,10 @@
 Library
 -------
 
+- Issue #26754: Some functions (compile() etc) accepted a filename argument
+ encoded as an iterable of integers. Now only strings and byte-like objects
+ are accepted.
+
 - Issue #26536: socket.ioctl now supports SIO_LOOPBACK_FAST_PATH. Patch by
 Daniel Stokes.
 
@@ -52,6 +56,12 @@
 
 - Issue #27310: Fix IDLE.app failure to launch on OS X due to vestigial import.
 
+C API
+-----
+
+- Issue #26754: PyUnicode_FSDecoder() accepted a filename argument encoded as
+ an iterable of integers. Now only strings and byte-like objects are accepted.
+
 Build
 -----
 
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -3837,7 +3837,7 @@
 output = arg;
 Py_INCREF(output);
 }
- else {
+ else if (PyObject_CheckBuffer(arg)) {
 arg = PyBytes_FromObject(arg);
 if (!arg)
 return 0;
@@ -3852,6 +3852,12 @@
 return 0;
 }
 }
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "path should be string or bytes, not %.200s",
+ Py_TYPE(arg)->tp_name);
+ return 0;
+ }
 if (PyUnicode_READY(output) == -1) {
 Py_DECREF(output);
 return 0;
-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /