Disallow opening files with modes 'aU' or 'wU' as specified by PEP

278. Closes bug 967182.
This commit is contained in:
Skip Montanaro 2005-05-20 03:07:06 +00:00
parent 7961aa6135
commit bbf12ba7b2
3 changed files with 64 additions and 0 deletions

View file

@ -40,6 +40,16 @@
raise TestFailed('expected exception setting file attr %r' % attr)
f.close()
# check invalid mode strings
for mode in ("", "aU", "wU+"):
try:
f = file(TESTFN, mode)
except ValueError:
pass
else:
f.close()
raise TestFailed('%r is an invalid file mode' % mode)
# verify writelines with instance sequence
l = UserList(['1', '2'])
f = open(TESTFN, 'wb')

View file

@ -12,6 +12,9 @@ What's New in Python 2.5 alpha 1?
Core and builtins
-----------------
- bug #967182: disallow opening files with 'wU' or 'aU' as specified by PEP
278.
- patch #1109424: int, long, float, complex, and unicode now check for the
proper magic slot for type conversions when subclassed. Previously the
magic slot was ignored during conversion. Semantics now match the way

View file

@ -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. */