summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/test/test_zipimport.py21
-rw-r--r--Misc/NEWS4
-rw-r--r--Modules/zipimport.c9
3 files changed, 31 insertions, 3 deletions
diff --git a/Lib/test/test_zipimport.py b/Lib/test/test_zipimport.py
index 26a2f1f..86acdd2 100644
--- a/Lib/test/test_zipimport.py
+++ b/Lib/test/test_zipimport.py
@@ -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
diff --git a/Misc/NEWS b/Misc/NEWS
index 7ba1218..af56c77 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -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
-----------------
diff --git a/Modules/zipimport.c b/Modules/zipimport.c
index 1c95d5a..afcd421 100644
--- a/Modules/zipimport.c
+++ b/Modules/zipimport.c
@@ -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;