diff options
author | Skip Montanaro <skip@pobox.com> | 2005-05-20 03:07:06 (GMT) |
---|---|---|
committer | Skip Montanaro <skip@pobox.com> | 2005-05-20 03:07:06 (GMT) |
commit | bbf12ba7b20059324cf10e26aa98bc0fa405ad3d (patch) | |
tree | fde2a9dead8987c5ddffe6cab4a997322483b0ac /Objects | |
parent | 7961aa6135e5a26c1cc14bbcaa2668d2ec98b0b9 (diff) | |
download | cpython-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')
-rw-r--r-- | Objects/fileobject.c | 51 |
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. */ |