diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2014-06-09 10:32:34 (GMT) |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2014-06-09 10:32:34 (GMT) |
commit | f10063e3c3dcd5fe5b99858fc618c574b6df7bf2 (patch) | |
tree | d549bcb1c89abdf86860b884f96b06c3aa846da9 /Modules/_io | |
parent | 8a8f7f983099f172d1f7c25d4fd99f5c0eb14072 (diff) | |
download | cpython-f10063e3c3dcd5fe5b99858fc618c574b6df7bf2.zip cpython-f10063e3c3dcd5fe5b99858fc618c574b6df7bf2.tar.gz cpython-f10063e3c3dcd5fe5b99858fc618c574b6df7bf2.tar.bz2 |
Issue #21310: Fixed possible resource leak in failed open().
Diffstat (limited to 'Modules/_io')
-rw-r--r-- | Modules/_io/_iomodule.c | 36 |
1 files changed, 27 insertions, 9 deletions
diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c index be0464c..1dbd563 100644 --- a/Modules/_io/_iomodule.c +++ b/Modules/_io/_iomodule.c @@ -235,11 +235,12 @@ io_open(PyObject *self, PyObject *args, PyObject *kwds) char rawmode[6], *m; int line_buffering, isatty; - PyObject *raw, *modeobj = NULL, *buffer = NULL, *wrapper = NULL; + PyObject *raw, *modeobj = NULL, *buffer, *wrapper, *result = NULL; _Py_IDENTIFIER(isatty); _Py_IDENTIFIER(fileno); _Py_IDENTIFIER(mode); + _Py_IDENTIFIER(close); if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|sizzziO:open", kwlist, &file, &mode, &buffering, @@ -354,6 +355,7 @@ io_open(PyObject *self, PyObject *args, PyObject *kwds) "OsiO", file, rawmode, closefd, opener); if (raw == NULL) return NULL; + result = raw; modeobj = PyUnicode_FromString(mode); if (modeobj == NULL) @@ -412,7 +414,7 @@ io_open(PyObject *self, PyObject *args, PyObject *kwds) } Py_DECREF(modeobj); - return raw; + return result; } /* wraps into a buffered file */ @@ -433,15 +435,16 @@ io_open(PyObject *self, PyObject *args, PyObject *kwds) buffer = PyObject_CallFunction(Buffered_class, "Oi", raw, buffering); } - Py_CLEAR(raw); if (buffer == NULL) goto error; + result = buffer; + Py_DECREF(raw); /* if binary, returns the buffered file */ if (binary) { Py_DECREF(modeobj); - return buffer; + return result; } /* wraps into a TextIOWrapper */ @@ -450,20 +453,35 @@ io_open(PyObject *self, PyObject *args, PyObject *kwds) buffer, encoding, errors, newline, line_buffering); - Py_CLEAR(buffer); if (wrapper == NULL) goto error; + result = wrapper; + Py_DECREF(buffer); if (_PyObject_SetAttrId(wrapper, &PyId_mode, modeobj) < 0) goto error; Py_DECREF(modeobj); - return wrapper; + return result; error: - Py_XDECREF(raw); + if (result != NULL) { + PyObject *exc, *val, *tb; + PyErr_Fetch(&exc, &val, &tb); + if (_PyObject_CallMethodId(result, &PyId_close, NULL) != NULL) + PyErr_Restore(exc, val, tb); + else { + PyObject *val2; + PyErr_NormalizeException(&exc, &val, &tb); + Py_XDECREF(exc); + Py_XDECREF(tb); + PyErr_Fetch(&exc, &val2, &tb); + PyErr_NormalizeException(&exc, &val2, &tb); + PyException_SetContext(val2, val); + PyErr_Restore(exc, val2, tb); + } + Py_DECREF(result); + } Py_XDECREF(modeobj); - Py_XDECREF(buffer); - Py_XDECREF(wrapper); return NULL; } |