Skip to content

Commit cf74c1f

Browse files
authored
fix: prevent empty separators (#108)
1 parent c426193 commit cf74c1f

File tree

3 files changed

+50
-2
lines changed

3 files changed

+50
-2
lines changed

src/env.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::json::JsonValueCommand;
2+
use crate::non_empty_separator;
23
use crate::ValueReader;
34
use clap::Args;
45
use serde_json::{Map, Value};
@@ -18,7 +19,7 @@ pub struct EnvArgs {
1819
#[arg(long)]
1920
expand_path: bool,
2021
/// Separator to use when expanding the Path variable. Defaults to the platform-specific separator.
21-
#[arg(long, requires = "expand_path")]
22+
#[arg(long, requires = "expand_path", value_parser = non_empty_separator)]
2223
path_separator: Option<String>,
2324
}
2425

@@ -103,6 +104,12 @@ mod tests {
103104
use crate::testing::TestBuffer;
104105
use serde_json::json;
105106

107+
#[derive(clap::Parser, Debug)]
108+
struct EnvArgsParser {
109+
#[command(flatten)]
110+
args: EnvArgs,
111+
}
112+
106113
fn env_args_from_stdin() -> EnvArgs {
107114
let mut args = EnvArgs::default();
108115
args.from_stdin = true;
@@ -356,4 +363,11 @@ mod tests {
356363
args.expand_path_variable(&mut json_value);
357364
assert_eq!(json_value["PATH"], json!(["/usr/bin", "/bin"]));
358365
}
366+
367+
#[test]
368+
fn empty_path_separator_is_rejected() {
369+
use clap::Parser;
370+
let result = EnvArgsParser::try_parse_from(["cmd", "--expand-path", "--path-separator="]);
371+
assert!(result.is_err());
372+
}
359373
}

src/lib.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@ pub mod objects;
88
pub mod strings;
99
pub mod testing;
1010

11+
pub fn non_empty_separator(s: &str) -> Result<String, String> {
12+
if s.is_empty() {
13+
Err("separator must not be empty".to_string())
14+
} else {
15+
Ok(s.to_string())
16+
}
17+
}
18+
1119
pub fn read_all(input: &mut dyn BufRead) -> std::io::Result<String> {
1220
let mut buffer = String::new();
1321
for l in input.lines() {
@@ -53,4 +61,16 @@ mod tests {
5361
let result = read_all(&mut buffer).unwrap();
5462
assert_eq!(result, "Hello, world!\nThis is a test");
5563
}
64+
65+
#[test]
66+
fn non_empty_separator_accepts_non_empty_string() {
67+
assert_eq!(non_empty_separator("="), Ok("=".to_string()));
68+
assert_eq!(non_empty_separator("=="), Ok("==".to_string()));
69+
assert_eq!(non_empty_separator(":"), Ok(":".to_string()));
70+
}
71+
72+
#[test]
73+
fn non_empty_separator_rejects_empty_string() {
74+
assert!(non_empty_separator("").is_err());
75+
}
5676
}

src/objects.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::json::JsonValueCommand;
2+
use crate::non_empty_separator;
23
use crate::ValueReader;
34
use clap::Args;
45
use serde_json::Map;
@@ -20,7 +21,7 @@ pub struct ObjectArgs {
2021
#[arg(long, group = "input")]
2122
empty: bool,
2223
/// Separator between key and value.
23-
#[arg(long, short, default_value = "=")]
24+
#[arg(long, short, default_value = "=", value_parser = non_empty_separator)]
2425
separator: String,
2526
}
2627

@@ -98,6 +99,12 @@ mod tests {
9899
use crate::testing::TestBuffer;
99100
use serde_json::json;
100101

102+
#[derive(clap::Parser, Debug)]
103+
struct ObjectArgsParser {
104+
#[command(flatten)]
105+
args: ObjectArgs,
106+
}
107+
101108
fn object_args(values: Vec<&str>) -> ObjectArgs {
102109
ObjectArgs {
103110
auto: false,
@@ -403,4 +410,11 @@ mod tests {
403410
let result = args.get_json_value();
404411
assert_eq!(result, json!({ "key": "value", "other": "thing" }));
405412
}
413+
414+
#[test]
415+
fn test_object_args_empty_separator_is_rejected() {
416+
use clap::Parser;
417+
let result = ObjectArgsParser::try_parse_from(["cmd", "--separator=", "key=value"]);
418+
assert!(result.is_err());
419+
}
406420
}

0 commit comments

Comments
 (0)