@@ -868,6 +868,7 @@ PHP_FUNCTION(inflate_init)
868
868
ctx -> zfree = php_zlib_free ;
869
869
((php_zlib_context * ) ctx )-> inflateDict = dict ;
870
870
((php_zlib_context * ) ctx )-> inflateDictlen = dictlen ;
871
+ ((php_zlib_context * ) ctx )-> status = Z_OK ;
871
872
872
873
if (encoding < 0 ) {
873
874
encoding += 15 - window ;
@@ -935,6 +936,13 @@ PHP_FUNCTION(inflate_add)
935
936
"flush mode must be ZLIB_NO_FLUSH, ZLIB_PARTIAL_FLUSH, ZLIB_SYNC_FLUSH, ZLIB_FULL_FLUSH, ZLIB_BLOCK or ZLIB_FINISH" );
936
937
RETURN_FALSE ;
937
938
}
939
+
940
+ /* Lazy-resetting the zlib stream so ctx->total_in remains available until the next inflate_add() call. */
941
+ if (((php_zlib_context * ) ctx )-> status == Z_STREAM_END )
942
+ {
943
+ ((php_zlib_context * ) ctx )-> status = Z_OK ;
944
+ inflateReset (ctx );
945
+ }
938
946
939
947
if (in_len <= 0 && flush_type != Z_FINISH ) {
940
948
RETURN_EMPTY_STRING ();
@@ -950,6 +958,8 @@ PHP_FUNCTION(inflate_add)
950
958
status = inflate (ctx , flush_type );
951
959
buffer_used = ZSTR_LEN (out ) - ctx -> avail_out ;
952
960
961
+ ((php_zlib_context * ) ctx )-> status = status ; /* Save status for exposing to userspace */
962
+
953
963
switch (status ) {
954
964
case Z_OK :
955
965
if (ctx -> avail_out == 0 ) {
@@ -962,7 +972,6 @@ PHP_FUNCTION(inflate_add)
962
972
goto complete ;
963
973
}
964
974
case Z_STREAM_END :
965
- inflateReset (ctx );
966
975
goto complete ;
967
976
case Z_BUF_ERROR :
968
977
if (flush_type == Z_FINISH && ctx -> avail_out == 0 ) {
@@ -1011,6 +1020,48 @@ PHP_FUNCTION(inflate_add)
1011
1020
}
1012
1021
/* }}} */
1013
1022
1023
+ /* {{{ proto bool inflate_get_status(resource context)
1024
+ Get decompression status, usually returns either ZLIB_OK or ZLIB_STREAM_END. */
1025
+ PHP_FUNCTION (inflate_get_status )
1026
+ {
1027
+ zval * res ;
1028
+ z_stream * ctx ;
1029
+
1030
+ if (SUCCESS != zend_parse_parameters (ZEND_NUM_ARGS (), "r" , & res ))
1031
+ {
1032
+ RETURN_NULL ();
1033
+ }
1034
+
1035
+ if (!(ctx = zend_fetch_resource_ex (res , NULL , le_inflate ))) {
1036
+ php_error_docref (NULL , E_WARNING , "Invalid zlib.inflate resource" );
1037
+ RETURN_FALSE ;
1038
+ }
1039
+
1040
+ RETURN_LONG (((php_zlib_context * ) ctx )-> status );
1041
+ }
1042
+ /* }}} */
1043
+
1044
+ /* {{{ proto bool inflate_get_read_len(resource context)
1045
+ Get number of bytes read so far. */
1046
+ PHP_FUNCTION (inflate_get_read_len )
1047
+ {
1048
+ zval * res ;
1049
+ z_stream * ctx ;
1050
+
1051
+ if (SUCCESS != zend_parse_parameters (ZEND_NUM_ARGS (), "r" , & res ))
1052
+ {
1053
+ RETURN_NULL ();
1054
+ }
1055
+
1056
+ if (!(ctx = zend_fetch_resource_ex (res , NULL , le_inflate ))) {
1057
+ php_error_docref (NULL , E_WARNING , "Invalid zlib.inflate resource" );
1058
+ RETURN_FALSE ;
1059
+ }
1060
+
1061
+ RETURN_LONG (ctx -> total_in );
1062
+ }
1063
+ /* }}} */
1064
+
1014
1065
/* {{{ proto resource deflate_init(int encoding[, array options])
1015
1066
Initialize an incremental deflate context using the specified encoding */
1016
1067
PHP_FUNCTION (deflate_init )
@@ -1322,6 +1373,14 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_inflate_add, 0, 0, 2)
1322
1373
ZEND_ARG_INFO (0 , flush_behavior )
1323
1374
ZEND_END_ARG_INFO ()
1324
1375
1376
+ ZEND_BEGIN_ARG_INFO_EX (arginfo_inflate_get_status , 0 , 0 , 1 )
1377
+ ZEND_ARG_INFO (0 , resource )
1378
+ ZEND_END_ARG_INFO ()
1379
+
1380
+ ZEND_BEGIN_ARG_INFO_EX (arginfo_inflate_get_read_len , 0 , 0 , 1 )
1381
+ ZEND_ARG_INFO (0 , resource )
1382
+ ZEND_END_ARG_INFO ()
1383
+
1325
1384
/* }}} */
1326
1385
1327
1386
/* {{{ php_zlib_functions[] */
@@ -1354,6 +1413,8 @@ static const zend_function_entry php_zlib_functions[] = {
1354
1413
PHP_FE (deflate_add , arginfo_deflate_add )
1355
1414
PHP_FE (inflate_init , arginfo_inflate_init )
1356
1415
PHP_FE (inflate_add , arginfo_inflate_add )
1416
+ PHP_FE (inflate_get_status , arginfo_inflate_get_status )
1417
+ PHP_FE (inflate_get_read_len , arginfo_inflate_get_read_len )
1357
1418
PHP_FE (ob_gzhandler , arginfo_ob_gzhandler )
1358
1419
PHP_FE_END
1359
1420
};
@@ -1469,6 +1530,16 @@ static PHP_MINIT_FUNCTION(zlib)
1469
1530
REGISTER_STRING_CONSTANT ("ZLIB_VERSION" , ZLIB_VERSION , CONST_CS |CONST_PERSISTENT );
1470
1531
REGISTER_LONG_CONSTANT ("ZLIB_VERNUM" , ZLIB_VERNUM , CONST_CS |CONST_PERSISTENT );
1471
1532
1533
+ REGISTER_LONG_CONSTANT ("ZLIB_OK" , Z_OK , CONST_CS |CONST_PERSISTENT );
1534
+ REGISTER_LONG_CONSTANT ("ZLIB_STREAM_END" , Z_STREAM_END , CONST_CS |CONST_PERSISTENT );
1535
+ REGISTER_LONG_CONSTANT ("ZLIB_NEED_DICT" , Z_NEED_DICT , CONST_CS |CONST_PERSISTENT );
1536
+ REGISTER_LONG_CONSTANT ("ZLIB_ERRNO" , Z_ERRNO , CONST_CS |CONST_PERSISTENT );
1537
+ REGISTER_LONG_CONSTANT ("ZLIB_STREAM_ERROR" , Z_STREAM_ERROR , CONST_CS |CONST_PERSISTENT );
1538
+ REGISTER_LONG_CONSTANT ("ZLIB_DATA_ERROR" , Z_DATA_ERROR , CONST_CS |CONST_PERSISTENT );
1539
+ REGISTER_LONG_CONSTANT ("ZLIB_MEM_ERROR" , Z_MEM_ERROR , CONST_CS |CONST_PERSISTENT );
1540
+ REGISTER_LONG_CONSTANT ("ZLIB_BUF_ERROR" , Z_BUF_ERROR , CONST_CS |CONST_PERSISTENT );
1541
+ REGISTER_LONG_CONSTANT ("ZLIB_VERSION_ERROR" , Z_VERSION_ERROR , CONST_CS |CONST_PERSISTENT );
1542
+
1472
1543
REGISTER_INI_ENTRIES ();
1473
1544
return SUCCESS ;
1474
1545
}
0 commit comments