lbarnaud Thu May 14 16:17:47 2009 UTC Added files: (Branch: PHP_5_2) /php-src/ext/zlib/tests gzinflate-bug42663.phpt gzinflate_length.phpt
Modified files: /php-src/ext/zlib zlib.c Log: MFB: Fixed #42663 (gzinflate() try to allocate all memory with truncated data) http://cvs.php.net/viewvc.cgi/php-src/ext/zlib/zlib.c?r1=1.183.2.6.2.8&r2=1.183.2.6.2.9&diff_format=u Index: php-src/ext/zlib/zlib.c diff -u php-src/ext/zlib/zlib.c:1.183.2.6.2.8 php-src/ext/zlib/zlib.c:1.183.2.6.2.9 --- php-src/ext/zlib/zlib.c:1.183.2.6.2.8 Wed Dec 31 11:17:47 2008 +++ php-src/ext/zlib/zlib.c Thu May 14 16:17:47 2009 @@ -19,7 +19,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zlib.c,v 1.183.2.6.2.8 2008/12/31 11:17:47 sebastian Exp $ */ +/* $Id: zlib.c,v 1.183.2.6.2.9 2009/05/14 16:17:47 lbarnaud Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -571,6 +571,20 @@ } plength = limit; + stream.zalloc = php_zlib_alloc; + stream.zfree = php_zlib_free; + stream.opaque = Z_NULL; + stream.avail_in = data_len + 1; /* there is room for \0 */ + stream.next_in = (Bytef *) data; + stream.total_out = 0; + + /* init with -MAX_WBITS disables the zlib internal headers */ + status = inflateInit2(&stream, -MAX_WBITS); + if (status != Z_OK) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", zError(status)); + RETURN_FALSE; + } + /* stream.avail_out wants to know the output data length if none was given as a parameter @@ -578,43 +592,32 @@ doubling it whenever it wasn't big enough that should be enaugh for all real life cases */ - - stream.zalloc = php_zlib_alloc; - stream.zfree = php_zlib_free; - do { length = plength ? plength : (unsigned long)data_len * (1 << factor++); s2 = (char *) erealloc(s1, length); - if (!s2 && s1) { - efree(s1); + if (!s2) { + if (s1) { + efree(s1); + } + inflateEnd(&stream); RETURN_FALSE; } + s1 = s2; - stream.next_in = (Bytef *) data; - stream.avail_in = (uInt) data_len + 1; /* there is room for \0 */ + stream.next_out = (Bytef *) &s2[stream.total_out]; + stream.avail_out = length - stream.total_out; + status = inflate(&stream, Z_NO_FLUSH); - stream.next_out = s2; - stream.avail_out = (uInt) length; + } while ((Z_BUF_ERROR == status || (Z_OK == status && stream.avail_in)) && !plength && factor < maxfactor); - /* init with -MAX_WBITS disables the zlib internal headers */ - status = inflateInit2(&stream, -MAX_WBITS); - if (status == Z_OK) { - status = inflate(&stream, Z_FINISH); - if (status != Z_STREAM_END) { - inflateEnd(&stream); - if (status == Z_OK) { - status = Z_BUF_ERROR; - } - } else { - status = inflateEnd(&stream); - } - } - s1 = s2; - - } while ((status == Z_BUF_ERROR) && (!plength) && (factor < maxfactor)); + inflateEnd(&stream); - if (status == Z_OK) { + if ((plength && Z_OK == status) || factor >= maxfactor) { + status = Z_MEM_ERROR; + } + + if (Z_STREAM_END == status || Z_OK == status) { s2 = erealloc(s2, stream.total_out + 1); /* room for \0 */ s2[ stream.total_out ] = '\0'; RETURN_STRINGL(s2, stream.total_out, 0); http://cvs.php.net/viewvc.cgi/php-src/ext/zlib/tests/gzinflate-bug42663.phpt?view=markup&rev=1.1 Index: php-src/ext/zlib/tests/gzinflate-bug42663.phpt +++ php-src/ext/zlib/tests/gzinflate-bug42663.phpt http://cvs.php.net/viewvc.cgi/php-src/ext/zlib/tests/gzinflate_length.phpt?view=markup&rev=1.1 Index: php-src/ext/zlib/tests/gzinflate_length.phpt +++ php-src/ext/zlib/tests/gzinflate_length.phpt -- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php