@@ -10,184 +10,53 @@ pub struct Crc32Reader<R> {
10
10
inner : R ,
11
11
hasher : Hasher ,
12
12
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 ,
16
13
}
17
14
18
15
impl < R > Crc32Reader < R > {
19
16
/// 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 {
22
18
Crc32Reader {
23
19
inner,
24
20
hasher : Hasher :: new ( ) ,
25
21
check : checksum,
26
- enabled : !ae2_encrypted,
27
22
}
28
23
}
29
24
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
+ }
32
33
}
33
34
34
35
pub fn into_inner ( self ) -> R {
35
36
self . inner
36
37
}
37
38
}
38
39
39
- #[ cold]
40
- fn invalid_checksum ( ) -> io:: Error {
41
- io:: Error :: new ( io:: ErrorKind :: InvalidData , "Invalid checksum" )
42
- }
43
-
44
40
impl < R : Read > Read for Crc32Reader < R > {
45
41
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) ;
107
48
}
108
49
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) ) ;
190
57
}
58
+ self . hasher . update ( & buf[ ..count] ) ;
59
+ Ok ( count)
191
60
}
192
61
}
193
62
@@ -200,10 +69,10 @@ mod test {
200
69
let data: & [ u8 ] = b"" ;
201
70
let mut buf = [ 0 ; 1 ] ;
202
71
203
- let mut reader = Crc32Reader :: new ( data, 0 , false ) ;
72
+ let mut reader = Crc32Reader :: new ( data, 0 ) ;
204
73
assert_eq ! ( reader. read( & mut buf) . unwrap( ) , 0 ) ;
205
74
206
- let mut reader = Crc32Reader :: new ( data, 1 , false ) ;
75
+ let mut reader = Crc32Reader :: new ( data, 1 ) ;
207
76
assert ! ( reader
208
77
. read( & mut buf)
209
78
. unwrap_err( )
@@ -216,7 +85,7 @@ mod test {
216
85
let data: & [ u8 ] = b"1234" ;
217
86
let mut buf = [ 0 ; 1 ] ;
218
87
219
- let mut reader = Crc32Reader :: new ( data, 0x9be3e0a3 , false ) ;
88
+ let mut reader = Crc32Reader :: new ( data, 0x9be3e0a3 ) ;
220
89
assert_eq ! ( reader. read( & mut buf) . unwrap( ) , 1 ) ;
221
90
assert_eq ! ( reader. read( & mut buf) . unwrap( ) , 1 ) ;
222
91
assert_eq ! ( reader. read( & mut buf) . unwrap( ) , 1 ) ;
@@ -231,7 +100,7 @@ mod test {
231
100
let data: & [ u8 ] = b"1234" ;
232
101
let mut buf = [ 0 ; 5 ] ;
233
102
234
- let mut reader = Crc32Reader :: new ( data, 0x9be3e0a3 , false ) ;
103
+ let mut reader = Crc32Reader :: new ( data, 0x9be3e0a3 ) ;
235
104
assert_eq ! ( reader. read( & mut buf[ ..0 ] ) . unwrap( ) , 0 ) ;
236
105
assert_eq ! ( reader. read( & mut buf) . unwrap( ) , 4 ) ;
237
106
}
0 commit comments