@@ -42,6 +42,10 @@ typedef struct _php_bz2_filter_data {
4242 unsigned int is_flushed : 1 ; /* only for compression */
4343
4444 int persistent ;
45+
46+ /* Configuration for reset - immutable */
47+ int blockSize100k ; /* compress only */
48+ int workFactor ; /* compress only */
4549} php_bz2_filter_data ;
4650
4751/* }}} */
@@ -178,6 +182,36 @@ static php_stream_filter_status_t php_bz2_decompress_filter(
178182 return exit_status ;
179183}
180184
185+ static zend_result php_bz2_decompress_seek (
186+ php_stream * stream ,
187+ php_stream_filter * thisfilter ,
188+ zend_off_t offset ,
189+ int whence
190+ )
191+ {
192+ if (!Z_PTR (thisfilter -> abstract )) {
193+ return FAILURE ;
194+ }
195+
196+ php_bz2_filter_data * data = Z_PTR (thisfilter -> abstract );
197+
198+ /* End current decompression if running */
199+ if (data -> status == PHP_BZ2_RUNNING ) {
200+ BZ2_bzDecompressEnd (& (data -> strm ));
201+ }
202+
203+ /* Reset stream state */
204+ data -> strm .next_in = data -> inbuf ;
205+ data -> strm .avail_in = 0 ;
206+ data -> strm .next_out = data -> outbuf ;
207+ data -> strm .avail_out = data -> outbuf_len ;
208+ data -> status = PHP_BZ2_UNINITIALIZED ;
209+
210+ /* Note: We don't reinitialize here - it will be done on first use in the filter function */
211+
212+ return SUCCESS ;
213+ }
214+
181215static void php_bz2_decompress_dtor (php_stream_filter * thisfilter )
182216{
183217 if (thisfilter && Z_PTR (thisfilter -> abstract )) {
@@ -193,6 +227,7 @@ static void php_bz2_decompress_dtor(php_stream_filter *thisfilter)
193227
194228static const php_stream_filter_ops php_bz2_decompress_ops = {
195229 php_bz2_decompress_filter ,
230+ php_bz2_decompress_seek ,
196231 php_bz2_decompress_dtor ,
197232 "bzip2.decompress"
198233};
@@ -288,6 +323,41 @@ static php_stream_filter_status_t php_bz2_compress_filter(
288323 return exit_status ;
289324}
290325
326+ static zend_result php_bz2_compress_seek (
327+ php_stream * stream ,
328+ php_stream_filter * thisfilter ,
329+ zend_off_t offset ,
330+ int whence
331+ )
332+ {
333+ int status ;
334+
335+ if (!Z_PTR (thisfilter -> abstract )) {
336+ return FAILURE ;
337+ }
338+
339+ php_bz2_filter_data * data = Z_PTR (thisfilter -> abstract );
340+
341+ /* End current compression */
342+ BZ2_bzCompressEnd (& (data -> strm ));
343+
344+ /* Reset stream state */
345+ data -> strm .next_in = data -> inbuf ;
346+ data -> strm .avail_in = 0 ;
347+ data -> strm .next_out = data -> outbuf ;
348+ data -> strm .avail_out = data -> outbuf_len ;
349+ data -> is_flushed = 1 ;
350+
351+ /* Reinitialize compression with saved configuration */
352+ status = BZ2_bzCompressInit (& (data -> strm ), data -> blockSize100k , 0 , data -> workFactor );
353+ if (status != BZ_OK ) {
354+ php_error_docref (NULL , E_WARNING , "bzip2.compress: failed to reset compression state" );
355+ return FAILURE ;
356+ }
357+
358+ return SUCCESS ;
359+ }
360+
291361static void php_bz2_compress_dtor (php_stream_filter * thisfilter )
292362{
293363 if (Z_PTR (thisfilter -> abstract )) {
@@ -301,6 +371,7 @@ static void php_bz2_compress_dtor(php_stream_filter *thisfilter)
301371
302372static const php_stream_filter_ops php_bz2_compress_ops = {
303373 php_bz2_compress_filter ,
374+ php_bz2_compress_seek ,
304375 php_bz2_compress_dtor ,
305376 "bzip2.compress"
306377};
@@ -309,7 +380,7 @@ static const php_stream_filter_ops php_bz2_compress_ops = {
309380
310381/* {{{ bzip2.* common factory */
311382
312- static php_stream_filter * php_bz2_filter_create (const char * filtername , zval * filterparams , uint8_t persistent )
383+ static php_stream_filter * php_bz2_filter_create (const char * filtername , zval * filterparams , bool persistent )
313384{
314385 const php_stream_filter_ops * fops = NULL ;
315386 php_bz2_filter_data * data ;
@@ -388,6 +459,10 @@ static php_stream_filter *php_bz2_filter_create(const char *filtername, zval *fi
388459 }
389460 }
390461
462+ /* Save configuration for reset */
463+ data -> blockSize100k = blockSize100k ;
464+ data -> workFactor = workFactor ;
465+
391466 status = BZ2_bzCompressInit (& (data -> strm ), blockSize100k , 0 , workFactor );
392467 data -> is_flushed = 1 ;
393468 fops = & php_bz2_compress_ops ;
@@ -403,7 +478,7 @@ static php_stream_filter *php_bz2_filter_create(const char *filtername, zval *fi
403478 return NULL ;
404479 }
405480
406- return php_stream_filter_alloc (fops , data , persistent );
481+ return php_stream_filter_alloc (fops , data , persistent , PSFS_SEEKABLE_START );
407482}
408483
409484const php_stream_filter_factory php_bz2_filter_factory = {
0 commit comments