hardware_enclave/internal/core/
quoting.rs1#![allow(dead_code, unused_imports, unused_qualifications, unreachable_patterns)]
2pub fn quote_config_value(value: &str) -> String {
19 if value.is_empty() {
20 return "\"\"".to_string();
21 }
22
23 let needs_quoting = value
24 .chars()
25 .any(|c| c.is_whitespace() || c == '"' || c == '\\');
26
27 if needs_quoting {
28 let escaped = value.replace('\\', "\\\\").replace('"', "\\\"");
29 format!("\"{escaped}\"")
30 } else {
31 value.to_string()
32 }
33}
34
35pub fn quote_ssh_path(path: &std::path::Path) -> String {
40 let s = path.display().to_string();
41
42 #[cfg(windows)]
43 let s = s.replace('\\', "/");
44
45 if s.contains(' ') {
46 format!("\"{s}\"")
47 } else {
48 s
49 }
50}
51
52pub fn quote_credential_process_arg(path: &std::path::Path) -> String {
56 quote_config_value(&path.display().to_string())
57}
58
59#[cfg(test)]
60#[allow(clippy::unwrap_used, clippy::panic)]
61mod tests {
62 use super::*;
63 use std::path::PathBuf;
64
65 #[test]
66 fn quote_config_value_no_quoting_needed() {
67 assert_eq!(quote_config_value("simple-path"), "simple-path");
68 assert_eq!(quote_config_value("/usr/bin/awsenc"), "/usr/bin/awsenc");
69 }
70
71 #[test]
72 fn quote_config_value_empty() {
73 assert_eq!(quote_config_value(""), "\"\"");
74 }
75
76 #[test]
77 fn quote_config_value_with_spaces() {
78 assert_eq!(
79 quote_config_value("/Program Files/app/bin"),
80 "\"/Program Files/app/bin\""
81 );
82 }
83
84 #[test]
85 fn quote_config_value_with_backslashes() {
86 assert_eq!(
87 quote_config_value("C:\\Users\\jay\\bin"),
88 "\"C:\\\\Users\\\\jay\\\\bin\""
89 );
90 }
91
92 #[test]
93 fn quote_config_value_with_quotes() {
94 assert_eq!(
95 quote_config_value("value with \"quotes\""),
96 "\"value with \\\"quotes\\\"\""
97 );
98 }
99
100 #[test]
101 fn quote_config_value_mixed() {
102 assert_eq!(
103 quote_config_value("C:\\Program Files\\app"),
104 "\"C:\\\\Program Files\\\\app\""
105 );
106 }
107
108 #[test]
109 fn quote_ssh_path_simple() {
110 let path = PathBuf::from("/home/user/.sshenc/agent.sock");
111 assert_eq!(quote_ssh_path(&path), "/home/user/.sshenc/agent.sock");
112 }
113
114 #[test]
115 fn quote_ssh_path_with_spaces() {
116 let path = PathBuf::from("/home/my user/.sshenc/agent.sock");
117 assert_eq!(
118 quote_ssh_path(&path),
119 "\"/home/my user/.sshenc/agent.sock\""
120 );
121 }
122
123 #[test]
124 fn quote_credential_process_simple() {
125 let path = PathBuf::from("/usr/local/bin/awsenc");
126 assert_eq!(quote_credential_process_arg(&path), "/usr/local/bin/awsenc");
127 }
128
129 #[test]
130 fn quote_credential_process_with_spaces() {
131 let path = PathBuf::from("/Program Files/awsenc/awsenc");
132 assert_eq!(
133 quote_credential_process_arg(&path),
134 "\"/Program Files/awsenc/awsenc\""
135 );
136 }
137
138 #[test]
139 fn quote_config_value_with_tab() {
140 let result = quote_config_value("key\tvalue");
142 assert!(result.starts_with('"'));
143 assert!(result.ends_with('"'));
144 }
145
146 #[test]
147 fn quote_config_value_only_backslash() {
148 assert_eq!(quote_config_value("\\"), "\"\\\\\"");
149 }
150
151 #[test]
152 fn quote_config_value_only_double_quote() {
153 assert_eq!(quote_config_value("\""), "\"\\\"\"");
154 }
155
156 #[test]
157 fn quote_config_value_backslash_and_space() {
158 let result = quote_config_value("C:\\Program Files");
160 assert!(result.starts_with('"'));
161 assert!(result.contains("\\\\"));
162 assert!(result.contains(' '));
163 }
164
165 #[test]
166 fn quote_config_value_newline_is_quoted() {
167 let result = quote_config_value("line1\nline2");
169 assert!(result.starts_with('"'));
170 }
171
172 #[test]
173 fn quote_ssh_path_no_spaces_not_quoted() {
174 let path = PathBuf::from("/home/user/bin");
175 let result = quote_ssh_path(&path);
176 assert!(!result.starts_with('"'));
177 assert_eq!(result, "/home/user/bin");
178 }
179
180 #[test]
181 fn quote_credential_process_backslash_path() {
182 let path = PathBuf::from("C:\\Windows\\System32\\app.exe");
184 let result = quote_credential_process_arg(&path);
185 assert!(result.starts_with('"'));
186 assert!(result.contains("\\\\"));
188 }
189}