• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #![cfg(not(windows))]
2 
3 use clap::error::ErrorKind;
4 use clap::Parser;
5 use std::ffi::OsString;
6 use std::os::unix::ffi::OsStringExt;
7 
8 #[derive(Parser, Debug, PartialEq, Eq)]
9 struct Positional {
10     arg: String,
11 }
12 
13 #[derive(Parser, Debug, PartialEq, Eq)]
14 struct Named {
15     #[arg(short, long)]
16     arg: String,
17 }
18 
19 #[test]
invalid_utf8_strict_positional()20 fn invalid_utf8_strict_positional() {
21     let m = Positional::try_parse_from(vec![OsString::from(""), OsString::from_vec(vec![0xe9])]);
22     assert!(m.is_err());
23     assert_eq!(m.unwrap_err().kind(), ErrorKind::InvalidUtf8);
24 }
25 
26 #[test]
invalid_utf8_strict_option_short_space()27 fn invalid_utf8_strict_option_short_space() {
28     let m = Named::try_parse_from(vec![
29         OsString::from(""),
30         OsString::from("-a"),
31         OsString::from_vec(vec![0xe9]),
32     ]);
33     assert!(m.is_err());
34     assert_eq!(m.unwrap_err().kind(), ErrorKind::InvalidUtf8);
35 }
36 
37 #[test]
invalid_utf8_strict_option_short_equals()38 fn invalid_utf8_strict_option_short_equals() {
39     let m = Named::try_parse_from(vec![
40         OsString::from(""),
41         OsString::from_vec(vec![0x2d, 0x61, 0x3d, 0xe9]),
42     ]);
43     assert!(m.is_err());
44     assert_eq!(m.unwrap_err().kind(), ErrorKind::InvalidUtf8);
45 }
46 
47 #[test]
invalid_utf8_strict_option_short_no_space()48 fn invalid_utf8_strict_option_short_no_space() {
49     let m = Named::try_parse_from(vec![
50         OsString::from(""),
51         OsString::from_vec(vec![0x2d, 0x61, 0xe9]),
52     ]);
53     assert!(m.is_err());
54     assert_eq!(m.unwrap_err().kind(), ErrorKind::InvalidUtf8);
55 }
56 
57 #[test]
invalid_utf8_strict_option_long_space()58 fn invalid_utf8_strict_option_long_space() {
59     let m = Named::try_parse_from(vec![
60         OsString::from(""),
61         OsString::from("--arg"),
62         OsString::from_vec(vec![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_equals()69 fn invalid_utf8_strict_option_long_equals() {
70     let m = Named::try_parse_from(vec![
71         OsString::from(""),
72         OsString::from_vec(vec![0x2d, 0x2d, 0x61, 0x72, 0x67, 0x3d, 0xe9]),
73     ]);
74     assert!(m.is_err());
75     assert_eq!(m.unwrap_err().kind(), ErrorKind::InvalidUtf8);
76 }
77 
78 #[derive(Parser, Debug, PartialEq, Eq)]
79 struct PositionalOs {
80     arg: OsString,
81 }
82 
83 #[derive(Parser, Debug, PartialEq, Eq)]
84 struct NamedOs {
85     #[arg(short, long)]
86     arg: OsString,
87 }
88 
89 #[test]
invalid_utf8_positional()90 fn invalid_utf8_positional() {
91     let r = PositionalOs::try_parse_from(vec![OsString::from(""), OsString::from_vec(vec![0xe9])]);
92     assert_eq!(
93         r.unwrap(),
94         PositionalOs {
95             arg: OsString::from_vec(vec![0xe9])
96         }
97     );
98 }
99 
100 #[test]
invalid_utf8_option_short_space()101 fn invalid_utf8_option_short_space() {
102     let r = NamedOs::try_parse_from(vec![
103         OsString::from(""),
104         OsString::from("-a"),
105         OsString::from_vec(vec![0xe9]),
106     ]);
107     assert_eq!(
108         r.unwrap(),
109         NamedOs {
110             arg: OsString::from_vec(vec![0xe9])
111         }
112     );
113 }
114 
115 #[test]
invalid_utf8_option_short_equals()116 fn invalid_utf8_option_short_equals() {
117     let r = NamedOs::try_parse_from(vec![
118         OsString::from(""),
119         OsString::from_vec(vec![0x2d, 0x61, 0x3d, 0xe9]),
120     ]);
121     assert_eq!(
122         r.unwrap(),
123         NamedOs {
124             arg: OsString::from_vec(vec![0xe9])
125         }
126     );
127 }
128 
129 #[test]
invalid_utf8_option_short_no_space()130 fn invalid_utf8_option_short_no_space() {
131     let r = NamedOs::try_parse_from(vec![
132         OsString::from(""),
133         OsString::from_vec(vec![0x2d, 0x61, 0xe9]),
134     ]);
135     assert_eq!(
136         r.unwrap(),
137         NamedOs {
138             arg: OsString::from_vec(vec![0xe9])
139         }
140     );
141 }
142 
143 #[test]
invalid_utf8_option_long_space()144 fn invalid_utf8_option_long_space() {
145     let r = NamedOs::try_parse_from(vec![
146         OsString::from(""),
147         OsString::from("--arg"),
148         OsString::from_vec(vec![0xe9]),
149     ]);
150     assert_eq!(
151         r.unwrap(),
152         NamedOs {
153             arg: OsString::from_vec(vec![0xe9])
154         }
155     );
156 }
157 
158 #[test]
invalid_utf8_option_long_equals()159 fn invalid_utf8_option_long_equals() {
160     let r = NamedOs::try_parse_from(vec![
161         OsString::from(""),
162         OsString::from_vec(vec![0x2d, 0x2d, 0x61, 0x72, 0x67, 0x3d, 0xe9]),
163     ]);
164     assert_eq!(
165         r.unwrap(),
166         NamedOs {
167             arg: OsString::from_vec(vec![0xe9])
168         }
169     );
170 }
171 
172 #[derive(Debug, PartialEq, Parser)]
173 enum External {
174     #[command(external_subcommand)]
175     Other(Vec<String>),
176 }
177 
178 #[test]
refuse_invalid_utf8_subcommand_with_allow_external_subcommands()179 fn refuse_invalid_utf8_subcommand_with_allow_external_subcommands() {
180     let m = External::try_parse_from(vec![
181         OsString::from(""),
182         OsString::from_vec(vec![0xe9]),
183         OsString::from("normal"),
184     ]);
185     assert!(m.is_err());
186     assert_eq!(m.unwrap_err().kind(), ErrorKind::InvalidUtf8);
187 }
188 
189 #[test]
refuse_invalid_utf8_subcommand_args_with_allow_external_subcommands()190 fn refuse_invalid_utf8_subcommand_args_with_allow_external_subcommands() {
191     let m = External::try_parse_from(vec![
192         OsString::from(""),
193         OsString::from("subcommand"),
194         OsString::from("normal"),
195         OsString::from_vec(vec![0xe9]),
196         OsString::from("--another_normal"),
197     ]);
198     assert!(m.is_err());
199     assert_eq!(m.unwrap_err().kind(), ErrorKind::InvalidUtf8);
200 }
201 
202 #[derive(Debug, PartialEq, Parser)]
203 enum ExternalOs {
204     #[command(external_subcommand)]
205     Other(Vec<OsString>),
206 }
207 
208 #[test]
allow_invalid_utf8_subcommand_args_with_allow_external_subcommands()209 fn allow_invalid_utf8_subcommand_args_with_allow_external_subcommands() {
210     let m = ExternalOs::try_parse_from(vec![
211         OsString::from(""),
212         OsString::from("subcommand"),
213         OsString::from("normal"),
214         OsString::from_vec(vec![0xe9]),
215         OsString::from("--another_normal"),
216     ]);
217     assert_eq!(
218         m.unwrap(),
219         ExternalOs::Other(vec![
220             OsString::from("subcommand"),
221             OsString::from("normal"),
222             OsString::from_vec(vec![0xe9]),
223             OsString::from("--another_normal"),
224         ])
225     );
226 }
227