Commits

Thomas Wouters committed 6860ba8

Backport trunk revision 53527:

SF patch #1630975: Fix crash when replacing sys.stdout in sitecustomize

When running the interpreter in an environment that would cause it to set
stdout/stderr/stdin's encoding, having a sitecustomize that would replace
them with something other than PyFile objects would crash the interpreter.
Fix it by simply ignoring the encoding-setting for non-files.

This could do with a test, but I can think of no maintainable and portable
way to test this bug, short of adding a sitecustomize.py to the buildsystem
and have it always run with it (hmmm....)

Comments (0)

Files changed (4)

 Core and builtins
 -----------------
 
+- patch #1630975: Fix crash when replacing sys.stdout in sitecustomize.py
+
 - Bug #1590891: random.randrange don't return correct value for big number
 
 - Bug #1542016: make sys.callstats() match its docstring and return an

Objects/fileobject.c

 {
 	PyFileObject *file = (PyFileObject*)f;
 	PyObject *str = PyString_FromString(enc);
+
+	assert(PyFile_Check(f));
 	if (!str)
 		return 0;
 	Py_DECREF(file->f_encoding);

Python/pythonrun.c

 		sys_isatty = PyObject_CallMethod(sys_stream, "isatty", "");
 		if (!sys_isatty)
 			PyErr_Clear();
-		if(sys_isatty && PyObject_IsTrue(sys_isatty)) {
+		if(sys_isatty && PyObject_IsTrue(sys_isatty) &&
+		   PyFile_Check(sys_stream)) {
 			if (!PyFile_SetEncoding(sys_stream, codeset))
 				Py_FatalError("Cannot set codeset of stdin");
 		}
 		sys_isatty = PyObject_CallMethod(sys_stream, "isatty", "");
 		if (!sys_isatty)
 			PyErr_Clear();
-		if(sys_isatty && PyObject_IsTrue(sys_isatty)) {
+		if(sys_isatty && PyObject_IsTrue(sys_isatty) &&
+		   PyFile_Check(sys_stream)) {
 			if (!PyFile_SetEncoding(sys_stream, codeset))
 				Py_FatalError("Cannot set codeset of stdout");
 		}

Python/sysmodule.c

 	if (PyErr_Occurred())
 		return NULL;
 #ifdef MS_WINDOWS
-	if(isatty(_fileno(stdin))){
+	if(isatty(_fileno(stdin)) && PyFile_Check(sysin)) {
 		sprintf(buf, "cp%d", GetConsoleCP());
 		if (!PyFile_SetEncoding(sysin, buf))
 			return NULL;
 	}
-	if(isatty(_fileno(stdout))) {
+	if(isatty(_fileno(stdout)) && PyFile_Check(sysout)) {
 		sprintf(buf, "cp%d", GetConsoleOutputCP());
 		if (!PyFile_SetEncoding(sysout, buf))
 			return NULL;