# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 2020-07-19 08:35:41
# Node ID f93a4e3d35ab4c241d00fe24ae858f8e9f727ad2
# Parent  2bc5d15312356080afc7c7746b559d188cd74386

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.

diff --git a/mercurial/cext/osutil.c b/mercurial/cext/osutil.c
--- a/mercurial/cext/osutil.c
+++ b/mercurial/cext/osutil.c
@@ -336,7 +336,7 @@ static PyObject *makestat(const struct s
 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 @@ static PyObject *_listdir_stat(char *pat
 		}
 
 		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 @@ static PyObject *_listdir_stat(char *pat
 					     kind);
 		if (!elem)
 			goto error;
-		stat = NULL;
 
 		PyList_Append(list, elem);
 		Py_DECREF(elem);
@@ -430,7 +429,6 @@ static PyObject *_listdir_stat(char *pat
 
 error:
 	Py_DECREF(list);
-	Py_XDECREF(stat);
 error_list:
 	closedir(dir);
 	/* closedir also closes its dirfd */
@@ -480,7 +478,7 @@ int attrkind(attrbuf_entry *entry)
 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 @@ static PyObject *_listdir_batch(char *pa
 			}
 
 			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 @@ static PyObject *_listdir_batch(char *pa
 						     filename, kind);
 			if (!elem)
 				goto error;
-			stat = NULL;
 
 			PyList_Append(list, elem);
 			Py_DECREF(elem);
@@ -615,7 +613,6 @@ static PyObject *_listdir_batch(char *pa
 
 error:
 	Py_DECREF(list);
-	Py_XDECREF(stat);
 error_dir:
 	close(dfd);
 error_value: