Change the zipimport implementation to accept files containing
arbitrary bytes before the actual zip compatible archive. Zipfiles containing comments at the end of the file are still not supported. Add a testcase to test_zipimport, and update NEWS. This closes sf #775637 and sf #669036.
This commit is contained in:
parent
fac083d14a
commit
354e3d90d3
|
@ -49,7 +49,7 @@ class UncompressedZipImportTestCase(ImportHooksBaseTestCase):
|
|||
zipimport._zip_directory_cache.clear()
|
||||
ImportHooksBaseTestCase.setUp(self)
|
||||
|
||||
def doTest(self, expected_ext, files, *modules):
|
||||
def doTest(self, expected_ext, files, *modules, **kw):
|
||||
z = ZipFile(TEMP_ZIP, "w")
|
||||
try:
|
||||
for name, (mtime, data) in files.items():
|
||||
|
@ -57,6 +57,19 @@ class UncompressedZipImportTestCase(ImportHooksBaseTestCase):
|
|||
zinfo.compress_type = self.compression
|
||||
z.writestr(zinfo, data)
|
||||
z.close()
|
||||
|
||||
stuff = kw.get("stuff", None)
|
||||
if stuff is not None:
|
||||
# Prepend 'stuff' to the start of the zipfile
|
||||
f = open(TEMP_ZIP, "rb")
|
||||
data = f.read()
|
||||
f.close()
|
||||
|
||||
f = open(TEMP_ZIP, "wb")
|
||||
f.write(stuff)
|
||||
f.write(data)
|
||||
f.close()
|
||||
|
||||
sys.path.insert(0, TEMP_ZIP)
|
||||
|
||||
mod = __import__(".".join(modules), globals(), locals(),
|
||||
|
@ -181,6 +194,12 @@ class UncompressedZipImportTestCase(ImportHooksBaseTestCase):
|
|||
"some.data": (NOW, "some data")}
|
||||
self.doTest(pyc_ext, files, TESTMOD)
|
||||
|
||||
def testImport_WithStuff(self):
|
||||
# try importing from a zipfile which contains additional
|
||||
# stuff at the beginning of the file
|
||||
files = {TESTMOD + ".py": (NOW, test_src)}
|
||||
self.doTest(".py", files, TESTMOD,
|
||||
stuff="Some Stuff"*31)
|
||||
|
||||
class CompressedZipImportTestCase(UncompressedZipImportTestCase):
|
||||
compression = ZIP_DEFLATED
|
||||
|
|
|
@ -12,6 +12,10 @@ What's New in Python 2.3 release candidate 2?
|
|||
Core and builtins
|
||||
-----------------
|
||||
|
||||
- It is now possible to import from zipfiles containing additional
|
||||
data bytes before the zip compatible archive. Zipfiles containing a
|
||||
comment at the end are still unsupported.
|
||||
|
||||
Extension modules
|
||||
-----------------
|
||||
|
||||
|
|
|
@ -655,11 +655,12 @@ read_directory(char *archive)
|
|||
PyObject *files = NULL;
|
||||
FILE *fp;
|
||||
long compress, crc, data_size, file_size, file_offset, date, time;
|
||||
long header_offset, name_size, header_size;
|
||||
long header_offset, name_size, header_size, header_position;
|
||||
long i, l, length, count;
|
||||
char path[MAXPATHLEN + 5];
|
||||
char name[MAXPATHLEN + 5];
|
||||
char *p, endof_central_dir[22];
|
||||
long arc_offset; /* offset from beginning of file to start of zip-archive */
|
||||
|
||||
if (strlen(archive) > MAXPATHLEN) {
|
||||
PyErr_SetString(PyExc_OverflowError,
|
||||
|
@ -675,6 +676,7 @@ read_directory(char *archive)
|
|||
return NULL;
|
||||
}
|
||||
fseek(fp, -22, SEEK_END);
|
||||
header_position = ftell(fp);
|
||||
if (fread(endof_central_dir, 1, 22, fp) != 22) {
|
||||
fclose(fp);
|
||||
PyErr_Format(ZipImportError, "can't read Zip file: "
|
||||
|
@ -689,7 +691,10 @@ read_directory(char *archive)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
header_size = get_long((unsigned char *)endof_central_dir + 12);
|
||||
header_offset = get_long((unsigned char *)endof_central_dir + 16);
|
||||
arc_offset = header_position - header_offset - header_size;
|
||||
header_offset += arc_offset;
|
||||
|
||||
files = PyDict_New();
|
||||
if (files == NULL)
|
||||
|
@ -720,7 +725,7 @@ read_directory(char *archive)
|
|||
PyMarshal_ReadShortFromFile(fp) +
|
||||
PyMarshal_ReadShortFromFile(fp);
|
||||
fseek(fp, header_offset + 42, 0);
|
||||
file_offset = PyMarshal_ReadLongFromFile(fp);
|
||||
file_offset = PyMarshal_ReadLongFromFile(fp) + arc_offset;
|
||||
if (name_size > MAXPATHLEN)
|
||||
name_size = MAXPATHLEN;
|
||||
|
||||
|
|
Loading…
Reference in New Issue