@@ -20,12 +20,13 @@ use std::io::{self, stdin, BufRead, BufReader, Read};
2020use std:: iter;
2121use std:: num:: ParseIntError ;
2222use std:: path:: Path ;
23+ use uucore:: error:: USimpleError ;
2324use uucore:: error:: { FromIo , UError , UResult } ;
2425use uucore:: sum:: {
2526 Blake2b , Blake3 , Digest , DigestWriter , Md5 , Sha1 , Sha224 , Sha256 , Sha384 , Sha3_224 , Sha3_256 ,
2627 Sha3_384 , Sha3_512 , Sha512 , Shake128 , Shake256 ,
2728} ;
28- use uucore:: { crash , display:: Quotable , show_warning} ;
29+ use uucore:: { display:: Quotable , show_warning} ;
2930use uucore:: { format_usage, help_about, help_usage} ;
3031
3132const NAME : & str = "hashsum" ;
@@ -51,28 +52,32 @@ struct Options {
5152///
5253/// # Returns
5354///
54- /// Returns a tuple containing the algorithm name, the hasher instance, and the output length in bits.
55- ///
56- /// # Panics
57- ///
58- /// Panics if the length is not a multiple of 8 or if it is greater than 512.
59- fn create_blake2b ( matches : & ArgMatches ) -> ( & ' static str , Box < dyn Digest > , usize ) {
55+ /// Returns a UResult of a tuple containing the algorithm name, the hasher instance, and
56+ /// the output length in bits or an Err if the length is not a multiple of 8 or if it is
57+ /// greater than 512.
58+ fn create_blake2b ( matches : & ArgMatches ) -> UResult < ( & ' static str , Box < dyn Digest > , usize ) > {
6059 match matches. get_one :: < usize > ( "length" ) {
61- Some ( 0 ) | None => ( "BLAKE2" , Box :: new ( Blake2b :: new ( ) ) as Box < dyn Digest > , 512 ) ,
60+ Some ( 0 ) | None => Ok ( ( "BLAKE2" , Box :: new ( Blake2b :: new ( ) ) as Box < dyn Digest > , 512 ) ) ,
6261 Some ( length_in_bits) => {
6362 if * length_in_bits > 512 {
64- crash ! ( 1 , "Invalid length (maximum digest length is 512 bits)" )
63+ return Err ( USimpleError :: new (
64+ 1 ,
65+ "Invalid length (maximum digest length is 512 bits)" ,
66+ ) ) ;
6567 }
6668
6769 if length_in_bits % 8 == 0 {
6870 let length_in_bytes = length_in_bits / 8 ;
69- (
71+ Ok ( (
7072 "BLAKE2" ,
7173 Box :: new ( Blake2b :: with_output_bytes ( length_in_bytes) ) ,
7274 * length_in_bits,
73- )
75+ ) )
7476 } else {
75- crash ! ( 1 , "Invalid length (expected a multiple of 8)" )
77+ Err ( USimpleError :: new (
78+ 1 ,
79+ "Invalid length (expected a multiple of 8)" ,
80+ ) )
7681 }
7782 }
7883 }
@@ -82,78 +87,70 @@ fn create_blake2b(matches: &ArgMatches) -> (&'static str, Box<dyn Digest>, usize
8287///
8388/// # Returns
8489///
85- /// Returns a tuple containing the algorithm name, the hasher instance, and the output length in bits.
86- ///
87- /// # Panics
88- ///
89- /// Panics if an unsupported output size is provided, or if the `--bits` flag is missing.
90- fn create_sha3 ( matches : & ArgMatches ) -> ( & ' static str , Box < dyn Digest > , usize ) {
90+ /// Returns a UResult of a tuple containing the algorithm name, the hasher instance, and
91+ /// the output length in bits or an Err if an unsupported output size is provided, or if
92+ /// the `--bits` flag is missing.
93+ fn create_sha3 ( matches : & ArgMatches ) -> UResult < ( & ' static str , Box < dyn Digest > , usize ) > {
9194 match matches. get_one :: < usize > ( "bits" ) {
92- Some ( 224 ) => (
95+ Some ( 224 ) => Ok ( (
9396 "SHA3-224" ,
9497 Box :: new ( Sha3_224 :: new ( ) ) as Box < dyn Digest > ,
9598 224 ,
96- ) ,
97- Some ( 256 ) => (
99+ ) ) ,
100+ Some ( 256 ) => Ok ( (
98101 "SHA3-256" ,
99102 Box :: new ( Sha3_256 :: new ( ) ) as Box < dyn Digest > ,
100103 256 ,
101- ) ,
102- Some ( 384 ) => (
104+ ) ) ,
105+ Some ( 384 ) => Ok ( (
103106 "SHA3-384" ,
104107 Box :: new ( Sha3_384 :: new ( ) ) as Box < dyn Digest > ,
105108 384 ,
106- ) ,
107- Some ( 512 ) => (
109+ ) ) ,
110+ Some ( 512 ) => Ok ( (
108111 "SHA3-512" ,
109112 Box :: new ( Sha3_512 :: new ( ) ) as Box < dyn Digest > ,
110113 512 ,
111- ) ,
112- Some ( _) => crash ! (
114+ ) ) ,
115+ Some ( _) => Err ( USimpleError :: new (
113116 1 ,
114- "Invalid output size for SHA3 (expected 224, 256, 384, or 512)"
115- ) ,
116- None => crash ! ( 1 , "--bits required for SHA3" ) ,
117+ "Invalid output size for SHA3 (expected 224, 256, 384, or 512)" ,
118+ ) ) ,
119+ None => Err ( USimpleError :: new ( 1 , "--bits required for SHA3" ) ) ,
117120 }
118121}
119122
120123/// Creates a SHAKE-128 hasher instance based on the specified bits argument.
121124///
122125/// # Returns
123126///
124- /// Returns a tuple containing the algorithm name, the hasher instance, and the output length in bits.
125- ///
126- /// # Panics
127- ///
128- /// Panics if the `--bits` flag is missing.
129- fn create_shake128 ( matches : & ArgMatches ) -> ( & ' static str , Box < dyn Digest > , usize ) {
127+ /// Returns a UResult of a tuple containing the algorithm name, the hasher instance, and
128+ /// the output length in bits, or an Err if `--bits` flag is missing.
129+ fn create_shake128 ( matches : & ArgMatches ) -> UResult < ( & ' static str , Box < dyn Digest > , usize ) > {
130130 match matches. get_one :: < usize > ( "bits" ) {
131- Some ( bits) => (
131+ Some ( bits) => Ok ( (
132132 "SHAKE128" ,
133133 Box :: new ( Shake128 :: new ( ) ) as Box < dyn Digest > ,
134134 * bits,
135- ) ,
136- None => crash ! ( 1 , "--bits required for SHAKE-128" ) ,
135+ ) ) ,
136+ None => Err ( USimpleError :: new ( 1 , "--bits required for SHAKE-128" ) ) ,
137137 }
138138}
139139
140140/// Creates a SHAKE-256 hasher instance based on the specified bits argument.
141141///
142142/// # Returns
143143///
144- /// Returns a tuple containing the algorithm name, the hasher instance, and the output length in bits.
145- ///
146- /// # Panics
147- ///
148- /// Panics if the `--bits` flag is missing.
149- fn create_shake256 ( matches : & ArgMatches ) -> ( & ' static str , Box < dyn Digest > , usize ) {
144+ /// Returns a UResult of a tuple containing the algorithm name, the hasher instance, and
145+ /// the output length in bits, or an Err if the `--bits` flag is missing.
146+ fn create_shake256 ( matches : & ArgMatches ) -> UResult < ( & ' static str , Box < dyn Digest > , usize ) > {
150147 match matches. get_one :: < usize > ( "bits" ) {
151- Some ( bits) => (
148+ Some ( bits) => Ok ( (
152149 "SHAKE256" ,
153150 Box :: new ( Shake256 :: new ( ) ) as Box < dyn Digest > ,
154151 * bits,
155- ) ,
156- None => crash ! ( 1 , "--bits required for SHAKE-256" ) ,
152+ ) ) ,
153+ None => Err ( USimpleError :: new ( 1 , "--bits required for SHAKE-256" ) ) ,
157154 }
158155}
159156
@@ -166,46 +163,46 @@ fn create_shake256(matches: &ArgMatches) -> (&'static str, Box<dyn Digest>, usiz
166163///
167164/// # Returns
168165///
169- /// Returns a tuple containing the algorithm name, the hasher instance, and the output length in bits.
166+ /// Returns a UResult of a tuple containing the algorithm name, the hasher instance, and
167+ /// the output length in bits, or an Err if a matching algorithm is not found.
170168fn detect_algo (
171169 program : & str ,
172170 matches : & ArgMatches ,
173- ) -> ( & ' static str , Box < dyn Digest + ' static > , usize ) {
174- let ( name , alg , output_bits ) = match program {
175- "md5sum" => ( "MD5" , Box :: new ( Md5 :: new ( ) ) as Box < dyn Digest > , 128 ) ,
176- "sha1sum" => ( "SHA1" , Box :: new ( Sha1 :: new ( ) ) as Box < dyn Digest > , 160 ) ,
177- "sha224sum" => ( "SHA224" , Box :: new ( Sha224 :: new ( ) ) as Box < dyn Digest > , 224 ) ,
178- "sha256sum" => ( "SHA256" , Box :: new ( Sha256 :: new ( ) ) as Box < dyn Digest > , 256 ) ,
179- "sha384sum" => ( "SHA384" , Box :: new ( Sha384 :: new ( ) ) as Box < dyn Digest > , 384 ) ,
180- "sha512sum" => ( "SHA512" , Box :: new ( Sha512 :: new ( ) ) as Box < dyn Digest > , 512 ) ,
171+ ) -> UResult < ( & ' static str , Box < dyn Digest + ' static > , usize ) > {
172+ match program {
173+ "md5sum" => Ok ( ( "MD5" , Box :: new ( Md5 :: new ( ) ) as Box < dyn Digest > , 128 ) ) ,
174+ "sha1sum" => Ok ( ( "SHA1" , Box :: new ( Sha1 :: new ( ) ) as Box < dyn Digest > , 160 ) ) ,
175+ "sha224sum" => Ok ( ( "SHA224" , Box :: new ( Sha224 :: new ( ) ) as Box < dyn Digest > , 224 ) ) ,
176+ "sha256sum" => Ok ( ( "SHA256" , Box :: new ( Sha256 :: new ( ) ) as Box < dyn Digest > , 256 ) ) ,
177+ "sha384sum" => Ok ( ( "SHA384" , Box :: new ( Sha384 :: new ( ) ) as Box < dyn Digest > , 384 ) ) ,
178+ "sha512sum" => Ok ( ( "SHA512" , Box :: new ( Sha512 :: new ( ) ) as Box < dyn Digest > , 512 ) ) ,
181179 "b2sum" => create_blake2b ( matches) ,
182- "b3sum" => ( "BLAKE3" , Box :: new ( Blake3 :: new ( ) ) as Box < dyn Digest > , 256 ) ,
180+ "b3sum" => Ok ( ( "BLAKE3" , Box :: new ( Blake3 :: new ( ) ) as Box < dyn Digest > , 256 ) ) ,
183181 "sha3sum" => create_sha3 ( matches) ,
184- "sha3-224sum" => (
182+ "sha3-224sum" => Ok ( (
185183 "SHA3-224" ,
186184 Box :: new ( Sha3_224 :: new ( ) ) as Box < dyn Digest > ,
187185 224 ,
188- ) ,
189- "sha3-256sum" => (
186+ ) ) ,
187+ "sha3-256sum" => Ok ( (
190188 "SHA3-256" ,
191189 Box :: new ( Sha3_256 :: new ( ) ) as Box < dyn Digest > ,
192190 256 ,
193- ) ,
194- "sha3-384sum" => (
191+ ) ) ,
192+ "sha3-384sum" => Ok ( (
195193 "SHA3-384" ,
196194 Box :: new ( Sha3_384 :: new ( ) ) as Box < dyn Digest > ,
197195 384 ,
198- ) ,
199- "sha3-512sum" => (
196+ ) ) ,
197+ "sha3-512sum" => Ok ( (
200198 "SHA3-512" ,
201199 Box :: new ( Sha3_512 :: new ( ) ) as Box < dyn Digest > ,
202200 512 ,
203- ) ,
201+ ) ) ,
204202 "shake128sum" => create_shake128 ( matches) ,
205203 "shake256sum" => create_shake256 ( matches) ,
206204 _ => create_algorithm_from_flags ( matches) ,
207- } ;
208- ( name, alg, output_bits)
205+ }
209206}
210207
211208/// Creates a hasher instance based on the command-line flags.
@@ -216,80 +213,89 @@ fn detect_algo(
216213///
217214/// # Returns
218215///
219- /// Returns a tuple containing the algorithm name, the hasher instance, and the output length in bits.
220- ///
221- /// # Panics
222- ///
223- /// Panics if multiple hash algorithms are specified or if a required flag is missing.
216+ /// Returns a UResult of a tuple containing the algorithm name, the hasher instance, and
217+ /// the output length in bits or an Err if multiple hash algorithms are specified or if a
218+ /// required flag is missing.
224219#[ allow( clippy:: cognitive_complexity) ]
225- fn create_algorithm_from_flags ( matches : & ArgMatches ) -> ( & ' static str , Box < dyn Digest > , usize ) {
220+ fn create_algorithm_from_flags (
221+ matches : & ArgMatches ,
222+ ) -> UResult < ( & ' static str , Box < dyn Digest > , usize ) > {
226223 let mut alg: Option < Box < dyn Digest > > = None ;
227224 let mut name: & ' static str = "" ;
228225 let mut output_bits = 0 ;
229- let mut set_or_crash = |n, val, bits| {
226+ let mut set_or_err = |n, val, bits| {
230227 if alg. is_some ( ) {
231- crash ! ( 1 , "You cannot combine multiple hash algorithms!" ) ;
228+ return Err ( USimpleError :: new (
229+ 1 ,
230+ "You cannot combine multiple hash algorithms!" ,
231+ ) ) ;
232232 } ;
233233 name = n;
234234 alg = Some ( val) ;
235235 output_bits = bits;
236+
237+ Ok ( ( ) )
236238 } ;
237239
238240 if matches. get_flag ( "md5" ) {
239- set_or_crash ( "MD5" , Box :: new ( Md5 :: new ( ) ) , 128 ) ;
241+ set_or_err ( "MD5" , Box :: new ( Md5 :: new ( ) ) , 128 ) ? ;
240242 }
241243 if matches. get_flag ( "sha1" ) {
242- set_or_crash ( "SHA1" , Box :: new ( Sha1 :: new ( ) ) , 160 ) ;
244+ set_or_err ( "SHA1" , Box :: new ( Sha1 :: new ( ) ) , 160 ) ? ;
243245 }
244246 if matches. get_flag ( "sha224" ) {
245- set_or_crash ( "SHA224" , Box :: new ( Sha224 :: new ( ) ) , 224 ) ;
247+ set_or_err ( "SHA224" , Box :: new ( Sha224 :: new ( ) ) , 224 ) ? ;
246248 }
247249 if matches. get_flag ( "sha256" ) {
248- set_or_crash ( "SHA256" , Box :: new ( Sha256 :: new ( ) ) , 256 ) ;
250+ set_or_err ( "SHA256" , Box :: new ( Sha256 :: new ( ) ) , 256 ) ? ;
249251 }
250252 if matches. get_flag ( "sha384" ) {
251- set_or_crash ( "SHA384" , Box :: new ( Sha384 :: new ( ) ) , 384 ) ;
253+ set_or_err ( "SHA384" , Box :: new ( Sha384 :: new ( ) ) , 384 ) ? ;
252254 }
253255 if matches. get_flag ( "sha512" ) {
254- set_or_crash ( "SHA512" , Box :: new ( Sha512 :: new ( ) ) , 512 ) ;
256+ set_or_err ( "SHA512" , Box :: new ( Sha512 :: new ( ) ) , 512 ) ? ;
255257 }
256258 if matches. get_flag ( "b2sum" ) {
257- set_or_crash ( "BLAKE2" , Box :: new ( Blake2b :: new ( ) ) , 512 ) ;
259+ set_or_err ( "BLAKE2" , Box :: new ( Blake2b :: new ( ) ) , 512 ) ? ;
258260 }
259261 if matches. get_flag ( "b3sum" ) {
260- set_or_crash ( "BLAKE3" , Box :: new ( Blake3 :: new ( ) ) , 256 ) ;
262+ set_or_err ( "BLAKE3" , Box :: new ( Blake3 :: new ( ) ) , 256 ) ? ;
261263 }
262264 if matches. get_flag ( "sha3" ) {
263- let ( n, val, bits) = create_sha3 ( matches) ;
264- set_or_crash ( n, val, bits) ;
265+ let ( n, val, bits) = create_sha3 ( matches) ? ;
266+ set_or_err ( n, val, bits) ? ;
265267 }
266268 if matches. get_flag ( "sha3-224" ) {
267- set_or_crash ( "SHA3-224" , Box :: new ( Sha3_224 :: new ( ) ) , 224 ) ;
269+ set_or_err ( "SHA3-224" , Box :: new ( Sha3_224 :: new ( ) ) , 224 ) ? ;
268270 }
269271 if matches. get_flag ( "sha3-256" ) {
270- set_or_crash ( "SHA3-256" , Box :: new ( Sha3_256 :: new ( ) ) , 256 ) ;
272+ set_or_err ( "SHA3-256" , Box :: new ( Sha3_256 :: new ( ) ) , 256 ) ? ;
271273 }
272274 if matches. get_flag ( "sha3-384" ) {
273- set_or_crash ( "SHA3-384" , Box :: new ( Sha3_384 :: new ( ) ) , 384 ) ;
275+ set_or_err ( "SHA3-384" , Box :: new ( Sha3_384 :: new ( ) ) , 384 ) ? ;
274276 }
275277 if matches. get_flag ( "sha3-512" ) {
276- set_or_crash ( "SHA3-512" , Box :: new ( Sha3_512 :: new ( ) ) , 512 ) ;
278+ set_or_err ( "SHA3-512" , Box :: new ( Sha3_512 :: new ( ) ) , 512 ) ? ;
277279 }
278280 if matches. get_flag ( "shake128" ) {
279281 match matches. get_one :: < usize > ( "bits" ) {
280- Some ( bits) => set_or_crash ( "SHAKE128" , Box :: new ( Shake128 :: new ( ) ) , * bits) ,
281- None => crash ! ( 1 , "--bits required for SHAKE-128" ) ,
282- }
282+ Some ( bits) => set_or_err ( "SHAKE128" , Box :: new ( Shake128 :: new ( ) ) , * bits) ? ,
283+ None => return Err ( USimpleError :: new ( 1 , "--bits required for SHAKE-128" ) ) ,
284+ } ;
283285 }
284286 if matches. get_flag ( "shake256" ) {
285287 match matches. get_one :: < usize > ( "bits" ) {
286- Some ( bits) => set_or_crash ( "SHAKE256" , Box :: new ( Shake256 :: new ( ) ) , * bits) ,
287- None => crash ! ( 1 , "--bits required for SHAKE-256" ) ,
288- }
288+ Some ( bits) => set_or_err ( "SHAKE256" , Box :: new ( Shake256 :: new ( ) ) , * bits) ? ,
289+ None => return Err ( USimpleError :: new ( 1 , "--bits required for SHAKE-256" ) ) ,
290+ } ;
289291 }
290292
291- let alg = alg. unwrap_or_else ( || crash ! ( 1 , "You must specify hash algorithm!" ) ) ;
292- ( name, alg, output_bits)
293+ let alg = match alg {
294+ Some ( a) => a,
295+ None => return Err ( USimpleError :: new ( 1 , "You must specify hash algorithm!" ) ) ,
296+ } ;
297+
298+ Ok ( ( name, alg, output_bits) )
293299}
294300
295301// TODO: return custom error type
@@ -319,7 +325,7 @@ pub fn uumain(mut args: impl uucore::Args) -> UResult<()> {
319325 // least somewhat better from a user's perspective.
320326 let matches = command. try_get_matches_from ( args) ?;
321327
322- let ( name, algo, bits) = detect_algo ( & binary_name, & matches) ;
328+ let ( name, algo, bits) = detect_algo ( & binary_name, & matches) ? ;
323329
324330 let binary = if matches. get_flag ( "binary" ) {
325331 true
0 commit comments