summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorThomas Wouters <thomas@python.org>2006-02-12 11:53:32 (GMT)
committerThomas Wouters <thomas@python.org>2006-02-12 11:53:32 (GMT)
commitc45251a48542e0074ad9865143359bdfec0f8467 (patch)
tree7d61df776dd020be7437f505c1f7ef4cc1779f2c /Objects
parentf5b3e36493da275334e29afdbd238863697dca35 (diff)
downloadcpython-c45251a48542e0074ad9865143359bdfec0f8467.zip
cpython-c45251a48542e0074ad9865143359bdfec0f8467.tar.gz
cpython-c45251a48542e0074ad9865143359bdfec0f8467.tar.bz2
SF patch #1397960: When mixing file-iteration and
readline/readlines/read/readinto, loudly break by raising ValueError, rather than silently deliver data out of order or hitting EOF prematurely. Probably not a bugfix candidate, even though it affects no 'working' code.
Diffstat (limited to 'Objects')
-rw-r--r--Objects/fileobject.c41
1 files changed, 39 insertions, 2 deletions
diff --git a/Objects/fileobject.c b/Objects/fileobject.c
index b34dd52..6faabc3 100644
--- a/Objects/fileobject.c
+++ b/Objects/fileobject.c
@@ -344,6 +344,17 @@ err_closed(void)
return NULL;
}
+/* Refuse regular file I/O if there's data in the iteration-buffer.
+ * Mixing them would cause data to arrive out of order, as the read*
+ * methods don't use the iteration buffer. */
+static PyObject *
+err_iterbuffered(void)
+{
+ PyErr_SetString(PyExc_ValueError,
+ "Mixing iteration and read methods would lose data");
+ return NULL;
+}
+
static void drop_readahead(PyFileObject *);
/* Methods */
@@ -795,6 +806,11 @@ file_read(PyFileObject *f, PyObject *args)
if (f->f_fp == NULL)
return err_closed();
+ /* refuse to mix with f.next() */
+ if (f->f_buf != NULL &&
+ (f->f_bufend - f->f_bufptr) > 0 &&
+ f->f_buf[0] != '\0')
+ return err_iterbuffered();
if (!PyArg_ParseTuple(args, "|l:read", &bytesrequested))
return NULL;
if (bytesrequested < 0)
@@ -858,6 +874,11 @@ file_readinto(PyFileObject *f, PyObject *args)
if (f->f_fp == NULL)
return err_closed();
+ /* refuse to mix with f.next() */
+ if (f->f_buf != NULL &&
+ (f->f_bufend - f->f_bufptr) > 0 &&
+ f->f_buf[0] != '\0')
+ return err_iterbuffered();
if (!PyArg_ParseTuple(args, "w#", &ptr, &ntodo))
return NULL;
ndone = 0;
@@ -1211,9 +1232,15 @@ PyFile_GetLine(PyObject *f, int n)
}
if (PyFile_Check(f)) {
- if (((PyFileObject*)f)->f_fp == NULL)
+ PyFileObject *fo = (PyFileObject *)f;
+ if (fo->f_fp == NULL)
return err_closed();
- result = get_line((PyFileObject *)f, n);
+ /* refuse to mix with f.next() */
+ if (fo->f_buf != NULL &&
+ (fo->f_bufend - fo->f_bufptr) > 0 &&
+ fo->f_buf[0] != '\0')
+ return err_iterbuffered();
+ result = get_line(fo, n);
}
else {
PyObject *reader;
@@ -1296,6 +1323,11 @@ file_readline(PyFileObject *f, PyObject *args)
if (f->f_fp == NULL)
return err_closed();
+ /* refuse to mix with f.next() */
+ if (f->f_buf != NULL &&
+ (f->f_bufend - f->f_bufptr) > 0 &&
+ f->f_buf[0] != '\0')
+ return err_iterbuffered();
if (!PyArg_ParseTuple(args, "|i:readline", &n))
return NULL;
if (n == 0)
@@ -1324,6 +1356,11 @@ file_readlines(PyFileObject *f, PyObject *args)
if (f->f_fp == NULL)
return err_closed();
+ /* refuse to mix with f.next() */
+ if (f->f_buf != NULL &&
+ (f->f_bufend - f->f_bufptr) > 0 &&
+ f->f_buf[0] != '\0')
+ return err_iterbuffered();
if (!PyArg_ParseTuple(args, "|l:readlines", &sizehint))
return NULL;
if ((list = PyList_New(0)) == NULL)