diff --git a/Python/modsupport.c b/Python/modsupport.c index f26d7b8eca2..197d99b1d1f 100644 --- a/Python/modsupport.c +++ b/Python/modsupport.c @@ -152,28 +152,32 @@ do_mkdict(char **p_format, va_list *p_va, int endchar, int n) { PyObject *d; int i; + int itemfailed = 0; if (n < 0) return NULL; if ((d = PyDict_New()) == 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) { PyObject *k, *v; int err; k = do_mkvalue(p_format, p_va); if (k == NULL) { - Py_DECREF(d); - return NULL; + itemfailed = 1; + Py_INCREF(Py_None); + k = Py_None; } v = do_mkvalue(p_format, p_va); if (v == NULL) { - Py_DECREF(k); - Py_DECREF(d); - return NULL; + itemfailed = 1; + Py_INCREF(Py_None); + v = Py_None; } err = PyDict_SetItem(d, k, v); Py_DECREF(k); Py_DECREF(v); - if (err < 0) { + if (err < 0 || itemfailed) { Py_DECREF(d); return NULL; } @@ -194,15 +198,19 @@ do_mklist(char **p_format, va_list *p_va, int endchar, int n) { PyObject *v; int i; + int itemfailed = 0; if (n < 0) return NULL; if ((v = PyList_New(n)) == 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++) { PyObject *w = do_mkvalue(p_format, p_va); if (w == NULL) { - Py_DECREF(v); - return NULL; + itemfailed = 1; + Py_INCREF(Py_None); + w = Py_None; } 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) ++*p_format; + if (itemfailed) { + Py_DECREF(v); + v = NULL; + } return v; } @@ -233,15 +245,19 @@ do_mktuple(char **p_format, va_list *p_va, int endchar, int n) { PyObject *v; int i; + int itemfailed = 0; if (n < 0) return NULL; if ((v = PyTuple_New(n)) == 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++) { PyObject *w = do_mkvalue(p_format, p_va); if (w == NULL) { - Py_DECREF(v); - return NULL; + itemfailed = 1; + Py_INCREF(Py_None); + w = Py_None; } 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) ++*p_format; + if (itemfailed) { + Py_DECREF(v); + v = NULL; + } return v; }