@@ -108,20 +108,40 @@ fn zlib_decompress(
108
108
wbits : OptionalArg < i8 > ,
109
109
bufsize : OptionalArg < usize > ,
110
110
vm : & VirtualMachine ,
111
- ) -> PyResult {
112
- let encoded_bytes = data. get_value ( ) ;
111
+ ) -> PyResult < Vec < u8 > > {
112
+ let data = data. get_value ( ) ;
113
113
114
114
let ( header, wbits) = header_from_wbits ( wbits) ;
115
115
let bufsize = bufsize. unwrap_or ( DEF_BUF_SIZE ) ;
116
116
117
- let mut decompressor = Decompress :: new_with_window_bits ( header, wbits) ;
118
- let mut decoded_bytes = Vec :: with_capacity ( bufsize ) ;
117
+ let mut d = Decompress :: new_with_window_bits ( header, wbits) ;
118
+ let mut buf = Vec :: new ( ) ;
119
119
120
- match decompressor. decompress_vec ( & encoded_bytes, & mut decoded_bytes, FlushDecompress :: Finish ) {
121
- Ok ( Status :: BufError ) => Err ( zlib_error ( "inconsistent or truncated state" , vm) ) ,
122
- Err ( _) => Err ( zlib_error ( "invalid input data" , vm) ) ,
123
- _ => Ok ( vm. ctx . new_bytes ( decoded_bytes) ) ,
120
+ // TODO: maybe deduplicate this with the Decompress.{decompress,flush}
121
+ ' outer: for chunk in data. chunks ( libc:: c_uint:: max_value ( ) as usize ) {
122
+ // if this is the final chunk, finish it
123
+ let flush = if d. total_in ( ) == ( data. len ( ) - chunk. len ( ) ) as u64 {
124
+ FlushDecompress :: Finish
125
+ } else {
126
+ FlushDecompress :: None
127
+ } ;
128
+ loop {
129
+ buf. reserve ( bufsize) ;
130
+ match d. decompress_vec ( chunk, & mut buf, flush) {
131
+ // we've run out of space, loop again and allocate more
132
+ Ok ( _) if buf. len ( ) == buf. capacity ( ) => { }
133
+ // we've reached the end of the stream, we're done
134
+ Ok ( Status :: StreamEnd ) => {
135
+ break ' outer;
136
+ }
137
+ // we've reached the end of this chunk of the data, do the next one
138
+ Ok ( _) => break ,
139
+ Err ( _) => return Err ( zlib_error ( "invalid input data" , vm) ) ,
140
+ }
141
+ }
124
142
}
143
+ buf. shrink_to_fit ( ) ;
144
+ Ok ( buf)
125
145
}
126
146
127
147
fn zlib_decompressobj (
0 commit comments