summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStanislav Malyshev <stas@php.net>2016-08-16 23:52:22 -0700
committerStanislav Malyshev <stas@php.net>2016-08-16 23:52:22 -0700
commit75d7666968573a0abea36b46aae2b0c0ad6eb488 (patch)
tree7f8ae5f118e05f973a96af81747317c62f075515
parentf3231a7c766f28cb7f14bc7c2d21986fcb9740cd (diff)
parentf8a75d4eee3446fb5c5c493b28b9ee80e34041cc (diff)
downloadphp-git-75d7666968573a0abea36b46aae2b0c0ad6eb488.tar.gz
Merge branch 'PHP-7.0.10' into PHP-7.0
* PHP-7.0.10: Fix bug #72749: wddx_deserialize allows illegal memory access Fixed bug #72627: Memory Leakage In exif_process_IFD_in_TIFF fix tests Fix bug#72697 - select_colors write out-of-bounds Fix bug #72708 - php_snmp_parse_oid integer overflow in memory allocation Fix bug #72730 - imagegammacorrect allows arbitrary write access Fix bug #72750: wddx_deserialize null dereference Fix bug #72771: ftps:// opendir wrapper is vulnerable to protocol downgrade attack fix tests add missing skipif section Fix for bug #72790 and bug #72799 Fix bug #72837 - integer overflow in bzdecompress caused heap corruption Fix bug #72742 - memory allocator fails to realloc small block to large one Use size_t for path length Check for string overflow Fix for bug #72782: mcrypt accepts only ints, so don't pass anything else Fix bug #72674 - check both curl_escape and curl_unescape
-rw-r--r--Zend/zend_alloc.c24
-rw-r--r--ext/bz2/bz2.c18
-rw-r--r--ext/curl/interface.c8
-rw-r--r--ext/exif/exif.c4
-rw-r--r--ext/exif/tests/bug72627.phpt71
-rw-r--r--ext/exif/tests/bug72627.tiffbin0 -> 1250 bytes
-rw-r--r--ext/gd/gd.c11
-rw-r--r--ext/gd/tests/bug72697.phpt17
-rw-r--r--ext/gd/tests/bug72730.phpt15
-rw-r--r--ext/gd/tests/imagetruecolortopalette_error3.phpt2
-rw-r--r--ext/gd/tests/imagetruecolortopalette_error4.phpt4
-rw-r--r--ext/mcrypt/mcrypt.c16
-rw-r--r--ext/snmp/snmp.c2
-rw-r--r--ext/standard/ftp_fopen_wrapper.c3
-rw-r--r--ext/standard/php_smart_string.h17
-rw-r--r--ext/wddx/tests/bug72142.phpt2
-rw-r--r--ext/wddx/tests/bug72749.phpt34
-rw-r--r--ext/wddx/tests/bug72750.phpt34
-rw-r--r--ext/wddx/tests/bug72790.phpt36
-rw-r--r--ext/wddx/tests/bug72799.phpt29
-rw-r--r--ext/wddx/wddx.c24
-rw-r--r--main/fopen_wrappers.c6
22 files changed, 327 insertions, 50 deletions
diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c
index 1876559317..a79d67b4b9 100644
--- a/Zend/zend_alloc.c
+++ b/Zend/zend_alloc.c
@@ -1548,21 +1548,21 @@ static void *zend_mm_realloc_heap(zend_mm_heap *heap, void *ptr, size_t size, si
ZEND_MM_CHECK(chunk->heap == heap, "zend_mm_heap corrupted");
if (info & ZEND_MM_IS_SRUN) {
- int old_bin_num, bin_num;
-
- old_bin_num = ZEND_MM_SRUN_BIN_NUM(info);
+ int old_bin_num = ZEND_MM_SRUN_BIN_NUM(info);
old_size = bin_data_size[old_bin_num];
- bin_num = ZEND_MM_SMALL_SIZE_TO_BIN(size);
- if (old_bin_num == bin_num) {
+ if (size <= ZEND_MM_MAX_SMALL_SIZE) {
+ int bin_num = ZEND_MM_SMALL_SIZE_TO_BIN(size);
+ if (old_bin_num == bin_num) {
#if ZEND_DEBUG
- dbg = zend_mm_get_debug_info(heap, ptr);
- dbg->size = real_size;
- dbg->filename = __zend_filename;
- dbg->orig_filename = __zend_orig_filename;
- dbg->lineno = __zend_lineno;
- dbg->orig_lineno = __zend_orig_lineno;
+ dbg = zend_mm_get_debug_info(heap, ptr);
+ dbg->size = real_size;
+ dbg->filename = __zend_filename;
+ dbg->orig_filename = __zend_orig_filename;
+ dbg->lineno = __zend_lineno;
+ dbg->orig_lineno = __zend_orig_lineno;
#endif
- return ptr;
+ return ptr;
+ }
}
} else /* if (info & ZEND_MM_IS_LARGE_RUN) */ {
ZEND_MM_CHECK(ZEND_MM_ALIGNED_OFFSET(page_offset, ZEND_MM_PAGE_SIZE) == 0, "zend_mm_heap corrupted");
diff --git a/ext/bz2/bz2.c b/ext/bz2/bz2.c
index bc6379aeea..60bb71ee8d 100644
--- a/ext/bz2/bz2.c
+++ b/ext/bz2/bz2.c
@@ -594,16 +594,26 @@ static PHP_FUNCTION(bzdecompress)
/* compression is better then 2:1, need to allocate more memory */
bzs.avail_out = source_len;
size = (bzs.total_out_hi32 * (unsigned int) -1) + bzs.total_out_lo32;
+ if (size > SIZE_MAX) {
+ /* no reason to continue if we're going to drop it anyway */
+ break;
+ }
dest = safe_erealloc(dest, 1, bzs.avail_out+1, (size_t) size );
bzs.next_out = dest + size;
}
if (error == BZ_STREAM_END || error == BZ_OK) {
size = (bzs.total_out_hi32 * (unsigned int) -1) + bzs.total_out_lo32;
- dest = safe_erealloc(dest, 1, (size_t) size, 1);
- dest[size] = '\0';
- RETVAL_STRINGL(dest, (int) size);
- efree(dest);
+ if (size > SIZE_MAX) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Decompressed size too big, max is %zd", SIZE_MAX);
+ efree(dest);
+ RETVAL_LONG(BZ_MEM_ERROR);
+ } else {
+ dest = safe_erealloc(dest, 1, (size_t) size, 1);
+ dest[size] = '\0';
+ RETVAL_STRINGL(dest, (size_t) size);
+ efree(dest);
+ }
} else { /* real error */
efree(dest);
RETVAL_LONG(error);
diff --git a/ext/curl/interface.c b/ext/curl/interface.c
index be15785cd0..7069710ece 100644
--- a/ext/curl/interface.c
+++ b/ext/curl/interface.c
@@ -3517,7 +3517,7 @@ PHP_FUNCTION(curl_reset)
PHP_FUNCTION(curl_escape)
{
char *str = NULL, *res = NULL;
- size_t str_len = 0;
+ size_t str_len = 0;
zval *zid;
php_curl *ch;
@@ -3529,6 +3529,10 @@ PHP_FUNCTION(curl_escape)
RETURN_FALSE;
}
+ if (ZEND_SIZE_T_INT_OVFL(str_len)) {
+ RETURN_FALSE;
+ }
+
if ((res = curl_easy_escape(ch->cp, str, str_len))) {
RETVAL_STRING(res);
curl_free(res);
@@ -3556,7 +3560,7 @@ PHP_FUNCTION(curl_unescape)
RETURN_FALSE;
}
- if (str_len > INT_MAX) {
+ if (ZEND_SIZE_T_INT_OVFL(str_len)) {
RETURN_FALSE;
}
diff --git a/ext/exif/exif.c b/ext/exif/exif.c
index 611b1067cc..2594cadf51 100644
--- a/ext/exif/exif.c
+++ b/ext/exif/exif.c
@@ -3757,6 +3757,10 @@ static int exif_process_IFD_in_TIFF(image_info_type *ImageInfo, size_t dir_offse
fgot = php_stream_read(ImageInfo->infile, ImageInfo->Thumbnail.data, ImageInfo->Thumbnail.size);
if (fgot < ImageInfo->Thumbnail.size) {
EXIF_ERRLOG_THUMBEOF(ImageInfo)
+ efree(ImageInfo->Thumbnail.data);
+ ImageInfo->Thumbnail.data = NULL;
+ } else {
+ exif_thumbnail_build(ImageInfo);
}
exif_thumbnail_build(ImageInfo);
}
diff --git a/ext/exif/tests/bug72627.phpt b/ext/exif/tests/bug72627.phpt
new file mode 100644
index 0000000000..bb6a1fae99
--- /dev/null
+++ b/ext/exif/tests/bug72627.phpt
@@ -0,0 +1,71 @@
+--TEST--
+Bug #72627 (Memory Leakage In exif_process_IFD_in_TIFF)
+--SKIPIF--
+<?php if (!extension_loaded('exif')) print 'skip exif extension not available';?>
+--FILE--
+<?php
+ $exif = exif_read_data(__DIR__ . '/bug72627.tiff',0,0,true);
+ var_dump($exif);
+?>
+--EXPECTF--
+Warning: exif_read_data(%s): Thumbnail goes IFD boundary or end of file reached in %sbug72627.php on line %d
+
+Warning: exif_read_data(%s): Error in TIFF: filesize(x04E2) less than start of IFD dir(x829A0004) in %sbug72627.php on line %d
+
+Warning: exif_read_data(%s): Thumbnail goes IFD boundary or end of file reached in %sbug72627.php on line %d
+array(11) {
+ ["FileName"]=>
+ string(13) "bug72627.tiff"
+ ["FileDateTime"]=>
+ int(%d)
+ ["FileSize"]=>
+ int(1250)
+ ["FileType"]=>
+ int(7)
+ ["MimeType"]=>
+ string(10) "image/tiff"
+ ["SectionsFound"]=>
+ string(30) "ANY_TAG, IFD0, THUMBNAIL, EXIF"
+ ["COMPUTED"]=>
+ array(10) {
+ ["html"]=>
+ string(24) "width="128" height="132""
+ ["Height"]=>
+ int(132)
+ ["Width"]=>
+ int(128)
+ ["IsColor"]=>
+ int(0)
+ ["ByteOrderMotorola"]=>
+ int(0)
+ ["ApertureFNumber"]=>
+ string(5) "f/1.0"
+ ["Thumbnail.FileType"]=>
+ int(2)
+ ["Thumbnail.MimeType"]=>
+ string(10) "image/jpeg"
+ ["Thumbnail.Height"]=>
+ int(132)
+ ["Thumbnail.Width"]=>
+ int(128)
+ }
+ ["XResolution"]=>
+ string(21) "1414812756/1414812756"
+ ["THUMBNAIL"]=>
+ array(5) {
+ ["ImageWidth"]=>
+ int(128)
+ ["ImageLength"]=>
+ int(132)
+ ["JPEGInterchangeFormat"]=>
+ int(1280)
+ ["JPEGInterchangeFormatLength"]=>
+ int(100)
+ ["THUMBNAIL"]=>
+ NULL
+ }
+ ["ExposureTime"]=>
+ string(21) "1414812756/1414812756"
+ ["FNumber"]=>
+ string(21) "1414812756/1414812756"
+}
diff --git a/ext/exif/tests/bug72627.tiff b/ext/exif/tests/bug72627.tiff
new file mode 100644
index 0000000000..229190a604
--- /dev/null
+++ b/ext/exif/tests/bug72627.tiff
Binary files differ
diff --git a/ext/gd/gd.c b/ext/gd/gd.c
index c7c6fe3fae..0346a74634 100644
--- a/ext/gd/gd.c
+++ b/ext/gd/gd.c
@@ -1537,11 +1537,11 @@ PHP_FUNCTION(imagetruecolortopalette)
RETURN_FALSE;
}
- if (ncolors <= 0) {
- php_error_docref(NULL, E_WARNING, "Number of colors has to be greater than zero");
+ if (ncolors <= 0 || ZEND_LONG_INT_OVFL(ncolors)) {
+ php_error_docref(NULL, E_WARNING, "Number of colors has to be greater than zero and no more than %d", INT_MAX);
RETURN_FALSE;
}
- gdImageTrueColorToPalette(im, dither, ncolors);
+ gdImageTrueColorToPalette(im, dither, (int)ncolors);
RETURN_TRUE;
}
@@ -3039,6 +3039,11 @@ PHP_FUNCTION(imagegammacorrect)
return;
}
+ if ( input <= 0.0 || output <= 0.0 ) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Gamma values should be positive");
+ RETURN_FALSE;
+ }
+
if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
RETURN_FALSE;
}
diff --git a/ext/gd/tests/bug72697.phpt b/ext/gd/tests/bug72697.phpt
new file mode 100644
index 0000000000..6110385fcb
--- /dev/null
+++ b/ext/gd/tests/bug72697.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Bug #72697: select_colors write out-of-bounds
+--SKIPIF--
+<?php
+if (!function_exists("imagecreatetruecolor")) die("skip");
+if (PHP_INT_MAX !== 9223372036854775807) die("skip for 64-bit long systems only");
+?>
+--FILE--
+<?php
+
+$img=imagecreatetruecolor(10, 10);
+imagetruecolortopalette($img, false, PHP_INT_MAX / 8);
+?>
+DONE
+--EXPECTF--
+Warning: imagetruecolortopalette(): Number of colors has to be greater than zero and no more than 2147483647 in %sbug72697.php on line %d
+DONE \ No newline at end of file
diff --git a/ext/gd/tests/bug72730.phpt b/ext/gd/tests/bug72730.phpt
new file mode 100644
index 0000000000..e7c13cb5e9
--- /dev/null
+++ b/ext/gd/tests/bug72730.phpt
@@ -0,0 +1,15 @@
+--TEST--
+Bug #72730: imagegammacorrect allows arbitrary write access
+--SKIPIF--
+<?php
+if (!function_exists("imagecreatetruecolor")) die("skip");
+?>
+--FILE--
+<?php
+$img = imagecreatetruecolor(1, 1);
+imagegammacorrect($img, -1, 1337);
+?>
+DONE
+--EXPECTF--
+Warning: imagegammacorrect(): Gamma values should be positive in %sbug72730.php on line %d
+DONE \ No newline at end of file
diff --git a/ext/gd/tests/imagetruecolortopalette_error3.phpt b/ext/gd/tests/imagetruecolortopalette_error3.phpt
index de3a62d0a5..46e3f487e0 100644
--- a/ext/gd/tests/imagetruecolortopalette_error3.phpt
+++ b/ext/gd/tests/imagetruecolortopalette_error3.phpt
@@ -25,4 +25,4 @@ Warning: imagetruecolortopalette() expects parameter 3 to be integer, resource g
Warning: imagetruecolortopalette() expects parameter 3 to be integer, array given in %s on line %d
-Warning: imagetruecolortopalette(): Number of colors has to be greater than zero in %s on line %d \ No newline at end of file
+Warning: imagetruecolortopalette(): Number of colors has to be greater than zero and no more than %d in %s on line %d
diff --git a/ext/gd/tests/imagetruecolortopalette_error4.phpt b/ext/gd/tests/imagetruecolortopalette_error4.phpt
index b9661e3b85..f0e18b86be 100644
--- a/ext/gd/tests/imagetruecolortopalette_error4.phpt
+++ b/ext/gd/tests/imagetruecolortopalette_error4.phpt
@@ -16,6 +16,6 @@ imagetruecolortopalette($image, true, -1);
?>
--EXPECTF--
-Warning: imagetruecolortopalette(): Number of colors has to be greater than zero in %s on line %d
+Warning: imagetruecolortopalette(): Number of colors has to be greater than zero and no more than %d in %s line %d
-Warning: imagetruecolortopalette(): Number of colors has to be greater than zero in %s on line %d \ No newline at end of file
+Warning: imagetruecolortopalette(): Number of colors has to be greater than zero and no more than %d in %s line %d
diff --git a/ext/mcrypt/mcrypt.c b/ext/mcrypt/mcrypt.c
index 73acaa29f2..9865cbb9fc 100644
--- a/ext/mcrypt/mcrypt.c
+++ b/ext/mcrypt/mcrypt.c
@@ -633,6 +633,10 @@ PHP_FUNCTION(mcrypt_generic)
RETURN_FALSE
}
+ if (data_len > INT_MAX) {
+ php_error_docref(NULL, E_WARNING, "Data size too large, %d maximum", INT_MAX);
+ RETURN_FALSE;
+ }
/* Check blocksize */
if (mcrypt_enc_is_block_mode(pm->td) == 1) { /* It's a block algorithm */
block_size = mcrypt_enc_get_block_size(pm->td);
@@ -645,10 +649,6 @@ PHP_FUNCTION(mcrypt_generic)
memset(ZSTR_VAL(data_str), 0, data_size);
memcpy(ZSTR_VAL(data_str), data, data_len);
} else { /* It's not a block algorithm */
- if (data_len > INT_MAX) {
- php_error_docref(NULL, E_WARNING, "Data size too large, %d maximum", INT_MAX);
- RETURN_FALSE;
- }
data_size = (int)data_len;
data_str = zend_string_alloc(data_size, 0);
memset(ZSTR_VAL(data_str), 0, data_size);
@@ -688,6 +688,10 @@ PHP_FUNCTION(mdecrypt_generic)
}
/* Check blocksize */
+ if (data_len > INT_MAX) {
+ php_error_docref(NULL, E_WARNING, "Data size too large, %d maximum", INT_MAX);
+ RETURN_FALSE;
+ }
if (mcrypt_enc_is_block_mode(pm->td) == 1) { /* It's a block algorithm */
block_size = mcrypt_enc_get_block_size(pm->td);
data_size = ((((int)data_len - 1) / block_size) + 1) * block_size;
@@ -699,10 +703,6 @@ PHP_FUNCTION(mdecrypt_generic)
memset(data_s, 0, data_size);
memcpy(data_s, data, data_len);
} else { /* It's not a block algorithm */
- if (data_len > INT_MAX) {
- php_error_docref(NULL, E_WARNING, "Data size too large, %d maximum", INT_MAX);
- RETURN_FALSE;
- }
data_size = (int)data_len;
data_s = emalloc(data_size + 1);
memset(data_s, 0, data_size);
diff --git a/ext/snmp/snmp.c b/ext/snmp/snmp.c
index 7b685ff5dc..63e8095ed7 100644
--- a/ext/snmp/snmp.c
+++ b/ext/snmp/snmp.c
@@ -1011,7 +1011,7 @@ static int php_snmp_parse_oid(zval *object, int st, struct objid_query *objid_qu
php_error_docref(NULL, E_WARNING, "Got empty OID array");
return FALSE;
}
- objid_query->vars = (snmpobjarg *)emalloc(sizeof(snmpobjarg) * zend_hash_num_elements(Z_ARRVAL_P(oid)));
+ objid_query->vars = (snmpobjarg *)safe_emalloc(sizeof(snmpobjarg), zend_hash_num_elements(Z_ARRVAL_P(oid)), 0);
if (objid_query->vars == NULL) {
php_error_docref(NULL, E_WARNING, "emalloc() failed while parsing oid array: %s", strerror(errno));
efree(objid_query->vars);
diff --git a/ext/standard/ftp_fopen_wrapper.c b/ext/standard/ftp_fopen_wrapper.c
index 8d0f19c516..f562827295 100644
--- a/ext/standard/ftp_fopen_wrapper.c
+++ b/ext/standard/ftp_fopen_wrapper.c
@@ -188,7 +188,8 @@ static php_stream *php_ftp_fopen_connect(php_stream_wrapper *wrapper, const char
/* get the response */
result = GET_FTP_RESULT(stream);
if (result != 334) {
- use_ssl = 0;
+ php_stream_wrapper_log_error(wrapper, options, "Server doesn't support FTPS.");
+ goto connect_errexit;
} else {
/* we must reuse the old SSL session id */
/* if we talk to an old ftpd-ssl */
diff --git a/ext/standard/php_smart_string.h b/ext/standard/php_smart_string.h
index a832376064..1175d32907 100644
--- a/ext/standard/php_smart_string.h
+++ b/ext/standard/php_smart_string.h
@@ -52,19 +52,22 @@
#define SMART_STRING_DO_REALLOC(d, what) \
(d)->c = SMART_STRING_REALLOC((d)->c, (d)->a + 1, (what))
-#define smart_string_alloc4(d, n, what, newlen) do { \
+#define smart_string_alloc4(d, n, what, newlen) do { \
if (!(d)->c) { \
(d)->len = 0; \
newlen = (n); \
- (d)->a = newlen < SMART_STRING_START_SIZE \
- ? SMART_STRING_START_SIZE \
- : newlen + SMART_STRING_PREALLOC; \
- SMART_STRING_DO_REALLOC(d, what); \
+ (d)->a = newlen < SMART_STRING_START_SIZE \
+ ? SMART_STRING_START_SIZE \
+ : newlen + SMART_STRING_PREALLOC; \
+ SMART_STRING_DO_REALLOC(d, what); \
} else { \
+ if(UNEXPECTED(n > SIZE_MAX - (d)->len)) { \
+ zend_error(E_ERROR, "String size overflow"); \
+ } \
newlen = (d)->len + (n); \
if (newlen >= (d)->a) { \
- (d)->a = newlen + SMART_STRING_PREALLOC; \
- SMART_STRING_DO_REALLOC(d, what); \
+ (d)->a = newlen + SMART_STRING_PREALLOC; \
+ SMART_STRING_DO_REALLOC(d, what); \
} \
} \
} while (0)
diff --git a/ext/wddx/tests/bug72142.phpt b/ext/wddx/tests/bug72142.phpt
index 3976bb2554..0c93ecc970 100644
--- a/ext/wddx/tests/bug72142.phpt
+++ b/ext/wddx/tests/bug72142.phpt
@@ -1,5 +1,7 @@
--TEST--
Bug #72142: WDDX Packet Injection Vulnerability in wddx_serialize_value()
+--SKIPIF--
+<?php if (!extension_loaded("wddx")) print "skip"; ?>
--FILE--
<?php
diff --git a/ext/wddx/tests/bug72749.phpt b/ext/wddx/tests/bug72749.phpt
new file mode 100644
index 0000000000..ee17d0f229
--- /dev/null
+++ b/ext/wddx/tests/bug72749.phpt
@@ -0,0 +1,34 @@
+--TEST--
+Bug #72749: wddx_deserialize allows illegal memory access
+--SKIPIF--
+<?php
+if (!extension_loaded('wddx')) {
+ die('skip. wddx not available');
+}
+?>
+--FILE--
+<?php
+$xml = <<<XML
+<?xml version='1.0'?>
+<!DOCTYPE wddxPacket SYSTEM 'wddx_0100.dtd'>
+<wddxPacket version='1.0'>
+<header/>
+ <data>
+ <struct>
+ <var name='aDateTime3'>
+ <dateTime>2\r2004-09-10T05:52:49+00</dateTime>
+ </var>
+ </struct>
+ </data>
+</wddxPacket>
+XML;
+
+$array = wddx_deserialize($xml);
+var_dump($array);
+?>
+--EXPECT--
+array(1) {
+ ["aDateTime3"]=>
+ string(24) "2
+2004-09-10T05:52:49+00"
+}
diff --git a/ext/wddx/tests/bug72750.phpt b/ext/wddx/tests/bug72750.phpt
new file mode 100644
index 0000000000..3a6794df28
--- /dev/null
+++ b/ext/wddx/tests/bug72750.phpt
@@ -0,0 +1,34 @@
+--TEST--
+Bug #72750: wddx_deserialize null dereference
+--SKIPIF--
+<?php
+if (!extension_loaded('wddx')) {
+ die('skip. wddx not available');
+}
+?>
+--FILE--
+<?php
+
+$xml = <<< XML
+<?xml version='1.0'?>
+<!DOCTYPE wddxPacket SYSTEM 'wddx_0100.dtd'>
+<wddxPacket version='1.0'>
+<header/>
+ <data>
+ <struct>
+ <var name='aBinary'>
+ <binary length='11'>\\tYmluYXJRhdGE=</binary>
+ </var>
+ </struct>
+ </data>
+</wddxPacket>
+XML;
+
+$array = wddx_deserialize($xml);
+var_dump($array);
+?>
+--EXPECT--
+array(1) {
+ ["aBinary"]=>
+ string(0) ""
+}
diff --git a/ext/wddx/tests/bug72790.phpt b/ext/wddx/tests/bug72790.phpt
new file mode 100644
index 0000000000..5bc4478401
--- /dev/null
+++ b/ext/wddx/tests/bug72790.phpt
@@ -0,0 +1,36 @@
+--TEST--
+Bug 72790: wddx_deserialize null dereference with invalid xml
+--SKIPIF--
+<?php
+if (!extension_loaded('wddx')) {
+ die('skip. wddx not available');
+}
+?>
+--FILE--
+<?php
+
+$xml = <<< XML
+<?xml version='1.0' ?>
+<!DOCTYPE wddxPacket SYSTEM 'wddx_0100.dtd'>
+<wddxPacket version='1.0'>
+ |array>
+ <var name="XXXX">
+ <boolean value="this">
+ </boolean>
+ </var>
+ <var name="YYYY">
+ <var name="UUUU">
+ <var name="EZEZ">
+ </var>
+ </var>
+ </var>
+ </array>
+</wddxPacket>
+XML;
+
+$array = wddx_deserialize($xml);
+var_dump($array);
+?>
+--EXPECTF--
+Notice: Undefined variable: array in %s%ebug72790.php on line %d
+NULL
diff --git a/ext/wddx/tests/bug72799.phpt b/ext/wddx/tests/bug72799.phpt
new file mode 100644
index 0000000000..53ac95bd6a
--- /dev/null
+++ b/ext/wddx/tests/bug72799.phpt
@@ -0,0 +1,29 @@
+--TEST--
+Bug #72799: wddx_deserialize null dereference in php_wddx_pop_element
+--SKIPIF--
+<?php
+if (!extension_loaded('wddx')) {
+ die('skip. wddx not available');
+}
+?>
+--FILE--
+<?php
+
+$xml = <<<XML
+<?xml version='1.0'?>
+<!DOCTYPE wddxPacket SYSTEM 'wddx_0100.dtd'>
+<wddxPacket version="1.0">
+ <var name="XXXX">
+ <boolean value="1">
+ <dateTime>1998-06-12T04:32:12+00</dateTime>
+ </boolean>
+ </var>
+</wddxPacket>
+XML;
+
+$array = wddx_deserialize($xml);
+var_dump($array);
+?>
+--EXPECTF--
+Notice: Undefined variable: array in %s%ebug72799.php on line 16
+NULL
diff --git a/ext/wddx/wddx.c b/ext/wddx/wddx.c
index d28cb7a0ac..a11efe66de 100644
--- a/ext/wddx/wddx.c
+++ b/ext/wddx/wddx.c
@@ -886,10 +886,10 @@ static void php_wddx_pop_element(void *user_data, const XML_Char *name)
if (Z_TYPE(ent1->data) == IS_UNDEF) {
if (stack->top > 1) {
stack->top--;
+ efree(ent1);
} else {
stack->done = 1;
}
- efree(ent1);
return;
}
@@ -897,7 +897,11 @@ static void php_wddx_pop_element(void *user_data, const XML_Char *name)
zend_string *new_str = php_base64_decode(
(unsigned char *)Z_STRVAL(ent1->data), Z_STRLEN(ent1->data));
zval_ptr_dtor(&ent1->data);
- ZVAL_STR(&ent1->data, new_str);
+ if (new_str) {
+ ZVAL_STR(&ent1->data, new_str);
+ } else {
+ ZVAL_EMPTY_STRING(&ent1->data);
+ }
}
/* Call __wakeup() method on the object. */
@@ -1034,14 +1038,22 @@ static void php_wddx_process_data(void *user_data, const XML_Char *s, int len)
case ST_DATETIME: {
char *tmp;
- tmp = emalloc(len + 1);
- memcpy(tmp, (char *)s, len);
+ if (Z_TYPE(ent->data) == IS_STRING) {
+ tmp = safe_emalloc(Z_STRLEN(ent->data), 1, (size_t)len + 1);
+ memcpy(tmp, Z_STRVAL(ent->data), Z_STRLEN(ent->data));
+ memcpy(tmp + Z_STRLEN(ent->data), s, len);
+ len += Z_STRLEN(ent->data);
+ zval_dtor(&ent->data);
+ } else {
+ tmp = emalloc(len + 1);
+ memcpy(tmp, (char *)s, len);
+ }
tmp[len] = '\0';
- Z_LVAL(ent->data) = php_parse_date(tmp, NULL);
+ ZVAL_LONG(&ent->data, php_parse_date(tmp, NULL));
/* date out of range < 1969 or > 2038 */
if (Z_LVAL(ent->data) == -1) {
- ZVAL_STRINGL(&ent->data, (char *)s, len);
+ ZVAL_STRINGL(&ent->data, (char *)tmp, len);
}
efree(tmp);
}
diff --git a/main/fopen_wrappers.c b/main/fopen_wrappers.c
index c3646ee0fd..bf78db3bdf 100644
--- a/main/fopen_wrappers.c
+++ b/main/fopen_wrappers.c
@@ -144,7 +144,7 @@ PHPAPI int php_check_specific_open_basedir(const char *basedir, const char *path
char *path_file;
int resolved_basedir_len;
int resolved_name_len;
- int path_len;
+ size_t path_len;
int nesting_level = 0;
/* Special case basedir==".": Use script-directory */
@@ -153,7 +153,7 @@ PHPAPI int php_check_specific_open_basedir(const char *basedir, const char *path
strlcpy(local_open_basedir, basedir, sizeof(local_open_basedir));
}
- path_len = (int)strlen(path);
+ path_len = strlen(path);
if (path_len > (MAXPATHLEN - 1)) {
/* empty and too long paths are invalid */
return -1;
@@ -164,7 +164,7 @@ PHPAPI int php_check_specific_open_basedir(const char *basedir, const char *path
return -1;
}
- path_len = (int)strlen(resolved_name);
+ path_len = strlen(resolved_name);
memcpy(path_tmp, resolved_name, path_len + 1); /* safe */
while (VCWD_REALPATH(path_tmp, resolved_name) == NULL) {