aboutsummaryrefslogtreecommitdiffstats
path: root/src/config.rs
diff options
context:
space:
mode:
authorTomasz Kramkowski <tomasz@kramkow.ski>2025-07-20 12:31:13 +0100
committerTomasz Kramkowski <tomasz@kramkow.ski>2025-07-20 12:31:13 +0100
commit847cfa692b20903a8c6a43c01948ded6db0035a7 (patch)
tree9aa5eb2751c5e6a360776f9585af37a198dbc11c /src/config.rs
parente6ac7b1643e01764c5fccddee985d25bf53494e2 (diff)
downloadmqttr-847cfa692b20903a8c6a43c01948ded6db0035a7.tar.gz
mqttr-847cfa692b20903a8c6a43c01948ded6db0035a7.tar.xz
mqttr-847cfa692b20903a8c6a43c01948ded6db0035a7.zip
Non-UTF8 path/argument support
Diffstat (limited to 'src/config.rs')
-rw-r--r--src/config.rs44
1 files changed, 24 insertions, 20 deletions
diff --git a/src/config.rs b/src/config.rs
index d3fc75b..570994c 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -4,8 +4,8 @@
mod helpers;
use std::{
- collections::HashMap, fs::File, io::Read, os::unix::fs::PermissionsExt, path::Path,
- time::Duration,
+ collections::HashMap, ffi::OsString, fs::File, io::Read, os::unix::fs::PermissionsExt,
+ path::Path, time::Duration,
};
use anyhow::bail;
@@ -66,9 +66,7 @@ fn default_level_filter() -> LevelFilter {
#[derive(Debug, PartialEq, Clone)]
pub struct Program {
- // TODO: Figure out a way to allow arbitrary unix paths (arbitrary
- // non-unicode) without base64
- pub command: Box<[String]>,
+ pub command: Box<[OsString]>,
pub timeout: Option<Duration>,
}
@@ -128,19 +126,25 @@ pub fn load<P: AsRef<Path>>(path: P) -> anyhow::Result<Config> {
mod tests {
use super::*;
use rumqttc::QoS;
- use std::time::Duration;
+ use std::{ffi::OsStr, os::unix::ffi::OsStrExt, time::Duration};
impl Program {
- fn new(command: Vec<&str>) -> Self {
+ fn new(command: Vec<&[u8]>) -> Self {
Program {
- command: command.into_iter().map(str::to_string).collect(),
+ command: command
+ .into_iter()
+ .map(|s| OsStr::from_bytes(s).to_owned())
+ .collect(),
timeout: None,
}
}
- fn new_with_timeout(command: Vec<&str>, timeout: Duration) -> Self {
+ fn new_with_timeout(command: Vec<&[u8]>, timeout: Duration) -> Self {
Program {
- command: command.into_iter().map(str::to_string).collect(),
+ command: command
+ .into_iter()
+ .map(|s| OsStr::from_bytes(s).to_owned())
+ .collect(),
timeout: Some(timeout),
}
}
@@ -170,7 +174,7 @@ mod tests {
{ command = ["/bin/program3", "arg"]},
], qos = "exactly-once" }
"topic/seq" = [
- ["/bin/program4", "arg"],
+ ["/bin/program4", "arg", { b64 = "//9hYmP//w==" }],
{ command = ["/bin/program5"], timeout = 1.2 },
]
"#;
@@ -196,9 +200,9 @@ mod tests {
assert_eq!(
route_map.programs,
vec![
- Program::new(vec!["/bin/program1"]),
- Program::new(vec!["/bin/program2", "arg"]),
- Program::new(vec!["/bin/program3", "arg"]),
+ Program::new(vec![b"/bin/program1"]),
+ Program::new(vec![b"/bin/program2", b"arg"]),
+ Program::new(vec![b"/bin/program3", b"arg"]),
]
.into()
);
@@ -208,8 +212,8 @@ mod tests {
assert_eq!(
route_seq.programs,
vec![
- Program::new(vec!["/bin/program4", "arg"]),
- Program::new_with_timeout(vec!["/bin/program5"], Duration::from_secs_f64(1.2)),
+ Program::new(vec![b"/bin/program4", b"arg", b"\xff\xffabc\xff\xff"]),
+ Program::new_with_timeout(vec![b"/bin/program5"], Duration::from_secs_f64(1.2)),
]
.into()
);
@@ -243,8 +247,8 @@ mod tests {
assert_eq!(
route.programs,
vec![
- Program::new(vec!["/foo/bar"]),
- Program::new(vec!["/baz/qux", "arg"])
+ Program::new(vec![b"/foo/bar"]),
+ Program::new(vec![b"/baz/qux", b"arg"])
]
.into()
);
@@ -264,14 +268,14 @@ mod tests {
let route_with_qos = config.routes.get("topic/with_qos").unwrap();
assert_eq!(
route_with_qos.programs,
- vec![Program::new(vec!["/foo/bar", "arg"])].into()
+ vec![Program::new(vec![b"/foo/bar", b"arg"])].into()
);
assert_eq!(route_with_qos.qos, Some(QoS::AtLeastOnce));
let route_without_qos = config.routes.get("topic/without_qos").unwrap();
assert_eq!(
route_without_qos.programs,
- vec![Program::new(vec!["/baz/qux"])].into()
+ vec![Program::new(vec![b"/baz/qux"])].into()
);
assert_eq!(route_without_qos.qos, None);
}