@@ -375,22 +375,8 @@ static const php_stream_filter_ops php_bz2_compress_ops = {
375375
376376/* }}} */
377377
378- /* {{{ bzip2.* common factory */
379-
380- static php_stream_filter * php_bz2_filter_create (const char * filtername , zval * filterparams , bool persistent )
381- {
382- const php_stream_filter_ops * fops = NULL ;
383- php_stream_filter_seekable_t write_seekable ;
384- php_bz2_filter_data * data ;
385- int status = BZ_OK ;
386-
387- if (php_stream_filter_parse_write_seek_mode (filterparams , & write_seekable ) == FAILURE ) {
388- return NULL ;
389- }
390-
391- /* Create this filter */
392- data = pecalloc (1 , sizeof (php_bz2_filter_data ), persistent );
393-
378+ static php_bz2_filter_data * php_bz2_filter_data_new (bool persistent ) {
379+ php_bz2_filter_data * data = pecalloc (1 , sizeof (php_bz2_filter_data ), persistent );
394380 /* Circular reference */
395381 data -> strm .opaque = (void * ) data ;
396382
@@ -401,86 +387,143 @@ static php_stream_filter *php_bz2_filter_create(const char *filtername, zval *fi
401387 data -> strm .next_in = data -> inbuf = (char * ) pemalloc (data -> inbuf_len , persistent );
402388 data -> strm .avail_in = 0 ;
403389 data -> strm .next_out = data -> outbuf = (char * ) pemalloc (data -> outbuf_len , persistent );
390+ return data ;
391+ }
404392
405- if (strcasecmp (filtername , "bzip2.decompress" ) == 0 ) {
406- data -> small_footprint = 0 ;
407- data -> expect_concatenated = 0 ;
408-
409- if (filterparams ) {
410- zval * tmpzval = NULL ;
393+ static php_stream_filter * php_bz2_decompress_filter_create (zval * filter_params , bool persistent ) {
394+ php_stream_filter_seekable_t write_seekable = PSFS_SEEKABLE_ALWAYS ;
395+ bool small_footprint = false;
396+ bool expect_concatenated = false;
397+
398+ if (filter_params ) {
399+ if (UNEXPECTED (
400+ Z_TYPE_P (filter_params ) != IS_TRUE
401+ && Z_TYPE_P (filter_params ) != IS_FALSE
402+ && Z_TYPE_P (filter_params ) != IS_ARRAY
403+ && Z_TYPE_P (filter_params ) != IS_OBJECT
404+ )) {
405+ php_error_docref (NULL , E_WARNING ,
406+ "Filter parameters for bzip2.decompress filter must be of type array|object|bool, %s given" ,
407+ zend_zval_type_name (filter_params )
408+ );
409+ return NULL ;
410+ }
411411
412- if (Z_TYPE_P (filterparams ) == IS_ARRAY || Z_TYPE_P (filterparams ) == IS_OBJECT ) {
413- HashTable * ht = HASH_OF (filterparams );
412+ if (Z_TYPE_P (filter_params ) == IS_TRUE || Z_TYPE_P (filter_params ) == IS_FALSE ) {
413+ small_footprint = Z_TYPE_P (filter_params ) == IS_TRUE ;
414+ } else {
415+ ZEND_ASSERT (Z_TYPE_P (filter_params ) == IS_ARRAY || Z_TYPE_P (filter_params ) == IS_OBJECT );
414416
415- if ((tmpzval = zend_hash_str_find_ind (ht , "concatenated" , sizeof ("concatenated" )- 1 ))) {
416- data -> expect_concatenated = zend_is_true (tmpzval );
417- tmpzval = NULL ;
418- }
417+ const HashTable * filter_params_ht = HASH_OF (filter_params );
418+ /* TODO: convert php_stream_filter_parse_write_seek_mode() to take HashTable */
419+ if (php_stream_filter_parse_write_seek_mode (filter_params , & write_seekable ) == FAILURE ) {
420+ return NULL ;
421+ }
419422
420- tmpzval = zend_hash_str_find_ind (ht , "small" , sizeof ( "small" ) - 1 );
421- } else {
422- tmpzval = filterparams ;
423+ const zval * concatenated = zend_hash_str_find_ind (filter_params_ht , ZEND_STRL ( "concatenated" ) );
424+ if ( concatenated ) {
425+ expect_concatenated = zend_is_true ( concatenated ) ;
423426 }
424427
425- if (tmpzval ) {
426- data -> small_footprint = zend_is_true (tmpzval );
428+ const zval * small = zend_hash_str_find_ind (filter_params_ht , ZEND_STRL ("small" ));
429+ if (small ) {
430+ small_footprint = zend_is_true (small );
427431 }
428432 }
433+ }
429434
430- data -> status = PHP_BZ2_UNINITIALIZED ;
431- fops = & php_bz2_decompress_ops ;
432- } else if (strcasecmp (filtername , "bzip2.compress" ) == 0 ) {
433- int blockSize100k = PHP_BZ2_FILTER_DEFAULT_BLOCKSIZE ;
434- int workFactor = PHP_BZ2_FILTER_DEFAULT_WORKFACTOR ;
435-
436- if (filterparams ) {
437- zval * tmpzval ;
438-
439- if (Z_TYPE_P (filterparams ) == IS_ARRAY || Z_TYPE_P (filterparams ) == IS_OBJECT ) {
440- HashTable * ht = HASH_OF (filterparams );
441-
442- if ((tmpzval = zend_hash_str_find_ind (ht , "blocks" , sizeof ("blocks" )- 1 ))) {
443- /* How much memory to allocate (1 - 9) x 100kb */
444- zend_long blocks = zval_get_long (tmpzval );
445- if (blocks < 1 || blocks > 9 ) {
446- php_error_docref (NULL , E_WARNING , "Invalid parameter given for number of blocks to allocate (" ZEND_LONG_FMT ")" , blocks );
447- } else {
448- blockSize100k = (int ) blocks ;
449- }
450- }
435+ php_bz2_filter_data * data = php_bz2_filter_data_new (persistent );
436+ /* Save configuration for reset */
437+ data -> small_footprint = small_footprint ;
438+ data -> expect_concatenated = expect_concatenated ;
439+ data -> status = PHP_BZ2_UNINITIALIZED ;
451440
452- if ((tmpzval = zend_hash_str_find_ind (ht , "work" , sizeof ("work" )- 1 ))) {
453- /* Work Factor (0 - 250) */
454- zend_long work = zval_get_long (tmpzval );
455- if (work < 0 || work > 250 ) {
456- php_error_docref (NULL , E_WARNING , "Invalid parameter given for work factor (" ZEND_LONG_FMT ")" , work );
457- } else {
458- workFactor = (int ) work ;
459- }
460- }
461- }
441+ return php_stream_filter_alloc (& php_bz2_decompress_ops , data , persistent , PSFS_SEEKABLE_START , write_seekable );
442+ }
443+
444+ static php_stream_filter * php_bz2_compress_filter_create (zval * filter_params , bool persistent ) {
445+ php_stream_filter_seekable_t write_seekable = PSFS_SEEKABLE_ALWAYS ;
446+ int blockSize100k = PHP_BZ2_FILTER_DEFAULT_BLOCKSIZE ;
447+ int workFactor = PHP_BZ2_FILTER_DEFAULT_WORKFACTOR ;
448+
449+ if (filter_params ) {
450+ if (UNEXPECTED (Z_TYPE_P (filter_params ) != IS_ARRAY && Z_TYPE_P (filter_params ) != IS_OBJECT )) {
451+ php_error_docref (NULL , E_WARNING ,
452+ "Filter parameters for bzip2.compress filter must be of type array|object, %s given" ,
453+ zend_zval_type_name (filter_params )
454+ );
455+ return NULL ;
462456 }
463457
464- /* Save configuration for reset */
465- data -> blockSize100k = blockSize100k ;
466- data -> workFactor = workFactor ;
458+ const HashTable * filter_params_ht = HASH_OF (filter_params );
459+ /* TODO: convert php_stream_filter_parse_write_seek_mode() to take HashTable */
460+ if (php_stream_filter_parse_write_seek_mode (filter_params , & write_seekable ) == FAILURE ) {
461+ return NULL ;
462+ }
467463
468- status = BZ2_bzCompressInit (& (data -> strm ), blockSize100k , 0 , workFactor );
469- data -> is_flushed = 1 ;
470- fops = & php_bz2_compress_ops ;
471- } else {
472- status = BZ_DATA_ERROR ;
464+ const zval * blocks_zv = zend_hash_str_find_ind (filter_params_ht , ZEND_STRL ("blocks" ));
465+ if (blocks_zv ) {
466+ ZEND_ASSERT (Z_TYPE_P (blocks_zv ) != IS_INDIRECT );
467+ bool failed = false;
468+ /* How much memory to allocate (1 - 9) x 100kb */
469+ zend_long blocks = zval_try_get_long (blocks_zv , & failed );
470+ if (UNEXPECTED (failed )) {
471+ php_error_docref (NULL , E_WARNING , "Number of blocks parameter must be of type int, %s given" , zend_zval_type_name (blocks_zv ));
472+ return NULL ;
473+ } else if (blocks < 1 || blocks > 9 ) {
474+ php_error_docref (NULL , E_WARNING , "Number of blocks to allocate must be between 1 and 9, " ZEND_LONG_FMT " given" , blocks );
475+ return NULL ;
476+ } else {
477+ blockSize100k = (int ) blocks ;
478+ }
479+ }
480+
481+ const zval * work_zv = zend_hash_str_find_ind (filter_params_ht , ZEND_STRL ("work" ));
482+ if (work_zv ) {
483+ ZEND_ASSERT (Z_TYPE_P (work_zv ) != IS_INDIRECT );
484+ bool failed = false;
485+ /* Work Factor (0 - 250) */
486+ zend_long work = zval_try_get_long (work_zv , & failed );
487+ if (UNEXPECTED (failed )) {
488+ php_error_docref (NULL , E_WARNING , "Work factor parameter must be of type int, %s given" , zend_zval_type_name (work_zv ));
489+ return NULL ;
490+ } else if (work < 0 || work > 250 ) {
491+ php_error_docref (NULL , E_WARNING , "Work factor must be between 0 and 250, " ZEND_LONG_FMT " given" , work );
492+ return NULL ;
493+ } else {
494+ workFactor = (int ) work ;
495+ }
496+ }
473497 }
474498
475- if (status != BZ_OK ) {
499+ php_bz2_filter_data * data = php_bz2_filter_data_new (persistent );
500+ /* Save configuration for reset */
501+ data -> blockSize100k = blockSize100k ;
502+ data -> workFactor = workFactor ;
503+
504+ int status = BZ2_bzCompressInit (& (data -> strm ), blockSize100k , 0 , workFactor );
505+ if (UNEXPECTED (status != BZ_OK )) {
476506 /* Unspecified (probably strm) error, let stream-filter error do its own whining */
477507 pefree (data -> strm .next_in , persistent );
478508 pefree (data -> strm .next_out , persistent );
479509 pefree (data , persistent );
480510 return NULL ;
481511 }
512+ data -> is_flushed = true;
513+
514+ return php_stream_filter_alloc (& php_bz2_compress_ops , data , persistent , PSFS_SEEKABLE_START , write_seekable );
515+ }
482516
483- return php_stream_filter_alloc (fops , data , persistent , PSFS_SEEKABLE_START , write_seekable );
517+ /* {{{ bzip2.* common factory */
518+ static php_stream_filter * php_bz2_filter_create (const char * filtername , zval * filterparams , bool persistent )
519+ {
520+ if (strcasecmp (filtername , "bzip2.decompress" ) == 0 ) {
521+ return php_bz2_decompress_filter_create (filterparams , persistent );
522+ } else if (strcasecmp (filtername , "bzip2.compress" ) == 0 ) {
523+ return php_bz2_compress_filter_create (filterparams , persistent );
524+ } else {
525+ return NULL ;
526+ }
484527}
485528
486529const php_stream_filter_factory php_bz2_filter_factory = {
0 commit comments