From: Mark Hansen Date: Fri, 8 Apr 2022 07:35:55 +0000 (+1000) Subject: Remove unintended recursion in vec_delete. X-Git-Tag: 4.0.0~50^2~1 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=73db2df2cd2143527c5f5c10520084174d8a38a6;p=graphviz Remove unintended recursion in vec_delete. This prevents a segfault: Fixes #2225. Add a little more documentation around the responsibilities of callers to make this a little less likely to happen again. I thought about calling this vec_vec_delete but went with cycles_delete; the only place this is used is for cycles. This effectively reverts c4ef19f483d577a8395a1a1f9ca5a321af3472b5, and fixes that commit's memory leak in a different way. --- diff --git a/lib/common/routespl.c b/lib/common/routespl.c index 66fd79a5f..cfd9d9475 100644 --- a/lib/common/routespl.c +++ b/lib/common/routespl.c @@ -835,13 +835,18 @@ static void* vec_get(vec* pvec, size_t index) static void vec_delete(vec* pvec) { - for (size_t i = 0; i < vec_length(pvec); ++i) { - vec_delete(vec_get(pvec, i)); - } free(pvec->_mem); free(pvec); } +// cycles is assumed to be a vec of vec of nodes. +static void cycles_delete(vec* cycles) { + for (size_t i = 0; i < vec_length(cycles); ++i) { + vec_delete(vec_get(cycles, i)); + } + vec_delete(cycles); +} + static void vec_push_back(vec* pvec, void* data) { if (pvec->_elems == pvec->_capelems) { @@ -961,6 +966,7 @@ static void dfs(graph_t *g, node_t* search, vec* visited, node_t* end, vec* cycl } } +// Returns a vec of vec of nodes (aka a vector of cycles), which must be freed using cycles_delete. static vec* find_all_cycles(graph_t *g) { node_t *n; @@ -976,7 +982,7 @@ static vec* find_all_cycles(graph_t *g) dfs(g, n, cycle, n, cycles); } - vec_delete(alloced_cycles); //cycles contains copied vecs + cycles_delete(alloced_cycles); //cycles contains copied vecs return cycles; } @@ -1019,7 +1025,7 @@ static pointf get_cycle_centroid(graph_t *g, edge_t* edge) if (cycle == NULL) { if (cycles != NULL) - vec_delete(cycles); + cycles_delete(cycles); return get_centroid(g); } @@ -1033,7 +1039,7 @@ static pointf get_cycle_centroid(graph_t *g, edge_t* edge) } if (cycles != NULL) - vec_delete(cycles); + cycles_delete(cycles); sum.x /= cnt; sum.y /= cnt; diff --git a/rtest/test_regression.py b/rtest/test_regression.py index aae323e40..aab58d34a 100644 --- a/rtest/test_regression.py +++ b/rtest/test_regression.py @@ -1741,7 +1741,6 @@ def test_gvpr_usage(): assert "-o - write output to ; stdout by default" in stderr, \ "truncated or malformed GVPR usage information" -@pytest.mark.xfail() # FIXME def test_2225(): """ sfdp should not segfault with curved splines