1use base64::Engine;
6use base64::engine::general_purpose::STANDARD as B64;
7
8#[derive(Debug)]
14pub struct CommandOutput {
15 pub stdout: Vec<u8>,
17 pub stderr: Vec<u8>,
19 pub exit_code: i32,
21}
22
23pub fn encode_powershell_command(script: &str) -> String {
29 let mut utf16 = Vec::with_capacity(script.len() * 2);
30 for c in script.encode_utf16() {
31 utf16.extend_from_slice(&c.to_le_bytes());
32 }
33 B64.encode(&utf16)
34}
35
36#[cfg(test)]
37mod tests {
38 use super::*;
39
40 #[test]
41 fn encode_powershell_roundtrip() {
42 let script = "Get-Process";
43 let encoded = encode_powershell_command(script);
44
45 let decoded_bytes = B64.decode(&encoded).unwrap();
47 let u16s: Vec<u16> = decoded_bytes
48 .chunks_exact(2)
49 .map(|c| u16::from_le_bytes([c[0], c[1]]))
50 .collect();
51 let decoded = String::from_utf16(&u16s).unwrap();
52 assert_eq!(decoded, script);
53 }
54
55 #[test]
56 fn encode_powershell_unicode() {
57 let script = "Write-Output 'h\u{00e9}llo w\u{00f6}rld'";
59 let encoded = encode_powershell_command(script);
60 let decoded_bytes = B64.decode(&encoded).unwrap();
61 let u16s: Vec<u16> = decoded_bytes
62 .chunks_exact(2)
63 .map(|c| u16::from_le_bytes([c[0], c[1]]))
64 .collect();
65 let decoded = String::from_utf16(&u16s).unwrap();
66 assert_eq!(decoded, script);
67 }
68
69 #[test]
70 fn encode_powershell_empty() {
71 let encoded = encode_powershell_command("");
72 assert!(encoded.is_empty());
74 }
75}