Patchwork [2,of,2] osutil: fix excessive decref on tuple creation failure in listdir()

login
register
mail settings
Submitter Yuya Nishihara
Date July 19, 2020, 10:08 a.m.
Message ID <a1ead7811a9b982b83bc.1595153318@mimosa>
Download mbox | patch
Permalink /patch/46808/
State Accepted
Headers show

Comments

Yuya Nishihara - July 19, 2020, 10:08 a.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1595147741 -32400
#      Sun Jul 19 17:35:41 2020 +0900
# Node ID a1ead7811a9b982b83bc6a0853645e2fdcf2bffd
# Parent  69b9623330ca581376bb215cafe1aac4033216b8
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.
Augie Fackler - July 20, 2020, 4:13 p.m.
On Sun, Jul 19, 2020 at 07:08:38PM +0900, Yuya Nishihara wrote:
> # HG changeset patch
> # User Yuya Nishihara <yuya@tcha.org>
> # Date 1595147741 -32400
> #      Sun Jul 19 17:35:41 2020 +0900
> # Node ID a1ead7811a9b982b83bc6a0853645e2fdcf2bffd
> # Parent  69b9623330ca581376bb215cafe1aac4033216b8
> osutil: fix excessive decref on tuple creation failure in listdir()

queued, thanks for the really nice subtle C fixes

Patch

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: