osutil: fix excessive decref on tuple creation failure in listdir()
The stat object would be freed on error for the same reason as the previous
patch. makestat() can be inlined, but this patch doesn't change it.
https://github.com/python/cpython/blob/2.7/Python/modsupport.c#L292
The __APPLE__ code is untested.
--- a/mercurial/cext/osutil.c Sun Jul 19 17:24:16 2020 +0900
+++ b/mercurial/cext/osutil.c Sun Jul 19 17:35:41 2020 +0900
@@ -336,7 +336,7 @@
static PyObject *_listdir_stat(char *path, int pathlen, int keepstat,
char *skip)
{
- PyObject *list, *elem, *stat = NULL, *ret = NULL;
+ PyObject *list, *elem, *ret = NULL;
char fullpath[PATH_MAX + 10];
int kind, err;
struct stat st;
@@ -409,7 +409,7 @@
}
if (keepstat) {
- stat = makestat(&st);
+ PyObject *stat = makestat(&st);
if (!stat)
goto error;
elem = Py_BuildValue(PY23("siN", "yiN"), ent->d_name,
@@ -419,7 +419,6 @@
kind);
if (!elem)
goto error;
- stat = NULL;
PyList_Append(list, elem);
Py_DECREF(elem);
@@ -430,7 +429,6 @@
error:
Py_DECREF(list);
- Py_XDECREF(stat);
error_list:
closedir(dir);
/* closedir also closes its dirfd */
@@ -480,7 +478,7 @@
static PyObject *_listdir_batch(char *path, int pathlen, int keepstat,
char *skip, bool *fallback)
{
- PyObject *list, *elem, *stat = NULL, *ret = NULL;
+ PyObject *list, *elem, *ret = NULL;
int kind, err;
unsigned long index;
unsigned int count, old_state, new_state;
@@ -586,6 +584,7 @@
}
if (keepstat) {
+ PyObject *stat = NULL;
/* from the getattrlist(2) man page: "Only the
permission bits ... are valid". */
st.st_mode = (entry->access_mask & ~S_IFMT) | kind;
@@ -601,7 +600,6 @@
filename, kind);
if (!elem)
goto error;
- stat = NULL;
PyList_Append(list, elem);
Py_DECREF(elem);
@@ -615,7 +613,6 @@
error:
Py_DECREF(list);
- Py_XDECREF(stat);
error_dir:
close(dfd);
error_value: