@@ -52,6 +52,7 @@ final class ZipStreamFilter extends php_user_filter
5252 private string $ header = '' ;
5353 private ?HashContext $ hashContext = null ;
5454 private ?DeflateContext $ deflateContext = null ;
55+ private int $ inflateMethod ;
5556 private ?InflateContext $ inflateContext = null ;
5657
5758 private int $ originalSize = 0 ;
@@ -81,7 +82,7 @@ public static function appendCompression(string $filename, $stream): void
8182 $ resource = stream_filter_append (
8283 $ stream ,
8384 self ::FILTERNAME_PREFIX .self ::MODE_COMPRESS ,
84- STREAM_FILTER_ALL ,
85+ STREAM_FILTER_READ ,
8586 $ filename
8687 );
8788 \assert (false !== $ resource );
@@ -95,7 +96,7 @@ public static function appendDecompression(string $filename, $stream): void
9596 $ resource = stream_filter_append (
9697 $ stream ,
9798 self ::FILTERNAME_PREFIX .self ::MODE_DECOMPRESS ,
98- STREAM_FILTER_ALL ,
99+ STREAM_FILTER_READ ,
99100 $ filename
100101 );
101102 \assert (false !== $ resource );
@@ -115,7 +116,7 @@ public function filter($in, $out, &$consumed, $closing): int
115116 $ this ->buffer .= $ bucket ->data ;
116117 }
117118
118- if ('' === $ this ->buffer ) {
119+ if ('' === $ this ->buffer && ! $ closing ) {
119120 return PSFS_FEED_ME ;
120121 }
121122
@@ -285,9 +286,6 @@ private function compressFilter($out, int &$consumed, bool $closing): void
285286 private function decompressFilter ($ out , int &$ consumed , bool $ closing ): void
286287 {
287288 if (null === $ this ->hashContext ) {
288- $ this ->hashContext = hash_init (self ::HASH_ALGORITHM );
289- $ this ->inflateContext = inflate_init (ZLIB_ENCODING_RAW );
290-
291289 $ header = substr ($ this ->buffer , 0 , self ::HEADER_LENGTH );
292290 $ this ->buffer = substr ($ this ->buffer , self ::HEADER_LENGTH );
293291 $ arrayHeader = unpack ('Vhead/vver/vbits/vmethod/Vtime/Vcrc/Vzlen/Vlen/vfilename/vfooter ' , $ header );
@@ -296,13 +294,20 @@ private function decompressFilter($out, int &$consumed, bool $closing): void
296294 throw new RuntimeException ('Stream is not Zip ' );
297295 }
298296
297+ \assert (\is_int ($ arrayHeader ['method ' ]));
298+ $ this ->inflateMethod = $ arrayHeader ['method ' ];
299299 \assert (\is_int ($ arrayHeader ['filename ' ]));
300300 $ this ->buffer = substr ($ this ->buffer , $ arrayHeader ['filename ' ]);
301301 \assert (\is_int ($ arrayHeader ['footer ' ]));
302302 $ this ->buffer = substr ($ this ->buffer , $ arrayHeader ['footer ' ]);
303303
304304 \assert (\is_int ($ arrayHeader ['crc ' ]));
305305 $ this ->crc = $ arrayHeader ['crc ' ];
306+
307+ $ this ->hashContext = hash_init (self ::HASH_ALGORITHM );
308+ if (self ::METHOD_DEFLATE === $ this ->inflateMethod ) {
309+ $ this ->inflateContext = inflate_init (ZLIB_ENCODING_RAW );
310+ }
306311 }
307312
308313 $ writeChunkSize = self ::CHUNK_SIZE ;
@@ -312,18 +317,26 @@ private function decompressFilter($out, int &$consumed, bool $closing): void
312317
313318 if ($ closing && '' === $ this ->buffer ) {
314319 $ dataDescriptorPosition = strpos ($ data , pack ('V ' , self ::DATA_DESCRIPTOR_SIGNATURE ));
315- if (false !== $ dataDescriptorPosition ) {
320+ if (false === $ dataDescriptorPosition ) {
321+ $ cdrFilePosition = strpos ($ data , pack ('V ' , self ::CDR_FILE_SIGNATURE ));
322+ \assert (false !== $ cdrFilePosition );
323+ $ data = substr ($ data , 0 , $ cdrFilePosition );
324+ } else {
316325 $ unpack = unpack ('Vcrc ' , substr ($ data , $ dataDescriptorPosition + 4 , 4 ));
317326 \assert (\is_int ($ unpack ['crc ' ]));
318327 $ this ->crc = $ unpack ['crc ' ];
328+ $ data = substr ($ data , 0 , $ dataDescriptorPosition );
319329 }
320330 }
321331
322- $ newBucketData = inflate_add (
323- $ this ->inflateContext ,
324- $ data ,
325- ZLIB_SYNC_FLUSH
326- );
332+ $ newBucketData = $ data ;
333+ if (self ::METHOD_DEFLATE === $ this ->inflateMethod ) {
334+ $ newBucketData = inflate_add (
335+ $ this ->inflateContext ,
336+ $ data ,
337+ ZLIB_SYNC_FLUSH
338+ );
339+ }
327340
328341 hash_update ($ this ->hashContext , $ newBucketData );
329342
0 commit comments