diff --git a/stdlib/src/notification.rs b/stdlib/src/notification.rs index 8db24c7a..67b0e6e5 100644 --- a/stdlib/src/notification.rs +++ b/stdlib/src/notification.rs @@ -33,13 +33,24 @@ impl StdlibRegistry { #[cfg(target_os = "windows")] { use std::process::Command; + use base64::Engine; + let b64_title = base64::prelude::BASE64_STANDARD.encode(title.as_bytes()); + let b64_body = base64::prelude::BASE64_STANDARD.encode(body.as_bytes()); + let script_text = format!( + "[System.Windows.MessageBox]::Show(\ + [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String('{}')), \ + [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String('{}'))\ + )", + b64_body, b64_title + ); + let mut script_utf16: Vec = Vec::with_capacity(script_text.len() * 2); + for c in script_text.encode_utf16() { + script_utf16.push((c & 0xFF) as u8); + script_utf16.push((c >> 8) as u8); + } + let encoded_cmd = base64::prelude::BASE64_STANDARD.encode(&script_utf16); let _ = Command::new("powershell") - .env("TS_NOTIFY_TITLE", &title) - .env("TS_NOTIFY_BODY", &body) - .args([ - "-Command", - "[System.Windows.MessageBox]::Show($env:TS_NOTIFY_BODY, $env:TS_NOTIFY_TITLE)" - ]) + .args(["-NoProfile", "-EncodedCommand", &encoded_cmd]) .spawn(); } #[cfg(not(target_os = "windows"))] diff --git a/stdlib/tests/stdlib_tests.rs b/stdlib/tests/stdlib_tests.rs index ce296064..50a54c49 100644 --- a/stdlib/tests/stdlib_tests.rs +++ b/stdlib/tests/stdlib_tests.rs @@ -540,7 +540,9 @@ fn test_http_module() { &mut ctx_unprivileged, vec![RuntimeValue::Str(format!("http://127.0.0.1:{}", port))], ); - assert!(matches!(res_get, Err(techscript_runtime::RuntimeError { kind: techscript_runtime::RuntimeErrorKind::InvalidOperation(msg), .. }) if msg.contains("Security policy violation"))); + assert!( + matches!(res_get, Err(techscript_runtime::RuntimeError { kind: techscript_runtime::RuntimeErrorKind::InvalidOperation(msg), .. }) if msg.contains("Security policy violation")) + ); let post = http.exports.get("post").unwrap(); let res_post = post.call( @@ -550,7 +552,9 @@ fn test_http_module() { RuntimeValue::Str("body".to_string()), ], ); - assert!(matches!(res_post, Err(techscript_runtime::RuntimeError { kind: techscript_runtime::RuntimeErrorKind::InvalidOperation(msg), .. }) if msg.contains("Security policy violation"))); + assert!( + matches!(res_post, Err(techscript_runtime::RuntimeError { kind: techscript_runtime::RuntimeErrorKind::InvalidOperation(msg), .. }) if msg.contains("Security policy violation")) + ); // Test with Network capability let mut caps = HashSet::new();