ignition_core/deploy/
mod.rs1pub mod apply;
13pub mod layout;
14pub mod ledger;
15pub mod lint;
16pub mod manifest;
17pub mod node;
18#[cfg(any(windows, test))]
19pub(crate) mod owner_acl;
20pub mod pair;
21pub mod plan;
22pub mod project_artifact;
23pub mod projects;
24pub mod pull;
25pub mod render;
26pub mod rules;
27pub mod target;
28pub mod transport;
29pub mod tree;
30pub mod uuid;
31pub mod verify;
32pub mod yamlio;
33
34pub fn component_problem(name: &str) -> Option<&'static str> {
41 if name.is_empty() {
42 Some("must not be empty")
43 } else if name == "." || name == ".." {
44 Some("must not be `.` or `..`")
45 } else if name.contains('/') || name.contains('\\') {
46 Some("must not contain a path separator")
47 } else if name.contains('\0') {
48 Some("must not contain a NUL byte")
49 } else if name.starts_with('.') {
50 Some("must not start with `.`")
51 } else {
52 None
53 }
54}
55
56#[cfg(test)]
57mod tests {
58 use super::component_problem;
59
60 #[test]
61 fn safe_names_pass() {
62 for ok in ["prod", "gw-1", "my_gateway", "a.b", "Ignition 8"] {
63 assert_eq!(component_problem(ok), None, "{ok}");
64 }
65 }
66
67 #[test]
68 fn unsafe_names_are_refused() {
69 for bad in [
70 "", ".", "..", "a/b", "a\\b", "a\0b", ".hidden", "../x", "/abs",
71 ] {
72 assert!(component_problem(bad).is_some(), "{bad:?}");
73 }
74 }
75}