lune_utils/process/
mod.rs1use std::ffi::{OsStr, OsString};
2
3use mlua::prelude::*;
4use os_str_bytes::{OsStrBytes, OsStringBytes};
5
6mod args;
7mod env;
8mod jit;
9
10pub use self::args::ProcessArgs;
11pub use self::env::ProcessEnv;
12pub use self::jit::ProcessJitEnablement;
13
14fn lua_value_to_os_string(res: LuaResult<LuaValue>, to: &'static str) -> LuaResult<OsString> {
15 let (btype, bs) = match res {
16 Ok(LuaValue::String(s)) => ("string", s.as_bytes().to_vec()),
17 Ok(LuaValue::Buffer(b)) => ("buffer", b.to_vec()),
18 res => {
19 let vtype = match res {
20 Ok(v) => v.type_name(),
21 Err(_) => "unknown",
22 };
23 return Err(LuaError::FromLuaConversionError {
24 from: vtype,
25 to: String::from(to),
26 message: Some(format!(
27 "Expected value to be a string or buffer, got '{vtype}'",
28 )),
29 });
30 }
31 };
32
33 let Some(s) = OsString::from_io_vec(bs) else {
34 return Err(LuaError::FromLuaConversionError {
35 from: btype,
36 to: String::from(to),
37 message: Some(String::from("Expected {btype} to contain valid OS bytes")),
38 });
39 };
40
41 Ok(s)
42}
43
44fn validate_os_key(key: &OsStr) -> LuaResult<()> {
45 let Some(key) = key.to_io_bytes() else {
46 return Err(LuaError::runtime("Key must be IO-safe"));
47 };
48 if key.is_empty() {
49 Err(LuaError::runtime("Key must not be empty"))
50 } else if key.contains(&b'=') {
51 Err(LuaError::runtime(
52 "Key must not contain the equals character '='",
53 ))
54 } else if key.contains(&b'\0') {
55 Err(LuaError::runtime("Key must not contain the NUL character"))
56 } else {
57 Ok(())
58 }
59}
60
61fn validate_os_value(val: &OsStr) -> LuaResult<()> {
62 let Some(val) = val.to_io_bytes() else {
63 return Err(LuaError::runtime("Value must be IO-safe"));
64 };
65 if val.contains(&b'\0') {
66 Err(LuaError::runtime(
67 "Value must not contain the NUL character",
68 ))
69 } else {
70 Ok(())
71 }
72}
73
74fn validate_os_pair((key, value): (&OsStr, &OsStr)) -> LuaResult<()> {
75 validate_os_key(key)?;
76 validate_os_value(value)?;
77 Ok(())
78}