Skip to content

Commit 156f141

Browse files
author
Riccardo Strina
committed
Quote args containing spaces in ArgsStringOrList
When ArgsStringOrList::List elements contain spaces, they are now wrapped in double quotes before joining. This prevents the debugger from splitting paths with spaces into multiple arguments. Add tests covering list with spaces, list without spaces, single element with spaces, empty list, and single string passthrough.
1 parent 3392cb7 commit 156f141

6 files changed

Lines changed: 81 additions & 2 deletions

File tree

src/util.rs

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ pub fn should_use_local_or_download(
414414
/// A type that can be deserialized from either a single string or a list of strings.
415415
///
416416
/// When serialized, it always produces a single string. If it was a list,
417-
/// the elements are joined with a space.
417+
/// the elements are joined with a space, quoting elements that contain spaces.
418418
#[derive(Deserialize, Debug, Clone)]
419419
#[serde(untagged)]
420420
pub enum ArgsStringOrList {
@@ -429,7 +429,71 @@ impl Serialize for ArgsStringOrList {
429429
{
430430
match self {
431431
ArgsStringOrList::String(s) => serializer.serialize_str(s),
432-
ArgsStringOrList::List(l) => serializer.serialize_str(&l.join(" ")),
432+
ArgsStringOrList::List(l) => {
433+
let quoted: Vec<String> = l
434+
.iter()
435+
.map(|s| if s.contains(' ') { format!("\"{}\"", s) } else { s.clone() })
436+
.collect();
437+
serializer.serialize_str(&quoted.join(" "))
438+
}
433439
}
434440
}
435441
}
442+
443+
#[cfg(test)]
444+
mod tests {
445+
use super::*;
446+
use serde_json;
447+
448+
#[derive(Deserialize, Serialize)]
449+
struct ArgsWrapper {
450+
args: ArgsStringOrList,
451+
}
452+
453+
#[test]
454+
fn test_args_list_with_spaces_quotes_elements() {
455+
let json = std::fs::read_to_string("testdata/args_with_spaces.json").unwrap();
456+
let wrapper: ArgsWrapper = serde_json::from_str(&json).unwrap();
457+
let serialized = serde_json::to_value(&wrapper).unwrap();
458+
assert_eq!(
459+
serialized["args"],
460+
r#""C:\path with spaces\some file.txt" arg2"#
461+
);
462+
}
463+
464+
#[test]
465+
fn test_args_single_string_preserved_as_is() {
466+
let json = std::fs::read_to_string("testdata/args_single_string.json").unwrap();
467+
let wrapper: ArgsWrapper = serde_json::from_str(&json).unwrap();
468+
let serialized = serde_json::to_value(&wrapper).unwrap();
469+
assert_eq!(
470+
serialized["args"],
471+
r#"C:\path with spaces\some file.txt"#
472+
);
473+
}
474+
475+
#[test]
476+
fn test_args_list_no_spaces_not_quoted() {
477+
let json = std::fs::read_to_string("testdata/args_list_no_spaces.json").unwrap();
478+
let wrapper: ArgsWrapper = serde_json::from_str(&json).unwrap();
479+
let serialized = serde_json::to_value(&wrapper).unwrap();
480+
assert_eq!(serialized["args"], "arg1 arg2");
481+
}
482+
483+
#[test]
484+
fn test_args_single_element_with_spaces_quoted() {
485+
let json =
486+
std::fs::read_to_string("testdata/args_single_element_with_spaces.json").unwrap();
487+
let wrapper: ArgsWrapper = serde_json::from_str(&json).unwrap();
488+
let serialized = serde_json::to_value(&wrapper).unwrap();
489+
assert_eq!(serialized["args"], r#""path with spaces""#);
490+
}
491+
492+
#[test]
493+
fn test_args_empty_list() {
494+
let json = std::fs::read_to_string("testdata/args_empty_list.json").unwrap();
495+
let wrapper: ArgsWrapper = serde_json::from_str(&json).unwrap();
496+
let serialized = serde_json::to_value(&wrapper).unwrap();
497+
assert_eq!(serialized["args"], "");
498+
}
499+
}

testdata/args_empty_list.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"args": []
3+
}

testdata/args_list_no_spaces.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"args": ["arg1", "arg2"]
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"args": ["path with spaces"]
3+
}

testdata/args_single_string.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"args": "C:\\path with spaces\\some file.txt"
3+
}

testdata/args_with_spaces.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"args": ["C:\\path with spaces\\some file.txt", "arg2"]
3+
}

0 commit comments

Comments
 (0)