Skip to content

Commit 0c4f11e

Browse files
MTres19bwoebi
authored andcommitted
Add more constants, improve comments, and add tests
1 parent 2fddc4a commit 0c4f11e

File tree

4 files changed

+162
-1
lines changed

4 files changed

+162
-1
lines changed

ext/zlib/php_zlib.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ typedef struct _php_zlib_buffer {
4848
typedef struct _php_zlib_context {
4949
z_stream Z;
5050
char *inflateDict;
51+
size_t status;
5152
size_t inflateDictlen;
5253
php_zlib_buffer buffer;
5354
} php_zlib_context;
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
--TEST--
2+
inflate_get_read_len()
3+
--SKIPIF--
4+
<?php if (!extension_loaded("zlib")) print "skip"; ?>
5+
--FILE--
6+
<?php
7+
8+
$uncompressed = "Hello world.";
9+
$random_junk = str_repeat("qebsouesl", 128);;
10+
11+
$compressed = zlib_encode($uncompressed, ZLIB_ENCODING_DEFLATE);
12+
$compressed_len = strlen($compressed);
13+
$compressed .= $random_junk;
14+
15+
$ctx = inflate_init(ZLIB_ENCODING_DEFLATE);
16+
$buf = inflate_add($ctx, $compressed);
17+
$detected_compressed_len = inflate_get_read_len($ctx);
18+
19+
echo 'Status: ' . inflate_get_status($ctx) . "\n";
20+
echo 'Original compressed length: ' . $compressed_len . "\n";
21+
echo 'Detected compressed length: ' . $detected_compressed_len . "\n";
22+
23+
echo ($compressed_len == $detected_compressed_len) ? 'The lengths are equal.' : 'The lengths are unequal.';
24+
?>
25+
--EXPECT--
26+
Status: 1
27+
Original compressed length: 20
28+
Detected compressed length: 20
29+
The lengths are equal.
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
--TEST--
2+
inflate_get_status()
3+
--SKIPIF--
4+
<?php if (!extension_loaded("zlib")) print "skip"; ?>
5+
--FILE--
6+
<?php
7+
8+
$uncompressed = "Hello world.";
9+
$random_junk = str_repeat("qebsouesl", 128);;
10+
11+
$compressed = zlib_encode($uncompressed, ZLIB_ENCODING_DEFLATE);
12+
$compressed_len = strlen($compressed);
13+
$compressed .= $random_junk;
14+
15+
$ctx = inflate_init(ZLIB_ENCODING_DEFLATE);
16+
$status = inflate_get_status($ctx);
17+
$buf = '';
18+
19+
for ($i = 0; $status == ZLIB_OK; ++$i)
20+
{
21+
$buf .= inflate_add($ctx, substr($compressed, $i, 1));
22+
echo '$i = ' . $i . ', ';
23+
$status = inflate_get_status($ctx);
24+
echo 'Status: ' . $status;
25+
echo "\n";
26+
}
27+
28+
echo '$buf = ' . $buf;
29+
echo "\n\n";
30+
31+
echo "Adding more data should reset the stream and result in a Z_OK (ZLIB_OK) status.\n";
32+
inflate_add($ctx, substr($compressed, 0, 12));
33+
echo 'Status: ' . inflate_get_status($ctx);
34+
35+
?>
36+
--EXPECT--
37+
$i = 0, Status: 0
38+
$i = 1, Status: 0
39+
$i = 2, Status: 0
40+
$i = 3, Status: 0
41+
$i = 4, Status: 0
42+
$i = 5, Status: 0
43+
$i = 6, Status: 0
44+
$i = 7, Status: 0
45+
$i = 8, Status: 0
46+
$i = 9, Status: 0
47+
$i = 10, Status: 0
48+
$i = 11, Status: 0
49+
$i = 12, Status: 0
50+
$i = 13, Status: 0
51+
$i = 14, Status: 0
52+
$i = 15, Status: 0
53+
$i = 16, Status: 0
54+
$i = 17, Status: 0
55+
$i = 18, Status: 0
56+
$i = 19, Status: 1
57+
$buf = Hello world.
58+
59+
Adding more data should reset the stream and result in a Z_OK (ZLIB_OK) status.
60+
Status: 0

ext/zlib/zlib.c

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -868,6 +868,7 @@ PHP_FUNCTION(inflate_init)
868868
ctx->zfree = php_zlib_free;
869869
((php_zlib_context *) ctx)->inflateDict = dict;
870870
((php_zlib_context *) ctx)->inflateDictlen = dictlen;
871+
((php_zlib_context *) ctx)->status = Z_OK;
871872

872873
if (encoding < 0) {
873874
encoding += 15 - window;
@@ -935,6 +936,13 @@ PHP_FUNCTION(inflate_add)
935936
"flush mode must be ZLIB_NO_FLUSH, ZLIB_PARTIAL_FLUSH, ZLIB_SYNC_FLUSH, ZLIB_FULL_FLUSH, ZLIB_BLOCK or ZLIB_FINISH");
936937
RETURN_FALSE;
937938
}
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+
}
938946

939947
if (in_len <= 0 && flush_type != Z_FINISH) {
940948
RETURN_EMPTY_STRING();
@@ -950,6 +958,8 @@ PHP_FUNCTION(inflate_add)
950958
status = inflate(ctx, flush_type);
951959
buffer_used = ZSTR_LEN(out) - ctx->avail_out;
952960

961+
((php_zlib_context *) ctx)->status = status; /* Save status for exposing to userspace */
962+
953963
switch (status) {
954964
case Z_OK:
955965
if (ctx->avail_out == 0) {
@@ -962,7 +972,6 @@ PHP_FUNCTION(inflate_add)
962972
goto complete;
963973
}
964974
case Z_STREAM_END:
965-
inflateReset(ctx);
966975
goto complete;
967976
case Z_BUF_ERROR:
968977
if (flush_type == Z_FINISH && ctx->avail_out == 0) {
@@ -1011,6 +1020,48 @@ PHP_FUNCTION(inflate_add)
10111020
}
10121021
/* }}} */
10131022

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+
10141065
/* {{{ proto resource deflate_init(int encoding[, array options])
10151066
Initialize an incremental deflate context using the specified encoding */
10161067
PHP_FUNCTION(deflate_init)
@@ -1322,6 +1373,14 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_inflate_add, 0, 0, 2)
13221373
ZEND_ARG_INFO(0, flush_behavior)
13231374
ZEND_END_ARG_INFO()
13241375

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+
13251384
/* }}} */
13261385

13271386
/* {{{ php_zlib_functions[] */
@@ -1354,6 +1413,8 @@ static const zend_function_entry php_zlib_functions[] = {
13541413
PHP_FE(deflate_add, arginfo_deflate_add)
13551414
PHP_FE(inflate_init, arginfo_inflate_init)
13561415
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)
13571418
PHP_FE(ob_gzhandler, arginfo_ob_gzhandler)
13581419
PHP_FE_END
13591420
};
@@ -1469,6 +1530,16 @@ static PHP_MINIT_FUNCTION(zlib)
14691530
REGISTER_STRING_CONSTANT("ZLIB_VERSION", ZLIB_VERSION, CONST_CS|CONST_PERSISTENT);
14701531
REGISTER_LONG_CONSTANT("ZLIB_VERNUM", ZLIB_VERNUM, CONST_CS|CONST_PERSISTENT);
14711532

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+
14721543
REGISTER_INI_ENTRIES();
14731544
return SUCCESS;
14741545
}

0 commit comments

Comments
 (0)