11use compression_core:: util:: PartialBuffer ;
2+ use flate2:: Crc ;
23use std:: io;
34
45#[ derive( Debug , Default ) ]
@@ -36,6 +37,7 @@ impl Default for State {
3637pub ( super ) struct Parser {
3738 state : State ,
3839 header : Header ,
40+ crc : Crc ,
3941}
4042
4143impl Header {
@@ -63,16 +65,33 @@ impl Header {
6365
6466impl Parser {
6567 pub ( super ) fn input ( & mut self , input : & mut PartialBuffer < & [ u8 ] > ) -> io:: Result < Option < Header > > {
68+ let consume_input = |n| {
69+ self . crc . update ( & input. unwritten ( ) [ ..n] ) ;
70+ input. advance ( n) ;
71+ } ;
72+
73+ let consume_cstr = || {
74+ if let Some ( len) = memchr:: memchr ( 0 , input. unwritten ( ) ) {
75+ consume_input ( len + 1 ) ;
76+ Some ( ( ) )
77+ } else {
78+ consume_input ( input. unwritten ( ) . len ( ) ) ;
79+ None
80+ }
81+ } ;
82+
6683 loop {
6784 match & mut self . state {
6885 State :: Fixed ( data) => {
6986 data. copy_unwritten_from ( input) ;
7087
7188 if data. unwritten ( ) . is_empty ( ) {
72- self . header = Header :: parse ( & data. take ( ) . into_inner ( ) ) ?;
89+ let data = data. get_mut ( ) ;
90+ self . crc . update ( data) ;
91+ self . header = Header :: parse ( data) ?;
7392 self . state = State :: ExtraLen ( <_ >:: default ( ) ) ;
7493 } else {
75- return Ok ( None ) ;
94+ break Ok ( None )
7695 }
7796 }
7897
@@ -85,22 +104,24 @@ impl Parser {
85104 data. copy_unwritten_from ( input) ;
86105
87106 if data. unwritten ( ) . is_empty ( ) {
88- let len = u16:: from_le_bytes ( data. take ( ) . into_inner ( ) ) ;
107+ let data = data. get_mut ( ) ;
108+ self . crc . update ( data) ;
109+ let len = u16:: from_le_bytes ( data) ;
89110 self . state = State :: Extra ( len. into ( ) ) ;
90111 } else {
91- return Ok ( None ) ;
112+ break Ok ( None )
92113 }
93114 }
94115
95116 State :: Extra ( bytes_to_consume) => {
96117 let n = input. unwritten ( ) . len ( ) . min ( * bytes_to_consume) ;
97118 * bytes_to_consume -= n;
98- input . advance ( n) ;
119+ consume_input ( n) ;
99120
100121 if * bytes_to_consume == 0 {
101122 self . state = State :: Filename ;
102123 } else {
103- return Ok ( None ) ;
124+ break Ok ( None )
104125 }
105126 }
106127
@@ -110,13 +131,8 @@ impl Parser {
110131 continue ;
111132 }
112133
113- if let Some ( len) = memchr:: memchr ( 0 , input. unwritten ( ) ) {
114- input. advance ( len + 1 ) ;
115- self . state = State :: Comment ;
116- } else {
117- input. advance ( input. unwritten ( ) . len ( ) ) ;
118- return Ok ( None ) ;
119- }
134+ consume_cstr ( ) ?;
135+ self . state = State :: Comment ;
120136 }
121137
122138 State :: Comment => {
@@ -125,35 +141,42 @@ impl Parser {
125141 continue ;
126142 }
127143
128- if let Some ( len) = memchr:: memchr ( 0 , input. unwritten ( ) ) {
129- input. advance ( len + 1 ) ;
130- self . state = State :: Crc ( <_ >:: default ( ) ) ;
131- } else {
132- input. advance ( input. unwritten ( ) . len ( ) ) ;
133- return Ok ( None ) ;
134- }
144+ consume_cstr ( ) ?;
145+ self . state = State :: Crc ( <_ >:: default ( ) ) ;
135146 }
136147
137148 State :: Crc ( data) => {
149+ let header = std:: mem:: take ( & mut self . header ) ;
150+
138151 if !self . header . flags . crc {
139152 self . state = State :: Done ;
140- return Ok ( Some ( std :: mem :: take ( & mut self . header ) ) ) ;
153+ break Ok ( Some ( header) )
141154 }
142155
143156 data. copy_unwritten_from ( input) ;
144157
145- if data. unwritten ( ) . is_empty ( ) {
158+ break if data. unwritten ( ) . is_empty ( ) {
146159 self . state = State :: Done ;
147- return Ok ( Some ( std:: mem:: take ( & mut self . header ) ) ) ;
160+ let checksum = self . crc . sum ( ) . to_le_bytes ( ) ;
161+ let data = data. get_mut ( ) ;
162+
163+ if data == checksum[ ..2 ] {
164+ Ok ( Some ( header) )
165+ } else {
166+ Err ( io:: Error :: new (
167+ io:: ErrorKind :: InvalidData ,
168+ "CRC computed for header does not match" ,
169+ ) )
170+ }
148171 } else {
149- return Ok ( None ) ;
172+ Ok ( None )
150173 }
151174 }
152175
153176 State :: Done => {
154- return Err ( io:: Error :: other ( "parser used after done" ) ) ;
177+ break Err ( io:: Error :: other ( "parser used after done" ) )
155178 }
156- } ;
179+ }
157180 }
158181 }
159182}
0 commit comments