Patchwork [2,of,4] reachableroots: unify bail cases to raise exception correctly

login
register
mail settings
Submitter Yuya Nishihara
Date Aug. 13, 2015, 10:48 a.m.
Message ID <d03c861b206b28574ba2.1439462889@mimosa>
Download mbox | patch
Permalink /patch/10204/
State Accepted
Headers show

Comments

Yuya Nishihara - Aug. 13, 2015, 10:48 a.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1439458178 -32400
#      Thu Aug 13 18:29:38 2015 +0900
# Node ID d03c861b206b28574ba277f58caa60a77d070f3e
# Parent  6f1931a8e6a31c650a4df10048914634e14da642
reachableroots: unify bail cases to raise exception correctly

Before this patch, release_seen_and_tovisit did not return NULL, so the
exception was not raised immediately. As Py_XDECREF() and free() are safe
for NULL, we can simply bail in any case.

Patch

diff --git a/mercurial/parsers.c b/mercurial/parsers.c
--- a/mercurial/parsers.c
+++ b/mercurial/parsers.c
@@ -1154,13 +1154,13 @@  static PyObject *reachableroots(indexObj
 	tovisit = (int *)malloc((len + 1) * sizeof(int));
 	if (tovisit == NULL) {
 		PyErr_NoMemory();
-		goto release_reachable;
+		goto bail;
 	}
 
 	seen = (char *)calloc(len+1, 1);
 	if (seen == NULL) {
 		PyErr_NoMemory();
-		goto release_seen_and_tovisit;
+		goto bail;
 	}
 
 	/* Populate tovisit with all the heads */
@@ -1192,7 +1192,7 @@  static PyObject *reachableroots(indexObj
 		if (revnum != -1) {
 			r = index_get_parents(self, revnum, parents, (int)len - 1);
 			if (r < 0)
-				goto release_seen_and_tovisit;
+				goto bail;
 
 			for (i = 0; i < 2; i++) {
 				if (seen[parents[i] + 1] == 0 && parents[i] >= minroot) {
@@ -1214,7 +1214,7 @@  static PyObject *reachableroots(indexObj
 				r = index_get_parents(self, i, parents, (int)len - 1);
 				/* Corrupted index file, error is set from index_get_parents */
 				if (r < 0)
-					goto release_seen_and_tovisit;
+					goto bail;
 				for (k = 0; k < 2; k++) {
 					PyObject *p = PyInt_FromLong(parents[k]);
 					if (PySet_Contains(reachable, p) == 1)
@@ -1225,13 +1225,13 @@  static PyObject *reachableroots(indexObj
 		}
 	}
 
-release_seen_and_tovisit:
 	free(seen);
 	free(tovisit);
 	return reachable;
-release_reachable:
+bail:
 	Py_XDECREF(reachable);
-bail:
+	free(seen);
+	free(tovisit);
 	return NULL;
 }
 
diff --git a/tests/test-parseindex.t b/tests/test-parseindex.t
--- a/tests/test-parseindex.t
+++ b/tests/test-parseindex.t
@@ -94,6 +94,8 @@  Test corrupted p1/p2 fields that could c
   > cl = changelog.changelog(scmutil.vfs(sys.argv[1]))
   > n0, n1 = cl.node(0), cl.node(1)
   > ops = [
+  >     ('reachableroots',
+  >      lambda: cl.index.reachableroots(0, [1], set([0]), False)),
   >     ('compute_phases_map_sets', lambda: cl.computephases([[0], []])),
   >     ('index_headrevs', lambda: cl.headrevs()),
   >     ('find_gca_candidates', lambda: cl.commonancestorsheads(n0, n1)),
@@ -109,11 +111,13 @@  Test corrupted p1/p2 fields that could c
   > EOF
 
   $ python test.py limit/.hg/store
+  reachableroots: parent out of range
   compute_phases_map_sets: parent out of range
   index_headrevs: parent out of range
   find_gca_candidates: parent out of range
   find_deepest: parent out of range
   $ python test.py segv/.hg/store
+  reachableroots: parent out of range
   compute_phases_map_sets: parent out of range
   index_headrevs: parent out of range
   find_gca_candidates: parent out of range