]> granicus.if.org Git - graphviz/commitdiff
fix: anticipate non-normal edges during path construction
authorMatthew Fernandez <matthew.fernandez@gmail.com>
Sat, 18 Jun 2022 22:23:41 +0000 (15:23 -0700)
committerMatthew Fernandez <matthew.fernandez@gmail.com>
Thu, 23 Jun 2022 00:11:54 +0000 (17:11 -0700)
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
lib/common/splines.c
tests/test_regression.py

index 6c8addf2896f181cf3cc30aca589e3e769df4725..f79ca989ea3680080deb7a5c83c301e158c0ddb1 100644 (file)
@@ -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
 
index b16cae792e8be1ff1b8b32b8f81594417625ab34..98aa6016526698de9c7e493803b6243971844aa3 100644 (file)
@@ -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
index cce35d8af392be6bfcb176cf1397e58ab1d27f1b..ca89458ab7dabf0663bb82508c4a893dd61291a4 100644 (file)
@@ -363,7 +363,6 @@ def test_797():
   # the escape sequences should have been preserved
   assert "&amp; &amp;" in output
 
-@pytest.mark.xfail()
 def test_827():
   """
   Graphviz should not crash when processing the b15.gv example