summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew MacIntyre <andymac@bullseye.apana.org.au>2004-04-04 07:01:35 (GMT)
committerAndrew MacIntyre <andymac@bullseye.apana.org.au>2004-04-04 07:01:35 (GMT)
commit4e10ed3b86cf08211ef0c9c5408799195c2c1881 (patch)
treeaa4ba6c69b025b087a79eea302c9ed6d0ccb6ca8
parentba813e20892157befdefa60df88c19bae52fc766 (diff)
downloadcpython-4e10ed3b86cf08211ef0c9c5408799195c2c1881.zip
cpython-4e10ed3b86cf08211ef0c9c5408799195c2c1881.tar.gz
cpython-4e10ed3b86cf08211ef0c9c5408799195c2c1881.tar.bz2
If a file is opened with an explicit buffer size >= 1, repeated
close() calls would attempt to free() the buffer already free()ed on the first close(). [bug introduced with patch #788249] Making sure that the buffer is free()ed in file object deallocation is a belt-n-braces bit of insurance against a memory leak.
-rw-r--r--Lib/test/test_file.py17
-rw-r--r--Misc/NEWS4
-rw-r--r--Objects/fileobject.c2
3 files changed, 23 insertions, 0 deletions
diff --git a/Lib/test/test_file.py b/Lib/test/test_file.py
index b8bcab7..22db9a2 100644
--- a/Lib/test/test_file.py
+++ b/Lib/test/test_file.py
@@ -109,6 +109,23 @@ f.close()
if not f.closed:
raise TestFailed, 'file.closed should be true'
+# make sure that explicitly setting the buffer size doesn't cause
+# misbehaviour especially with repeated close() calls
+for s in (-1, 0, 1, 512):
+ try:
+ f = open(TESTFN, 'w', s)
+ f.write(str(s))
+ f.close()
+ f.close()
+ f = open(TESTFN, 'r', s)
+ d = int(f.read())
+ f.close()
+ f.close()
+ except IOError, msg:
+ raise TestFailed, 'error setting buffer size %d: %s' % (s, str(msg))
+ if d != s:
+ raise TestFailed, 'readback failure using buffer size %d'
+
methods = ['fileno', 'flush', 'isatty', 'next', 'read', 'readinto',
'readline', 'readlines', 'seek', 'tell', 'truncate', 'write',
'xreadlines', '__iter__']
diff --git a/Misc/NEWS b/Misc/NEWS
index 9fc3ba7..b1f2043 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -194,6 +194,10 @@ Core and builtins
the data and the data length. Instead, the appropriate tp_as_buffer
method is called as necessary.
+- fixed: if a file is opened with an explicit buffer size >= 1, repeated
+ close() calls would attempt to free() the buffer already free()ed on
+ the first call.
+
Extension modules
-----------------
diff --git a/Objects/fileobject.c b/Objects/fileobject.c
index c973366..6b7e01b 100644
--- a/Objects/fileobject.c
+++ b/Objects/fileobject.c
@@ -312,6 +312,7 @@ file_dealloc(PyFileObject *f)
(*f->f_close)(f->f_fp);
Py_END_ALLOW_THREADS
}
+ PyMem_Free(f->f_setbuf);
Py_XDECREF(f->f_name);
Py_XDECREF(f->f_mode);
Py_XDECREF(f->f_encoding);
@@ -358,6 +359,7 @@ file_close(PyFileObject *f)
f->f_fp = NULL;
}
PyMem_Free(f->f_setbuf);
+ f->f_setbuf = NULL;
if (sts == EOF)
return PyErr_SetFromErrno(PyExc_IOError);
if (sts != 0)