From 9a3129c14866f21ce3cee053c085db374cb61b78 Mon Sep 17 00:00:00 2001 From: Just van Rossum Date: Fri, 3 Jan 2003 11:18:56 +0000 Subject: Fix for bug #661136 Lesson learned: kids should not be allowed to use API's starting with an underscore :-/ zipimport in 2.3a1 is even more broken than I thought: I attemped to _PyString_Resize a string created by PyString_FromStringAndSize, which fails for strings with length 0 or 1 since the latter returns an interned string in those cases. This would cause a SystemError with empty source files (and no matching pyc) in the zip archive. I rewrote the offending code to simply allocate a new buffer and avoid _PyString_Resize altogether. Added a test that would've caught the problem. --- Lib/test/test_zipimport.py | 11 ++++++++--- Modules/zipimport.c | 26 ++++++++++++++------------ 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/Lib/test/test_zipimport.py b/Lib/test/test_zipimport.py index 5f6d8ef..3c790eb 100644 --- a/Lib/test/test_zipimport.py +++ b/Lib/test/test_zipimport.py @@ -56,9 +56,10 @@ class UncompressedZipImportTestCase(ImportHooksBaseTestCase): mod = __import__(".".join(modules), globals(), locals(), ["__dummy__"]) - file = mod.get_file() - self.assertEquals(file, os.path.join(TEMP_ZIP, - os.sep.join(modules) + expected_ext)) + if expected_ext: + file = mod.get_file() + self.assertEquals(file, os.path.join(TEMP_ZIP, + os.sep.join(modules) + expected_ext)) finally: z.close() os.remove(TEMP_ZIP) @@ -101,6 +102,10 @@ class UncompressedZipImportTestCase(ImportHooksBaseTestCase): TESTMOD + pyc_ext: (NOW, test_pyc)} self.doTest(pyc_ext, files, TESTMOD) + def testEmptyPy(self): + files = {TESTMOD + ".py": (NOW, "")} + self.doTest(None, files, TESTMOD) + def testBadMagic(self): # make pyc magic word invalid, forcing loading from .py m0 = ord(test_pyc[0]) diff --git a/Modules/zipimport.c b/Modules/zipimport.c index b12f1ab..159a6b0 100644 --- a/Modules/zipimport.c +++ b/Modules/zipimport.c @@ -906,7 +906,8 @@ unmarshal_code(char *pathname, PyObject *data, time_t mtime) return Py_None; /* signal caller to try alternative */ } - if (mtime != 0 && !eq_mtime(get_long((unsigned char *)buf + 4), mtime)) { + if (mtime != 0 && !eq_mtime(get_long((unsigned char *)buf + 4), + mtime)) { if (Py_VerboseFlag) PySys_WriteStderr("# %s has bad mtime\n", pathname); @@ -934,23 +935,23 @@ unmarshal_code(char *pathname, PyObject *data, time_t mtime) static PyObject * normalize_line_endings(PyObject *source) { - char *q, *p = PyString_AsString(source); - int length = PyString_Size(source) + 1; + char *buf, *q, *p = PyString_AsString(source); PyObject *fixed_source; - fixed_source = PyString_FromStringAndSize(p, length); - if (fixed_source == NULL) + /* one char extra for trailing \n and one for terminating \0 */ + buf = PyMem_Malloc(PyString_Size(source) + 2); + if (buf == NULL) { + PyErr_SetString(PyExc_MemoryError, + "zipimport: no memory to allocate " + "source buffer"); return NULL; - - q = PyString_AsString(fixed_source); + } /* replace "\r\n?" by "\n" */ - for (;;) { + for (q = buf;;) { if (*p == '\r') { *q++ = '\n'; - if (*(p + 1) == '\n') { + if (*(p + 1) == '\n') p++; - length--; - } } else *q++ = *p; @@ -960,7 +961,8 @@ normalize_line_endings(PyObject *source) } *q++ = '\n'; /* add trailing \n */ *q = '\0'; - _PyString_Resize(&fixed_source, length); + fixed_source = PyString_FromString(buf); + PyMem_Free(buf); return fixed_source; } -- cgit v0.12