summaryrefslogtreecommitdiff
path: root/ext/zlib
diff options
context:
space:
mode:
authorBob Weinand <bobwei9@hotmail.com>2015-05-14 22:58:13 +0200
committerBob Weinand <bobwei9@hotmail.com>2015-05-15 02:28:37 +0200
commita129ded3c18e9446ca75c12d03f678177808a26e (patch)
treec2c4a1ba44351534c8fae19c58eb77e35983962a /ext/zlib
parent738c71aa9a019fb9b72c8cb90f546ab9b27f4e31 (diff)
downloadphp-git-a129ded3c18e9446ca75c12d03f678177808a26e.tar.gz
Add window option to {de,in}flate_init()
Diffstat (limited to 'ext/zlib')
-rw-r--r--ext/zlib/zlib.c96
1 files changed, 63 insertions, 33 deletions
diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c
index c375613eba..e99e3760e2 100644
--- a/ext/zlib/zlib.c
+++ b/ext/zlib/zlib.c
@@ -757,12 +757,22 @@ PHP_ZLIB_DECODE_FUNC(gzuncompress, PHP_ZLIB_ENCODING_DEFLATE);
PHP_FUNCTION(inflate_init)
{
z_stream *ctx;
- zend_long encoding;
+ zend_long encoding, window = 15;
+ HashTable *options;
+ zval *option_buffer;
- if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "l", &encoding)) {
+ if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "l|H", &encoding, &options)) {
return;
}
+ if (options && (option_buffer = zend_hash_str_find(options, ZEND_STRL("window"))) != NULL) {
+ window = zval_get_long(option_buffer);
+ }
+ if (window < 8 || window > 15) {
+ php_error_docref(NULL, E_WARNING, "zlib window size (lograithm) (%pd) must be within 8..15", window);
+ RETURN_FALSE;
+ }
+
switch (encoding) {
case PHP_ZLIB_ENCODING_RAW:
case PHP_ZLIB_ENCODING_GZIP:
@@ -772,12 +782,18 @@ PHP_FUNCTION(inflate_init)
php_error_docref(NULL, E_WARNING,
"encoding mode must be ZLIB_ENCODING_RAW, ZLIB_ENCODING_GZIP or ZLIB_ENCODING_DEFLATE");
RETURN_FALSE;
- }
+ }
ctx = ecalloc(1, sizeof(php_zlib_context));
ctx->zalloc = php_zlib_alloc;
ctx->zfree = php_zlib_free;
+ if (encoding < 0) {
+ encoding += 15 - window;
+ } else {
+ encoding &= window;
+ }
+
if (Z_OK == inflateInit2(ctx, encoding)) {
RETURN_RES(zend_register_resource(ctx, le_inflate));
} else {
@@ -839,34 +855,34 @@ PHP_FUNCTION(inflate_add)
buffer_used = out->len - ctx->avail_out;
switch (status) {
- case Z_OK:
- if (ctx->avail_out == 0) {
- /* more output buffer space needed; realloc and try again */
- out = zend_string_realloc(out, out->len + CHUNK_SIZE, 0);
- ctx->avail_out = CHUNK_SIZE;
- ctx->next_out = (Bytef *) out->val + buffer_used;
- break;
- } else {
- goto complete;
- }
- case Z_STREAM_END:
- inflateReset(ctx);
- goto complete;
- case Z_BUF_ERROR:
- if (flush_type == Z_FINISH && ctx->avail_out == 0) {
- /* more output buffer space needed; realloc and try again */
- out = zend_string_realloc(out, out->len + CHUNK_SIZE, 0);
- ctx->avail_out = CHUNK_SIZE;
- ctx->next_out = (Bytef *) out->val + buffer_used;
- break;
- } else {
- /* No more input data; we're finished */
+ case Z_OK:
+ if (ctx->avail_out == 0) {
+ /* more output buffer space needed; realloc and try again */
+ out = zend_string_realloc(out, out->len + CHUNK_SIZE, 0);
+ ctx->avail_out = CHUNK_SIZE;
+ ctx->next_out = (Bytef *) out->val + buffer_used;
+ break;
+ } else {
+ goto complete;
+ }
+ case Z_STREAM_END:
+ inflateReset(ctx);
goto complete;
- }
- default:
- zend_string_release(out);
- php_error_docref(NULL, E_WARNING, "%s", zError(status));
- RETURN_FALSE;
+ case Z_BUF_ERROR:
+ if (flush_type == Z_FINISH && ctx->avail_out == 0) {
+ /* more output buffer space needed; realloc and try again */
+ out = zend_string_realloc(out, out->len + CHUNK_SIZE, 0);
+ ctx->avail_out = CHUNK_SIZE;
+ ctx->next_out = (Bytef *) out->val + buffer_used;
+ break;
+ } else {
+ /* No more input data; we're finished */
+ goto complete;
+ }
+ default:
+ zend_string_release(out);
+ php_error_docref(NULL, E_WARNING, "%s", zError(status));
+ RETURN_FALSE;
}
} while (1);
@@ -883,7 +899,7 @@ PHP_FUNCTION(inflate_add)
PHP_FUNCTION(deflate_init)
{
z_stream *ctx;
- zend_long encoding, level = -1, memory = 8;
+ zend_long encoding, level = -1, memory = 8, window = 15;
HashTable *options = 0;
zval *option_buffer;
@@ -891,7 +907,7 @@ PHP_FUNCTION(deflate_init)
return;
}
- if (options && (option_buffer = zend_hash_str_find(options, "level", sizeof("level")-1)) != NULL) {
+ if (options && (option_buffer = zend_hash_str_find(options, ZEND_STRL("level"))) != NULL) {
level = zval_get_long(option_buffer);
}
if (level < -1 || level > 9) {
@@ -899,7 +915,7 @@ PHP_FUNCTION(deflate_init)
RETURN_FALSE;
}
- if (options && (option_buffer = zend_hash_str_find(options, "memory", sizeof("memory")-1)) != NULL) {
+ if (options && (option_buffer = zend_hash_str_find(options, ZEND_STRL("memory"))) != NULL) {
memory = zval_get_long(option_buffer);
}
if (memory < 1 || memory > 9) {
@@ -907,6 +923,14 @@ PHP_FUNCTION(deflate_init)
RETURN_FALSE;
}
+ if (options && (option_buffer = zend_hash_str_find(options, ZEND_STRL("window"))) != NULL) {
+ window = zval_get_long(option_buffer);
+ }
+ if (window < 8 || window > 15) {
+ php_error_docref(NULL, E_WARNING, "zlib window size (lograithm) (%pd) must be within 8..15", window);
+ RETURN_FALSE;
+ }
+
/* @TODO: in the future we may add "strategy" and "dictionary" options */
switch (encoding) {
@@ -924,6 +948,12 @@ PHP_FUNCTION(deflate_init)
ctx->zalloc = php_zlib_alloc;
ctx->zfree = php_zlib_free;
+ if (encoding < 0) {
+ encoding += 15 - window;
+ } else {
+ encoding &= window;
+ }
+
if (Z_OK == deflateInit2(ctx, level, Z_DEFLATED, encoding, memory, Z_DEFAULT_STRATEGY)) {
RETURN_RES(zend_register_resource(ctx, le_deflate));
} else {