Commit 3729d7de authored by Marc-André Lemburg's avatar Marc-André Lemburg

Fix to bug [ Bug #111860 ] file.writelines() crashes.

file.writelines() now tries to emulate the behaviour of file.write()
as closely as possible. Due to the problems with releasing the
interpreter lock the solution isn't exactly optimal, but still better
than not supporting the file.write() semantics at all.
parent e0862e40
......@@ -980,8 +980,7 @@ file_writelines(PyFileObject *f, PyObject *args)
line = PySequence_GetItem(args, index+j);
if (line == NULL) {
if (PyErr_ExceptionMatches(
PyExc_IndexError))
{
PyExc_IndexError)) {
PyErr_Clear();
break;
}
......@@ -989,23 +988,49 @@ file_writelines(PyFileObject *f, PyObject *args)
XXX We may lose some output. */
goto error;
}
if (!PyString_Check(line)) {
Py_DECREF(line);
PyErr_SetString(PyExc_TypeError,
"writelines() requires sequences of strings");
goto error;
}
PyList_SetItem(list, j, line);
}
}
if (j == 0)
break;
/* Check that all entries are indeed strings. If not,
apply the same rules as for file.write() and
convert the results to strings. This is slow, but
seems to be the only way since all conversion APIs
could potentially execute Python code. */
for (i = 0; i < j; i++) {
PyObject *v = PyList_GET_ITEM(list, i);
if (!PyString_Check(v)) {
const char *buffer;
int len;
if (((f->f_binary &&
PyObject_AsReadBuffer(v,
(const void**)&buffer,
&len)) ||
PyObject_AsCharBuffer(v,
&buffer,
&len))) {
PyErr_SetString(PyExc_TypeError,
"writelines() requires sequences of strings");
goto error;
}
line = PyString_FromStringAndSize(buffer,
len);
if (line == NULL)
goto error;
Py_DECREF(v);
PyList_SET_ITEM(list, i, v);
}
}
/* Since we are releasing the global lock, the
following code may *not* execute Python code. */
Py_BEGIN_ALLOW_THREADS
f->f_softspace = 0;
errno = 0;
for (i = 0; i < j; i++) {
line = PyList_GET_ITEM(list, i);
line = PyList_GET_ITEM(list, i);
len = PyString_GET_SIZE(line);
nwritten = fwrite(PyString_AS_STRING(line),
1, len, f->f_fp);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment