diff options
author | Martin v. Löwis <martin@v.loewis.de> | 2008-12-23 13:10:43 +0000 |
---|---|---|
committer | Martin v. Löwis <martin@v.loewis.de> | 2008-12-23 13:10:43 +0000 |
commit | ddfe86b3c84d6d7b20968483bd7e68d31be0711b (patch) | |
tree | 55e43fa6f90900e2d2e2a4257ac1e1d874182d6e | |
parent | 157834a31c88ab612d5fd83759a548e2fcf24c5b (diff) | |
download | cpython-ddfe86b3c84d6d7b20968483bd7e68d31be0711b.tar.gz |
Revert patch for #1706039, as it can crash the interpreter.
-rw-r--r-- | Lib/test/test_file.py | 42 | ||||
-rw-r--r-- | Misc/NEWS | 2 | ||||
-rw-r--r-- | Objects/fileobject.c | 42 |
3 files changed, 19 insertions, 67 deletions
diff --git a/Lib/test/test_file.py b/Lib/test/test_file.py index f678df6f37..fbf85e3c76 100644 --- a/Lib/test/test_file.py +++ b/Lib/test/test_file.py @@ -357,48 +357,6 @@ class StdoutTests(unittest.TestCase): finally: sys.stdout = save_stdout - def testReadAfterEOF(self): - # Regression test for SF bug #1523853. - # Verify read works after hitting EOF - - # Prepare the testfile - teststring = "spam" - bag = open(TESTFN, "w") - bag.write(teststring) - bag.close() - - # And buf for readinto - buf = array("c", " "*len(teststring)) - - # Test for appropriate errors mixing read* and iteration - methods = [("readline", ()), ("read",()), ("readlines", ()), - ("readinto", (buf,))] - - for attr in 'r', 'rU': - for methodname, args in methods: - f = open(TESTFN, "rU") - f.seek(0, 2) - meth = getattr(f, methodname) - meth(*args) # hits EOF - try: - # Writing the same file with another file descriptor - append = open(TESTFN, "a+") - append.write(teststring) - append.flush() - append.close() - try: - meth = getattr(f, methodname) - if methodname == 'readlines': - self.failUnlessEqual(meth(*args), [teststring]) - elif methodname == 'readinto': - meth(*args) - self.failUnlessEqual(buf.tostring(), teststring) - else: - self.failUnlessEqual(meth(*args), teststring) - except ValueError: - self.fail("read* failed after hitting EOF") - finally: - f.close() def test_main(): # Historically, these tests have been sloppy about removing TESTFN. @@ -12,6 +12,8 @@ What's New in Python 2.5.4? Core and builtins ----------------- +- Revert patch for #1706039, as it can crash the interpreter. + - Added test case to ensure attempts to read from a file opened for writing fail. diff --git a/Objects/fileobject.c b/Objects/fileobject.c index 5b76b0d0cc..565bf5ca2f 100644 --- a/Objects/fileobject.c +++ b/Objects/fileobject.c @@ -861,16 +861,16 @@ file_read(PyFileObject *f, PyObject *args) buffersize - bytesread, f->f_fp, (PyObject *)f); Py_END_ALLOW_THREADS if (chunksize == 0) { - if (!PyErr_ExceptionMatches(PyExc_IOError)) + if (!ferror(f->f_fp)) break; + clearerr(f->f_fp); /* When in non-blocking mode, data shouldn't * be discarded if a blocking signal was * received. That will also happen if * chunksize != 0, but bytesread < buffersize. */ - if (bytesread > 0 && BLOCKED_ERRNO(errno)) { - PyErr_Clear(); + if (bytesread > 0 && BLOCKED_ERRNO(errno)) break; - } + PyErr_SetFromErrno(PyExc_IOError); Py_DECREF(v); return NULL; } @@ -917,8 +917,10 @@ file_readinto(PyFileObject *f, PyObject *args) (PyObject *)f); Py_END_ALLOW_THREADS if (nnow == 0) { - if (!PyErr_ExceptionMatches(PyExc_IOError)) + if (!ferror(f->f_fp)) break; + PyErr_SetFromErrno(PyExc_IOError); + clearerr(f->f_fp); return NULL; } ndone += nnow; @@ -1410,8 +1412,10 @@ file_readlines(PyFileObject *f, PyObject *args) } if (nread == 0) { sizehint = 0; - if (!PyErr_ExceptionMatches(PyExc_IOError)) + if (!ferror(f->f_fp)) break; + PyErr_SetFromErrno(PyExc_IOError); + clearerr(f->f_fp); error: Py_DECREF(list); list = NULL; @@ -1859,7 +1863,9 @@ readahead(PyFileObject *f, int bufsize) f->f_buf, bufsize, f->f_fp, (PyObject *)f); Py_END_ALLOW_THREADS if (chunksize == 0) { - if (PyErr_ExceptionMatches(PyExc_IOError)) { + if (ferror(f->f_fp)) { + PyErr_SetFromErrno(PyExc_IOError); + clearerr(f->f_fp); drop_readahead(f); return -1; } @@ -2410,7 +2416,6 @@ Py_UniversalNewlineFread(char *buf, size_t n, char *dst = buf; PyFileObject *f = (PyFileObject *)fobj; int newlinetypes, skipnextlf; - size_t nread; assert(buf != NULL); assert(stream != NULL); @@ -2419,35 +2424,22 @@ Py_UniversalNewlineFread(char *buf, size_t n, errno = ENXIO; /* What can you do... */ return 0; } - if (!f->f_univ_newline) { - nread = fread(buf, 1, n, stream); - if (nread == 0) { - if (ferror(stream)) - PyErr_SetFromErrno(PyExc_IOError); - clearerr(stream); - } - return nread; - } + if (!f->f_univ_newline) + return fread(buf, 1, n, stream); newlinetypes = f->f_newlinetypes; skipnextlf = f->f_skipnextlf; /* Invariant: n is the number of bytes remaining to be filled * in the buffer. */ while (n) { + size_t nread; int shortread; char *src = dst; nread = fread(dst, 1, n, stream); assert(nread <= n); - if (nread == 0) { - if (ferror(stream)) { - clearerr(stream); - PyErr_SetFromErrno(PyExc_IOError); - return 0; - } - clearerr(stream); + if (nread == 0) break; - } n -= nread; /* assuming 1 byte out for each in; will adjust */ shortread = n != 0; /* true iff EOF or error */ |