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.
This commit is contained in:
Just van Rossum 2003-01-03 11:18:56 +00:00
parent 1618cedfac
commit 9a3129c148
2 changed files with 22 additions and 15 deletions

View file

@ -56,6 +56,7 @@ class UncompressedZipImportTestCase(ImportHooksBaseTestCase):
mod = __import__(".".join(modules), globals(), locals(), mod = __import__(".".join(modules), globals(), locals(),
["__dummy__"]) ["__dummy__"])
if expected_ext:
file = mod.get_file() file = mod.get_file()
self.assertEquals(file, os.path.join(TEMP_ZIP, self.assertEquals(file, os.path.join(TEMP_ZIP,
os.sep.join(modules) + expected_ext)) os.sep.join(modules) + expected_ext))
@ -101,6 +102,10 @@ class UncompressedZipImportTestCase(ImportHooksBaseTestCase):
TESTMOD + pyc_ext: (NOW, test_pyc)} TESTMOD + pyc_ext: (NOW, test_pyc)}
self.doTest(pyc_ext, files, TESTMOD) self.doTest(pyc_ext, files, TESTMOD)
def testEmptyPy(self):
files = {TESTMOD + ".py": (NOW, "")}
self.doTest(None, files, TESTMOD)
def testBadMagic(self): def testBadMagic(self):
# make pyc magic word invalid, forcing loading from .py # make pyc magic word invalid, forcing loading from .py
m0 = ord(test_pyc[0]) m0 = ord(test_pyc[0])

View file

@ -906,7 +906,8 @@ unmarshal_code(char *pathname, PyObject *data, time_t mtime)
return Py_None; /* signal caller to try alternative */ 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) if (Py_VerboseFlag)
PySys_WriteStderr("# %s has bad mtime\n", PySys_WriteStderr("# %s has bad mtime\n",
pathname); pathname);
@ -934,23 +935,23 @@ unmarshal_code(char *pathname, PyObject *data, time_t mtime)
static PyObject * static PyObject *
normalize_line_endings(PyObject *source) normalize_line_endings(PyObject *source)
{ {
char *q, *p = PyString_AsString(source); char *buf, *q, *p = PyString_AsString(source);
int length = PyString_Size(source) + 1;
PyObject *fixed_source; PyObject *fixed_source;
fixed_source = PyString_FromStringAndSize(p, length); /* one char extra for trailing \n and one for terminating \0 */
if (fixed_source == NULL) buf = PyMem_Malloc(PyString_Size(source) + 2);
if (buf == NULL) {
PyErr_SetString(PyExc_MemoryError,
"zipimport: no memory to allocate "
"source buffer");
return NULL; return NULL;
}
q = PyString_AsString(fixed_source);
/* replace "\r\n?" by "\n" */ /* replace "\r\n?" by "\n" */
for (;;) { for (q = buf;;) {
if (*p == '\r') { if (*p == '\r') {
*q++ = '\n'; *q++ = '\n';
if (*(p + 1) == '\n') { if (*(p + 1) == '\n')
p++; p++;
length--;
}
} }
else else
*q++ = *p; *q++ = *p;
@ -960,7 +961,8 @@ normalize_line_endings(PyObject *source)
} }
*q++ = '\n'; /* add trailing \n */ *q++ = '\n'; /* add trailing \n */
*q = '\0'; *q = '\0';
_PyString_Resize(&fixed_source, length); fixed_source = PyString_FromString(buf);
PyMem_Free(buf);
return fixed_source; return fixed_source;
} }