@@ -10,184 +10,53 @@ pub struct Crc32Reader<R> {
1010 inner : R ,
1111 hasher : Hasher ,
1212 check : u32 ,
13- /// Signals if `inner` stores aes encrypted data.
14- /// AE-2 encrypted data doesn't use crc and sets the value to 0.
15- enabled : bool ,
1613}
1714
1815impl < R > Crc32Reader < R > {
1916 /// Get a new Crc32Reader which checks the inner reader against checksum.
20- /// The check is disabled if `ae2_encrypted == true`.
21- pub ( crate ) fn new ( inner : R , checksum : u32 , ae2_encrypted : bool ) -> Crc32Reader < R > {
17+ pub ( crate ) fn new ( inner : R , checksum : u32 ) -> Self {
2218 Crc32Reader {
2319 inner,
2420 hasher : Hasher :: new ( ) ,
2521 check : checksum,
26- enabled : !ae2_encrypted,
2722 }
2823 }
2924
30- fn check_matches ( & self ) -> bool {
31- self . check == self . hasher . clone ( ) . finalize ( )
25+ fn check_matches ( & self ) -> Result < ( ) , & ' static str > {
26+ let res = self . hasher . clone ( ) . finalize ( ) ;
27+ if self . check == res {
28+ Ok ( ( ) )
29+ } else {
30+ /* TODO: make this into our own Crc32Error error type! */
31+ Err ( "Invalid checksum" )
32+ }
3233 }
3334
3435 pub fn into_inner ( self ) -> R {
3536 self . inner
3637 }
3738}
3839
39- #[ cold]
40- fn invalid_checksum ( ) -> io:: Error {
41- io:: Error :: new ( io:: ErrorKind :: InvalidData , "Invalid checksum" )
42- }
43-
4440impl < R : Read > Read for Crc32Reader < R > {
4541 fn read ( & mut self , buf : & mut [ u8 ] ) -> io:: Result < usize > {
46- let count = self . inner . read ( buf) ?;
47-
48- if self . enabled {
49- if count == 0 && !buf. is_empty ( ) && !self . check_matches ( ) {
50- return Err ( invalid_checksum ( ) ) ;
51- }
52- self . hasher . update ( & buf[ ..count] ) ;
53- }
54- Ok ( count)
55- }
56-
57- fn read_to_end ( & mut self , buf : & mut Vec < u8 > ) -> io:: Result < usize > {
58- let start = buf. len ( ) ;
59- let n = self . inner . read_to_end ( buf) ?;
60-
61- if self . enabled {
62- self . hasher . update ( & buf[ start..] ) ;
63- if !self . check_matches ( ) {
64- return Err ( invalid_checksum ( ) ) ;
65- }
66- }
67-
68- Ok ( n)
69- }
70-
71- fn read_to_string ( & mut self , buf : & mut String ) -> io:: Result < usize > {
72- let start = buf. len ( ) ;
73- let n = self . inner . read_to_string ( buf) ?;
74-
75- if self . enabled {
76- self . hasher . update ( & buf. as_bytes ( ) [ start..] ) ;
77- if !self . check_matches ( ) {
78- return Err ( invalid_checksum ( ) ) ;
79- }
80- }
81-
82- Ok ( n)
83- }
84- }
85-
86- pub ( crate ) mod non_crypto {
87- use std:: io;
88- use std:: io:: prelude:: * ;
89-
90- use crc32fast:: Hasher ;
91-
92- /// Reader that validates the CRC32 when it reaches the EOF.
93- pub struct Crc32Reader < R > {
94- inner : R ,
95- hasher : Hasher ,
96- check : u32 ,
97- }
98-
99- impl < R > Crc32Reader < R > {
100- /// Get a new Crc32Reader which checks the inner reader against checksum.
101- pub ( crate ) fn new ( inner : R , checksum : u32 ) -> Self {
102- Crc32Reader {
103- inner,
104- hasher : Hasher :: new ( ) ,
105- check : checksum,
106- }
42+ /* We want to make sure we only check the hash when the input stream is exhausted. */
43+ if buf. is_empty ( ) {
44+ /* If the input buf is empty (this shouldn't happen, but isn't guaranteed), we
45+ * still want to "pull" from the source in case it surfaces an i/o error. This will
46+ * always return a count of Ok(0) if successful. */
47+ return self . inner . read ( buf) ;
10748 }
10849
109- fn check_matches ( & self ) -> Result < ( ) , & ' static str > {
110- let res = self . hasher . clone ( ) . finalize ( ) ;
111- if self . check == res {
112- Ok ( ( ) )
113- } else {
114- /* TODO: make this into our own Crc32Error error type! */
115- Err ( "Invalid checksum" )
116- }
117- }
118-
119- pub fn into_inner ( self ) -> R {
120- self . inner
121- }
122- }
123-
124- impl < R : Read > Read for Crc32Reader < R > {
125- fn read ( & mut self , buf : & mut [ u8 ] ) -> io:: Result < usize > {
126- /* We want to make sure we only check the hash when the input stream is exhausted. */
127- if buf. is_empty ( ) {
128- /* If the input buf is empty (this shouldn't happen, but isn't guaranteed), we
129- * still want to "pull" from the source in case it surfaces an i/o error. This will
130- * always return a count of Ok(0) if successful. */
131- return self . inner . read ( buf) ;
132- }
133-
134- let count = self . inner . read ( buf) ?;
135- if count == 0 {
136- return self
137- . check_matches ( )
138- . map ( |( ) | 0 )
139- /* TODO: use io::Error::other for MSRV >=1.74 */
140- . map_err ( |e| io:: Error :: new ( io:: ErrorKind :: Other , e) ) ;
141- }
142- self . hasher . update ( & buf[ ..count] ) ;
143- Ok ( count)
144- }
145- }
146-
147- #[ cfg( test) ]
148- mod test {
149- use super :: * ;
150-
151- #[ test]
152- fn test_empty_reader ( ) {
153- let data: & [ u8 ] = b"" ;
154- let mut buf = [ 0 ; 1 ] ;
155-
156- let mut reader = Crc32Reader :: new ( data, 0 ) ;
157- assert_eq ! ( reader. read( & mut buf) . unwrap( ) , 0 ) ;
158-
159- let mut reader = Crc32Reader :: new ( data, 1 ) ;
160- assert ! ( reader
161- . read( & mut buf)
162- . unwrap_err( )
163- . to_string( )
164- . contains( "Invalid checksum" ) ) ;
165- }
166-
167- #[ test]
168- fn test_byte_by_byte ( ) {
169- let data: & [ u8 ] = b"1234" ;
170- let mut buf = [ 0 ; 1 ] ;
171-
172- let mut reader = Crc32Reader :: new ( data, 0x9be3e0a3 ) ;
173- assert_eq ! ( reader. read( & mut buf) . unwrap( ) , 1 ) ;
174- assert_eq ! ( reader. read( & mut buf) . unwrap( ) , 1 ) ;
175- assert_eq ! ( reader. read( & mut buf) . unwrap( ) , 1 ) ;
176- assert_eq ! ( reader. read( & mut buf) . unwrap( ) , 1 ) ;
177- assert_eq ! ( reader. read( & mut buf) . unwrap( ) , 0 ) ;
178- // Can keep reading 0 bytes after the end
179- assert_eq ! ( reader. read( & mut buf) . unwrap( ) , 0 ) ;
180- }
181-
182- #[ test]
183- fn test_zero_read ( ) {
184- let data: & [ u8 ] = b"1234" ;
185- let mut buf = [ 0 ; 5 ] ;
186-
187- let mut reader = Crc32Reader :: new ( data, 0x9be3e0a3 ) ;
188- assert_eq ! ( reader. read( & mut buf[ ..0 ] ) . unwrap( ) , 0 ) ;
189- assert_eq ! ( reader. read( & mut buf) . unwrap( ) , 4 ) ;
50+ let count = self . inner . read ( buf) ?;
51+ if count == 0 {
52+ return self
53+ . check_matches ( )
54+ . map ( |( ) | 0 )
55+ /* TODO: use io::Error::other for MSRV >=1.74 */
56+ . map_err ( |e| io:: Error :: new ( io:: ErrorKind :: Other , e) ) ;
19057 }
58+ self . hasher . update ( & buf[ ..count] ) ;
59+ Ok ( count)
19160 }
19261}
19362
@@ -200,10 +69,10 @@ mod test {
20069 let data: & [ u8 ] = b"" ;
20170 let mut buf = [ 0 ; 1 ] ;
20271
203- let mut reader = Crc32Reader :: new ( data, 0 , false ) ;
72+ let mut reader = Crc32Reader :: new ( data, 0 ) ;
20473 assert_eq ! ( reader. read( & mut buf) . unwrap( ) , 0 ) ;
20574
206- let mut reader = Crc32Reader :: new ( data, 1 , false ) ;
75+ let mut reader = Crc32Reader :: new ( data, 1 ) ;
20776 assert ! ( reader
20877 . read( & mut buf)
20978 . unwrap_err( )
@@ -216,7 +85,7 @@ mod test {
21685 let data: & [ u8 ] = b"1234" ;
21786 let mut buf = [ 0 ; 1 ] ;
21887
219- let mut reader = Crc32Reader :: new ( data, 0x9be3e0a3 , false ) ;
88+ let mut reader = Crc32Reader :: new ( data, 0x9be3e0a3 ) ;
22089 assert_eq ! ( reader. read( & mut buf) . unwrap( ) , 1 ) ;
22190 assert_eq ! ( reader. read( & mut buf) . unwrap( ) , 1 ) ;
22291 assert_eq ! ( reader. read( & mut buf) . unwrap( ) , 1 ) ;
@@ -231,7 +100,7 @@ mod test {
231100 let data: & [ u8 ] = b"1234" ;
232101 let mut buf = [ 0 ; 5 ] ;
233102
234- let mut reader = Crc32Reader :: new ( data, 0x9be3e0a3 , false ) ;
103+ let mut reader = Crc32Reader :: new ( data, 0x9be3e0a3 ) ;
235104 assert_eq ! ( reader. read( & mut buf[ ..0 ] ) . unwrap( ) , 0 ) ;
236105 assert_eq ! ( reader. read( & mut buf) . unwrap( ) , 4 ) ;
237106 }
0 commit comments