diff --git a/internal/graph/dotgraph.go b/internal/graph/dotgraph.go index d704fc4e13..9776640fe9 100644 --- a/internal/graph/dotgraph.go +++ b/internal/graph/dotgraph.go @@ -247,7 +247,7 @@ func (b *builder) addNodelets(node *Node, nodeID int) bool { continue } weight := b.config.FormatValue(w) - nodelets += fmt.Sprintf(`N%d_%d [label = "%s" id="N%d_%d" fontsize=8 shape=box3d tooltip="%s"]`+"\n", nodeID, i, t.Name, nodeID, i, weight) + nodelets += fmt.Sprintf(`N%d_%d [label = "%s" id="N%d_%d" fontsize=8 shape=box3d tooltip="%s"]`+"\n", nodeID, i, escapeForDot(t.Name), nodeID, i, weight) nodelets += fmt.Sprintf(`N%d -> N%d_%d [label=" %s" weight=100 tooltip="%s" labeltooltip="%s"]`+"\n", nodeID, nodeID, i, weight, weight, weight) if nts := lnts[t.Name]; nts != nil { nodelets += b.numericNodelets(nts, maxNodelets, flatTags, fmt.Sprintf(`N%d_%d`, nodeID, i)) @@ -274,7 +274,7 @@ func (b *builder) numericNodelets(nts []*Tag, maxNumNodelets int, flatTags bool, } if w != 0 { weight := b.config.FormatValue(w) - nodelets += fmt.Sprintf(`N%s_%d [label = "%s" id="N%s_%d" fontsize=8 shape=box3d tooltip="%s"]`+"\n", source, j, t.Name, source, j, weight) + nodelets += fmt.Sprintf(`N%s_%d [label = "%s" id="N%s_%d" fontsize=8 shape=box3d tooltip="%s"]`+"\n", source, j, escapeForDot(t.Name), source, j, weight) nodelets += fmt.Sprintf(`%s -> N%s_%d [label=" %s" weight=100 tooltip="%s" labeltooltip="%s"%s]`+"\n", source, source, j, weight, weight, weight, attr) } } diff --git a/internal/graph/dotgraph_test.go b/internal/graph/dotgraph_test.go index b375bb6225..55ec50c00b 100644 --- a/internal/graph/dotgraph_test.go +++ b/internal/graph/dotgraph_test.go @@ -150,6 +150,39 @@ func TestComposeWithNamesThatNeedEscaping(t *testing.T) { compareGraphs(t, buf.Bytes(), "compose7.dot") } +func TestComposeWithTagNamesThatNeedEscaping(t *testing.T) { + g := baseGraph() + a, c := baseAttrsAndConfig() + + // Add tags with quotes and backslashes to Node 1. + g.Nodes[0].LabelTags[`tag"with"quotes`] = &Tag{ + Name: `tag"with"quotes`, + Cum: 10, + Flat: 10, + } + g.Nodes[0].NumericTags[""] = TagMap{ + `num"tag"`: &Tag{ + Name: `num"tag"`, + Cum: 20, + Flat: 20, + Unit: "ms", + }, + } + + var buf bytes.Buffer + ComposeDot(&buf, g, a, c) + + dot := buf.String() + wantLabel := `label = "tag\"with\"quotes"` + if !strings.Contains(dot, wantLabel) { + t.Errorf("expected dot output to contain %q, but got:\n%s", wantLabel, dot) + } + wantNumLabel := `label = "num\"tag\""` + if !strings.Contains(dot, wantNumLabel) { + t.Errorf("expected dot output to contain %q, but got:\n%s", wantNumLabel, dot) + } +} + func TestComposeWithCommentsWithNewlines(t *testing.T) { g := baseGraph() a, c := baseAttrsAndConfig()