diff --git a/Lib/test/test_file.py b/Lib/test/test_file.py index b4f494ba96a..a134a89c057 100644 --- a/Lib/test/test_file.py +++ b/Lib/test/test_file.py @@ -154,7 +154,7 @@ def testModeStrings(self): for name in (TESTFN, unicode(TESTFN), unicode(TESTFN + '\t')): try: f = open(name, "rr") - except IOError: + except (IOError, ValueError): pass else: f.close() diff --git a/Modules/timemodule.c b/Modules/timemodule.c index e8de2c5706e..2f4092d64e1 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -470,6 +470,23 @@ time_strftime(PyObject *self, PyObject *args) return NULL; } +#ifdef MS_WINDOWS + /* check that the format string contains only valid directives */ + for(outbuf = strchr(fmt, '%'); + outbuf != NULL; + outbuf = strchr(outbuf+2, '%')) + { + if (outbuf[1]=='#') + ++outbuf; /* not documented by python, */ + if (outbuf[1]=='\0' || + !strchr("aAbBcdfHIjmMpSUwWxXyYzZ%", outbuf[1])) + { + PyErr_SetString(PyExc_ValueError, "Invalid format string"); + return 0; + } + } +#endif + fmtlen = strlen(fmt); /* I hate these functions that presume you know how big the output diff --git a/Objects/fileobject.c b/Objects/fileobject.c index e01f38efdd0..77724d49421 100644 --- a/Objects/fileobject.c +++ b/Objects/fileobject.c @@ -181,6 +181,87 @@ fill_file_fields(PyFileObject *f, FILE *fp, PyObject *name, char *mode, return (PyObject *) f; } +#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__) +#define Py_VERIFY_WINNT +/* The CRT on windows compiled with Visual Studio 2005 and higher may + * assert if given invalid mode strings. This is all fine and well + * in static languages like C where the mode string is typcially hard + * coded. But in Python, were we pass in the mode string from the user, + * we need to verify it first manually + */ +static int _PyVerify_Mode_WINNT(const char *mode) +{ + /* See if mode string is valid on Windows to avoid hard assertions */ + /* remove leading spacese */ + int singles = 0; + int pairs = 0; + int encoding = 0; + const char *s, *c; + + while(*mode == ' ') /* strip initial spaces */ + ++mode; + if (!strchr("rwa", *mode)) /* must start with one of these */ + return 0; + while (*++mode) { + if (*mode == ' ' || *mode == 'N') /* ignore spaces and N */ + continue; + s = "+TD"; /* each of this can appear only once */ + c = strchr(s, *mode); + if (c) { + ptrdiff_t idx = s-c; + if (singles & (1<