• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #![cfg(not(windows))]
2 
3 use clap::{arg, error::ErrorKind, value_parser, Arg, ArgAction, Command};
4 use std::ffi::OsString;
5 use std::os::unix::ffi::OsStringExt;
6 
7 #[test]
invalid_utf8_strict_positional()8 fn invalid_utf8_strict_positional() {
9     let m = Command::new("bad_utf8")
10         .arg(Arg::new("arg"))
11         .try_get_matches_from(vec![OsString::from(""), OsString::from_vec(vec![0xe9])]);
12     assert!(m.is_err());
13     assert_eq!(m.unwrap_err().kind(), ErrorKind::InvalidUtf8);
14 }
15 
16 #[test]
invalid_utf8_strict_option_short_space()17 fn invalid_utf8_strict_option_short_space() {
18     let m = Command::new("bad_utf8")
19         .arg(
20             Arg::new("arg")
21                 .short('a')
22                 .long("arg")
23                 .action(ArgAction::Set),
24         )
25         .try_get_matches_from(vec![
26             OsString::from(""),
27             OsString::from("-a"),
28             OsString::from_vec(vec![0xe9]),
29         ]);
30     assert!(m.is_err());
31     assert_eq!(m.unwrap_err().kind(), ErrorKind::InvalidUtf8);
32 }
33 
34 #[test]
invalid_utf8_strict_option_short_equals()35 fn invalid_utf8_strict_option_short_equals() {
36     let m = Command::new("bad_utf8")
37         .arg(
38             Arg::new("arg")
39                 .short('a')
40                 .long("arg")
41                 .action(ArgAction::Set),
42         )
43         .try_get_matches_from(vec![
44             OsString::from(""),
45             OsString::from_vec(vec![0x2d, 0x61, 0x3d, 0xe9]),
46         ]);
47     assert!(m.is_err());
48     assert_eq!(m.unwrap_err().kind(), ErrorKind::InvalidUtf8);
49 }
50 
51 #[test]
invalid_utf8_strict_option_short_no_space()52 fn invalid_utf8_strict_option_short_no_space() {
53     let m = Command::new("bad_utf8")
54         .arg(
55             Arg::new("arg")
56                 .short('a')
57                 .long("arg")
58                 .action(ArgAction::Set),
59         )
60         .try_get_matches_from(vec![
61             OsString::from(""),
62             OsString::from_vec(vec![0x2d, 0x61, 0xe9]),
63         ]);
64     assert!(m.is_err());
65     assert_eq!(m.unwrap_err().kind(), ErrorKind::InvalidUtf8);
66 }
67 
68 #[test]
invalid_utf8_strict_option_long_space()69 fn invalid_utf8_strict_option_long_space() {
70     let m = Command::new("bad_utf8")
71         .arg(
72             Arg::new("arg")
73                 .short('a')
74                 .long("arg")
75                 .action(ArgAction::Set),
76         )
77         .try_get_matches_from(vec![
78             OsString::from(""),
79             OsString::from("--arg"),
80             OsString::from_vec(vec![0xe9]),
81         ]);
82     assert!(m.is_err());
83     assert_eq!(m.unwrap_err().kind(), ErrorKind::InvalidUtf8);
84 }
85 
86 #[test]
invalid_utf8_strict_option_long_equals()87 fn invalid_utf8_strict_option_long_equals() {
88     let m = Command::new("bad_utf8")
89         .arg(
90             Arg::new("arg")
91                 .short('a')
92                 .long("arg")
93                 .action(ArgAction::Set),
94         )
95         .try_get_matches_from(vec![
96             OsString::from(""),
97             OsString::from_vec(vec![0x2d, 0x2d, 0x61, 0x72, 0x67, 0x3d, 0xe9]),
98         ]);
99     assert!(m.is_err());
100     assert_eq!(m.unwrap_err().kind(), ErrorKind::InvalidUtf8);
101 }
102 
103 #[test]
invalid_utf8_strict_invalid_short()104 fn invalid_utf8_strict_invalid_short() {
105     let m = Command::new("bad_utf8").try_get_matches_from(vec![
106         OsString::from(""),
107         OsString::from("-a"),
108         OsString::from_vec(vec![0xe9]),
109     ]);
110     assert!(m.is_err());
111     assert_eq!(m.unwrap_err().kind(), ErrorKind::UnknownArgument);
112 }
113 
114 #[test]
invalid_utf8_strict_invalid_long()115 fn invalid_utf8_strict_invalid_long() {
116     let m = Command::new("bad_utf8").try_get_matches_from(vec![
117         OsString::from(""),
118         OsString::from("--arg"),
119         OsString::from_vec(vec![0xe9]),
120     ]);
121     assert!(m.is_err());
122     assert_eq!(m.unwrap_err().kind(), ErrorKind::UnknownArgument);
123 }
124 
125 #[test]
invalid_utf8_positional()126 fn invalid_utf8_positional() {
127     let r = Command::new("bad_utf8")
128         .arg(Arg::new("arg").value_parser(value_parser!(OsString)))
129         .try_get_matches_from(vec![OsString::from(""), OsString::from_vec(vec![0xe9])]);
130     assert!(r.is_ok(), "{}", r.unwrap_err());
131     let m = r.unwrap();
132     assert!(m.contains_id("arg"));
133     assert_eq!(
134         m.get_one::<OsString>("arg").unwrap(),
135         &*OsString::from_vec(vec![0xe9])
136     );
137 }
138 
139 #[test]
invalid_utf8_option_short_space()140 fn invalid_utf8_option_short_space() {
141     let r = Command::new("bad_utf8")
142         .arg(
143             Arg::new("arg")
144                 .short('a')
145                 .long("arg")
146                 .action(ArgAction::Set)
147                 .value_parser(value_parser!(OsString)),
148         )
149         .try_get_matches_from(vec![
150             OsString::from(""),
151             OsString::from("-a"),
152             OsString::from_vec(vec![0xe9]),
153         ]);
154     assert!(r.is_ok(), "{}", r.unwrap_err());
155     let m = r.unwrap();
156     assert!(m.contains_id("arg"));
157     assert_eq!(
158         m.get_one::<OsString>("arg").unwrap(),
159         &*OsString::from_vec(vec![0xe9])
160     );
161 }
162 
163 #[test]
invalid_utf8_option_short_equals()164 fn invalid_utf8_option_short_equals() {
165     let r = Command::new("bad_utf8")
166         .arg(
167             Arg::new("arg")
168                 .short('a')
169                 .long("arg")
170                 .action(ArgAction::Set)
171                 .value_parser(value_parser!(OsString)),
172         )
173         .try_get_matches_from(vec![
174             OsString::from(""),
175             OsString::from_vec(vec![0x2d, 0x61, 0x3d, 0xe9]),
176         ]);
177     assert!(r.is_ok(), "{}", r.unwrap_err());
178     let m = r.unwrap();
179     assert!(m.contains_id("arg"));
180     assert_eq!(
181         m.get_one::<OsString>("arg").unwrap(),
182         &*OsString::from_vec(vec![0xe9])
183     );
184 }
185 
186 #[test]
invalid_utf8_option_short_no_space()187 fn invalid_utf8_option_short_no_space() {
188     let r = Command::new("bad_utf8")
189         .arg(
190             Arg::new("arg")
191                 .short('a')
192                 .long("arg")
193                 .action(ArgAction::Set)
194                 .value_parser(value_parser!(OsString)),
195         )
196         .try_get_matches_from(vec![
197             OsString::from(""),
198             OsString::from_vec(vec![0x2d, 0x61, 0xe9]),
199         ]);
200     assert!(r.is_ok(), "{}", r.unwrap_err());
201     let m = r.unwrap();
202     assert!(m.contains_id("arg"));
203     assert_eq!(
204         m.get_one::<OsString>("arg").unwrap(),
205         &*OsString::from_vec(vec![0xe9])
206     );
207 }
208 
209 #[test]
invalid_utf8_option_long_space()210 fn invalid_utf8_option_long_space() {
211     let r = Command::new("bad_utf8")
212         .arg(
213             Arg::new("arg")
214                 .short('a')
215                 .long("arg")
216                 .action(ArgAction::Set)
217                 .value_parser(value_parser!(OsString)),
218         )
219         .try_get_matches_from(vec![
220             OsString::from(""),
221             OsString::from("--arg"),
222             OsString::from_vec(vec![0xe9]),
223         ]);
224     assert!(r.is_ok(), "{}", r.unwrap_err());
225     let m = r.unwrap();
226     assert!(m.contains_id("arg"));
227     assert_eq!(
228         m.get_one::<OsString>("arg").unwrap(),
229         &*OsString::from_vec(vec![0xe9])
230     );
231 }
232 
233 #[test]
invalid_utf8_option_long_equals()234 fn invalid_utf8_option_long_equals() {
235     let r = Command::new("bad_utf8")
236         .arg(
237             Arg::new("arg")
238                 .short('a')
239                 .long("arg")
240                 .action(ArgAction::Set)
241                 .value_parser(value_parser!(OsString)),
242         )
243         .try_get_matches_from(vec![
244             OsString::from(""),
245             OsString::from_vec(vec![0x2d, 0x2d, 0x61, 0x72, 0x67, 0x3d, 0xe9]),
246         ]);
247     assert!(r.is_ok(), "{}", r.unwrap_err());
248     let m = r.unwrap();
249     assert!(m.contains_id("arg"));
250     assert_eq!(
251         m.get_one::<OsString>("arg").unwrap(),
252         &*OsString::from_vec(vec![0xe9])
253     );
254 }
255 
256 #[test]
refuse_invalid_utf8_subcommand_with_allow_external_subcommands()257 fn refuse_invalid_utf8_subcommand_with_allow_external_subcommands() {
258     let m = Command::new("bad_utf8")
259         .allow_external_subcommands(true)
260         .external_subcommand_value_parser(value_parser!(String))
261         .try_get_matches_from(vec![
262             OsString::from(""),
263             OsString::from_vec(vec![0xe9]),
264             OsString::from("normal"),
265         ]);
266     assert!(m.is_err());
267     assert_eq!(m.unwrap_err().kind(), ErrorKind::InvalidUtf8);
268 }
269 
270 #[test]
refuse_invalid_utf8_subcommand_when_args_are_allowed_with_allow_external_subcommands()271 fn refuse_invalid_utf8_subcommand_when_args_are_allowed_with_allow_external_subcommands() {
272     let m = Command::new("bad_utf8")
273         .allow_external_subcommands(true)
274         .try_get_matches_from(vec![
275             OsString::from(""),
276             OsString::from_vec(vec![0xe9]),
277             OsString::from("normal"),
278         ]);
279     assert!(m.is_err());
280     assert_eq!(m.unwrap_err().kind(), ErrorKind::InvalidUtf8);
281 }
282 
283 #[test]
refuse_invalid_utf8_subcommand_args_with_allow_external_subcommands()284 fn refuse_invalid_utf8_subcommand_args_with_allow_external_subcommands() {
285     let m = Command::new("bad_utf8")
286         .allow_external_subcommands(true)
287         .external_subcommand_value_parser(value_parser!(String))
288         .try_get_matches_from(vec![
289             OsString::from(""),
290             OsString::from("subcommand"),
291             OsString::from("normal"),
292             OsString::from_vec(vec![0xe9]),
293             OsString::from("--another_normal"),
294         ]);
295     assert!(m.is_err());
296     assert_eq!(m.unwrap_err().kind(), ErrorKind::InvalidUtf8);
297 }
298 
299 #[test]
allow_invalid_utf8_subcommand_args_with_allow_external_subcommands()300 fn allow_invalid_utf8_subcommand_args_with_allow_external_subcommands() {
301     let m = Command::new("bad_utf8")
302         .allow_external_subcommands(true)
303         .try_get_matches_from(vec![
304             OsString::from(""),
305             OsString::from("subcommand"),
306             OsString::from("normal"),
307             OsString::from_vec(vec![0xe9]),
308             OsString::from("--another_normal"),
309         ]);
310     assert!(m.is_ok(), "{}", m.unwrap_err());
311     let m = m.unwrap();
312     let (subcommand, args) = m.subcommand().unwrap();
313     let args = args
314         .get_many::<OsString>("")
315         .unwrap()
316         .cloned()
317         .collect::<Vec<_>>();
318     assert_eq!(subcommand, OsString::from("subcommand"));
319     assert_eq!(
320         args,
321         vec![
322             OsString::from("normal"),
323             OsString::from_vec(vec![0xe9]),
324             OsString::from("--another_normal"),
325         ]
326     );
327 }
328 
329 #[test]
allow_validated_utf8_value_of()330 fn allow_validated_utf8_value_of() {
331     let a = Command::new("test").arg(arg!(--name <NAME>));
332     let m = a.try_get_matches_from(["test", "--name", "me"]).unwrap();
333     let _ = m.get_one::<String>("name").map(|v| v.as_str());
334 }
335 
336 #[test]
allow_validated_utf8_external_subcommand_values_of()337 fn allow_validated_utf8_external_subcommand_values_of() {
338     let a = Command::new("test")
339         .allow_external_subcommands(true)
340         .external_subcommand_value_parser(value_parser!(String));
341     let m = a.try_get_matches_from(vec!["test", "cmd", "arg"]).unwrap();
342     let (_ext, args) = m.subcommand().unwrap();
343     args.get_many::<String>("").unwrap_or_default().count();
344 }
345 
346 #[test]
347 #[should_panic = "Mismatch between definition and access of ``. Could not downcast to std::ffi::os_str::OsString, need to downcast to alloc::string::String"]
panic_validated_utf8_external_subcommand_values_of_os()348 fn panic_validated_utf8_external_subcommand_values_of_os() {
349     let a = Command::new("test")
350         .allow_external_subcommands(true)
351         .external_subcommand_value_parser(value_parser!(String));
352     let m = a.try_get_matches_from(vec!["test", "cmd", "arg"]).unwrap();
353     let (_ext, args) = m.subcommand().unwrap();
354     args.get_many::<OsString>("").unwrap_or_default().count();
355 }
356 
357 #[test]
allow_invalid_utf8_external_subcommand_values_of_os()358 fn allow_invalid_utf8_external_subcommand_values_of_os() {
359     let a = Command::new("test").allow_external_subcommands(true);
360     let m = a.try_get_matches_from(vec!["test", "cmd", "arg"]).unwrap();
361     let (_ext, args) = m.subcommand().unwrap();
362     args.get_many::<OsString>("").unwrap_or_default().count();
363 }
364 
365 #[test]
366 #[should_panic = "Mismatch between definition and access of ``. Could not downcast to alloc::string::String, need to downcast to std::ffi::os_str::OsString"]
panic_invalid_utf8_external_subcommand_values_of()367 fn panic_invalid_utf8_external_subcommand_values_of() {
368     let a = Command::new("test").allow_external_subcommands(true);
369     let m = a.try_get_matches_from(vec!["test", "cmd", "arg"]).unwrap();
370     let (_ext, args) = m.subcommand().unwrap();
371     args.get_many::<String>("").unwrap_or_default().count();
372 }
373