Patch #788249: Pass an explicit buffer to setvbuf in PyFile_SetBufSize().
Fixes #603724. Will backport to 2.3.
diff --git a/Objects/fileobject.c b/Objects/fileobject.c
index 13354c8..bddd81e 100644
--- a/Objects/fileobject.c
+++ b/Objects/fileobject.c
@@ -283,25 +283,37 @@
 void
 PyFile_SetBufSize(PyObject *f, int bufsize)
 {
+	PyFileObject *file = (PyFileObject *)f;
 	if (bufsize >= 0) {
-#ifdef HAVE_SETVBUF
 		int type;
 		switch (bufsize) {
 		case 0:
 			type = _IONBF;
 			break;
+#ifdef HAVE_SETVBUF
 		case 1:
 			type = _IOLBF;
 			bufsize = BUFSIZ;
 			break;
+#endif
 		default:
 			type = _IOFBF;
+#ifndef HAVE_SETVBUF
+			bufsize = BUFSIZ;
+#endif
+			break;
 		}
-		setvbuf(((PyFileObject *)f)->f_fp, (char *)NULL,
-			type, bufsize);
+		fflush(file->f_fp);
+		if (type == _IONBF) {
+			PyMem_Free(file->f_setbuf);
+			file->f_setbuf = NULL;
+		} else {
+			file->f_setbuf = PyMem_Realloc(file->f_setbuf, bufsize);
+		}
+#ifdef HAVE_SETVBUF
+		setvbuf(file->f_fp, file->f_setbuf, type, bufsize);
 #else /* !HAVE_SETVBUF */
-		if (bufsize <= 1)
-			setbuf(((PyFileObject *)f)->f_fp, (char *)NULL);
+		setbuf(file->f_fp, file->f_setbuf);
 #endif /* !HAVE_SETVBUF */
 	}
 }
@@ -376,6 +388,7 @@
 file_close(PyFileObject *f)
 {
 	int sts = 0;
+	PyMem_Free(f->f_setbuf);
 	if (f->f_fp != NULL) {
 		if (f->f_close != NULL) {
 			Py_BEGIN_ALLOW_THREADS
@@ -1928,6 +1941,7 @@
 	}
 	if (open_the_file(foself, name, mode) == NULL)
 		goto Error;
+	foself->f_setbuf = NULL;
 	PyFile_SetBufSize(self, bufsize);
 	goto Done;