Commit 354e3d90 authored by Thomas Heller's avatar Thomas Heller

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.
parent fac083d1
......@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment