Fix for bug #661136
authorJust van Rossum <just@letterror.com>
Fri, 3 Jan 2003 11:18:56 +0000 (11:18 +0000)
committerJust van Rossum <just@letterror.com>
Fri, 3 Jan 2003 11:18:56 +0000 (11:18 +0000)
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
Modules/zipimport.c

index 5f6d8ef056854706432fec9fba0fba672896b059..3c790eb4deaa501926c765a6471f9951e3821615 100644 (file)
@@ -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])
index b12f1ab4637bb71901e8bddaf2a59378232de6ef..159a6b089522cec40608dcae2ffef15e1421087c 100644 (file)
@@ -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;
 }