Merge change 54982 from the trunk. This fixes the test_subprocess test in the testsuite for VisualStudio2005 builds, by "sanitizing" the "mode" that is used in the posixmodule's fdopen(). In particular the non-standard "U" mode character is removed.

This commit is contained in:
Kristján Valur Jónsson 2007-05-07 19:25:38 +00:00
parent dffe9a214b
commit a1392d5ace
3 changed files with 26 additions and 14 deletions

View File

@ -57,6 +57,11 @@ PyAPI_DATA(const char *) Py_FileSystemDefaultEncoding;
char *Py_UniversalNewlineFgets(char *, int, FILE*, PyObject *);
size_t Py_UniversalNewlineFread(char *, size_t, FILE *, PyObject *);
/* A routine to do sanity checking on the file mode string. returns
non-zero on if an exception occurred
*/
int _PyFile_SanitizeMode(char *mode);
#ifdef __cplusplus
}
#endif

View File

@ -6170,16 +6170,23 @@ static PyObject *
posix_fdopen(PyObject *self, PyObject *args)
{
int fd;
char *mode = "r";
char *orgmode = "r";
int bufsize = -1;
FILE *fp;
PyObject *f;
if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
char *mode;
if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize))
return NULL;
if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
PyErr_Format(PyExc_ValueError,
"invalid file mode '%s'", mode);
/* Sanitize mode. See fileobject.c */
mode = PyMem_MALLOC(strlen(orgmode)+3);
if (!mode) {
PyErr_NoMemory();
return NULL;
}
strcpy(mode, orgmode);
if (_PyFile_SanitizeMode(mode)) {
PyMem_FREE(mode);
return NULL;
}
Py_BEGIN_ALLOW_THREADS
@ -6200,10 +6207,11 @@ posix_fdopen(PyObject *self, PyObject *args)
#else
fp = fdopen(fd, mode);
#endif
PyMem_FREE(mode);
Py_END_ALLOW_THREADS
if (fp == NULL)
return posix_error();
f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
f = PyFile_FromFile(fp, "<fdopen>", orgmode, fclose);
if (f != NULL)
PyFile_SetBufSize(f, bufsize);
return f;

View File

@ -139,17 +139,16 @@ fill_file_fields(PyFileObject *f, FILE *fp, PyObject *name, char *mode,
ignore stuff they don't understand... write or append mode with
universal newline support is expressly forbidden by PEP 278.
Additionally, remove the 'U' from the mode string as platforms
won't know what it is. */
/* zero return is kewl - one is un-kewl */
static int
sanitize_the_mode(char *mode)
won't know what it is. Non-zero return signals an exception */
int
_PyFile_SanitizeMode(char *mode)
{
char *upos;
size_t len = strlen(mode);
if (!len) {
PyErr_SetString(PyExc_ValueError, "empty mode string");
return 1;
return -1;
}
upos = strchr(mode, 'U');
@ -160,7 +159,7 @@ sanitize_the_mode(char *mode)
PyErr_Format(PyExc_ValueError, "universal newline "
"mode can only be used with modes "
"starting with 'r'");
return 1;
return -1;
}
if (mode[0] != 'r') {
@ -175,7 +174,7 @@ sanitize_the_mode(char *mode)
} else if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
PyErr_Format(PyExc_ValueError, "mode string must begin with "
"one of 'r', 'w', 'a' or 'U', not '%.200s'", mode);
return 1;
return -1;
}
return 0;
@ -204,7 +203,7 @@ open_the_file(PyFileObject *f, char *name, char *mode)
}
strcpy(newmode, mode);
if (sanitize_the_mode(newmode)) {
if (_PyFile_SanitizeMode(newmode)) {
f = NULL;
goto cleanup;
}