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.
This commit is contained in:
parent
1618cedfac
commit
9a3129c148
|
@ -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])
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue