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