mirror of
https://github.com/python/cpython.git
synced 2025-12-05 00:52:25 +00:00
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
2 changed files with 22 additions and 15 deletions
|
|
@ -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])
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue