summaryrefslogtreecommitdiffstats
path: root/Objects/fileobject.c
diff options
context:
space:
mode:
authorAntoine Pitrou <solipsis@pitrou.net>2010-02-05 17:11:32 (GMT)
committerAntoine Pitrou <solipsis@pitrou.net>2010-02-05 17:11:32 (GMT)
commit2483728850cc3c12920d7794ac01a3e890995622 (patch)
tree8ff5e130979103dda76979f4fa5e962ddf266a08 /Objects/fileobject.c
parent6e127db0ed5288f1917bb166b561bd601fcc51c6 (diff)
downloadcpython-2483728850cc3c12920d7794ac01a3e890995622.zip
cpython-2483728850cc3c12920d7794ac01a3e890995622.tar.gz
cpython-2483728850cc3c12920d7794ac01a3e890995622.tar.bz2
Merged revisions 77989 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r77989 | antoine.pitrou | 2010-02-05 18:05:54 +0100 (ven., 05 févr. 2010) | 6 lines Issue #5677: Explicitly forbid write operations on read-only file objects, and read operations on write-only file objects. On Windows, the system C library would return a bogus result; on Solaris, it was possible to crash the interpreter. Patch by Stefan Krah. ........
Diffstat (limited to 'Objects/fileobject.c')
-rw-r--r--Objects/fileobject.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/Objects/fileobject.c b/Objects/fileobject.c
index e01f38e..52d8120 100644
--- a/Objects/fileobject.c
+++ b/Objects/fileobject.c
@@ -173,6 +173,13 @@ fill_file_fields(PyFileObject *f, FILE *fp, PyObject *name, char *mode,
f->f_encoding = Py_None;
Py_INCREF(Py_None);
f->f_errors = Py_None;
+ f->readable = f->writable = 0;
+ if (strchr(mode, 'r') != NULL || f->f_univ_newline)
+ f->readable = 1;
+ if (strchr(mode, 'w') != NULL || strchr(mode, 'a') != NULL)
+ f->writable = 1;
+ if (strchr(mode, '+') != NULL)
+ f->readable = f->writable = 1;
if (f->f_mode == NULL)
return NULL;
@@ -487,6 +494,13 @@ err_closed(void)
return NULL;
}
+static PyObject *
+err_mode(char *action)
+{
+ PyErr_Format(PyExc_IOError, "File not open for %s", action);
+ 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. */
@@ -701,6 +715,8 @@ file_truncate(PyFileObject *f, PyObject *args)
if (f->f_fp == NULL)
return err_closed();
+ if (!f->writable)
+ return err_mode("writing");
if (!PyArg_UnpackTuple(args, "truncate", 0, 1, &newsizeobj))
return NULL;
@@ -949,6 +965,8 @@ file_read(PyFileObject *f, PyObject *args)
if (f->f_fp == NULL)
return err_closed();
+ if (!f->readable)
+ return err_mode("reading");
/* refuse to mix with f.next() */
if (f->f_buf != NULL &&
(f->f_bufend - f->f_bufptr) > 0 &&
@@ -1018,6 +1036,8 @@ file_readinto(PyFileObject *f, PyObject *args)
if (f->f_fp == NULL)
return err_closed();
+ if (!f->readable)
+ return err_mode("reading");
/* refuse to mix with f.next() */
if (f->f_buf != NULL &&
(f->f_bufend - f->f_bufptr) > 0 &&
@@ -1389,6 +1409,8 @@ PyFile_GetLine(PyObject *f, int n)
PyFileObject *fo = (PyFileObject *)f;
if (fo->f_fp == NULL)
return err_closed();
+ if (!fo->readable)
+ return err_mode("reading");
/* refuse to mix with f.next() */
if (fo->f_buf != NULL &&
(fo->f_bufend - fo->f_bufptr) > 0 &&
@@ -1477,6 +1499,8 @@ file_readline(PyFileObject *f, PyObject *args)
if (f->f_fp == NULL)
return err_closed();
+ if (!f->readable)
+ return err_mode("reading");
/* refuse to mix with f.next() */
if (f->f_buf != NULL &&
(f->f_bufend - f->f_bufptr) > 0 &&
@@ -1510,6 +1534,8 @@ file_readlines(PyFileObject *f, PyObject *args)
if (f->f_fp == NULL)
return err_closed();
+ if (!f->readable)
+ return err_mode("reading");
/* refuse to mix with f.next() */
if (f->f_buf != NULL &&
(f->f_bufend - f->f_bufptr) > 0 &&
@@ -1628,6 +1654,8 @@ file_write(PyFileObject *f, PyObject *args)
Py_ssize_t n, n2;
if (f->f_fp == NULL)
return err_closed();
+ if (!f->writable)
+ return err_mode("writing");
if (f->f_binary) {
if (!PyArg_ParseTuple(args, "s*", &pbuf))
return NULL;
@@ -1665,6 +1693,8 @@ file_writelines(PyFileObject *f, PyObject *seq)
assert(seq != NULL);
if (f->f_fp == NULL)
return err_closed();
+ if (!f->writable)
+ return err_mode("writing");
result = NULL;
list = NULL;
@@ -2105,6 +2135,8 @@ file_iternext(PyFileObject *f)
if (f->f_fp == NULL)
return err_closed();
+ if (!f->readable)
+ return err_mode("reading");
l = readahead_get_line_skip(f, 0, READAHEAD_BUFSIZE);
if (l == NULL || PyString_GET_SIZE(l) == 0) {