From e7b42aae6b9176e3417b51cd9ce8cb989ad16dfc Mon Sep 17 00:00:00 2001 From: Jens Reimann Date: Thu, 21 Aug 2025 10:57:28 +0200 Subject: [PATCH] fix(analysis): properly escape when exporting to graphviz --- .../analysis/src/service/render/graphviz.rs | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/modules/analysis/src/service/render/graphviz.rs b/modules/analysis/src/service/render/graphviz.rs index fb84afb39..4fc9b6e96 100644 --- a/modules/analysis/src/service/render/graphviz.rs +++ b/modules/analysis/src/service/render/graphviz.rs @@ -1,18 +1,32 @@ -use crate::service::Visitor; +use crate::{ + model::graph::{self, Node}, + service::Visitor, +}; +use std::fmt::Write; use trustify_entity::relationship::Relationship; +/// Escape a string to be used as dot string value. The result +/// must be placed within double quotes. +/// +/// Double quotes and backspace are prefixed with another backspace. +/// +/// Newlines are replaced with `\n`. CR, form-feed, and backspace are +/// just dropped. fn escape(id: &str) -> String { let mut escaped = String::with_capacity(id.len()); for ch in id.chars() { match ch { - '"' => { + '"' | '\\' => { escaped.push('\\'); escaped.push(ch); } '\n' => { escaped.push_str("\\n"); } + '\r' | '\x08' | '\x0C' => { + // just drop + } _ => escaped.push(ch), } } @@ -20,10 +34,6 @@ fn escape(id: &str) -> String { escaped } -use crate::model::graph; -use crate::model::graph::Node; -use std::fmt::Write; - pub struct Renderer { data: String, } @@ -104,9 +114,9 @@ impl Visitor for Renderer { #[cfg(test)] mod test { - #[test] fn escape() { assert_eq!(super::escape("foo\"bar\nbaz"), r#"foo\"bar\nbaz"#); + assert_eq!(super::escape("foo\\\"bar\rbaz"), r#"foo\\\"barbaz"#); } }