Author: Ronan Lamy <[email protected]>
Branch: py3.5
Changeset: r93235:e6985c577de2
Date: 2017-12-01 21:16 +0000
http://bitbucket.org/pypy/pypy/changeset/e6985c577de2/
Log: Fix handling of arguments containing null bytes in zipimporter
methods
diff --git a/pypy/module/imp/importing.py b/pypy/module/imp/importing.py
--- a/pypy/module/imp/importing.py
+++ b/pypy/module/imp/importing.py
@@ -292,7 +292,7 @@
ext + PYC_TAG + '.pyc')
return result
-#@signature(types.str0(), returns=types.str0())
+@signature(types.str0(), returns=types.any())
def make_source_pathname(pathname):
"Given the path to a .pyc file, return the path to its .py file."
# (...)/__pycache__/foo.<tag>.pyc -> (...)/foo.py
diff --git a/pypy/module/zipimport/interp_zipimport.py
b/pypy/module/zipimport/interp_zipimport.py
--- a/pypy/module/zipimport/interp_zipimport.py
+++ b/pypy/module/zipimport/interp_zipimport.py
@@ -1,6 +1,15 @@
import os
import stat
+from rpython.annotator.model import s_Str0
+from rpython.rlib.objectmodel import enforceargs
+from rpython.rlib.unroll import unrolling_iterable
+from rpython.rlib.rzipfile import RZipFile, BadZipfile
+from rpython.rlib.rzlib import RZlibError
+from rpython.rlib.rstring import assert_str0
+from rpython.rlib.signature import signature, finishsigs
+from rpython.rlib import types
+
from pypy.interpreter.baseobjspace import W_Root
from pypy.interpreter.error import OperationError, oefmt
from pypy.interpreter.gateway import interp2app, unwrap_spec
@@ -8,9 +17,6 @@
from pypy.interpreter.module import Module
from pypy.module.imp import importing
from pypy.module.zlib.interp_zlib import zlib_error
-from rpython.rlib.unroll import unrolling_iterable
-from rpython.rlib.rzipfile import RZipFile, BadZipfile
-from rpython.rlib.rzlib import RZlibError
ZIPSEP = '/'
# note that zipfiles always use slash, but for OSes with other
@@ -116,6 +122,7 @@
zip_cache = W_ZipCache()
+@finishsigs
class W_ZipImporter(W_Root):
def __init__(self, space, name, filename, zip_file, prefix):
self.space = space
@@ -138,12 +145,14 @@
filename = filename.replace(os.path.sep, ZIPSEP)
return filename
+ @signature(types.self(), types.str0(), returns=types.str0())
def corr_zname(self, fname):
if ZIPSEP != os.path.sep:
return fname.replace(ZIPSEP, os.path.sep)
else:
return fname
+ @enforceargs(filename=s_Str0, typecheck=False)
def import_py_file(self, space, modname, filename, buf, pkgpath):
w_mod = Module(space, space.newtext(modname))
real_name = self.filename + os.path.sep + self.corr_zname(filename)
@@ -194,20 +203,21 @@
return False
return True
+ @enforceargs(filename=s_Str0, typecheck=False)
def import_pyc_file(self, space, modname, filename, buf, pkgpath):
magic = importing._get_long(buf[:4])
timestamp = importing._get_long(buf[4:8])
if not self.can_use_pyc(space, filename, magic, timestamp):
return None
# zipimport ignores the size field
- buf = buf[12:] # XXX ugly copy, should use sequential read instead
+ buf = buf[12:] # XXX ugly copy, should use sequential read instead
w_mod = Module(space, space.newtext(modname))
real_name = self.filename + os.path.sep + self.corr_zname(filename)
space.setattr(w_mod, space.newtext('__loader__'), self)
importing._prepare_module(space, w_mod, real_name, pkgpath)
- result = importing.load_compiled_module(space, space.newtext(modname),
w_mod,
- real_name, magic, timestamp,
- buf)
+ result = importing.load_compiled_module(
+ space, space.newtext(modname),
+ w_mod, real_name, magic, timestamp, buf)
return result
def have_modulefile(self, space, filename):
@@ -227,14 +237,14 @@
return self
def make_filename(self, fullname):
- startpos = fullname.rfind('.') + 1 # 0 when not found
+ startpos = fullname.rfind('.') + 1 # 0 when not found
assert startpos >= 0
subname = fullname[startpos:]
if ZIPSEP == os.path.sep:
return self.prefix + subname.replace('.', '/')
else:
- return self.prefix.replace(os.path.sep, ZIPSEP) + \
- subname.replace('.', '/')
+ return (self.prefix.replace(os.path.sep, ZIPSEP) +
+ subname.replace('.', '/'))
def make_co_filename(self, filename):
"""
@@ -248,6 +258,12 @@
fullname = space.text_w(w_fullname)
filename = self.make_filename(fullname)
for compiled, is_package, ext in ENUMERATE_EXTS:
+ if '\x00' in filename:
+ # Special case to make the annotator happy:
+ # filenames inside ZIPs shouldn't contain NULs so no module can
+ # possibly be found in this case
+ break
+ filename = assert_str0(filename)
fname = filename + ext
try:
buf = self.zip_file.read(fname)
@@ -302,6 +318,12 @@
fullname = space.text_w(w_fullname)
filename = self.make_filename(fullname)
for compiled, _, ext in ENUMERATE_EXTS:
+ if '\x00' in filename:
+ # Special case to make the annotator happy:
+ # filenames inside ZIPs shouldn't contain NULs so no module can
+ # possibly be found in this case
+ break
+ filename = assert_str0(filename)
if self.have_modulefile(space, filename + ext):
w_source = self.get_data(space, filename + ext)
source = space.bytes_w(w_source)
@@ -328,6 +350,12 @@
filename = self.make_filename(fullname)
found = False
for compiled, _, ext in ENUMERATE_EXTS:
+ if '\x00' in filename:
+ # Special case to make the annotator happy:
+ # filenames inside ZIPs shouldn't contain NULs so no module can
+ # possibly be found in this case
+ break
+ filename = assert_str0(filename)
fname = filename + ext
if self.have_modulefile(space, fname):
if not compiled:
@@ -349,6 +377,12 @@
fullname = space.text_w(w_fullname)
filename = self.make_filename(fullname)
for _, is_package, ext in ENUMERATE_EXTS:
+ if '\x00' in filename:
+ # Special case to make the annotator happy:
+ # filenames inside ZIPs shouldn't contain NULs so no module can
+ # possibly be found in this case
+ break
+ filename = assert_str0(filename)
if self.have_modulefile(space, filename + ext):
return space.newfilename(self.filename + os.path.sep +
self.corr_zname(filename + ext))
@@ -361,6 +395,12 @@
fullname = space.text_w(w_fullname)
filename = self.make_filename(fullname)
for _, is_package, ext in ENUMERATE_EXTS:
+ if '\x00' in filename:
+ # Special case to make the annotator happy:
+ # filenames inside ZIPs shouldn't contain NULs so no module can
+ # possibly be found in this case
+ break
+ filename = assert_str0(filename)
if self.have_modulefile(space, filename + ext):
return space.newbool(is_package)
raise oefmt(get_error(space),
@@ -373,7 +413,14 @@
return space.newfilename(self.filename)
def _find_loader(self, space, fullname):
+ if '\x00' in fullname:
+ # Special case to make the annotator happy:
+ # filenames inside ZIPs shouldn't contain NULs so no module can
+ # possibly be found in this case
+ return False, None
+ fullname = assert_str0(fullname)
filename = self.make_filename(fullname)
+ filename = assert_str0(filename)
for _, _, ext in ENUMERATE_EXTS:
if self.have_modulefile(space, filename + ext):
return True, None
diff --git a/pypy/module/zipimport/test/test_zipimport.py
b/pypy/module/zipimport/test/test_zipimport.py
--- a/pypy/module/zipimport/test/test_zipimport.py
+++ b/pypy/module/zipimport/test/test_zipimport.py
@@ -394,10 +394,19 @@
assert z.get_code('ä')
raises(ImportError, z.get_code, 'xx')
mod = z.load_module('ä')
+ #assert z.load_module('ä') is mod
assert z.get_filename('ä') == mod.__file__
raises(ImportError, z.load_module, 'xx')
raises(ImportError, z.get_filename, 'xx')
assert z.archive == self.zipfile
+ # PyPy fix: check null byte behavior:
+ import sys
+ if '__pypy__' in sys.builtin_module_names:
+ raises(ImportError, z.is_package, 'ä\0 b')
+ raises(ImportError, z.get_source, 'ä\0 b')
+ raises(ImportError, z.get_code, 'ä\0 b')
+ raises(ImportError, z.load_module, 'ä\0 b')
+ raises(ImportError, z.get_filename, 'ä\0 b')
def test_co_filename(self):
self.writefile('mymodule.py', """
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit