summaryrefslogtreecommitdiffstats
path: root/Modules/_io
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2014-06-09 10:35:43 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2014-06-09 10:35:43 (GMT)
commit3a56117a60ef71709c9a779bfae8b8793600c513 (patch)
tree0aadd6e84ebf1652f4d3e0bbc6124f139b6adda8 /Modules/_io
parent047f14c3c6ed39371fab2d93db8dfd5b5fdb06f1 (diff)
parentf10063e3c3dcd5fe5b99858fc618c574b6df7bf2 (diff)
downloadcpython-3a56117a60ef71709c9a779bfae8b8793600c513.zip
cpython-3a56117a60ef71709c9a779bfae8b8793600c513.tar.gz
cpython-3a56117a60ef71709c9a779bfae8b8793600c513.tar.bz2
Issue #21310: Fixed possible resource leak in failed open().
Diffstat (limited to 'Modules/_io')
-rw-r--r--Modules/_io/_iomodule.c36
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;
}