Revert patch for #1706039, as it can crash the interpreter.

This commit is contained in:
Martin v. Löwis 2008-12-23 13:10:43 +00:00
parent edf14317e3
commit 3c08e45b70
3 changed files with 19 additions and 67 deletions

View File

@ -357,48 +357,6 @@ class StdoutTests(unittest.TestCase):
finally: finally:
sys.stdout = save_stdout 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(): def test_main():
# Historically, these tests have been sloppy about removing TESTFN. # Historically, these tests have been sloppy about removing TESTFN.

View File

@ -12,6 +12,8 @@ What's New in Python 2.5.4?
Core and builtins 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 - Added test case to ensure attempts to read from a file opened for writing
fail. fail.

View File

@ -861,16 +861,16 @@ file_read(PyFileObject *f, PyObject *args)
buffersize - bytesread, f->f_fp, (PyObject *)f); buffersize - bytesread, f->f_fp, (PyObject *)f);
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
if (chunksize == 0) { if (chunksize == 0) {
if (!PyErr_ExceptionMatches(PyExc_IOError)) if (!ferror(f->f_fp))
break; break;
clearerr(f->f_fp);
/* When in non-blocking mode, data shouldn't /* When in non-blocking mode, data shouldn't
* be discarded if a blocking signal was * be discarded if a blocking signal was
* received. That will also happen if * received. That will also happen if
* chunksize != 0, but bytesread < buffersize. */ * chunksize != 0, but bytesread < buffersize. */
if (bytesread > 0 && BLOCKED_ERRNO(errno)) { if (bytesread > 0 && BLOCKED_ERRNO(errno))
PyErr_Clear();
break; break;
} PyErr_SetFromErrno(PyExc_IOError);
Py_DECREF(v); Py_DECREF(v);
return NULL; return NULL;
} }
@ -917,8 +917,10 @@ file_readinto(PyFileObject *f, PyObject *args)
(PyObject *)f); (PyObject *)f);
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
if (nnow == 0) { if (nnow == 0) {
if (!PyErr_ExceptionMatches(PyExc_IOError)) if (!ferror(f->f_fp))
break; break;
PyErr_SetFromErrno(PyExc_IOError);
clearerr(f->f_fp);
return NULL; return NULL;
} }
ndone += nnow; ndone += nnow;
@ -1410,8 +1412,10 @@ file_readlines(PyFileObject *f, PyObject *args)
} }
if (nread == 0) { if (nread == 0) {
sizehint = 0; sizehint = 0;
if (!PyErr_ExceptionMatches(PyExc_IOError)) if (!ferror(f->f_fp))
break; break;
PyErr_SetFromErrno(PyExc_IOError);
clearerr(f->f_fp);
error: error:
Py_DECREF(list); Py_DECREF(list);
list = NULL; list = NULL;
@ -1859,7 +1863,9 @@ readahead(PyFileObject *f, int bufsize)
f->f_buf, bufsize, f->f_fp, (PyObject *)f); f->f_buf, bufsize, f->f_fp, (PyObject *)f);
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
if (chunksize == 0) { if (chunksize == 0) {
if (PyErr_ExceptionMatches(PyExc_IOError)) { if (ferror(f->f_fp)) {
PyErr_SetFromErrno(PyExc_IOError);
clearerr(f->f_fp);
drop_readahead(f); drop_readahead(f);
return -1; return -1;
} }
@ -2410,7 +2416,6 @@ Py_UniversalNewlineFread(char *buf, size_t n,
char *dst = buf; char *dst = buf;
PyFileObject *f = (PyFileObject *)fobj; PyFileObject *f = (PyFileObject *)fobj;
int newlinetypes, skipnextlf; int newlinetypes, skipnextlf;
size_t nread;
assert(buf != NULL); assert(buf != NULL);
assert(stream != NULL); assert(stream != NULL);
@ -2419,35 +2424,22 @@ Py_UniversalNewlineFread(char *buf, size_t n,
errno = ENXIO; /* What can you do... */ errno = ENXIO; /* What can you do... */
return 0; return 0;
} }
if (!f->f_univ_newline) { if (!f->f_univ_newline)
nread = fread(buf, 1, n, stream); return fread(buf, 1, n, stream);
if (nread == 0) {
if (ferror(stream))
PyErr_SetFromErrno(PyExc_IOError);
clearerr(stream);
}
return nread;
}
newlinetypes = f->f_newlinetypes; newlinetypes = f->f_newlinetypes;
skipnextlf = f->f_skipnextlf; skipnextlf = f->f_skipnextlf;
/* Invariant: n is the number of bytes remaining to be filled /* Invariant: n is the number of bytes remaining to be filled
* in the buffer. * in the buffer.
*/ */
while (n) { while (n) {
size_t nread;
int shortread; int shortread;
char *src = dst; char *src = dst;
nread = fread(dst, 1, n, stream); nread = fread(dst, 1, n, stream);
assert(nread <= n); assert(nread <= n);
if (nread == 0) { if (nread == 0)
if (ferror(stream)) {
clearerr(stream);
PyErr_SetFromErrno(PyExc_IOError);
return 0;
}
clearerr(stream);
break; break;
}
n -= nread; /* assuming 1 byte out for each in; will adjust */ n -= nread; /* assuming 1 byte out for each in; will adjust */
shortread = n != 0; /* true iff EOF or error */ shortread = n != 0; /* true iff EOF or error */