diff --git a/crates/engine/src/cmd/layer.rs b/crates/engine/src/cmd/layer.rs index 806641ef6..c5fa89403 100644 --- a/crates/engine/src/cmd/layer.rs +++ b/crates/engine/src/cmd/layer.rs @@ -182,7 +182,7 @@ fn loaded_linetype(d: &cadcraft_doc::Drawing, cmd: &str, p: &Value) -> Result bool { - !n.trim().is_empty() && n.len() <= 255 && !n.chars().any(|c| "<>/\\\":;?*|,=`".contains(c)) + !n.trim().is_empty() && n.len() <= 255 && !n.chars().any(|c| c.is_control() || "<>/\\\":;?*|,=`".contains(c)) } fn run_new(s: &mut Session, p: &Value) -> Result { diff --git a/crates/engine/tests/layer_name_control_chars.rs b/crates/engine/tests/layer_name_control_chars.rs new file mode 100644 index 000000000..4e00a1454 --- /dev/null +++ b/crates/engine/tests/layer_name_control_chars.rs @@ -0,0 +1,14 @@ +//! `layer.new` refuses control characters in a layer name (the DXF writer would turn them into +//! spaces and the name would change on reopen). + +use cadcraft_engine::Session; +use serde_json::json; + +#[test] +fn layer_new_rejects_control_characters() { + let mut s = Session::new(); + for name in ["A\nB", "A\tB", "A\u{0}B"] { + assert!(s.execute("layer.new", &json!({"name": name})).is_err(), "{name:?} was accepted"); + } + assert!(s.execute("layer.new", &json!({"name": "A B"})).is_ok()); +}