Commit 6d562319 authored by Serhiy Storchaka's avatar Serhiy Storchaka

Issue #17976: Fixed potential problem with file.write() not detecting IO error

by inspecting the return value of fwrite().  Based on patches by Jaakko Moisio
and test by Victor Stinner.
parent 2f43b635
...@@ -415,6 +415,14 @@ class OtherFileTests(unittest.TestCase): ...@@ -415,6 +415,14 @@ class OtherFileTests(unittest.TestCase):
finally: finally:
os.unlink(TESTFN) os.unlink(TESTFN)
@unittest.skipUnless(os.name == 'posix', 'test requires a posix system.')
def test_write_full(self):
# Issue #17976
with open('/dev/full', 'w', 1) as f:
with self.assertRaises(IOError):
f.write('hello')
f.write('\n')
class FileSubclassTests(unittest.TestCase): class FileSubclassTests(unittest.TestCase):
def testExit(self): def testExit(self):
......
...@@ -710,6 +710,7 @@ Dustin J. Mitchell ...@@ -710,6 +710,7 @@ Dustin J. Mitchell
Dom Mitchell Dom Mitchell
Florian Mladitsch Florian Mladitsch
Doug Moen Doug Moen
Jaakko Moisio
The Dragon De Monsyne The Dragon De Monsyne
Skip Montanaro Skip Montanaro
Paul Moore Paul Moore
......
...@@ -9,6 +9,10 @@ What's New in Python 2.7.7? ...@@ -9,6 +9,10 @@ What's New in Python 2.7.7?
Core and Builtins Core and Builtins
----------------- -----------------
- Issue #17976: Fixed potential problem with file.write() not detecting IO error
by inspecting the return value of fwrite(). Based on patches by Jaakko Moisio
and Victor Stinner.
- Issue #14432: Generator now clears the borrowed reference to the thread - Issue #14432: Generator now clears the borrowed reference to the thread
state. Fix a crash when a generator is created in a C thread that is state. Fix a crash when a generator is created in a C thread that is
destroyed while the generator is still used. The issue was that a generator destroyed while the generator is still used. The issue was that a generator
......
...@@ -1804,6 +1804,7 @@ file_write(PyFileObject *f, PyObject *args) ...@@ -1804,6 +1804,7 @@ file_write(PyFileObject *f, PyObject *args)
const char *s; const char *s;
Py_ssize_t n, n2; Py_ssize_t n, n2;
PyObject *encoded = NULL; PyObject *encoded = NULL;
int err = 0;
if (f->f_fp == NULL) if (f->f_fp == NULL)
return err_closed(); return err_closed();
...@@ -1849,11 +1850,14 @@ file_write(PyFileObject *f, PyObject *args) ...@@ -1849,11 +1850,14 @@ file_write(PyFileObject *f, PyObject *args)
FILE_BEGIN_ALLOW_THREADS(f) FILE_BEGIN_ALLOW_THREADS(f)
errno = 0; errno = 0;
n2 = fwrite(s, 1, n, f->f_fp); n2 = fwrite(s, 1, n, f->f_fp);
if (n2 != n || ferror(f->f_fp))
err = errno;
FILE_END_ALLOW_THREADS(f) FILE_END_ALLOW_THREADS(f)
Py_XDECREF(encoded); Py_XDECREF(encoded);
if (f->f_binary) if (f->f_binary)
PyBuffer_Release(&pbuf); PyBuffer_Release(&pbuf);
if (n2 != n) { if (err) {
errno = err;
PyErr_SetFromErrno(PyExc_IOError); PyErr_SetFromErrno(PyExc_IOError);
clearerr(f->f_fp); clearerr(f->f_fp);
return NULL; return NULL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment