summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2016-06-18 10:53:36 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2016-06-18 10:53:36 (GMT)
commit9305d83425e2ec63b2769336907dd07b3151cd5f (patch)
treeaf956a2eff3d5241bfa64dd3dc2890fb44896ada
parentbae5d81f5d1f388aad48c2ce1aee8682b157e1bd (diff)
downloadcpython-9305d83425e2ec63b2769336907dd07b3151cd5f.zip
cpython-9305d83425e2ec63b2769336907dd07b3151cd5f.tar.gz
cpython-9305d83425e2ec63b2769336907dd07b3151cd5f.tar.bz2
Issue #26754: PyUnicode_FSDecoder() accepted a filename argument encoded as
an iterable of integers. Now only strings and byte-like objects are accepted.
-rw-r--r--Lib/test/test_compile.py7
-rw-r--r--Lib/test/test_parser.py16
-rw-r--r--Lib/test/test_symtable.py6
-rw-r--r--Lib/test/test_zipimport.py15
-rw-r--r--Misc/NEWS11
-rw-r--r--Objects/unicodeobject.c8
6 files changed, 62 insertions, 1 deletions
diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py
index e0fdee3..824e843 100644
--- a/Lib/test/test_compile.py
+++ b/Lib/test/test_compile.py
@@ -472,6 +472,13 @@ if 1:
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
index 3d301b4..ab6577f 100644
--- a/Lib/test/test_parser.py
+++ b/Lib/test/test_parser.py
@@ -627,6 +627,22 @@ class CompileTestCase(unittest.TestCase):
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
index e5e7b83..c5d7fac 100644
--- a/Lib/test/test_symtable.py
+++ b/Lib/test/test_symtable.py
@@ -157,6 +157,12 @@ class SymtableTest(unittest.TestCase):
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
index 0da5906..8e5e12d 100644
--- a/Lib/test/test_zipimport.py
+++ b/Lib/test/test_zipimport.py
@@ -600,6 +600,19 @@ class UncompressedZipImportTestCase(ImportHooksBaseTestCase):
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):
@@ -620,6 +633,8 @@ class BadFileZipImportTestCase(unittest.TestCase):
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
index 5dff4db..3c6d3ae 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -13,6 +13,10 @@ Core and Builtins
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 #27048: Prevents distutils failing on Windows when environment
variables contain non-ASCII characters
@@ -43,6 +47,13 @@ Library
- Issue #26930: Update Windows builds to use OpenSSL 1.0.2h.
+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.
+
+
What's New in Python 3.5.2 final?
=================================
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index f11a082..1fcc83e 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -3666,7 +3666,7 @@ PyUnicode_FSDecoder(PyObject* arg, void* addr)
output = arg;
Py_INCREF(output);
}
- else {
+ else if (PyObject_CheckBuffer(arg)) {
arg = PyBytes_FromObject(arg);
if (!arg)
return 0;
@@ -3681,6 +3681,12 @@ PyUnicode_FSDecoder(PyObject* arg, void* addr)
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;