diff options
author | Stanislav Malyshev <stas@php.net> | 2016-08-16 23:52:22 -0700 |
---|---|---|
committer | Stanislav Malyshev <stas@php.net> | 2016-08-16 23:52:22 -0700 |
commit | 75d7666968573a0abea36b46aae2b0c0ad6eb488 (patch) | |
tree | 7f8ae5f118e05f973a96af81747317c62f075515 | |
parent | f3231a7c766f28cb7f14bc7c2d21986fcb9740cd (diff) | |
parent | f8a75d4eee3446fb5c5c493b28b9ee80e34041cc (diff) | |
download | php-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.c | 24 | ||||
-rw-r--r-- | ext/bz2/bz2.c | 18 | ||||
-rw-r--r-- | ext/curl/interface.c | 8 | ||||
-rw-r--r-- | ext/exif/exif.c | 4 | ||||
-rw-r--r-- | ext/exif/tests/bug72627.phpt | 71 | ||||
-rw-r--r-- | ext/exif/tests/bug72627.tiff | bin | 0 -> 1250 bytes | |||
-rw-r--r-- | ext/gd/gd.c | 11 | ||||
-rw-r--r-- | ext/gd/tests/bug72697.phpt | 17 | ||||
-rw-r--r-- | ext/gd/tests/bug72730.phpt | 15 | ||||
-rw-r--r-- | ext/gd/tests/imagetruecolortopalette_error3.phpt | 2 | ||||
-rw-r--r-- | ext/gd/tests/imagetruecolortopalette_error4.phpt | 4 | ||||
-rw-r--r-- | ext/mcrypt/mcrypt.c | 16 | ||||
-rw-r--r-- | ext/snmp/snmp.c | 2 | ||||
-rw-r--r-- | ext/standard/ftp_fopen_wrapper.c | 3 | ||||
-rw-r--r-- | ext/standard/php_smart_string.h | 17 | ||||
-rw-r--r-- | ext/wddx/tests/bug72142.phpt | 2 | ||||
-rw-r--r-- | ext/wddx/tests/bug72749.phpt | 34 | ||||
-rw-r--r-- | ext/wddx/tests/bug72750.phpt | 34 | ||||
-rw-r--r-- | ext/wddx/tests/bug72790.phpt | 36 | ||||
-rw-r--r-- | ext/wddx/tests/bug72799.phpt | 29 | ||||
-rw-r--r-- | ext/wddx/wddx.c | 24 | ||||
-rw-r--r-- | main/fopen_wrappers.c | 6 |
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 Binary files differnew file mode 100644 index 0000000000..229190a604 --- /dev/null +++ b/ext/exif/tests/bug72627.tiff 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) { |