[Python-checkins] r77990 - in python/branches/release26-maint: Include/fileobject.h Lib/test/test_file.py Lib/test/test_sys.py Misc/ACKS Misc/NEWS Objects/fileobject.c

antoine.pitrou python-checkins at python.org
Fri Feb 5 18:11:33 CET 2010


Author: antoine.pitrou
Date: Fri Feb 5 18:11:32 2010
New Revision: 77990
Log:
Merged revisions 77989 via svnmerge from 
svn+ssh://pythondev@svn.python.org/python/trunk
........
 r77989 | antoine.pitrou | 2010年02月05日 18:05:54 +0100 (ven., 05 févr. 2010) | 6 lines
 
 Issue #5677: Explicitly forbid write operations on read-only file objects,
 and read operations on write-only file objects. On Windows, the system C
 library would return a bogus result; on Solaris, it was possible to crash
 the interpreter. Patch by Stefan Krah.
........
Modified:
 python/branches/release26-maint/ (props changed)
 python/branches/release26-maint/Include/fileobject.h
 python/branches/release26-maint/Lib/test/test_file.py
 python/branches/release26-maint/Lib/test/test_sys.py
 python/branches/release26-maint/Misc/ACKS
 python/branches/release26-maint/Misc/NEWS
 python/branches/release26-maint/Objects/fileobject.c
Modified: python/branches/release26-maint/Include/fileobject.h
==============================================================================
--- python/branches/release26-maint/Include/fileobject.h	(original)
+++ python/branches/release26-maint/Include/fileobject.h	Fri Feb 5 18:11:32 2010
@@ -28,6 +28,8 @@
 	PyObject *weakreflist; /* List of weak references */
 	int unlocked_count;	/* Num. currently running sections of code
 				 using f_fp with the GIL released. */
+	int readable;
+	int writable;
 } PyFileObject;
 
 PyAPI_DATA(PyTypeObject) PyFile_Type;
Modified: python/branches/release26-maint/Lib/test/test_file.py
==============================================================================
--- python/branches/release26-maint/Lib/test/test_file.py	(original)
+++ python/branches/release26-maint/Lib/test/test_file.py	Fri Feb 5 18:11:32 2010
@@ -86,6 +86,8 @@
 self.assert_(repr(self.f).startswith("<open file '" + TESTFN))
 
 def testErrors(self):
+ self.f.close()
+ self.f = open(TESTFN, 'rb')
 f = self.f
 self.assertEquals(f.name, TESTFN)
 self.assert_(not f.isatty())
@@ -123,6 +125,40 @@
 def testReadWhenWriting(self):
 self.assertRaises(IOError, self.f.read)
 
+ def testIssue5677(self):
+ # Remark: Do not perform more than one test per open file,
+ # since that does NOT catch the readline error on Windows.
+ data = 'xxx'
+ for mode in ['w', 'wb', 'a', 'ab']:
+ for attr in ['read', 'readline', 'readlines']:
+ self.f = open(TESTFN, mode)
+ self.f.write(data)
+ self.assertRaises(IOError, getattr(self.f, attr))
+ self.f.close()
+
+ self.f = open(TESTFN, mode)
+ self.f.write(data)
+ self.assertRaises(IOError, lambda: [line for line in self.f])
+ self.f.close()
+
+ self.f = open(TESTFN, mode)
+ self.f.write(data)
+ self.assertRaises(IOError, self.f.readinto, bytearray(len(data)))
+ self.f.close()
+
+ for mode in ['r', 'rb', 'U', 'Ub', 'Ur', 'rU', 'rbU', 'rUb']:
+ self.f = open(TESTFN, mode)
+ self.assertRaises(IOError, self.f.write, data)
+ self.f.close()
+
+ self.f = open(TESTFN, mode)
+ self.assertRaises(IOError, self.f.writelines, [data, data])
+ self.f.close()
+
+ self.f = open(TESTFN, mode)
+ self.assertRaises(IOError, self.f.truncate)
+ self.f.close()
+
 class OtherFileTests(unittest.TestCase):
 
 def testOpenDir(self):
Modified: python/branches/release26-maint/Lib/test/test_sys.py
==============================================================================
--- python/branches/release26-maint/Lib/test/test_sys.py	(original)
+++ python/branches/release26-maint/Lib/test/test_sys.py	Fri Feb 5 18:11:32 2010
@@ -538,7 +538,7 @@
 # enumerate
 check(enumerate([]), size(h + 'l3P'))
 # file
- check(self.file, size(h + '4P2i4P3i3Pi'))
+ check(self.file, size(h + '4P2i4P3i3P3i'))
 # float
 check(float(0), size(h + 'd'))
 # sys.floatinfo
Modified: python/branches/release26-maint/Misc/ACKS
==============================================================================
--- python/branches/release26-maint/Misc/ACKS	(original)
+++ python/branches/release26-maint/Misc/ACKS	Fri Feb 5 18:11:32 2010
@@ -391,6 +391,7 @@
 Greg Kochanski
 Damon Kohler
 Joseph Koshy
+Stefan Krah
 Bob Kras
 Holger Krekel
 Michael Kremer
Modified: python/branches/release26-maint/Misc/NEWS
==============================================================================
--- python/branches/release26-maint/Misc/NEWS	(original)
+++ python/branches/release26-maint/Misc/NEWS	Fri Feb 5 18:11:32 2010
@@ -12,6 +12,11 @@
 Core and Builtins
 -----------------
 
+- Issue #5677: Explicitly forbid write operations on read-only file objects,
+ and read operations on write-only file objects. On Windows, the system C
+ library would return a bogus result; on Solaris, it was possible to crash
+ the interpreter. Patch by Stefan Krah.
+
 - Issue #7819: Check sys.call_tracing() arguments types.
 
 - Issue #7788: Fix an interpreter crash produced by deleting a list
Modified: python/branches/release26-maint/Objects/fileobject.c
==============================================================================
--- python/branches/release26-maint/Objects/fileobject.c	(original)
+++ python/branches/release26-maint/Objects/fileobject.c	Fri Feb 5 18:11:32 2010
@@ -173,6 +173,13 @@
 	f->f_encoding = Py_None;
 	Py_INCREF(Py_None);
 	f->f_errors = Py_None;
+	f->readable = f->writable = 0;
+	if (strchr(mode, 'r') != NULL || f->f_univ_newline)
+		f->readable = 1;
+	if (strchr(mode, 'w') != NULL || strchr(mode, 'a') != NULL)
+		f->writable = 1;
+	if (strchr(mode, '+') != NULL)
+		f->readable = f->writable = 1;
 
 	if (f->f_mode == NULL)
 		return NULL;
@@ -487,6 +494,13 @@
 	return NULL;
 }
 
+static PyObject *
+err_mode(char *action)
+{
+ PyErr_Format(PyExc_IOError, "File not open for %s", action);
+ return NULL;
+}
+
 /* Refuse regular file I/O if there's data in the iteration-buffer.
 * Mixing them would cause data to arrive out of order, as the read*
 * methods don't use the iteration buffer. */
@@ -701,6 +715,8 @@
 
 	if (f->f_fp == NULL)
 		return err_closed();
+	if (!f->writable)
+		return err_mode("writing");
 	if (!PyArg_UnpackTuple(args, "truncate", 0, 1, &newsizeobj))
 		return NULL;
 
@@ -949,6 +965,8 @@
 
 	if (f->f_fp == NULL)
 		return err_closed();
+	if (!f->readable)
+		return err_mode("reading");
 	/* refuse to mix with f.next() */
 	if (f->f_buf != NULL &&
 	 (f->f_bufend - f->f_bufptr) > 0 &&
@@ -1018,6 +1036,8 @@
 
 	if (f->f_fp == NULL)
 		return err_closed();
+	if (!f->readable)
+		return err_mode("reading");
 	/* refuse to mix with f.next() */
 	if (f->f_buf != NULL &&
 	 (f->f_bufend - f->f_bufptr) > 0 &&
@@ -1389,6 +1409,8 @@
 		PyFileObject *fo = (PyFileObject *)f;
 		if (fo->f_fp == NULL)
 			return err_closed();
+		if (!fo->readable)
+			return err_mode("reading");
 		/* refuse to mix with f.next() */
 		if (fo->f_buf != NULL &&
 		 (fo->f_bufend - fo->f_bufptr) > 0 &&
@@ -1477,6 +1499,8 @@
 
 	if (f->f_fp == NULL)
 		return err_closed();
+	if (!f->readable)
+		return err_mode("reading");
 	/* refuse to mix with f.next() */
 	if (f->f_buf != NULL &&
 	 (f->f_bufend - f->f_bufptr) > 0 &&
@@ -1510,6 +1534,8 @@
 
 	if (f->f_fp == NULL)
 		return err_closed();
+	if (!f->readable)
+		return err_mode("reading");
 	/* refuse to mix with f.next() */
 	if (f->f_buf != NULL &&
 	 (f->f_bufend - f->f_bufptr) > 0 &&
@@ -1628,6 +1654,8 @@
 	Py_ssize_t n, n2;
 	if (f->f_fp == NULL)
 		return err_closed();
+	if (!f->writable)
+		return err_mode("writing");
 	if (f->f_binary) {
 		if (!PyArg_ParseTuple(args, "s*", &pbuf))
 			return NULL;
@@ -1665,6 +1693,8 @@
 	assert(seq != NULL);
 	if (f->f_fp == NULL)
 		return err_closed();
+	if (!f->writable)
+		return err_mode("writing");
 
 	result = NULL;
 	list = NULL;
@@ -2105,6 +2135,8 @@
 
 	if (f->f_fp == NULL)
 		return err_closed();
+	if (!f->readable)
+		return err_mode("reading");
 
 	l = readahead_get_line_skip(f, 0, READAHEAD_BUFSIZE);
 	if (l == NULL || PyString_GET_SIZE(l) == 0) {


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /