diff options
author | Thomas Wouters <thomas@python.org> | 2006-02-12 11:53:32 (GMT) |
---|---|---|
committer | Thomas Wouters <thomas@python.org> | 2006-02-12 11:53:32 (GMT) |
commit | c45251a48542e0074ad9865143359bdfec0f8467 (patch) | |
tree | 7d61df776dd020be7437f505c1f7ef4cc1779f2c /Objects | |
parent | f5b3e36493da275334e29afdbd238863697dca35 (diff) | |
download | cpython-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.c | 41 |
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) |