• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! These Windows-only tests are ported from the Unix-only tests in
2 //! tests/utf16.rs. The tests that use StrictUtf8 mode are omitted here,
3 //! because that's a Unix-only feature.
4 
5 #![cfg(windows)]
6 
7 use clap::{arg, value_parser, Command};
8 use std::ffi::OsString;
9 use std::os::windows::ffi::OsStringExt;
10 
11 // Take a slice of ASCII bytes, convert them to UTF-16, and then append a
12 // dangling surrogate character to make the result invalid UTF-16.
bad_osstring(ascii: &[u8]) -> OsString13 fn bad_osstring(ascii: &[u8]) -> OsString {
14     let mut wide_chars: Vec<u16> = ascii.iter().map(|&c| c as u16).collect();
15     // UTF-16 surrogate characters are only valid in pairs.
16     let surrogate_char: u16 = 0xDC00;
17     wide_chars.push(surrogate_char);
18     let os = OsString::from_wide(&wide_chars);
19     assert!(os.to_str().is_none(), "invalid Unicode");
20     os
21 }
22 
23 #[test]
invalid_utf16_positional()24 fn invalid_utf16_positional() {
25     let r = Command::new("bad_utf16")
26         .arg(arg!(<arg> "some arg").value_parser(value_parser!(OsString)))
27         .try_get_matches_from(vec![OsString::from(""), bad_osstring(b"")]);
28     assert!(r.is_ok(), "{}", r.unwrap_err());
29     let m = r.unwrap();
30     assert!(m.contains_id("arg"));
31     assert_eq!(&*m.get_one::<OsString>("arg").unwrap(), &*bad_osstring(b""));
32 }
33 
34 #[test]
invalid_utf16_option_short_space()35 fn invalid_utf16_option_short_space() {
36     let r = Command::new("bad_utf16")
37         .arg(arg!(-a --arg <arg> "some arg").value_parser(value_parser!(OsString)))
38         .try_get_matches_from(vec![
39             OsString::from(""),
40             OsString::from("-a"),
41             bad_osstring(b""),
42         ]);
43     assert!(r.is_ok(), "{}", r.unwrap_err());
44     let m = r.unwrap();
45     assert!(m.contains_id("arg"));
46     assert_eq!(&*m.get_one::<OsString>("arg").unwrap(), &*bad_osstring(b""));
47 }
48 
49 #[test]
invalid_utf16_option_short_equals()50 fn invalid_utf16_option_short_equals() {
51     let r = Command::new("bad_utf16")
52         .arg(arg!(-a --arg <arg> "some arg").value_parser(value_parser!(OsString)))
53         .try_get_matches_from(vec![OsString::from(""), bad_osstring(b"-a=")]);
54     assert!(r.is_ok(), "{}", r.unwrap_err());
55     let m = r.unwrap();
56     assert!(m.contains_id("arg"));
57     assert_eq!(&*m.get_one::<OsString>("arg").unwrap(), &*bad_osstring(b""));
58 }
59 
60 #[test]
invalid_utf16_option_short_no_space()61 fn invalid_utf16_option_short_no_space() {
62     let r = Command::new("bad_utf16")
63         .arg(arg!(-a --arg <arg> "some arg").value_parser(value_parser!(OsString)))
64         .try_get_matches_from(vec![OsString::from(""), bad_osstring(b"-a")]);
65     assert!(r.is_ok(), "{}", r.unwrap_err());
66     let m = r.unwrap();
67     assert!(m.contains_id("arg"));
68     assert_eq!(&*m.get_one::<OsString>("arg").unwrap(), &*bad_osstring(b""));
69 }
70 
71 #[test]
invalid_utf16_option_long_space()72 fn invalid_utf16_option_long_space() {
73     let r = Command::new("bad_utf16")
74         .arg(arg!(-a --arg <arg> "some arg").value_parser(value_parser!(OsString)))
75         .try_get_matches_from(vec![
76             OsString::from(""),
77             OsString::from("--arg"),
78             bad_osstring(b""),
79         ]);
80     assert!(r.is_ok(), "{}", r.unwrap_err());
81     let m = r.unwrap();
82     assert!(m.contains_id("arg"));
83     assert_eq!(&*m.get_one::<OsString>("arg").unwrap(), &*bad_osstring(b""));
84 }
85 
86 #[test]
invalid_utf16_option_long_equals()87 fn invalid_utf16_option_long_equals() {
88     let r = Command::new("bad_utf16")
89         .arg(arg!(-a --arg <arg> "some arg").value_parser(value_parser!(OsString)))
90         .try_get_matches_from(vec![OsString::from(""), bad_osstring(b"--arg=")]);
91     assert!(r.is_ok(), "{}", r.unwrap_err());
92     let m = r.unwrap();
93     assert!(m.contains_id("arg"));
94     assert_eq!(&*m.get_one::<OsString>("arg").unwrap(), &*bad_osstring(b""));
95 }
96