From 2c07d238d7badf47879cbe98837ef658276f515f Mon Sep 17 00:00:00 2001 From: Matthew Fernandez Date: Sat, 18 Jun 2022 15:23:41 -0700 Subject: [PATCH] fix: anticipate non-normal edges during path construction When constructing a path, the `beginpath` and `endpath` functions assumed they could follow a chain of `.to_orig` back pointers to eventually reach a normal edge. However this is not necessarily true, a situation exemplified by tests/graphs/b15.gv that caused these traversal loops to eventually reach the start of this linked list and then dereference a null pointer. The fix in this commit is to simply treat the head of the list as the original edge if we have not encountered a normal edge before then. Whether this is correct or not seems unimportant, as a graph that causes this scenario is incorrect. This change turns a crash during path construction into a graceful exit later when the lack of normal edges is discovered. This fix has similarities with 84e468e775e1d1b293624f1c8e70c226eb4a6e41. Perhaps the code base should be audited for all such traversal loops, which seem to have been written prior to a time when constructing a non-normal-edge-containing list became possible. Gitlab: fixes #827 --- CHANGELOG.md | 1 + lib/common/splines.c | 12 ++++++++---- tests/test_regression.py | 1 - 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c8addf28..f79ca989e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Segmentation Fault with splines="ortho". #1658 - Transparent Label appear in SVG output #146 - Binary tcl modules should compile with -module #1285 +- b15.gv crashes dot #827 ## [4.0.0] – 2022-05-29 diff --git a/lib/common/splines.c b/lib/common/splines.c index b16cae792..98aa60165 100644 --- a/lib/common/splines.c +++ b/lib/common/splines.c @@ -476,7 +476,8 @@ beginpath(path * P, edge_t * e, int et, pathend_t * endp, bool merge) endp->boxn = 1; ++P->start.p.x; } - for (orig = e; ED_edge_type(orig) != NORMAL; orig = ED_to_orig(orig)); + for (orig = e; ED_to_orig(orig) != NULL && ED_edge_type(orig) != NORMAL; + orig = ED_to_orig(orig)); if (n == agtail(orig)) ED_tail_port(orig).clip = false; else @@ -541,7 +542,8 @@ beginpath(path * P, edge_t * e, int et, pathend_t * endp, bool merge) endp->boxn = 1; ++P->start.p.x; } - for (orig = e; ED_edge_type(orig) != NORMAL; orig = ED_to_orig(orig)); + for (orig = e; ED_to_orig(orig) != NULL && ED_edge_type(orig) != NORMAL; + orig = ED_to_orig(orig)); if (n == agtail(orig)) ED_tail_port(orig).clip = false; else @@ -670,7 +672,8 @@ void endpath(path * P, edge_t * e, int et, pathend_t * endp, bool merge) endp->boxn = 1; ++P->end.p.x; } - for (orig = e; ED_edge_type(orig) != NORMAL; orig = ED_to_orig(orig)); + for (orig = e; ED_to_orig(orig) != NULL && ED_edge_type(orig) != NORMAL; + orig = ED_to_orig(orig)); if (n == aghead(orig)) ED_head_port(orig).clip = false; else @@ -737,7 +740,8 @@ void endpath(path * P, edge_t * e, int et, pathend_t * endp, bool merge) endp->boxn = 1; ++P->end.p.x; } - for (orig = e; ED_edge_type(orig) != NORMAL; orig = ED_to_orig(orig)); + for (orig = e; ED_to_orig(orig) != NULL && ED_edge_type(orig) != NORMAL; + orig = ED_to_orig(orig)); if (n == aghead(orig)) ED_head_port(orig).clip = false; else diff --git a/tests/test_regression.py b/tests/test_regression.py index cce35d8af..ca89458ab 100644 --- a/tests/test_regression.py +++ b/tests/test_regression.py @@ -363,7 +363,6 @@ def test_797(): # the escape sequences should have been preserved assert "& &" in output -@pytest.mark.xfail() def test_827(): """ Graphviz should not crash when processing the b15.gv example -- 2.40.0