summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Hristov <andrey@php.net>2014-08-06 16:52:44 +0300
committerAndrey Hristov <andrey@php.net>2014-08-06 16:52:44 +0300
commitfa19a22279124d1c6587d516574dc9a4ffa26a93 (patch)
tree9104ec259311397bb4f661f3b3942e16a74290a9
parent1d609d2d262944d5a897a31d49b93f8f732f6a03 (diff)
parent9959ead30942e7b1d016b7ce1e428e7f5dc167ee (diff)
downloadphp-git-fa19a22279124d1c6587d516574dc9a4ffa26a93.tar.gz
Merge branch 'PHP-5.6'
-rw-r--r--ext/fileinfo/data_file.c2
-rw-r--r--ext/fileinfo/libmagic/softmagic.c29
-rw-r--r--ext/fileinfo/magicdata.patch56
-rw-r--r--ext/fileinfo/tests/cve-2014-3538.phpt35
-rw-r--r--ext/gd/libgd/gdxpm.c7
-rw-r--r--ext/mysqli/tests/mysqli_stmt_multires.phpt120
-rw-r--r--ext/mysqlnd/mysqlnd_ps.c54
-rw-r--r--ext/mysqlnd/mysqlnd_structs.h3
-rw-r--r--ext/standard/info.c8
-rw-r--r--ext/zlib/tests/bug67724.gz.gzbin0 -> 171 bytes
-rw-r--r--ext/zlib/tests/bug67724.phpt26
-rw-r--r--ext/zlib/zlib_filter.c3
12 files changed, 309 insertions, 34 deletions
diff --git a/ext/fileinfo/data_file.c b/ext/fileinfo/data_file.c
index 8bcd5aa0e1..5b24670a72 100644
--- a/ext/fileinfo/data_file.c
+++ b/ext/fileinfo/data_file.c
@@ -121057,7 +121057,7 @@ const unsigned char php_magic_database[2803888] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x40, 0x00, 0x3D, 0x1B, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x5E, 0x5C, 0x73, 0x7B, 0x30, 0x2C, 0x31, 0x30, 0x30, 0x7D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x5C,
0x73, 0x7B, 0x30, 0x2C, 0x31, 0x30, 0x30, 0x7D, 0x5B, 0x7B, 0x5D, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
diff --git a/ext/fileinfo/libmagic/softmagic.c b/ext/fileinfo/libmagic/softmagic.c
index 3dd07820a4..e000dff92e 100644
--- a/ext/fileinfo/libmagic/softmagic.c
+++ b/ext/fileinfo/libmagic/softmagic.c
@@ -67,7 +67,7 @@ private int32_t mprint(struct magic_set *, struct magic *);
private int32_t moffset(struct magic_set *, struct magic *);
private void mdebug(uint32_t, const char *, size_t);
private int mcopy(struct magic_set *, union VALUETYPE *, int, int,
- const unsigned char *, uint32_t, size_t, size_t);
+ const unsigned char *, uint32_t, size_t, struct magic *);
private int mconvert(struct magic_set *, struct magic *, int);
private int print_sep(struct magic_set *, int);
private int handle_annotation(struct magic_set *, struct magic *);
@@ -1038,7 +1038,7 @@ mdebug(uint32_t offset, const char *str, size_t len)
private int
mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
- const unsigned char *s, uint32_t offset, size_t nbytes, size_t linecnt)
+ const unsigned char *s, uint32_t offset, size_t nbytes, struct magic *m)
{
/*
* Note: FILE_SEARCH and FILE_REGEX do not actually copy
@@ -1058,15 +1058,24 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
const char *last; /* end of search region */
const char *buf; /* start of search region */
const char *end;
- size_t lines;
+ size_t lines, linecnt, bytecnt;
+ linecnt = m->str_range;
+ bytecnt = linecnt * 80;
+
+ if (bytecnt == 0) {
+ bytecnt = 8192;
+ }
+ if (bytecnt > nbytes) {
+ bytecnt = nbytes;
+ }
if (s == NULL) {
ms->search.s_len = 0;
ms->search.s = NULL;
return 0;
}
buf = RCAST(const char *, s) + offset;
- end = last = RCAST(const char *, s) + nbytes;
+ end = last = RCAST(const char *, s) + bytecnt;
/* mget() guarantees buf <= last */
for (lines = linecnt, b = buf; lines && b < end &&
((b = CAST(const char *,
@@ -1079,7 +1088,7 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
b++;
}
if (lines)
- last = RCAST(const char *, s) + nbytes;
+ last = RCAST(const char *, s) + bytecnt;
ms->search.s = buf;
ms->search.s_len = last - buf;
@@ -1150,7 +1159,6 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
int *need_separator, int *returnval)
{
uint32_t soffset, offset = ms->offset;
- uint32_t count = m->str_range;
int rv, oneed_separator, in_type;
char *sbuf, *rbuf;
union VALUETYPE *p = &ms->ms_value;
@@ -1162,13 +1170,12 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
}
if (mcopy(ms, p, m->type, m->flag & INDIR, s, (uint32_t)(offset + o),
- (uint32_t)nbytes, count) == -1)
+ (uint32_t)nbytes, m) == -1)
return -1;
if ((ms->flags & MAGIC_DEBUG) != 0) {
fprintf(stderr, "mget(type=%d, flag=%x, offset=%u, o=%zu, "
- "nbytes=%zu, count=%u)\n", m->type, m->flag, offset, o,
- nbytes, count);
+ "nbytes=%zu)\n", m->type, m->flag, offset, o, nbytes);
mdebug(offset, (char *)(void *)p, sizeof(union VALUETYPE));
}
@@ -1661,7 +1668,7 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
if ((ms->flags & MAGIC_DEBUG) != 0)
fprintf(stderr, "indirect +offs=%u\n", offset);
}
- if (mcopy(ms, p, m->type, 0, s, offset, nbytes, count) == -1)
+ if (mcopy(ms, p, m->type, 0, s, offset, nbytes, m) == -1)
return -1;
ms->offset = offset;
@@ -2093,7 +2100,7 @@ magiccheck(struct magic_set *ms, struct magic *m)
zval *retval;
zval *subpats;
char *haystack;
-
+
MAKE_STD_ZVAL(retval);
ALLOC_INIT_ZVAL(subpats);
diff --git a/ext/fileinfo/magicdata.patch b/ext/fileinfo/magicdata.patch
index fb34c3c533..524d40b567 100644
--- a/ext/fileinfo/magicdata.patch
+++ b/ext/fileinfo/magicdata.patch
@@ -1,4 +1,58 @@
-Patches applied to file sources tree before generating magic.mgc
+Patches applied to file 5.17 sources tree before generating magic.mgc
and before running create_data_file.php to create data_file.c.
+
+From 0b478f445b6b7540b58af5d1fe583fa9e48fd745 Mon Sep 17 00:00:00 2001
+From: Christos Zoulas <christos@zoulas.com>
+Date: Wed, 28 May 2014 19:52:36 +0000
+Subject: [PATCH] further optimize awk by not looking for the BEGIN regex until
+ we found the BEGIN (Jan Kaluza)
+
+---
+ magic/Magdir/commands | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/magic/Magdir/commands b/magic/Magdir/commands
+index bfffdef..26b2869 100644
+--- a/magic/Magdir/commands
++++ b/magic/Magdir/commands
+@@ -49,7 +49,8 @@
+ !:mime text/x-awk
+ 0 string/wt #!\ /usr/bin/awk awk script text executable
+ !:mime text/x-awk
+-0 regex =^\\s{0,100}BEGIN\\s{0,100}[{] awk script text
++0 search/16384 BEGIN
++>0 regex =^\\s{0,100}BEGIN\\s{0,100}[{] awk script text
+
+ # AT&T Bell Labs' Plan 9 shell
+ 0 string/wt #!\ /bin/rc Plan 9 rc shell script text executable
+--
+2.0.3
+
+From 71a8b6c0d758acb0f73e2e51421a711b5e9d6668 Mon Sep 17 00:00:00 2001
+From: Christos Zoulas <christos@zoulas.com>
+Date: Fri, 30 May 2014 16:48:44 +0000
+Subject: [PATCH] Limit regex search for BEGIN to the first 4K of the file.
+
+---
+ magic/Magdir/commands | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/magic/Magdir/commands b/magic/Magdir/commands
+index 26b2869..bcd0f43 100644
+--- a/magic/Magdir/commands
++++ b/magic/Magdir/commands
+@@ -49,8 +49,7 @@
+ !:mime text/x-awk
+ 0 string/wt #!\ /usr/bin/awk awk script text executable
+ !:mime text/x-awk
+-0 search/16384 BEGIN
+->0 regex =^\\s{0,100}BEGIN\\s{0,100}[{] awk script text
++0 regex/4096 =^\\s{0,100}BEGIN\\s{0,100}[{] awk script text
+
+ # AT&T Bell Labs' Plan 9 shell
+ 0 string/wt #!\ /bin/rc Plan 9 rc shell script text executable
+--
+2.0.3
+
diff --git a/ext/fileinfo/tests/cve-2014-3538.phpt b/ext/fileinfo/tests/cve-2014-3538.phpt
new file mode 100644
index 0000000000..d6bc9c68c8
--- /dev/null
+++ b/ext/fileinfo/tests/cve-2014-3538.phpt
@@ -0,0 +1,35 @@
+--TEST--
+Bug #66731: file: extensive backtraking
+--SKIPIF--
+<?php
+if (!class_exists('finfo'))
+ die('skip no fileinfo extension');
+--FILE--
+<?php
+$fd = __DIR__.'/cve-2014-3538.data';
+
+file_put_contents($fd,
+ 'try:' .
+ str_repeat("\n", 1000000));
+
+$fi = finfo_open(FILEINFO_NONE);
+$t = microtime(true);
+var_dump(finfo_file($fi, $fd));
+$t = microtime(true) - $t;
+finfo_close($fi);
+if ($t < 1) {
+ echo "Ok\n";
+} else {
+ printf("Failed, time=%.2f\n", $t);
+}
+
+?>
+Done
+--CLEAN--
+<?php
+@unlink(__DIR__.'/cve-2014-3538.data');
+?>
+--EXPECTF--
+string(%d) "%s"
+Ok
+Done \ No newline at end of file
diff --git a/ext/gd/libgd/gdxpm.c b/ext/gd/libgd/gdxpm.c
index 73f86e5df7..b69414e60d 100644
--- a/ext/gd/libgd/gdxpm.c
+++ b/ext/gd/libgd/gdxpm.c
@@ -31,12 +31,17 @@ gdImagePtr gdImageCreateFromXpm (char *filename)
if (ret != XpmSuccess) {
return 0;
}
+ number = image.ncolors;
+ for(i = 0; i < number; i++) {
+ if (!image.colorTable[i].c_color) {
+ goto done;
+ }
+ }
if (!(im = gdImageCreate(image.width, image.height))) {
goto done;
}
- number = image.ncolors;
colors = (int *) safe_emalloc(number, sizeof(int), 0);
for (i = 0; i < number; i++) {
switch (strlen (image.colorTable[i].c_color)) {
diff --git a/ext/mysqli/tests/mysqli_stmt_multires.phpt b/ext/mysqli/tests/mysqli_stmt_multires.phpt
new file mode 100644
index 0000000000..28cf5e38f4
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_stmt_multires.phpt
@@ -0,0 +1,120 @@
+--TEST--
+Multiple result set with PS
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once("connect.inc");
+if (!$IS_MYSQLND) {
+ die("skip mysqlnd only test");
+}
+require_once('skipifconnectfailure.inc');
+?>
+--FILE--
+<?php
+ require_once("connect.inc");
+ require('table.inc');
+
+ $stmt = mysqli_stmt_init($link);
+ if (!$link->query('DROP PROCEDURE IF EXISTS p123')) {
+ printf("[001] [%d] %s\n", $link->error, $link->errno);
+ }
+
+ if (!$link->query("CREATE PROCEDURE p123() BEGIN SELECT id+12, CONCAT_WS('-',label,'ahoi') FROM test ORDER BY id LIMIT 1; SELECT id + 42, CONCAT_WS('---',label, label) FROM test ORDER BY id LIMIT 1; END")) {
+ printf("[002] [%d] %s\n", $link->error, $link->errno);
+ }
+
+ if (!($stmt = $link->prepare("CALL p123"))) {
+ printf("[003] [%d] %s\n", $stmt->error, $stmt->errno);
+ }
+
+ if (!$stmt->execute()) {
+ printf("[005] [%d] %s\n", $stmt->error, $stmt->errno);
+ }
+
+ $c_id = NULL;
+ $c_label = NULL;
+ if (!$stmt->bind_result($c_id, $c_label)) {
+ printf("[004] [%d] %s\n", $stmt->error, $stmt->errno);
+ }
+ var_dump("pre:",$c_id, $c_label);
+
+ if (!$stmt->fetch()) {
+ printf("[006] [%d] %s\n", $stmt->error, $stmt->errno);
+ }
+
+ var_dump("post:",$c_id, $c_label);
+
+ if ($stmt->fetch()) {
+ printf("[007] Shouldn't have fetched anything\n");
+ var_dump($c_id, $c_label);
+ }
+
+ if ($stmt->fetch()) {
+ printf("[008] No more rows expected\n");
+ }
+
+ if (!$stmt->more_results()) {
+ printf("[009] Expected more results\n");
+ } else {
+ var_dump("[009] next_result:", $stmt->next_result());
+ }
+
+ if (!$stmt->bind_result($c_id, $c_label)) {
+ printf("[010] [%d] %s\n", $stmt->error, $stmt->errno);
+ }
+ var_dump("pre:",$c_id, $c_label);
+
+ if (!$stmt->fetch()) {
+ printf("[011] [%d] %s\n", $stmt->error, $stmt->errno);
+ }
+
+ var_dump("post:",$c_id, $c_label);
+
+ if ($stmt->fetch()) {
+ printf("[012] No more rows expected\n");
+ }
+
+ if (!$stmt->more_results()) {
+ printf("[013] Expected more results\n");
+ } else {
+ var_dump("[013] next_result:", $stmt->next_result());
+ }
+
+ if ($stmt->more_results()) {
+ printf("[014] No more results expected\n");
+ } else {
+ printf("[014] No result, as expected\n");
+ }
+
+ $stmt->close();
+ $link->close();
+
+
+ echo "done";
+?>
+--CLEAN--
+<?php
+ require_once("connect.inc");
+ if (!$link->query('DROP PROCEDURE IF EXISTS p123')) {
+ printf("[001] [%d] %s\n", $link->error, $link->errno);
+ }
+?>
+--EXPECTF--
+string(4) "pre:"
+NULL
+NULL
+string(5) "post:"
+int(13)
+string(6) "a-ahoi"
+string(18) "[009] next_result:"
+bool(true)
+string(4) "pre:"
+int(13)
+string(6) "a-ahoi"
+string(5) "post:"
+int(43)
+string(5) "a---a"
+string(18) "[013] next_result:"
+bool(true)
+[014] No result, as expected
+done \ No newline at end of file
diff --git a/ext/mysqlnd/mysqlnd_ps.c b/ext/mysqlnd/mysqlnd_ps.c
index 539d1c8f83..94833bf4d4 100644
--- a/ext/mysqlnd/mysqlnd_ps.c
+++ b/ext/mysqlnd/mysqlnd_ps.c
@@ -43,7 +43,6 @@ enum_func_status mysqlnd_stmt_execute_batch_generate_request(MYSQLND_STMT * cons
static void mysqlnd_stmt_separate_result_bind(MYSQLND_STMT * const stmt TSRMLS_DC);
static void mysqlnd_stmt_separate_one_result_bind(MYSQLND_STMT * const stmt, unsigned int param_no TSRMLS_DC);
-
/* {{{ mysqlnd_stmt::store_result */
static MYSQLND_RES *
MYSQLND_METHOD(mysqlnd_stmt, store_result)(MYSQLND_STMT * const s TSRMLS_DC)
@@ -246,7 +245,7 @@ MYSQLND_METHOD(mysqlnd_stmt, next_result)(MYSQLND_STMT * s TSRMLS_DC)
DBG_INF_FMT("server_status=%u cursor=%u", stmt->upsert_status->server_status, stmt->upsert_status->server_status & SERVER_STATUS_CURSOR_EXISTS);
/* Free space for next result */
- s->m->free_stmt_content(s TSRMLS_CC);
+ s->m->free_stmt_result(s TSRMLS_CC);
{
enum_func_status ret = s->m->parse_execute_response(s TSRMLS_CC);
DBG_RETURN(ret);
@@ -2091,6 +2090,37 @@ mysqlnd_stmt_separate_one_result_bind(MYSQLND_STMT * const s, unsigned int param
/* }}} */
+/* {{{ mysqlnd_stmt::free_stmt_result */
+static void
+MYSQLND_METHOD(mysqlnd_stmt, free_stmt_result)(MYSQLND_STMT * const s TSRMLS_DC)
+{
+ MYSQLND_STMT_DATA * stmt = s? s->data:NULL;
+ DBG_ENTER("mysqlnd_stmt::free_stmt_result");
+ if (!stmt) {
+ DBG_VOID_RETURN;
+ }
+
+ /*
+ First separate the bound variables, which point to the result set, then
+ destroy the set.
+ */
+ mysqlnd_stmt_separate_result_bind(s TSRMLS_CC);
+ /* Not every statement has a result set attached */
+ if (stmt->result) {
+ stmt->result->m.free_result_internal(stmt->result TSRMLS_CC);
+ stmt->result = NULL;
+ }
+ if (stmt->error_info->error_list) {
+ zend_llist_clean(stmt->error_info->error_list);
+ mnd_pefree(stmt->error_info->error_list, s->persistent);
+ stmt->error_info->error_list = NULL;
+ }
+
+ DBG_VOID_RETURN;
+}
+/* }}} */
+
+
/* {{{ mysqlnd_stmt::free_stmt_content */
static void
MYSQLND_METHOD(mysqlnd_stmt, free_stmt_content)(MYSQLND_STMT * const s TSRMLS_DC)
@@ -2123,22 +2153,7 @@ MYSQLND_METHOD(mysqlnd_stmt, free_stmt_content)(MYSQLND_STMT * const s TSRMLS_DC
stmt->param_bind = NULL;
}
- /*
- First separate the bound variables, which point to the result set, then
- destroy the set.
- */
- mysqlnd_stmt_separate_result_bind(s TSRMLS_CC);
- /* Not every statement has a result set attached */
- if (stmt->result) {
- stmt->result->m.free_result_internal(stmt->result TSRMLS_CC);
- stmt->result = NULL;
- }
- if (stmt->error_info->error_list) {
- zend_llist_clean(stmt->error_info->error_list);
- mnd_pefree(stmt->error_info->error_list, s->persistent);
- stmt->error_info->error_list = NULL;
- }
-
+ s->m->free_stmt_result(s TSRMLS_CC);
DBG_VOID_RETURN;
}
/* }}} */
@@ -2357,7 +2372,8 @@ MYSQLND_CLASS_METHODS_START(mysqlnd_stmt)
mysqlnd_stmt_execute_generate_request,
mysqlnd_stmt_execute_parse_response,
MYSQLND_METHOD(mysqlnd_stmt, free_stmt_content),
- MYSQLND_METHOD(mysqlnd_stmt, flush)
+ MYSQLND_METHOD(mysqlnd_stmt, flush),
+ MYSQLND_METHOD(mysqlnd_stmt, free_stmt_result)
MYSQLND_CLASS_METHODS_END;
diff --git a/ext/mysqlnd/mysqlnd_structs.h b/ext/mysqlnd/mysqlnd_structs.h
index 66920e47be..b743dada3c 100644
--- a/ext/mysqlnd/mysqlnd_structs.h
+++ b/ext/mysqlnd/mysqlnd_structs.h
@@ -787,6 +787,7 @@ typedef enum_func_status (*func_mysqlnd_stmt__generate_execute_request)(MYSQLND
typedef enum_func_status (*func_mysqlnd_stmt__parse_execute_response)(MYSQLND_STMT * const s TSRMLS_DC);
typedef void (*func_mysqlnd_stmt__free_stmt_content)(MYSQLND_STMT * const s TSRMLS_DC);
typedef enum_func_status (*func_mysqlnd_stmt__flush)(MYSQLND_STMT * const stmt TSRMLS_DC);
+typedef void (*func_mysqlnd_stmt__free_stmt_result)(MYSQLND_STMT * const s TSRMLS_DC);
struct st_mysqlnd_stmt_methods
{
@@ -842,6 +843,8 @@ struct st_mysqlnd_stmt_methods
func_mysqlnd_stmt__free_stmt_content free_stmt_content;
func_mysqlnd_stmt__flush flush;
+
+ func_mysqlnd_stmt__free_stmt_result free_stmt_result;
};
diff --git a/ext/standard/info.c b/ext/standard/info.c
index 1b1b8f202b..343244c21c 100644
--- a/ext/standard/info.c
+++ b/ext/standard/info.c
@@ -592,6 +592,14 @@ PHPAPI char *php_get_uname(char mode)
php_get_windows_cpu(wincpu, sizeof(wincpu));
dwBuild = (DWORD)(HIWORD(dwVersion));
+
+ /* Windows "version" 6.2 could be Windows 8/Windows Server 2012, but also Windows 8.1/Windows Server 2012 R2 */
+ if (dwWindowsMajorVersion == 6 && dwWindowsMinorVersion == 2) {
+ if (strncmp(winver, "Windows 8.1", 11) == 0 || strncmp(winver, "Windows Server 2012 R2", 22) == 0) {
+ dwWindowsMinorVersion = 3;
+ }
+ }
+
snprintf(tmp_uname, sizeof(tmp_uname), "%s %s %d.%d build %d (%s) %s",
"Windows NT", ComputerName,
dwWindowsMajorVersion, dwWindowsMinorVersion, dwBuild, winver?winver:"unknown", wincpu);
diff --git a/ext/zlib/tests/bug67724.gz.gz b/ext/zlib/tests/bug67724.gz.gz
new file mode 100644
index 0000000000..ab1db9258e
--- /dev/null
+++ b/ext/zlib/tests/bug67724.gz.gz
Binary files differ
diff --git a/ext/zlib/tests/bug67724.phpt b/ext/zlib/tests/bug67724.phpt
new file mode 100644
index 0000000000..1e5026f650
--- /dev/null
+++ b/ext/zlib/tests/bug67724.phpt
@@ -0,0 +1,26 @@
+--TEST--
+Bug #67724 (chained zlib filters silently fail with large amounts of data)
+--SKIPIF--
+<?php
+extension_loaded("zlib") or die("skip need ext/zlib");
+?>
+--FILE--
+<?php
+echo "Test\n";
+
+$f = fopen(__DIR__."/bug67724.gz.gz", "rb")
+ or die(current(error_get_last()));
+stream_filter_append($f, "zlib.inflate", STREAM_FILTER_READ, ["window" => 30]);
+stream_filter_append($f, "zlib.inflate", STREAM_FILTER_READ, ["window" => 30]);
+for ($i = 0; !feof($f); $i += strlen(fread($f, 0x1000)))
+ ;
+fclose($f);
+
+var_dump($i);
+
+?>
+DONE
+--EXPECT--
+Test
+int(25600000)
+DONE
diff --git a/ext/zlib/zlib_filter.c b/ext/zlib/zlib_filter.c
index 9a59c3a855..4bde5f63cd 100644
--- a/ext/zlib/zlib_filter.c
+++ b/ext/zlib/zlib_filter.c
@@ -302,7 +302,8 @@ static php_stream_filter *php_zlib_filter_create(const char *filtername, zval *f
data->strm.zalloc = (alloc_func) php_zlib_alloc;
data->strm.zfree = (free_func) php_zlib_free;
- data->strm.avail_out = data->outbuf_len = data->inbuf_len = 2048;
+ data->strm.avail_out = data->outbuf_len = 0x8000;
+ data->inbuf_len = 2048;
data->strm.next_in = data->inbuf = (Bytef *) pemalloc(data->inbuf_len, persistent);
if (!data->inbuf) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed allocating %zd bytes", data->inbuf_len);