]> granicus.if.org Git - graphviz/commitdiff
fix: anticipate duplicate nodes in UF_union()
authorMatthew Fernandez <matthew.fernandez@gmail.com>
Sun, 7 Jun 2020 21:47:33 +0000 (14:47 -0700)
committerMatthew Fernandez <matthew.fernandez@gmail.com>
Sun, 7 Jun 2020 21:53:48 +0000 (14:53 -0700)
It is possible to construct (invalid) input to Graphviz that leads to two copies
of the same node being encountered during UF_union(). Previously this would
cause an integer overflow. This was detectable with Undefined Behavior Sanitizer
using the following input:

  digraph G { {rank=same a b     n A;C;E;G;I;K;M;O;Q;S;U;W;Y;
    B;D;F;H;J;L;N;P;R;T;V;X;Z;  }

   a{rank=same a b       A;C;E;G;I;K;M;O;Q;S;U;W;Y    B;D;F;H;J;L;N;P;R;T;V;X;Z;
      }Courier6;
  } ?

We now anticipate this scenario and handle it gracefully, copying the pattern
from UF_union() in lib/spine/union_find.c. Fixes #1682. This issue was
originally found by the Google Autofuzz project.

lib/common/utils.c

index 2e8bf039928e9acc96e75417dc41cc6006258c93..c574ddc0e0044a6dc2e11729349bd28bd7810b88 100644 (file)
@@ -167,6 +167,9 @@ node_t *UF_union(node_t * u, node_t * v)
        ND_UF_size(v) = 1;
     } else
        v = UF_find(v);
+       /* if we have two copies of the same node, their union is just that node */
+    if (u == v)
+       return u;
     if (ND_id(u) > ND_id(v)) {
        ND_UF_parent(u) = v;
        ND_UF_size(v) += ND_UF_size(u);