diff options
| author | Remi Collet <remi@php.net> | 2017-06-26 17:22:01 +0200 |
|---|---|---|
| committer | Remi Collet <remi@php.net> | 2017-06-26 17:22:01 +0200 |
| commit | 85c32322acfc07628140bf631e7c52b12e6050b4 (patch) | |
| tree | ae79035283e68957177407123d7d342278e021d9 /ext/zlib/zlib.c | |
| parent | 4ed8ff509001b35e0cb971a1d6a294345c5d7673 (diff) | |
| parent | caaeb4849aa56cbbdc66ea015c11a58bd47a43ff (diff) | |
| download | php-git-85c32322acfc07628140bf631e7c52b12e6050b4.tar.gz | |
Merge branch 'master' of git.php.net:php-src
* 'master' of git.php.net:php-src: (24 commits)
Removed EG(valid_symbol_table). Used EG(active) instead.
Release temporary string reference
Remove superfluous semicolons
Fix tests on Windows
Produce a better exception message when IntlDateFormatter constructor fails.
Fix format arguments
Remove unused variable op2. It is redeclared later.
Fix typo
Implement object type annotation
Fixed bug #73173
Expose inflate_get_status() and inflate_get_read_len() functions
Add more constants, improve comments, and add tests
Fixed bug #73900
Add OPENSSL_DONT_ZERO_PAD_KEY constant to prevent key padding
Drop soap_hash_str_find_deref()
Only compute callback name in error cases
Extract zend_get_callable_name() API
Move va_copy compatibility code into zend_portability.h
Remove unnecessary string copy
Fix FE_FETCH_* exception check
...
Diffstat (limited to 'ext/zlib/zlib.c')
| -rw-r--r-- | ext/zlib/zlib.c | 106 |
1 files changed, 87 insertions, 19 deletions
diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c index dd0a1c23ef..3478fe536b 100644 --- a/ext/zlib/zlib.c +++ b/ext/zlib/zlib.c @@ -761,24 +761,6 @@ static zend_bool zlib_create_dictionary_string(HashTable *options, char **dict, switch (Z_TYPE_P(option_buffer)) { case IS_STRING: { zend_string *str = Z_STR_P(option_buffer); - size_t i; - zend_bool last_null = 1; - - for (i = 0; i < ZSTR_LEN(str); i++) { - if (ZSTR_VAL(str)[i]) { - last_null = 0; - } else { - if (last_null) { - php_error_docref(NULL, E_WARNING, "dictionary string must not contain empty entries (two consecutive NULL-bytes or one at the very beginning)"); - return 0; - } - last_null = 1; - } - } - if (!last_null) { - php_error_docref(NULL, E_WARNING, "dictionary string must be NULL-byte terminated (each dictionary entry has to be NULL-terminated)"); - } - *dict = emalloc(ZSTR_LEN(str)); memcpy(*dict, ZSTR_VAL(str), ZSTR_LEN(str)); *dictlen = ZSTR_LEN(str); @@ -886,6 +868,7 @@ PHP_FUNCTION(inflate_init) ctx->zfree = php_zlib_free; ((php_zlib_context *) ctx)->inflateDict = dict; ((php_zlib_context *) ctx)->inflateDictlen = dictlen; + ((php_zlib_context *) ctx)->status = Z_OK; if (encoding < 0) { encoding += 15 - window; @@ -894,6 +877,21 @@ PHP_FUNCTION(inflate_init) } if (Z_OK == inflateInit2(ctx, encoding)) { + if (encoding == PHP_ZLIB_ENCODING_RAW && dictlen > 0) { + php_zlib_context *php_ctx = (php_zlib_context *) ctx; + switch (inflateSetDictionary(ctx, (Bytef *) php_ctx->inflateDict, php_ctx->inflateDictlen)) { + case Z_OK: + efree(php_ctx->inflateDict); + php_ctx->inflateDict = NULL; + break; + case Z_DATA_ERROR: + php_error_docref(NULL, E_WARNING, "dictionary does not match expected dictionary (incorrect adler32 hash)"); + efree(php_ctx->inflateDict); + php_ctx->inflateDict = NULL; + RETURN_FALSE; + EMPTY_SWITCH_DEFAULT_CASE() + } + } RETURN_RES(zend_register_resource(ctx, le_inflate)); } else { efree(ctx); @@ -938,6 +936,13 @@ PHP_FUNCTION(inflate_add) "flush mode must be ZLIB_NO_FLUSH, ZLIB_PARTIAL_FLUSH, ZLIB_SYNC_FLUSH, ZLIB_FULL_FLUSH, ZLIB_BLOCK or ZLIB_FINISH"); RETURN_FALSE; } + + /* Lazy-resetting the zlib stream so ctx->total_in remains available until the next inflate_add() call. */ + if (((php_zlib_context *) ctx)->status == Z_STREAM_END) + { + ((php_zlib_context *) ctx)->status = Z_OK; + inflateReset(ctx); + } if (in_len <= 0 && flush_type != Z_FINISH) { RETURN_EMPTY_STRING(); @@ -953,6 +958,8 @@ PHP_FUNCTION(inflate_add) status = inflate(ctx, flush_type); buffer_used = ZSTR_LEN(out) - ctx->avail_out; + ((php_zlib_context *) ctx)->status = status; /* Save status for exposing to userspace */ + switch (status) { case Z_OK: if (ctx->avail_out == 0) { @@ -965,7 +972,6 @@ PHP_FUNCTION(inflate_add) goto complete; } case Z_STREAM_END: - inflateReset(ctx); goto complete; case Z_BUF_ERROR: if (flush_type == Z_FINISH && ctx->avail_out == 0) { @@ -1014,6 +1020,48 @@ PHP_FUNCTION(inflate_add) } /* }}} */ +/* {{{ proto bool inflate_get_status(resource context) + Get decompression status, usually returns either ZLIB_OK or ZLIB_STREAM_END. */ +PHP_FUNCTION(inflate_get_status) +{ + zval *res; + z_stream *ctx; + + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "r", &res)) + { + RETURN_NULL(); + } + + if (!(ctx = zend_fetch_resource_ex(res, NULL, le_inflate))) { + php_error_docref(NULL, E_WARNING, "Invalid zlib.inflate resource"); + RETURN_FALSE; + } + + RETURN_LONG(((php_zlib_context *) ctx)->status); +} +/* }}} */ + +/* {{{ proto bool inflate_get_read_len(resource context) + Get number of bytes read so far. */ +PHP_FUNCTION(inflate_get_read_len) +{ + zval *res; + z_stream *ctx; + + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "r", &res)) + { + RETURN_NULL(); + } + + if (!(ctx = zend_fetch_resource_ex(res, NULL, le_inflate))) { + php_error_docref(NULL, E_WARNING, "Invalid zlib.inflate resource"); + RETURN_FALSE; + } + + RETURN_LONG(ctx->total_in); +} +/* }}} */ + /* {{{ proto resource deflate_init(int encoding[, array options]) Initialize an incremental deflate context using the specified encoding */ PHP_FUNCTION(deflate_init) @@ -1325,6 +1373,14 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_inflate_add, 0, 0, 2) ZEND_ARG_INFO(0, flush_behavior) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(arginfo_inflate_get_status, 0, 0, 1) + ZEND_ARG_INFO(0, resource) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_inflate_get_read_len, 0, 0, 1) + ZEND_ARG_INFO(0, resource) +ZEND_END_ARG_INFO() + /* }}} */ /* {{{ php_zlib_functions[] */ @@ -1357,6 +1413,8 @@ static const zend_function_entry php_zlib_functions[] = { PHP_FE(deflate_add, arginfo_deflate_add) PHP_FE(inflate_init, arginfo_inflate_init) PHP_FE(inflate_add, arginfo_inflate_add) + PHP_FE(inflate_get_status, arginfo_inflate_get_status) + PHP_FE(inflate_get_read_len, arginfo_inflate_get_read_len) PHP_FE(ob_gzhandler, arginfo_ob_gzhandler) PHP_FE_END }; @@ -1472,6 +1530,16 @@ static PHP_MINIT_FUNCTION(zlib) REGISTER_STRING_CONSTANT("ZLIB_VERSION", ZLIB_VERSION, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("ZLIB_VERNUM", ZLIB_VERNUM, CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("ZLIB_OK", Z_OK, CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("ZLIB_STREAM_END", Z_STREAM_END, CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("ZLIB_NEED_DICT", Z_NEED_DICT, CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("ZLIB_ERRNO", Z_ERRNO, CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("ZLIB_STREAM_ERROR", Z_STREAM_ERROR, CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("ZLIB_DATA_ERROR", Z_DATA_ERROR, CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("ZLIB_MEM_ERROR", Z_MEM_ERROR, CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("ZLIB_BUF_ERROR", Z_BUF_ERROR, CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("ZLIB_VERSION_ERROR", Z_VERSION_ERROR, CONST_CS|CONST_PERSISTENT); + REGISTER_INI_ENTRIES(); return SUCCESS; } |
