Graphviz 16.1.0 C Bug & Hazard Ledger (docs/c-bugs-ledger.md)
Copied at build time from docs/c-bugs-ledger.md.
Ledger Summary
Section titled “Ledger Summary”| Bug ID | Upstream C Location | Category | Severity | Status in graphviz-pure |
|---|---|---|---|---|
| GV-BUG-001 | lib/cgraph/scan.l (line_num, InputFile, Sbuf, lexbuf) |
Re-entrancy / Global Mutable State | High (Corrupts concurrent parses) | Fixed (State encapsulated in Lexer<'a>) |
| GV-BUG-002 | lib/common/ns.c (Tree_node, Tree_edge, Low, Lim, Slack) |
Re-entrancy / Global Mutable State | Critical (Crashes concurrent Network Simplex layouts) | Not applicable (network_simplex_solve in crates/graphviz-pure-layout/src/dot.rs keeps all state in local variables, so there are no globals to encapsulate; there is no SimplexSolver type, and the loop is a simplified port of ns.c, capped at NS_MAX_ITER) |
| GV-BUG-003 | lib/dotgen/mincross.c (Root, GlobalMinRank, GlobalMaxRank, TE_list, TI_list) |
Re-entrancy / Global Mutable State | High (Corrupts crossing minimization across threads/workers) | Not applicable (mincross state lives in the local VirtualGraph in crates/graphviz-pure-layout/src/dot.rs, not in globals; there is no MincrossWorkspace type) |
| GV-BUG-004 | lib/util/exit.h (graphviz_exit), lib/cgraph/agerror.c (AGMAX) |
Process Abort on Recoverable Error | Critical (Traps WASM module / kills host process) | Fixed (Replaced with Result<T, GraphvizError>) |
| GV-BUG-005 | lib/cgraph/grammar.y & lib/common/htmlparse.y |
Memory Leak on Syntax Error | Medium (Leaks AST/HTML strings on malformed input) | Fixed (RAII drop + arena-scoped allocations) |
| GV-BUG-006 | lib/common/splines.c & lib/common/arrows.c |
Numerical (NaN propagation on zero-length edge vectors) |
Medium (Produces NaN in SVG path d="..." attributes) |
Fixed (Explicit epsilon / zero-length vector guards) |
| GV-BUG-007 | lib/common/ns.c (tight_tree / enter_edge floating-point slack tie-breaking) |
Non-determinism / Infinite Pivot Loop | Medium (Pointer-address order & float drift across architectures) | Partly addressed (the pivot loop is capped at NS_MAX_ITER = 2000 iterations; leaving and entering edges are chosen by index scan order, with no pointer-address ordering; this is not a line-for-line port of ns.c) |
| GV-BUG-008 | lib/dotgen/compound.c & lib/dotgen/fastgr.c |
Dangling Virtual Edge / Node Pointers | High (Use-after-free when deleting cloned virtual edges) | Not applicable / not yet ported (compound.c is not ported, so compound=true edge clipping is absent; the layout code uses plain NodeId/EdgeId u32 indices into Vecs instead of pointers, which are not generational, so cloned virtual edges cannot dangle) |
| GV-BUG-009 | lib/pathplan/shortest.c & lib/pathplan/route.c |
Unchecked Stack/Heap Scratch Growth & Degenerate Triangle Collinearity | Medium (Collinear polygon vertices can fail Pshortestpath) | Not applicable / not yet ported (pathplan and Pshortestpath are not ported; edge routing in crates/graphviz-pure-geom/src/splines.rs is a simpler spline router with a collinear-control-point guard in clip_spline_arrowheads) |
| GV-BUG-010 | lib/cgraph/refstr.c (Refstr_t bitfield counter overflow & global dict) |
Reference Count / Thread-Safety | Medium (Shared static string dict is not thread-safe) | Not applicable (there is no global string dictionary and no StringInterner: names and attribute values are owned Strings in Graph, so there is no shared refcount to overflow) |
| GV-BUG-011 | lib/common/textspan.c & textspan_lut.c (estimate_textspan_size) |
Font Alias Ignored in LUT Width Lookup | Medium ("Times-Bold" / "Helvetica-Bold" ignores postscript_alias and falls back to non-bold Times width) |
Reproduced (output fidelity wins: estimate_text_width_1pt looks the name up in the LUT families only, as C does; Times-Bold measures as regular Times) |
| GV-BUG-012 | lib/common/labels.c (storeline empty line height truncation) |
Integer Truncation Bug | Low (Empty lines cast (int)(fontsize * 1.20) losing .8 pt vs non-empty lines) |
Reproduced (storeline truncates empty-line height to (int)(fontsize * 1.2) exactly like C; node/label sizes depend on it) |
| GV-BUG-013 | lib/common/textspan_lut.c (estimate_text_width_1pt UTF-8 byte loop) |
Multi-byte UTF-8 Mis-measurement | Medium (Iterates const char * byte-by-byte, counting 1 UTF-8 codepoint as 3–4 spaces) |
Reproduced (measures text.bytes(), each byte >= 0x80 as a space, matching C widths) |
| GV-BUG-014 | lib/common/colxlate.c (colorxlate permissive sscanf & _Thread_local leak) |
Memory Leak & Malformed Hex Parsing | Low (setColorScheme leaks gv_strdup buffer; sscanf accepts 5-digit hex strings) |
Fixed in part (setColorScheme is not ported: the colorscheme is a function argument, so nothing leaks. colorxlate hex parsing now deliberately follows the C sscanf semantics, so a 5-digit #12345 is accepted as in C) |
| GV-BUG-015 | lib/common/shapes.c (parse_reclbl shared text/port buffer) |
Aliased Buffers | Low (abc <p> def writes the port name over the field text, so the field label becomes empty; text typed while a port is open lands in the text buffer) |
Reproduced (byte-level port in graphviz_pure_geom::node_size keeps one buffer with C’s pointer arithmetic) |
| GV-BUG-016 | lib/common/shapes.c (parse_reclbl ishardspace) |
Sticky Flag | Low (after the first \ hard space, every later space in the same field list is kept, and a leading hard space is dropped) |
Reproduced |
| GV-BUG-017 | lib/common/htmltable.c (size_html_tbl static textfont_t savef) |
Shared Static State | Low (nested tables with <FONT> overwrite the outer table’s saved font, so the restored font can leak to later cells) |
Reproduced (one save slot shared by every nesting level) |
| GV-BUG-018 | lib/common/htmltable.c (pos_html_tbl fixed-size ALIGN="LEFT") |
Wrong Variable | Low (uses the table height as the width when left-aligning a FIXEDSIZE table) |
Reproduced |
| GV-BUG-019 | lib/common/htmltable.c (make_html_label on parse error) |
Silent Label Loss | Low (any expat/grammar error, e.g. <b>x</B>, leaves the label with dimen = 0 and nothing drawn instead of falling back to text) |
Reproduced |