summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Heller <theller@ctypes.org>2003-07-22 18:10:15 (GMT)
committerThomas Heller <theller@ctypes.org>2003-07-22 18:10:15 (GMT)
commit354e3d90d346afdc6c70211b130aa76bb18e19ed (patch)
treee03da58869310f187315670c86523d4ce4b69763
parentfac083d14a94137999559d895a4e6d1d9a2ea74c (diff)
downloadcpython-354e3d90d346afdc6c70211b130aa76bb18e19ed.zip
cpython-354e3d90d346afdc6c70211b130aa76bb18e19ed.tar.gz
cpython-354e3d90d346afdc6c70211b130aa76bb18e19ed.tar.bz2
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.
-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;