mirror of https://github.com/python/cpython
This is Pete Shinners' patch from his bug report
[ 984722 ] Py_BuildValue loses reference counts on error I'm ever-so-slightly uneasy at the amount of work this can do with an exception pending, but I don't think that this can result in anything more serious than a strange error message.
This commit is contained in:
parent
8cec3ab0e4
commit
c849e63eb0
|
@ -152,28 +152,32 @@ do_mkdict(char **p_format, va_list *p_va, int endchar, int n)
|
||||||
{
|
{
|
||||||
PyObject *d;
|
PyObject *d;
|
||||||
int i;
|
int i;
|
||||||
|
int itemfailed = 0;
|
||||||
if (n < 0)
|
if (n < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
if ((d = PyDict_New()) == NULL)
|
if ((d = PyDict_New()) == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
/* Note that we can't bail immediately on error as this will leak
|
||||||
|
refcounts on any 'N' arguments. */
|
||||||
for (i = 0; i < n; i+= 2) {
|
for (i = 0; i < n; i+= 2) {
|
||||||
PyObject *k, *v;
|
PyObject *k, *v;
|
||||||
int err;
|
int err;
|
||||||
k = do_mkvalue(p_format, p_va);
|
k = do_mkvalue(p_format, p_va);
|
||||||
if (k == NULL) {
|
if (k == NULL) {
|
||||||
Py_DECREF(d);
|
itemfailed = 1;
|
||||||
return NULL;
|
Py_INCREF(Py_None);
|
||||||
|
k = Py_None;
|
||||||
}
|
}
|
||||||
v = do_mkvalue(p_format, p_va);
|
v = do_mkvalue(p_format, p_va);
|
||||||
if (v == NULL) {
|
if (v == NULL) {
|
||||||
Py_DECREF(k);
|
itemfailed = 1;
|
||||||
Py_DECREF(d);
|
Py_INCREF(Py_None);
|
||||||
return NULL;
|
v = Py_None;
|
||||||
}
|
}
|
||||||
err = PyDict_SetItem(d, k, v);
|
err = PyDict_SetItem(d, k, v);
|
||||||
Py_DECREF(k);
|
Py_DECREF(k);
|
||||||
Py_DECREF(v);
|
Py_DECREF(v);
|
||||||
if (err < 0) {
|
if (err < 0 || itemfailed) {
|
||||||
Py_DECREF(d);
|
Py_DECREF(d);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -194,15 +198,19 @@ do_mklist(char **p_format, va_list *p_va, int endchar, int n)
|
||||||
{
|
{
|
||||||
PyObject *v;
|
PyObject *v;
|
||||||
int i;
|
int i;
|
||||||
|
int itemfailed = 0;
|
||||||
if (n < 0)
|
if (n < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
if ((v = PyList_New(n)) == NULL)
|
if ((v = PyList_New(n)) == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
/* Note that we can't bail immediately on error as this will leak
|
||||||
|
refcounts on any 'N' arguments. */
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
PyObject *w = do_mkvalue(p_format, p_va);
|
PyObject *w = do_mkvalue(p_format, p_va);
|
||||||
if (w == NULL) {
|
if (w == NULL) {
|
||||||
Py_DECREF(v);
|
itemfailed = 1;
|
||||||
return NULL;
|
Py_INCREF(Py_None);
|
||||||
|
w = Py_None;
|
||||||
}
|
}
|
||||||
PyList_SetItem(v, i, w);
|
PyList_SetItem(v, i, w);
|
||||||
}
|
}
|
||||||
|
@ -214,6 +222,10 @@ do_mklist(char **p_format, va_list *p_va, int endchar, int n)
|
||||||
}
|
}
|
||||||
else if (endchar)
|
else if (endchar)
|
||||||
++*p_format;
|
++*p_format;
|
||||||
|
if (itemfailed) {
|
||||||
|
Py_DECREF(v);
|
||||||
|
v = NULL;
|
||||||
|
}
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,15 +245,19 @@ do_mktuple(char **p_format, va_list *p_va, int endchar, int n)
|
||||||
{
|
{
|
||||||
PyObject *v;
|
PyObject *v;
|
||||||
int i;
|
int i;
|
||||||
|
int itemfailed = 0;
|
||||||
if (n < 0)
|
if (n < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
if ((v = PyTuple_New(n)) == NULL)
|
if ((v = PyTuple_New(n)) == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
/* Note that we can't bail immediately on error as this will leak
|
||||||
|
refcounts on any 'N' arguments. */
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
PyObject *w = do_mkvalue(p_format, p_va);
|
PyObject *w = do_mkvalue(p_format, p_va);
|
||||||
if (w == NULL) {
|
if (w == NULL) {
|
||||||
Py_DECREF(v);
|
itemfailed = 1;
|
||||||
return NULL;
|
Py_INCREF(Py_None);
|
||||||
|
w = Py_None;
|
||||||
}
|
}
|
||||||
PyTuple_SetItem(v, i, w);
|
PyTuple_SetItem(v, i, w);
|
||||||
}
|
}
|
||||||
|
@ -253,6 +269,10 @@ do_mktuple(char **p_format, va_list *p_va, int endchar, int n)
|
||||||
}
|
}
|
||||||
else if (endchar)
|
else if (endchar)
|
||||||
++*p_format;
|
++*p_format;
|
||||||
|
if (itemfailed) {
|
||||||
|
Py_DECREF(v);
|
||||||
|
v = NULL;
|
||||||
|
}
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue