summaryrefslogtreecommitdiffstats
path: root/Objects/fileobject.c
diff options
context:
space:
mode:
authorSkip Montanaro <skip@pobox.com>2005-05-20 03:07:06 (GMT)
committerSkip Montanaro <skip@pobox.com>2005-05-20 03:07:06 (GMT)
commitbbf12ba7b20059324cf10e26aa98bc0fa405ad3d (patch)
treefde2a9dead8987c5ddffe6cab4a997322483b0ac /Objects/fileobject.c
parent7961aa6135e5a26c1cc14bbcaa2668d2ec98b0b9 (diff)
downloadcpython-bbf12ba7b20059324cf10e26aa98bc0fa405ad3d.zip
cpython-bbf12ba7b20059324cf10e26aa98bc0fa405ad3d.tar.gz
cpython-bbf12ba7b20059324cf10e26aa98bc0fa405ad3d.tar.bz2
Disallow opening files with modes 'aU' or 'wU' as specified by PEP
278. Closes bug 967182.
Diffstat (limited to 'Objects/fileobject.c')
-rw-r--r--Objects/fileobject.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/Objects/fileobject.c b/Objects/fileobject.c
index c08345c..7e40547 100644
--- a/Objects/fileobject.c
+++ b/Objects/fileobject.c
@@ -128,6 +128,54 @@ fill_file_fields(PyFileObject *f, FILE *fp, PyObject *name, char *mode,
return (PyObject *) f;
}
+/* check for known incorrect mode strings - problem is, platforms are
+ free to accept any mode characters they like and are supposed to
+ ignore stuff they don't understand... write or append mode with
+ universal newline support is expressly forbidden by PEP 278. */
+/* zero return is kewl - one is un-kewl */
+static int
+check_the_mode(char *mode)
+{
+ unsigned int len = strlen(mode);
+
+ switch (len) {
+ case 0:
+ PyErr_SetString(PyExc_ValueError, "empty mode string");
+ return 1;
+
+ /* reject wU, aU */
+ case 2:
+ switch (mode[0]) {
+ case 'w':
+ case 'a':
+ if (mode[1] == 'U') {
+ PyErr_SetString(PyExc_ValueError,
+ "invalid mode string");
+ return 1;
+ }
+ break;
+ }
+ break;
+
+ /* reject w+U, a+U, wU+, aU+ */
+ case 3:
+ switch (mode[0]) {
+ case 'w':
+ case 'a':
+ if ((mode[1] == '+' && mode[2] == 'U') ||
+ (mode[1] == 'U' && mode[2] == '+')) {
+ PyErr_SetString(PyExc_ValueError,
+ "invalid mode string");
+ return 1;
+ }
+ break;
+ }
+ break;
+ }
+
+ return 0;
+}
+
static PyObject *
open_the_file(PyFileObject *f, char *name, char *mode)
{
@@ -142,6 +190,9 @@ open_the_file(PyFileObject *f, char *name, char *mode)
assert(mode != NULL);
assert(f->f_fp == NULL);
+ if (check_the_mode(mode))
+ return NULL;
+
/* rexec.py can't stop a user from getting the file() constructor --
all they have to do is get *any* file object f, and then do
type(f). Here we prevent them from doing damage with it. */