From 03df764d1c1a4d910d437e40ee4631bac3bdf573 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Tue, 11 Oct 2016 16:26:35 -0700 Subject: Merge branch 'PHP-5.6.27' into PHP-5.6 * PHP-5.6.27: Fix tests fix tsrm Fix bug #73284 - heap overflow in php_ereg_replace function Fix bug #73276 - crash in openssl_random_pseudo_bytes function Fix bug #73293 - NULL pointer dereference in SimpleXMLElement::asXML() fix bug #73275 - crash in openssl_encrypt function Fix for #73240 - Write out of bounds at number_format Bug #73218: add mitigation for ICU int overflow Add more locale length checks, due to ICU bugs. Fix bug #73208 - another missing length check Fix bug #73190: memcpy negative parameter _bc_new_num_ex Fix bug #73189 - Memcpy negative size parameter php_resolve_path Fixed bug #73174 - heap overflow in php_pcre_replace_impl Fix bug #73150: missing NULL check in dom_document_save_html Fix bug #73147: Use After Free in PHP7 unserialize() Fix bug #73082 Fix bug #73073 - CachingIterator null dereference when convert to string --- Zend/zend_API.c | 24 ++ Zend/zend_API.h | 3 +- Zend/zend_exceptions.c | 32 ++- ext/bcmath/libbcmath/src/init.c | 5 +- ext/bcmath/libbcmath/src/outofmem.c | 3 +- ext/curl/curl_file.c | 5 +- ext/curl/tests/bug73147.phpt | 20 ++ ext/dom/document.c | 4 +- ext/ereg/ereg.c | 44 ++-- ext/imap/php_imap.c | 2 +- ext/intl/locale/locale_methods.c | 8 + ext/intl/resourcebundle/resourcebundle_class.c | 42 ++-- ext/intl/tests/bug72241.phpt | 4 +- ext/mbstring/mbstring.c | 96 ++++---- ext/openssl/openssl.c | 20 +- ext/pcre/php_pcre.c | 22 +- ext/simplexml/simplexml.c | 33 ++- ext/spl/spl_iterators.c | 250 +++++++++++---------- ext/spl/tests/bug73073.phpt | 9 + .../spl_cachingiterator___toString_basic.phpt | 2 +- ext/standard/math.c | 108 +++++---- ext/standard/tests/serialize/bug69793.phpt | 2 - main/fopen_wrappers.c | 15 +- 23 files changed, 443 insertions(+), 310 deletions(-) create mode 100644 ext/curl/tests/bug73147.phpt create mode 100644 ext/spl/tests/bug73073.phpt diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 8202b9a505..0757cc9261 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -3776,6 +3776,30 @@ ZEND_API void zend_update_property(zend_class_entry *scope, zval *object, const } /* }}} */ +ZEND_API void zend_unset_property(zend_class_entry *scope, zval *object, const char *name, int name_length TSRMLS_DC) /* {{{ */ +{ + zval *property; + zend_class_entry *old_scope = EG(scope); + + EG(scope) = scope; + + if (!Z_OBJ_HT_P(object)->unset_property) { + const char *class_name; + zend_uint class_name_len; + + zend_get_object_classname(object, &class_name, &class_name_len TSRMLS_CC); + + zend_error(E_CORE_ERROR, "Property %s of class %s cannot be unset", name, class_name); + } + MAKE_STD_ZVAL(property); + ZVAL_STRINGL(property, name, name_length, 1); + Z_OBJ_HT_P(object)->unset_property(object, property, 0 TSRMLS_CC); + zval_ptr_dtor(&property); + + EG(scope) = old_scope; +} +/* }}} */ + ZEND_API void zend_update_property_null(zend_class_entry *scope, zval *object, const char *name, int name_length TSRMLS_DC) /* {{{ */ { zval *tmp; diff --git a/Zend/zend_API.h b/Zend/zend_API.h index 53c1a4cbb5..dadeaf5849 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -330,6 +330,7 @@ ZEND_API void zend_update_property_long(zend_class_entry *scope, zval *object, c ZEND_API void zend_update_property_double(zend_class_entry *scope, zval *object, const char *name, int name_length, double value TSRMLS_DC); ZEND_API void zend_update_property_string(zend_class_entry *scope, zval *object, const char *name, int name_length, const char *value TSRMLS_DC); ZEND_API void zend_update_property_stringl(zend_class_entry *scope, zval *object, const char *name, int name_length, const char *value, int value_length TSRMLS_DC); +ZEND_API void zend_unset_property(zend_class_entry *scope, zval *object, const char *name, int name_length TSRMLS_DC); ZEND_API int zend_update_static_property(zend_class_entry *scope, const char *name, int name_length, zval *value TSRMLS_DC); ZEND_API int zend_update_static_property_null(zend_class_entry *scope, const char *name, int name_length TSRMLS_DC); @@ -664,7 +665,7 @@ END_EXTERN_C() } \ RETURN_FALSE; \ } \ - RETVAL_STRINGL((s), __len, (dup)); \ + RETVAL_STRINGL((s), (int)__len, (dup)); \ } while (0) diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c index fda4d21e03..e656575446 100644 --- a/Zend/zend_exceptions.c +++ b/Zend/zend_exceptions.c @@ -229,13 +229,9 @@ ZEND_METHOD(exception, __construct) /* {{{ proto Exception::__wakeup() Exception unserialize checks */ #define CHECK_EXC_TYPE(name, type) \ - value = zend_read_property(default_exception_ce, object, name, sizeof(name)-1, 0 TSRMLS_CC); \ + value = zend_read_property(default_exception_ce, object, name, sizeof(name)-1, 1 TSRMLS_CC); \ if (value && Z_TYPE_P(value) != IS_NULL && Z_TYPE_P(value) != type) { \ - zval *tmp; \ - MAKE_STD_ZVAL(tmp); \ - ZVAL_STRINGL(tmp, name, sizeof(name)-1, 1); \ - Z_OBJ_HANDLER_P(object, unset_property)(object, tmp, 0 TSRMLS_CC); \ - zval_ptr_dtor(&tmp); \ + zend_unset_property(default_exception_ce, object, name, sizeof(name)-1 TSRMLS_CC); \ } ZEND_METHOD(exception, __wakeup) @@ -248,7 +244,12 @@ ZEND_METHOD(exception, __wakeup) CHECK_EXC_TYPE("file", IS_STRING); CHECK_EXC_TYPE("line", IS_LONG); CHECK_EXC_TYPE("trace", IS_ARRAY); - CHECK_EXC_TYPE("previous", IS_OBJECT); + value = zend_read_property(default_exception_ce, object, "previous", sizeof("previous")-1, 1 TSRMLS_CC); + if (value && Z_TYPE_P(value) != IS_NULL && (Z_TYPE_P(value) != IS_OBJECT || + !instanceof_function(Z_OBJCE_P(value), default_exception_ce TSRMLS_CC) || + value == object)) { + zend_unset_property(default_exception_ce, object, "previous", sizeof("previous")-1 TSRMLS_CC); + } } /* }}} */ @@ -727,7 +728,11 @@ ZEND_METHOD(exception, __toString) zval_dtor(&file); zval_dtor(&line); - exception = zend_read_property(default_exception_ce, exception, "previous", sizeof("previous")-1, 0 TSRMLS_CC); + Z_OBJPROP_P(exception)->nApplyCount++; + exception = zend_read_property(default_exception_ce, exception, "previous", sizeof("previous")-1, 1 TSRMLS_CC); + if (exception && Z_TYPE_P(exception) == IS_OBJECT && Z_OBJPROP_P(exception)->nApplyCount > 0) { + exception = NULL; + } if (trace) { zval_ptr_dtor(&trace); @@ -736,6 +741,17 @@ ZEND_METHOD(exception, __toString) } zval_dtor(&fname); + /* Reset apply counts */ + exception = getThis(); + while (exception && Z_TYPE_P(exception) == IS_OBJECT && instanceof_function(Z_OBJCE_P(exception), default_exception_ce TSRMLS_CC)) { + if(Z_OBJPROP_P(exception)->nApplyCount) { + Z_OBJPROP_P(exception)->nApplyCount--; + } else { + break; + } + exception = zend_read_property(default_exception_ce, exception, "previous", sizeof("previous")-1, 1 TSRMLS_CC); + } + /* We store the result in the private property string so we can access * the result in uncaught exception handlers without memleaks. */ zend_update_property_string(default_exception_ce, getThis(), "string", sizeof("string")-1, str TSRMLS_CC); diff --git a/ext/bcmath/libbcmath/src/init.c b/ext/bcmath/libbcmath/src/init.c index 986ad1df24..c51133be73 100644 --- a/ext/bcmath/libbcmath/src/init.c +++ b/ext/bcmath/libbcmath/src/init.c @@ -49,7 +49,10 @@ _bc_new_num_ex (length, scale, persistent) int length, scale, persistent; { bc_num temp; - + /* PHP Change: add length check */ + if ((size_t)length+(size_t)scale > INT_MAX) { + zend_error(E_ERROR, "Result too long, max is %d", INT_MAX); + } /* PHP Change: malloc() -> pemalloc(), removed free_list code */ temp = (bc_num) safe_pemalloc (1, sizeof(bc_struct)+length, scale, persistent); #if 0 diff --git a/ext/bcmath/libbcmath/src/outofmem.c b/ext/bcmath/libbcmath/src/outofmem.c index 799a32d2ae..05fa484e11 100644 --- a/ext/bcmath/libbcmath/src/outofmem.c +++ b/ext/bcmath/libbcmath/src/outofmem.c @@ -41,6 +41,5 @@ void bc_out_of_memory (void) { - (void) fprintf (stderr, "bcmath: out of memory!\n"); - exit (1); + zend_error_noreturn(E_ERROR, "bcmath: out of memory!"); } diff --git a/ext/curl/curl_file.c b/ext/curl/curl_file.c index 56c1bbe68b..029a58a914 100644 --- a/ext/curl/curl_file.c +++ b/ext/curl/curl_file.c @@ -137,7 +137,10 @@ ZEND_METHOD(CURLFile, setPostFilename) Unserialization handler */ ZEND_METHOD(CURLFile, __wakeup) { - zend_update_property_string(curl_CURLFile_class, getThis(), "name", sizeof("name")-1, "" TSRMLS_CC); + zval *_this = getThis(); + + zend_unset_property(curl_CURLFile_class, _this, "name", sizeof("name")-1 TSRMLS_CC); + zend_update_property_string(curl_CURLFile_class, _this, "name", sizeof("name")-1, "" TSRMLS_CC); zend_throw_exception(NULL, "Unserialization of CURLFile instances is not allowed", 0 TSRMLS_CC); } /* }}} */ diff --git a/ext/curl/tests/bug73147.phpt b/ext/curl/tests/bug73147.phpt new file mode 100644 index 0000000000..118177d871 --- /dev/null +++ b/ext/curl/tests/bug73147.phpt @@ -0,0 +1,20 @@ +--TEST-- +Bug #73147: Use After Free in PHP7 unserialize() +--SKIPIF-- + +--FILE-- +getMessage(); +} +?> +--EXPECT-- +Unserialization of CURLFile instances is not allowed diff --git a/ext/dom/document.c b/ext/dom/document.c index d33aaf160e..1970c38574 100644 --- a/ext/dom/document.c +++ b/ext/dom/document.c @@ -1792,7 +1792,7 @@ PHP_FUNCTION(dom_document_savexml) if (options & LIBXML_SAVE_NOEMPTYTAG) { xmlSaveNoEmptyTags = saveempty; } - if (!size) { + if (!size || !mem) { RETURN_FALSE; } RETVAL_STRINGL(mem, size, 1); @@ -2327,7 +2327,7 @@ PHP_FUNCTION(dom_document_save_html) #else htmlDocDumpMemory(docp, &mem, &size); #endif - if (!size) { + if (!size || !mem) { RETVAL_FALSE; } else { RETVAL_STRINGL((const char*) mem, size, 1); diff --git a/ext/ereg/ereg.c b/ext/ereg/ereg.c index 8eb833ac87..b645c0f920 100644 --- a/ext/ereg/ereg.c +++ b/ext/ereg/ereg.c @@ -14,7 +14,7 @@ +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf | | Jim Winstead | - | Jaakko Hyvätti | + | Jaakko Hyvätti | +----------------------------------------------------------------------+ */ /* $Id$ */ @@ -29,7 +29,7 @@ /* {{{ arginfo */ ZEND_BEGIN_ARG_INFO_EX(arginfo_ereg, 0, 0, 2) ZEND_ARG_INFO(0, pattern) - ZEND_ARG_INFO(0, string) + ZEND_ARG_INFO(0, string) ZEND_ARG_INFO(1, registers) /* ARRAY_INFO(1, registers, 1) */ ZEND_END_ARG_INFO() @@ -41,8 +41,8 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_split, 0, 0, 2) ZEND_ARG_INFO(0, pattern) - ZEND_ARG_INFO(0, string) - ZEND_ARG_INFO(0, limit) + ZEND_ARG_INFO(0, string) + ZEND_ARG_INFO(0, limit) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO(arginfo_sql_regcase, 0) @@ -204,7 +204,7 @@ static int _php_regcomp(regex_t *preg, const char *pattern, int cflags TSRMLS_DC } /* }}} */ -static void _free_ereg_cache(reg_cache *rc) +static void _free_ereg_cache(reg_cache *rc) { regfree(&rc->preg); } @@ -309,7 +309,7 @@ static void php_ereg(INTERNAL_FUNCTION_PARAMETERS, int icase) if (icase) { copts |= REG_ICASE; } - + if (argc == 2) { copts |= REG_NOSUB; } @@ -337,7 +337,7 @@ static void php_ereg(INTERNAL_FUNCTION_PARAMETERS, int icase) /* allocate storage for (sub-)expression-matches */ subs = (regmatch_t *)ecalloc(sizeof(regmatch_t),re.re_nsub+1); - + /* actually execute the regular expression */ err = regexec(&re, string, re.re_nsub+1, subs, 0); if (err && err != REG_NOMATCH) { @@ -409,8 +409,8 @@ PHP_EREG_API char *php_ereg_replace(const char *pattern, const char *replace, co *nbuf, /* nbuf is used when we grow the buffer */ *walkbuf; /* used to walk buf when replacing backrefs */ const char *walk; /* used to walk replacement string for backrefs */ - int buf_len; - int pos, tmp, string_len, new_l; + size_t buf_len, new_l; + int pos, tmp, string_len; int err, copts = 0; string_len = strlen(string); @@ -434,8 +434,8 @@ PHP_EREG_API char *php_ereg_replace(const char *pattern, const char *replace, co /* start with a buffer that is twice the size of the stringo we're doing replacements in */ + buf = safe_emalloc(string_len, 2, 1); buf_len = 2 * string_len + 1; - buf = safe_emalloc(buf_len, sizeof(char), 0); err = pos = 0; buf[0] = '\0'; @@ -472,8 +472,8 @@ PHP_EREG_API char *php_ereg_replace(const char *pattern, const char *replace, co } } if (new_l + 1 > buf_len) { + nbuf = safe_emalloc(new_l + 1, 2, buf_len); buf_len = 1 + buf_len + 2 * new_l; - nbuf = emalloc(buf_len); strncpy(nbuf, buf, buf_len - 1); nbuf[buf_len - 1] = '\0'; efree(buf); @@ -491,7 +491,7 @@ PHP_EREG_API char *php_ereg_replace(const char *pattern, const char *replace, co if (subs[walk[1] - '0'].rm_so > -1 && subs[walk[1] - '0'].rm_eo > -1 /* this next case shouldn't happen. it does. */ && subs[walk[1] - '0'].rm_so <= subs[walk[1] - '0'].rm_eo) { - + tmp = subs[walk[1] - '0'].rm_eo - subs[walk[1] - '0'].rm_so; memcpy (walkbuf, &string[pos + subs[walk[1] - '0'].rm_so], tmp); walkbuf += tmp; @@ -510,8 +510,8 @@ PHP_EREG_API char *php_ereg_replace(const char *pattern, const char *replace, co } new_l = strlen (buf) + 1; if (new_l + 1 > buf_len) { + nbuf = safe_emalloc(new_l + 1, 2, buf_len); buf_len = 1 + buf_len + 2 * new_l; - nbuf = safe_emalloc(buf_len, sizeof(char), 0); strncpy(nbuf, buf, buf_len-1); efree(buf); buf = nbuf; @@ -526,7 +526,7 @@ PHP_EREG_API char *php_ereg_replace(const char *pattern, const char *replace, co new_l = strlen(buf) + strlen(&string[pos]); if (new_l + 1 > buf_len) { buf_len = new_l + 1; /* now we know exactly how long it is */ - nbuf = safe_emalloc(buf_len, sizeof(char), 0); + nbuf = safe_emalloc(new_l, 1, 1); strncpy(nbuf, buf, buf_len-1); efree(buf); buf = nbuf; @@ -556,7 +556,7 @@ static void php_do_ereg_replace(INTERNAL_FUNCTION_PARAMETERS, int icase) char *replace; char *ret; int arg_string_len; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZs", &arg_pattern, &arg_replace, &arg_string, &arg_string_len) == FAILURE) { return; } @@ -598,7 +598,7 @@ static void php_do_ereg_replace(INTERNAL_FUNCTION_PARAMETERS, int icase) if (ret == (char *) -1) { RETVAL_FALSE; } else { - RETVAL_STRING(ret, 1); + RETVAL_STRINGL_CHECK(ret, strlen(ret), 1); STR_FREE(ret); } @@ -664,9 +664,9 @@ static void php_split(INTERNAL_FUNCTION_PARAMETERS, int icase) } else if (subs[0].rm_so == 0 && subs[0].rm_eo == 0) { /* No more matches */ regfree(&re); - + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Regular Expression"); - + zend_hash_destroy(Z_ARRVAL_P(return_value)); efree(Z_ARRVAL_P(return_value)); RETURN_FALSE; @@ -675,7 +675,7 @@ static void php_split(INTERNAL_FUNCTION_PARAMETERS, int icase) /* make a copy of the substring */ size = subs[0].rm_so; - + /* add it to the array */ add_next_index_stringl(return_value, strp, size, 1); @@ -701,7 +701,7 @@ static void php_split(INTERNAL_FUNCTION_PARAMETERS, int icase) /* otherwise we just have one last element to add to the array */ size = endp - strp; - + add_next_index_stringl(return_value, strp, size, 1); regfree(&re); @@ -738,9 +738,9 @@ PHP_EREG_API PHP_FUNCTION(sql_regcase) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &string, &string_len) == FAILURE) { return; } - + tmp = safe_emalloc(string_len, 4, 1); - + for (i = j = 0; i < string_len; i++) { c = (unsigned char) string[i]; if ( j >= INT_MAX - 1 || (isalpha(c) && j >= INT_MAX - 4)) { diff --git a/ext/imap/php_imap.c b/ext/imap/php_imap.c index 8fe9de9ea8..564473b738 100644 --- a/ext/imap/php_imap.c +++ b/ext/imap/php_imap.c @@ -2523,7 +2523,7 @@ PHP_FUNCTION(imap_8bit) RETURN_FALSE; } - RETVAL_STRINGL(decode, newlength, 1); + RETVAL_STRINGL_CHECK(decode, newlength, 1); fs_give((void**) &decode); } /* }}} */ diff --git a/ext/intl/locale/locale_methods.c b/ext/intl/locale/locale_methods.c index 443856ff5e..862b9f5c87 100644 --- a/ext/intl/locale/locale_methods.c +++ b/ext/intl/locale/locale_methods.c @@ -395,6 +395,8 @@ static void get_icu_value_src_php( char* tag_name, INTERNAL_FUNCTION_PARAMETERS) if(loc_name_len == 0) { loc_name = intl_locale_get_default(TSRMLS_C); } + + INTL_CHECK_LOCALE_LEN(strlen(loc_name)); /* Call ICU get */ tag_value = get_icu_value_internal( loc_name , tag_name , &result ,0); @@ -1159,6 +1161,7 @@ PHP_FUNCTION(locale_get_all_variants) loc_name = intl_locale_get_default(TSRMLS_C); } + INTL_CHECK_LOCALE_LEN(strlen(loc_name)); array_init( return_value ); @@ -1267,6 +1270,9 @@ PHP_FUNCTION(locale_filter_matches) RETURN_TRUE; } + INTL_CHECK_LOCALE_LEN(strlen(loc_range)); + INTL_CHECK_LOCALE_LEN(strlen(lang_tag)); + if( boolCanonical ){ /* canonicalize loc_range */ can_loc_range=get_icu_value_internal( loc_range , LOC_CANONICALIZE_TAG , &result , 0); @@ -1549,6 +1555,8 @@ PHP_FUNCTION(locale_lookup) loc_range = intl_locale_get_default(TSRMLS_C); } + INTL_CHECK_LOCALE_LEN(strlen(loc_range)); + hash_arr = HASH_OF(arr); if( !hash_arr || zend_hash_num_elements( hash_arr ) == 0 ) { diff --git a/ext/intl/resourcebundle/resourcebundle_class.c b/ext/intl/resourcebundle/resourcebundle_class.c index dc1212431a..90aebd4a76 100644 --- a/ext/intl/resourcebundle/resourcebundle_class.c +++ b/ext/intl/resourcebundle/resourcebundle_class.c @@ -77,7 +77,7 @@ static zend_object_value ResourceBundle_object_create( zend_class_entry *ce TSRM /* }}} */ /* {{{ ResourceBundle_ctor */ -static void resourcebundle_ctor(INTERNAL_FUNCTION_PARAMETERS) +static void resourcebundle_ctor(INTERNAL_FUNCTION_PARAMETERS) { const char *bundlename; int bundlename_len = 0; @@ -90,7 +90,7 @@ static void resourcebundle_ctor(INTERNAL_FUNCTION_PARAMETERS) intl_error_reset( NULL TSRMLS_CC ); - if( zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "s!s!|b", + if( zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "s!s!|b", &locale, &locale_len, &bundlename, &bundlename_len, &fallback ) == FAILURE ) { intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, @@ -100,11 +100,18 @@ static void resourcebundle_ctor(INTERNAL_FUNCTION_PARAMETERS) } INTL_CHECK_LOCALE_LEN_OBJ(locale_len, return_value); - + if (locale == NULL) { locale = intl_locale_get_default(TSRMLS_C); } + if (bundlename_len >= MAXPATHLEN) { + intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "Bundle name too long", 0 TSRMLS_CC ); + zval_dtor(return_value); + ZVAL_NULL(return_value); + RETURN_NULL(); + } + if (fallback) { rb->me = ures_open(bundlename, locale, &INTL_DATA_ERROR_CODE(rb)); } else { @@ -151,7 +158,7 @@ PHP_METHOD( ResourceBundle, __construct ) /* {{{ proto ResourceBundle ResourceBundle::create( string $locale [, string $bundlename [, bool $fallback = true ]] ) proto ResourceBundle resourcebundle_create( string $locale [, string $bundlename [, bool $fallback = true ]] ) */ -PHP_FUNCTION( resourcebundle_create ) +PHP_FUNCTION( resourcebundle_create ) { object_init_ex( return_value, ResourceBundle_ce_ptr ); resourcebundle_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU); @@ -159,7 +166,7 @@ PHP_FUNCTION( resourcebundle_create ) /* }}} */ /* {{{ resourcebundle_array_fetch */ -static void resourcebundle_array_fetch(zval *object, zval *offset, zval *return_value, int fallback TSRMLS_DC) +static void resourcebundle_array_fetch(zval *object, zval *offset, zval *return_value, int fallback TSRMLS_DC) { int32_t meindex = 0; char * mekey = NULL; @@ -167,7 +174,7 @@ static void resourcebundle_array_fetch(zval *object, zval *offset, zval *return_ char *pbuf; ResourceBundle_object *rb; - intl_error_reset( NULL TSRMLS_CC ); + intl_error_reset( NULL TSRMLS_CC ); RESOURCEBUNDLE_METHOD_FETCH_OBJECT; if(Z_TYPE_P(offset) == IS_LONG) { @@ -178,12 +185,12 @@ static void resourcebundle_array_fetch(zval *object, zval *offset, zval *return_ mekey = Z_STRVAL_P(offset); rb->child = ures_getByKey(rb->me, mekey, rb->child, &INTL_DATA_ERROR_CODE(rb) ); } else { - intl_errors_set(INTL_DATA_ERROR_P(rb), U_ILLEGAL_ARGUMENT_ERROR, + intl_errors_set(INTL_DATA_ERROR_P(rb), U_ILLEGAL_ARGUMENT_ERROR, "resourcebundle_get: index should be integer or string", 0 TSRMLS_CC); RETURN_NULL(); } - intl_error_set_code( NULL, INTL_DATA_ERROR_CODE(rb) TSRMLS_CC ); + intl_error_set_code( NULL, INTL_DATA_ERROR_CODE(rb) TSRMLS_CC ); if (U_FAILURE(INTL_DATA_ERROR_CODE(rb))) { if (is_numeric) { spprintf( &pbuf, 0, "Cannot load resource element %d", meindex ); @@ -213,7 +220,7 @@ static void resourcebundle_array_fetch(zval *object, zval *offset, zval *return_ /* }}} */ /* {{{ resourcebundle_array_get */ -zval *resourcebundle_array_get(zval *object, zval *offset, int type TSRMLS_DC) +zval *resourcebundle_array_get(zval *object, zval *offset, int type TSRMLS_DC) { zval *retval; @@ -246,7 +253,7 @@ PHP_FUNCTION( resourcebundle_get ) zval * object; if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oz|b", &object, ResourceBundle_ce_ptr, &offset, &fallback ) == FAILURE) { - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, + intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "resourcebundle_get: unable to parse input params", 0 TSRMLS_CC); RETURN_FALSE; } @@ -256,7 +263,7 @@ PHP_FUNCTION( resourcebundle_get ) /* }}} */ /* {{{ resourcebundle_array_count */ -int resourcebundle_array_count(zval *object, long *count TSRMLS_DC) +int resourcebundle_array_count(zval *object, long *count TSRMLS_DC) { ResourceBundle_object *rb; RESOURCEBUNDLE_METHOD_FETCH_OBJECT_NO_CHECK; @@ -288,7 +295,7 @@ PHP_FUNCTION( resourcebundle_count ) RESOURCEBUNDLE_METHOD_INIT_VARS; if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, ResourceBundle_ce_ptr ) == FAILURE ) { - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, + intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "resourcebundle_count: unable to parse input params", 0 TSRMLS_CC); RETURN_FALSE; } @@ -322,21 +329,26 @@ PHP_FUNCTION( resourcebundle_locales ) if( zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &bundlename, &bundlename_len ) == FAILURE ) { - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, + intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "resourcebundle_locales: unable to parse input params", 0 TSRMLS_CC); RETURN_FALSE; } + if (bundlename_len >= MAXPATHLEN) { + intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "resourcebundle_locales: bundle name too long", 0 TSRMLS_CC ); + RETURN_FALSE; + } + if(bundlename_len == 0) { // fetch default locales list bundlename = NULL; } icuenum = ures_openAvailableLocales( bundlename, &icuerror ); - INTL_CHECK_STATUS(icuerror, "Cannot fetch locales list"); + INTL_CHECK_STATUS(icuerror, "Cannot fetch locales list"); uenum_reset( icuenum, &icuerror ); - INTL_CHECK_STATUS(icuerror, "Cannot iterate locales list"); + INTL_CHECK_STATUS(icuerror, "Cannot iterate locales list"); array_init( return_value ); while ((entry = uenum_next( icuenum, &entry_len, &icuerror ))) { diff --git a/ext/intl/tests/bug72241.phpt b/ext/intl/tests/bug72241.phpt index 397e1e7834..7ac5a5b503 100644 --- a/ext/intl/tests/bug72241.phpt +++ b/ext/intl/tests/bug72241.phpt @@ -9,6 +9,4 @@ $out = locale_get_primary_language($var1); echo strlen($out) . PHP_EOL; echo unpack('H*', $out)[1] . PHP_EOL; --EXPECT-- -1000 -61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161 - +0 diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 56f7cfaa3e..cf5f8ed423 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -213,7 +213,7 @@ static const struct mb_overload_def mb_ovld[] = { {MB_OVERLOAD_REGEX, "split", "mb_split", "mb_orig_split"}, #endif {0, NULL, NULL, NULL} -}; +}; /* }}} */ /* {{{ arginfo */ @@ -648,7 +648,7 @@ static void *_php_mb_allocators_calloc(unsigned int nelems, unsigned int szelem) static void _php_mb_allocators_free(void *ptr) { efree(ptr); -} +} static void *_php_mb_allocators_pmalloc(unsigned int sz) { @@ -663,7 +663,7 @@ static void *_php_mb_allocators_prealloc(void *ptr, unsigned int sz) static void _php_mb_allocators_pfree(void *ptr) { pefree(ptr, 1); -} +} static mbfl_allocators _php_mb_allocators = { _php_mb_allocators_malloc, @@ -686,7 +686,7 @@ static sapi_post_entry mbstr_post_entries[] = { /* {{{ static int php_mb_parse_encoding_list() * Return 0 if input contains any illegal encoding, otherwise 1. - * Even if any illegal encoding is detected the result may contain a list + * Even if any illegal encoding is detected the result may contain a list * of parsed encodings. */ static int @@ -805,7 +805,7 @@ php_mb_parse_encoding_list(const char *value, size_t value_length, const mbfl_en /* {{{ static int php_mb_parse_encoding_array() * Return 0 if input contains any illegal encoding, otherwise 1. - * Even if any illegal encoding is detected the result may contain a list + * Even if any illegal encoding is detected the result may contain a list * of parsed encodings. */ static int @@ -960,7 +960,7 @@ static size_t php_mb_zend_encoding_converter(unsigned char **to, size_t *to_leng if (!mbfl_buffer_converter_result(convd, &result)) { mbfl_buffer_converter_delete(convd); return (size_t)-1; - } + } *to = result.val; *to_length = result.len; @@ -1192,7 +1192,7 @@ static char *php_mb_rfc1867_basename(const zend_encoding *encoding, char *filena * to nill or problem is fixed this code must remain enabled for all systems. */ s = php_mb_safe_strrchr_ex(filename, '\\', filename_len, (const mbfl_encoding *)encoding); s2 = php_mb_safe_strrchr_ex(filename, '/', filename_len, (const mbfl_encoding *)encoding); - + if (s && s2) { if (s > s2) { return ++s; @@ -1476,13 +1476,13 @@ PHP_INI_BEGIN() PHP_INI_ENTRY("mbstring.http_output", NULL, PHP_INI_ALL, OnUpdate_mbstring_http_output) STD_PHP_INI_ENTRY("mbstring.internal_encoding", NULL, PHP_INI_ALL, OnUpdate_mbstring_internal_encoding, internal_encoding_name, zend_mbstring_globals, mbstring_globals) PHP_INI_ENTRY("mbstring.substitute_character", NULL, PHP_INI_ALL, OnUpdate_mbstring_substitute_character) - STD_PHP_INI_ENTRY("mbstring.func_overload", "0", + STD_PHP_INI_ENTRY("mbstring.func_overload", "0", PHP_INI_SYSTEM, OnUpdateLong, func_overload, zend_mbstring_globals, mbstring_globals) STD_PHP_INI_BOOLEAN("mbstring.encoding_translation", "0", PHP_INI_SYSTEM | PHP_INI_PERDIR, - OnUpdate_mbstring_encoding_translation, - encoding_translation, zend_mbstring_globals, mbstring_globals) + OnUpdate_mbstring_encoding_translation, + encoding_translation, zend_mbstring_globals, mbstring_globals) PHP_INI_ENTRY("mbstring.http_output_conv_mimetypes", "^(text/|application/xhtml\\+xml)", PHP_INI_ALL, @@ -1624,21 +1624,21 @@ PHP_RINIT_FUNCTION(mbstring) /* override original function. */ if (MBSTRG(func_overload)){ p = &(mb_ovld[0]); - + while (p->type > 0) { - if ((MBSTRG(func_overload) & p->type) == p->type && + if ((MBSTRG(func_overload) & p->type) == p->type && zend_hash_find(EG(function_table), p->save_func, strlen(p->save_func)+1, (void **)&orig) != SUCCESS) { zend_hash_find(EG(function_table), p->ovld_func, strlen(p->ovld_func)+1 , (void **)&func); - + if (zend_hash_find(EG(function_table), p->orig_func, strlen(p->orig_func)+1, (void **)&orig) != SUCCESS) { php_error_docref("ref.mbstring" TSRMLS_CC, E_WARNING, "mbstring couldn't find function %s.", p->orig_func); return FAILURE; } else { zend_hash_add(EG(function_table), p->save_func, strlen(p->save_func)+1, orig, sizeof(zend_function), NULL); - if (zend_hash_update(EG(function_table), p->orig_func, strlen(p->orig_func)+1, func, sizeof(zend_function), + if (zend_hash_update(EG(function_table), p->orig_func, strlen(p->orig_func)+1, func, sizeof(zend_function), NULL) == FAILURE) { php_error_docref("ref.mbstring" TSRMLS_CC, E_WARNING, "mbstring couldn't replace function %s.", p->orig_func); return FAILURE; @@ -1685,10 +1685,10 @@ PHP_RSHUTDOWN_FUNCTION(mbstring) if (MBSTRG(func_overload)){ p = &(mb_ovld[0]); while (p->type > 0) { - if ((MBSTRG(func_overload) & p->type) == p->type && + if ((MBSTRG(func_overload) & p->type) == p->type && zend_hash_find(EG(function_table), p->save_func, strlen(p->save_func)+1, (void **)&orig) == SUCCESS) { - + zend_hash_update(EG(function_table), p->orig_func, strlen(p->orig_func)+1, orig, sizeof(zend_function), NULL); zend_hash_del(EG(function_table), p->save_func, strlen(p->save_func)+1); } @@ -1710,7 +1710,7 @@ PHP_MINFO_FUNCTION(mbstring) php_info_print_table_start(); php_info_print_table_row(2, "Multibyte Support", "enabled"); php_info_print_table_row(2, "Multibyte string engine", "libmbfl"); - php_info_print_table_row(2, "HTTP input encoding translation", MBSTRG(encoding_translation) ? "enabled": "disabled"); + php_info_print_table_row(2, "HTTP input encoding translation", MBSTRG(encoding_translation) ? "enabled": "disabled"); { char tmp[256]; snprintf(tmp, sizeof(tmp), "%d.%d.%d", MBFL_VERSION_MAJOR, MBFL_VERSION_MINOR, MBFL_VERSION_TEENY); @@ -1846,7 +1846,7 @@ PHP_FUNCTION(mb_http_input) temp = list; spprintf(&list, 0, "%s,%s", temp, (*entry)->name); efree(temp); - if (!list) { + if (!list) { break; } } else { @@ -2078,12 +2078,12 @@ PHP_FUNCTION(mb_parse_str) encstr = estrndup(encstr, encstr_len); info.data_type = PARSE_STRING; - info.separator = PG(arg_separator).input; + info.separator = PG(arg_separator).input; info.report_errors = 1; info.to_encoding = MBSTRG(current_internal_encoding); info.to_language = MBSTRG(language); info.from_encodings = MBSTRG(http_input_list); - info.num_from_encodings = MBSTRG(http_input_list_size); + info.num_from_encodings = MBSTRG(http_input_list_size); info.from_language = MBSTRG(language); if (track_vars_array != NULL) { @@ -2093,8 +2093,8 @@ PHP_FUNCTION(mb_parse_str) if (!EG(active_symbol_table)) { zend_rebuild_symbol_table(TSRMLS_C); } - Z_ARRVAL(tmp) = EG(active_symbol_table); - detected = _php_mb_encoding_handler_ex(&info, &tmp, encstr TSRMLS_CC); + Z_ARRVAL(tmp) = EG(active_symbol_table); + detected = _php_mb_encoding_handler_ex(&info, &tmp, encstr TSRMLS_CC); } MBSTRG(http_input_identify) = detected; @@ -2158,7 +2158,7 @@ PHP_FUNCTION(mb_output_handler) if (SG(sapi_headers).send_default_content_type || send_text_mimetype) { charset = encoding->mime_name; if (charset) { - len = spprintf( &p, 0, "Content-Type: %s; charset=%s", mimetype, charset ); + len = spprintf( &p, 0, "Content-Type: %s; charset=%s", mimetype, charset ); if (sapi_add_header(p, len, 0) != FAILURE) { SG(sapi_headers).send_default_content_type = 0; } @@ -2181,7 +2181,7 @@ PHP_FUNCTION(mb_output_handler) /* mode */ mbfl_buffer_converter_illegal_mode(MBSTRG(outconv), MBSTRG(current_filter_illegal_mode)); mbfl_buffer_converter_illegal_substchar(MBSTRG(outconv), MBSTRG(current_filter_illegal_substchar)); - + /* feed the string */ mbfl_string_init(&string); /* these are not needed. convd has encoding info. @@ -2193,11 +2193,11 @@ PHP_FUNCTION(mb_output_handler) mbfl_buffer_converter_feed(MBSTRG(outconv), &string); if (last_feed) { mbfl_buffer_converter_flush(MBSTRG(outconv)); - } + } /* get the converter output, and return it */ mbfl_buffer_converter_result(MBSTRG(outconv), &result); RETVAL_STRINGL((char *)result.val, result.len, 0); /* the string is already strdup()'ed */ - + /* delete the converter if it is the last feed. */ if (last_feed) { MBSTRG(illegalchars) += mbfl_buffer_illegalchars(MBSTRG(outconv)); @@ -3156,7 +3156,7 @@ PHP_FUNCTION(mb_convert_case) if (newstr) { RETVAL_STRINGL(newstr, ret_len, 0); - } + } } /* }}} */ @@ -3380,7 +3380,7 @@ PHP_FUNCTION(mb_encode_mimeheader) mbfl_string_init(&result); ret = mbfl_mime_header_encode(&string, &result, charset, transenc, linefeed, indent); if (ret != NULL) { - RETVAL_STRINGL((char *)ret->val, ret->len, 0); /* the string is already strdup()'ed */ + RETVAL_STRINGL_CHECK((char *)ret->val, ret->len, 0); /* the string is already strdup()'ed */ } else { RETVAL_FALSE; } @@ -3507,7 +3507,7 @@ PHP_FUNCTION(mb_convert_kana) ret = mbfl_ja_jp_hantozen(&string, &result, opt); if (ret != NULL) { - RETVAL_STRINGL((char *)ret->val, ret->len, 0); /* the string is already strdup()'ed */ + RETVAL_STRINGL_CHECK((char *)ret->val, ret->len, 0); /* the string is already strdup()'ed */ } else { RETVAL_FALSE; } @@ -3841,7 +3841,7 @@ php_mb_numericentity_exec(INTERNAL_FUNCTION_PARAMETERS, int type) ret = mbfl_html_numeric_entity(&string, &result, convmap, mapsize, type); if (ret != NULL) { - RETVAL_STRINGL((char *)ret->val, ret->len, 0); + RETVAL_STRINGL_CHECK((char *)ret->val, ret->len, 0); } else { RETVAL_FALSE; } @@ -3929,12 +3929,12 @@ static int _php_mbstr_parse_mail_headers(HashTable *ht, const char *str, size_t /* * C o n t e n t - T y p e : t e x t / h t m l \r\n - * ^ ^^^^^^^^^^^^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^ ^^^^ - * state 0 1 2 3 + * ^ ^^^^^^^^^^^^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^ ^^^^ + * state 0 1 2 3 * * C o n t e n t - T y p e : t e x t / h t m l \r\n - * ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ - * crlf_state -1 0 1 -1 + * ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ + * crlf_state -1 0 1 -1 * */ @@ -4000,7 +4000,7 @@ static int _php_mbstr_parse_mail_headers(HashTable *ht, const char *str, size_t token.a = 0; state = 1; break; - + case 2: if (crlf_state != -1) { token.c = (char *)ps; @@ -4177,14 +4177,14 @@ PHP_FUNCTION(mb_send_mail) if ((param_name = php_strtok_r(p, "= ", &tmp)) != NULL) { if (strcasecmp(param_name, "charset") == 0) { enum mbfl_no_encoding _tran_cs = tran_cs; - + charset = php_strtok_r(NULL, "= \"", &tmp); if (charset != NULL) { _tran_cs = mbfl_name2no_encoding(charset); } if (_tran_cs == mbfl_no_encoding_invalid) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unsupported charset \"%s\" - will be regarded as ascii", charset); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unsupported charset \"%s\" - will be regarded as ascii", charset); _tran_cs = mbfl_no_encoding_ascii; } tran_cs = _tran_cs; @@ -4209,7 +4209,7 @@ PHP_FUNCTION(mb_send_mail) break; default: - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unsupported transfer encoding \"%s\" - will be regarded as 8bit", s->c); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unsupported transfer encoding \"%s\" - will be regarded as 8bit", s->c); body_enc = mbfl_no_encoding_8bit; break; } @@ -4342,7 +4342,7 @@ PHP_FUNCTION(mb_send_mail) extra_cmd = php_escape_shell_cmd(force_extra_parameters); } else if (extra_cmd) { extra_cmd = php_escape_shell_cmd(extra_cmd); - } + } if (!err && php_mail(to_r, subject, message, headers, extra_cmd TSRMLS_CC)) { RETVAL_TRUE; @@ -4441,7 +4441,7 @@ PHP_FUNCTION(mb_get_info) } if ((name = (char *)mbfl_no_language2name(MBSTRG(language))) != NULL) { add_assoc_string(return_value, "language", name, 1); - } + } n = MBSTRG(current_detect_order_list_size); entry = MBSTRG(current_detect_order_list); if (n > 0) { @@ -4471,15 +4471,15 @@ PHP_FUNCTION(mb_get_info) } else if (!strcasecmp("internal_encoding", typ)) { if (MBSTRG(current_internal_encoding)) { RETVAL_STRING((char *)MBSTRG(current_internal_encoding)->name, 1); - } + } } else if (!strcasecmp("http_input", typ)) { if (MBSTRG(http_input_identify)) { RETVAL_STRING((char *)MBSTRG(http_input_identify)->name, 1); - } + } } else if (!strcasecmp("http_output", typ)) { if (MBSTRG(current_http_output_encoding)) { RETVAL_STRING((char *)MBSTRG(current_http_output_encoding)->name, 1); - } + } } else if (!strcasecmp("http_output_conv_mimetypes", typ)) { if ((name = (char *)zend_ini_string("mbstring.http_output_conv_mimetypes", sizeof("mbstring.http_output_conv_mimetypes"), 0)) != NULL) { RETVAL_STRING(name, 1); @@ -4522,7 +4522,7 @@ PHP_FUNCTION(mb_get_info) } else if (!strcasecmp("language", typ)) { if ((name = (char *)mbfl_no_language2name(MBSTRG(language))) != NULL) { RETVAL_STRING(name, 1); - } + } } else if (!strcasecmp("detect_order", typ)) { n = MBSTRG(current_detect_order_list_size); entry = MBSTRG(current_detect_order_list); @@ -4589,9 +4589,9 @@ PHP_FUNCTION(mb_check_encoding) if (convd == NULL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create converter"); RETURN_FALSE; - } + } mbfl_buffer_converter_illegal_mode(convd, MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE); - mbfl_buffer_converter_illegal_substchar(convd, 0); + mbfl_buffer_converter_illegal_substchar(convd, 0); /* initialize string */ mbfl_string_init_set(&string, mbfl_no_language_neutral, encoding->no_encoding); @@ -4642,7 +4642,7 @@ static void php_mb_populate_current_detect_order_list(TSRMLS_D) } /* {{{ static int php_mb_encoding_translation() */ -static int php_mb_encoding_translation(TSRMLS_D) +static int php_mb_encoding_translation(TSRMLS_D) { return MBSTRG(encoding_translation); } @@ -4768,7 +4768,7 @@ MBSTRING_API int php_mb_stripos(int mode, const char *old_haystack, unsigned int { int haystack_char_len = mbfl_strlen(&haystack); - + if (mode) { if ((offset > 0 && offset > haystack_char_len) || (offset < 0 && -offset > haystack_char_len)) { diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 844132b2cc..01f2a099a8 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -5260,7 +5260,7 @@ PHP_FUNCTION(openssl_encrypt) free_iv = php_openssl_validate_iv(&iv, &iv_len, max_iv_len TSRMLS_CC); outlen = data_len + EVP_CIPHER_block_size(cipher_type); - outbuf = emalloc(outlen + 1); + outbuf = safe_emalloc(outlen, 1, 1); EVP_EncryptInit(&cipher_ctx, cipher_type, NULL, NULL); if (password_len > keylen) { @@ -5278,14 +5278,18 @@ PHP_FUNCTION(openssl_encrypt) outlen += i; if (options & OPENSSL_RAW_DATA) { outbuf[outlen] = '\0'; - RETVAL_STRINGL((char *)outbuf, outlen, 0); + RETVAL_STRINGL_CHECK((char *)outbuf, outlen, 0); } else { int base64_str_len; char *base64_str; base64_str = (char*)php_base64_encode(outbuf, outlen, &base64_str_len); efree(outbuf); - RETVAL_STRINGL(base64_str, base64_str_len, 0); + if (!base64_str) { + RETVAL_FALSE; + } else { + RETVAL_STRINGL(base64_str, base64_str_len, 0); + } } } else { efree(outbuf); @@ -5462,16 +5466,16 @@ PHP_FUNCTION(openssl_random_pseudo_bytes) return; } - if (buffer_length <= 0) { - RETURN_FALSE; - } - if (zstrong_result_returned) { zval_dtor(zstrong_result_returned); ZVAL_BOOL(zstrong_result_returned, 0); } - buffer = emalloc(buffer_length + 1); + if (buffer_length <= 0 || buffer_length > INT_MAX) { + RETURN_FALSE; + } + + buffer = safe_emalloc(buffer_length, 1, 1); #ifdef PHP_WIN32 /* random/urandom equivalent on Windows */ diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 7589a7803c..2a8ff199b8 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -1075,8 +1075,8 @@ PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int sub char **subpat_names; /* Array for named subpatterns */ int num_subpats; /* Number of captured subpatterns */ int size_offsets; /* Size of the offsets array */ - int new_len; /* Length of needed storage */ - int alloc_len; /* Actual allocated length */ + size_t new_len; /* Length of needed storage */ + size_t alloc_len; /* Actual allocated length */ int eval_result_len=0; /* Length of the eval'ed or function-returned string */ int match_len; /* Length of the current match */ @@ -1146,8 +1146,8 @@ PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int sub offsets = (int *)safe_emalloc(size_offsets, sizeof(int), 0); - alloc_len = 2 * subject_len + 1; - result = safe_emalloc(alloc_len, sizeof(char), 0); + result = safe_emalloc(subject_len, 2*sizeof(char), 1); + alloc_len = 2 * (size_t)subject_len + 1; /* Initialize */ match = NULL; @@ -1212,8 +1212,8 @@ PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int sub } if (new_len + 1 > alloc_len) { - alloc_len = 1 + alloc_len + 2 * new_len; - new_buf = emalloc(alloc_len); + new_buf = safe_emalloc(2, new_len + 1, alloc_len); + alloc_len = 1 + alloc_len + 2 * (size_t)new_len; memcpy(new_buf, result, *result_len); efree(result); result = new_buf; @@ -1276,8 +1276,8 @@ PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int sub } else { new_len = *result_len + subject_len - start_offset; if (new_len + 1 > alloc_len) { - alloc_len = new_len + 1; /* now we know exactly how long it is */ - new_buf = safe_emalloc(alloc_len, sizeof(char), 0); + new_buf = safe_emalloc(new_len, sizeof(char), 1); + alloc_len = (size_t)new_len + 1; /* now we know exactly how long it is */ memcpy(new_buf, result, *result_len); efree(result); result = new_buf; @@ -1308,6 +1308,12 @@ PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int sub efree(offsets); efree(subpat_names); + if(result && (size_t)(*result_len) > INT_MAX) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Result is too big, max is %d", INT_MAX); + efree(result); + result = NULL; + } + return result; } /* }}} */ diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c index 07fc6546e8..d7077fc935 100644 --- a/ext/simplexml/simplexml.c +++ b/ext/simplexml/simplexml.c @@ -989,7 +989,7 @@ static inline char * sxe_xmlNodeListGetString(xmlDocPtr doc, xmlNodePtr list, in { xmlChar *tmp = xmlNodeListGetString(doc, list, inLine); char *res; - + if (tmp) { res = estrdup((char*)tmp); xmlFree(tmp); @@ -1147,7 +1147,7 @@ static HashTable * sxe_get_prop_hash(zval *object, int is_debug TSRMLS_DC) /* {{ } else { if (node->type == XML_TEXT_NODE) { const xmlChar *cur = node->content; - + if (*cur != 0) { MAKE_STD_ZVAL(value); ZVAL_STRING(value, sxe_xmlNodeListGetString(node->doc, node, 1), 0); @@ -1198,7 +1198,7 @@ next_iter: static HashTable * sxe_get_gc(zval *object, zval ***table, int *n TSRMLS_DC) /* {{{ */ { php_sxe_object *sxe; sxe = php_sxe_fetch_object(object TSRMLS_CC); - + *table = NULL; *n = 0; return sxe->properties; @@ -1302,7 +1302,7 @@ SXE_METHOD(xpath) result = retval->nodesetval; array_init(return_value); - + if (result != NULL) { for (i = 0; i < result->nodeNr; ++i) { nodeptr = result->nodeTab[i]; @@ -1412,9 +1412,15 @@ SXE_METHOD(asXML) if (node) { if (node->parent && (XML_DOCUMENT_NODE == node->parent->type)) { xmlDocDumpMemoryEnc((xmlDocPtr) sxe->document->ptr, &strval, &strval_len, ((xmlDocPtr) sxe->document->ptr)->encoding); - RETVAL_STRINGL((char *)strval, strval_len, 1); + if (!strval) { + RETVAL_FALSE; + } else { + RETVAL_STRINGL((char *)strval, strval_len, 1); + } xmlFree(strval); } else { + char *return_content; + size_t return_len; /* Should we be passing encoding information instead of NULL? */ outbuf = xmlAllocOutputBuffer(NULL); @@ -1425,10 +1431,17 @@ SXE_METHOD(asXML) xmlNodeDumpOutput(outbuf, (xmlDocPtr) sxe->document->ptr, node, 0, 0, ((xmlDocPtr) sxe->document->ptr)->encoding); xmlOutputBufferFlush(outbuf); #ifdef LIBXML2_NEW_BUFFER - RETVAL_STRINGL((char *)xmlOutputBufferGetContent(outbuf), xmlOutputBufferGetSize(outbuf), 1); + return_content = (char *)xmlOutputBufferGetContent(outbuf); + return_len = xmlOutputBufferGetSize(outbuf); #else - RETVAL_STRINGL((char *)outbuf->buffer->content, outbuf->buffer->use, 1); + return_content = (char *)outbuf->buffer->content; + return_len = outbuf->buffer->use; #endif + if (!return_content) { + RETVAL_FALSE; + } else { + RETVAL_STRINGL_CHECK(return_content, return_len, 1); + } xmlOutputBufferClose(outbuf); } } else { @@ -1542,11 +1555,11 @@ SXE_METHOD(getDocNamespaces) }else{ GET_NODE(sxe, node); } - + if (node == NULL) { RETURN_FALSE; } - + array_init(return_value); sxe_add_registered_namespaces(sxe, node, recursive, return_value TSRMLS_CC); } @@ -1933,7 +1946,7 @@ SXE_METHOD(count) } php_sxe_count_elements_helper(sxe, &count TSRMLS_CC); - + RETURN_LONG(count); } /* }}} */ diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c index 878e5a10f0..d91d81d458 100644 --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@ -195,7 +195,7 @@ static int spl_recursive_it_valid_ex(spl_recursive_it_object *object, zval *zthi static int spl_recursive_it_valid(zend_object_iterator *iter TSRMLS_DC) { spl_recursive_it_object *object = (spl_recursive_it_object*)iter->data; - + return spl_recursive_it_valid_ex(object, ((spl_recursive_it_iterator*)iter)->zobject TSRMLS_CC); } @@ -203,7 +203,7 @@ static void spl_recursive_it_get_current_data(zend_object_iterator *iter, zval * { spl_recursive_it_object *object = (spl_recursive_it_object*)iter->data; zend_object_iterator *sub_iter = object->iterators[object->level].iterator; - + sub_iter->funcs->get_current_data(sub_iter, data TSRMLS_CC); } @@ -248,7 +248,7 @@ next_step: if (iterator->funcs->valid(iterator TSRMLS_CC) == FAILURE) { break; } - object->iterators[object->level].state = RS_TEST; + object->iterators[object->level].state = RS_TEST; /* break; */ case RS_TEST: ce = object->iterators[object->level].ce; @@ -394,7 +394,7 @@ next_step: static void spl_recursive_it_rewind_ex(spl_recursive_it_object *object, zval *zthis TSRMLS_DC) { zend_object_iterator *sub_iter; - + SPL_FETCH_SUB_ITERATOR(sub_iter, object); while (object->level) { @@ -606,7 +606,7 @@ SPL_METHOD(RecursiveIteratorIterator, __construct) SPL_METHOD(RecursiveIteratorIterator, rewind) { spl_recursive_it_object *object = (spl_recursive_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -654,7 +654,7 @@ SPL_METHOD(RecursiveIteratorIterator, current) spl_recursive_it_object *object = (spl_recursive_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); zend_object_iterator *iterator; zval **data; - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -672,7 +672,7 @@ SPL_METHOD(RecursiveIteratorIterator, current) SPL_METHOD(RecursiveIteratorIterator, next) { spl_recursive_it_object *object = (spl_recursive_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -685,11 +685,11 @@ SPL_METHOD(RecursiveIteratorIterator, next) SPL_METHOD(RecursiveIteratorIterator, getDepth) { spl_recursive_it_object *object = (spl_recursive_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } - + RETURN_LONG(object->level); } /* }}} */ @@ -700,7 +700,7 @@ SPL_METHOD(RecursiveIteratorIterator, getSubIterator) spl_recursive_it_object *object = (spl_recursive_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); long level = object->level; zval *zobject; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &level) == FAILURE) { return; } @@ -723,7 +723,7 @@ SPL_METHOD(RecursiveIteratorIterator, getInnerIterator) { spl_recursive_it_object *object = (spl_recursive_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); zval *zobject; - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -760,7 +760,7 @@ SPL_METHOD(RecursiveIteratorIterator, callHasChildren) spl_recursive_it_object *object = (spl_recursive_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); zend_class_entry *ce; zval *retval, *zobject; - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -791,7 +791,7 @@ SPL_METHOD(RecursiveIteratorIterator, callGetChildren) spl_recursive_it_object *object = (spl_recursive_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); zend_class_entry *ce; zval *retval, *zobject; - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -845,7 +845,7 @@ SPL_METHOD(RecursiveIteratorIterator, setMaxDepth) { spl_recursive_it_object *object = (spl_recursive_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); long max_depth = -1; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &max_depth) == FAILURE) { return; } @@ -865,7 +865,7 @@ SPL_METHOD(RecursiveIteratorIterator, getMaxDepth) if (zend_parse_parameters_none() == FAILURE) { return; } - + if (object->max_depth == -1) { RETURN_FALSE; } else { @@ -982,7 +982,7 @@ static zend_object_value spl_RecursiveTreeIterator_new(zend_class_entry *class_t } /* }}} */ -ZEND_BEGIN_ARG_INFO_EX(arginfo_recursive_it___construct, 0, 0, 1) +ZEND_BEGIN_ARG_INFO_EX(arginfo_recursive_it___construct, 0, 0, 1) ZEND_ARG_OBJ_INFO(0, iterator, Traversable, 0) ZEND_ARG_INFO(0, mode) ZEND_ARG_INFO(0, flags) @@ -1025,7 +1025,7 @@ static void spl_recursive_tree_iterator_get_prefix(spl_recursive_it_object *obje int level; smart_str_appendl(&str, object->prefix[0].c, object->prefix[0].len); - + for (level = 0; level < object->level; ++level) { zend_call_method_with_0_params(&object->iterators[level].zobject, object->iterators[level].ce, NULL, "hasnext", &has_next); if (has_next) { @@ -1094,7 +1094,7 @@ SPL_METHOD(RecursiveTreeIterator, setPrefixPart) long part; char* prefix; int prefix_len; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &part, &prefix, &prefix_len) == FAILURE) { return; } @@ -1102,7 +1102,7 @@ SPL_METHOD(RecursiveTreeIterator, setPrefixPart) zend_throw_exception_ex(spl_ce_OutOfRangeException, 0 TSRMLS_CC, "Use RecursiveTreeIterator::PREFIX_* constant"); return; } - + smart_str_free(&object->prefix[part]); smart_str_appendl(&object->prefix[part], prefix, prefix_len); } /* }}} */ @@ -1121,8 +1121,8 @@ SPL_METHOD(RecursiveTreeIterator, getPrefix) zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "The object is in an invalid state as the parent constructor was not called"); return; - } - + } + spl_recursive_tree_iterator_get_prefix(object, return_value TSRMLS_CC); } /* }}} */ @@ -1157,7 +1157,7 @@ SPL_METHOD(RecursiveTreeIterator, getEntry) "The object is in an invalid state as the parent constructor was not called"); return; } - + spl_recursive_tree_iterator_get_entry(object, return_value TSRMLS_CC); } /* }}} */ @@ -1176,7 +1176,7 @@ SPL_METHOD(RecursiveTreeIterator, getPostfix) "The object is in an invalid state as the parent constructor was not called"); return; } - + spl_recursive_tree_iterator_get_postfix(object, return_value TSRMLS_CC); } /* }}} */ @@ -1188,7 +1188,7 @@ SPL_METHOD(RecursiveTreeIterator, current) zval prefix, entry, postfix; char *str, *ptr; size_t str_len; - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1197,7 +1197,7 @@ SPL_METHOD(RecursiveTreeIterator, current) zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "The object is in an invalid state as the parent constructor was not called"); return; - } + } if (object->flags & RTIT_BYPASS_CURRENT) { zend_object_iterator *iterator; @@ -1251,7 +1251,7 @@ SPL_METHOD(RecursiveTreeIterator, key) zval prefix, key, postfix, key_copy; char *str, *ptr; size_t str_len; - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1301,7 +1301,7 @@ SPL_METHOD(RecursiveTreeIterator, key) RETVAL_STRINGL(str, str_len, 0); } /* }}} */ -ZEND_BEGIN_ARG_INFO_EX(arginfo_recursive_tree_it___construct, 0, 0, 1) +ZEND_BEGIN_ARG_INFO_EX(arginfo_recursive_tree_it___construct, 0, 0, 1) ZEND_ARG_OBJ_INFO(0, iterator, Traversable, 0) ZEND_ARG_INFO(0, flags) ZEND_ARG_INFO(0, caching_it_flags) @@ -1405,14 +1405,14 @@ int spl_dual_it_call_method(char *method, INTERNAL_FUNCTION_PARAMETERS) if (call_user_function_ex(EG(function_table), NULL, &func, &retval_ptr, arg_count, func_params, 0, NULL TSRMLS_CC) == SUCCESS && retval_ptr) { RETURN_ZVAL(retval_ptr, 0, 1); - + success = SUCCESS; } else { php_error_docref(NULL TSRMLS_CC, E_ERROR, "Unable to call %s::%s()", intern->inner.ce->name, method); success = FAILURE; } - efree(func_params); + efree(func_params); return success; } #endif @@ -1436,7 +1436,7 @@ static inline int spl_cit_check_flags(int flags) cnt += (flags & CIT_TOSTRING_USE_KEY) ? 1 : 0; cnt += (flags & CIT_TOSTRING_USE_CURRENT) ? 1 : 0; cnt += (flags & CIT_TOSTRING_USE_INNER) ? 1 : 0; - + return cnt <= 1 ? SUCCESS : FAILURE; } @@ -1449,7 +1449,7 @@ static spl_dual_it_object* spl_dual_it_construct(INTERNAL_FUNCTION_PARAMETERS, z zend_error_handling error_handling; intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (intern->dit_type != DIT_Unknown) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "%s::getIterator() must be called exactly once per instance", ce_base->name); return NULL; @@ -1507,7 +1507,7 @@ static spl_dual_it_object* spl_dual_it_construct(INTERNAL_FUNCTION_PARAMETERS, z ce = Z_OBJCE_P(zobject); if (!instanceof_function(ce, zend_ce_iterator TSRMLS_CC)) { if (ZEND_NUM_ARGS() > 1) { - if (zend_lookup_class(class_name, class_name_len, &pce_cast TSRMLS_CC) == FAILURE + if (zend_lookup_class(class_name, class_name_len, &pce_cast TSRMLS_CC) == FAILURE || !instanceof_function(ce, *pce_cast TSRMLS_CC) || !(*pce_cast)->get_iterator ) { @@ -1616,21 +1616,21 @@ static spl_dual_it_object* spl_dual_it_construct(INTERNAL_FUNCTION_PARAMETERS, z return intern; } -/* {{{ proto void FilterIterator::__construct(Iterator it) +/* {{{ proto void FilterIterator::__construct(Iterator it) Create an Iterator from another iterator */ SPL_METHOD(FilterIterator, __construct) { spl_dual_it_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, spl_ce_FilterIterator, zend_ce_iterator, DIT_FilterIterator); } /* }}} */ -/* {{{ proto void CallbackFilterIterator::__construct(Iterator it, callback) +/* {{{ proto void CallbackFilterIterator::__construct(Iterator it, callback) Create an Iterator from another iterator */ SPL_METHOD(CallbackFilterIterator, __construct) { spl_dual_it_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, spl_ce_CallbackFilterIterator, zend_ce_iterator, DIT_CallbackFilterIterator); } /* }}} */ -/* {{{ proto Iterator FilterIterator::getInnerIterator() +/* {{{ proto Iterator FilterIterator::getInnerIterator() proto Iterator CachingIterator::getInnerIterator() proto Iterator LimitIterator::getInnerIterator() proto Iterator ParentIterator::getInnerIterator() @@ -1638,11 +1638,11 @@ SPL_METHOD(CallbackFilterIterator, __construct) SPL_METHOD(dual_it, getInnerIterator) { spl_dual_it_object *intern; - + if (zend_parse_parameters_none() == FAILURE) { return; } - + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); if (intern->inner.zobject) { @@ -1747,13 +1747,13 @@ static inline void spl_dual_it_next(spl_dual_it_object *intern, int do_free TSRM SPL_METHOD(dual_it, rewind) { spl_dual_it_object *intern; - + if (zend_parse_parameters_none() == FAILURE) { return; } - + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); - + spl_dual_it_rewind(intern TSRMLS_CC); spl_dual_it_fetch(intern, 1 TSRMLS_CC); } /* }}} */ @@ -1770,7 +1770,7 @@ SPL_METHOD(dual_it, valid) if (zend_parse_parameters_none() == FAILURE) { return; } - + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); RETURN_BOOL(intern->current.data); @@ -1791,7 +1791,7 @@ SPL_METHOD(dual_it, key) if (zend_parse_parameters_none() == FAILURE) { return; } - + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); if (intern->current.key) { @@ -1811,7 +1811,7 @@ SPL_METHOD(dual_it, key) SPL_METHOD(dual_it, current) { spl_dual_it_object *intern; - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1832,7 +1832,7 @@ SPL_METHOD(dual_it, current) SPL_METHOD(dual_it, next) { spl_dual_it_object *intern; - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1881,7 +1881,7 @@ static inline void spl_filter_it_next(zval *zthis, spl_dual_it_object *intern TS SPL_METHOD(FilterIterator, rewind) { spl_dual_it_object *intern; - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1895,7 +1895,7 @@ SPL_METHOD(FilterIterator, rewind) SPL_METHOD(FilterIterator, next) { spl_dual_it_object *intern; - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1925,7 +1925,7 @@ SPL_METHOD(RecursiveFilterIterator, hasChildren) { spl_dual_it_object *intern; zval *retval; - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1946,7 +1946,7 @@ SPL_METHOD(RecursiveFilterIterator, getChildren) { spl_dual_it_object *intern; zval *retval; - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1968,7 +1968,7 @@ SPL_METHOD(RecursiveCallbackFilterIterator, getChildren) { spl_dual_it_object *intern; zval *retval; - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1991,7 +1991,7 @@ SPL_METHOD(ParentIterator, __construct) } /* }}} */ #if HAVE_PCRE || HAVE_BUNDLED_PCRE -/* {{{ proto void RegexIterator::__construct(Iterator it, string regex [, int mode [, int flags [, int preg_flags]]]) +/* {{{ proto void RegexIterator::__construct(Iterator it, string regex [, int mode [, int flags [, int preg_flags]]]) Create an RegexIterator from another iterator and a regular expression */ SPL_METHOD(RegexIterator, __construct) { @@ -2044,13 +2044,13 @@ SPL_METHOD(RegexIterator, accept) char *subject, *result; int subject_len, use_copy, count = 0, result_len; zval *subject_ptr, subject_copy, zcount, *replacement, tmp_replacement; - + if (zend_parse_parameters_none() == FAILURE) { return; } - + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); - + if (intern->current.data == NULL) { RETURN_FALSE; } @@ -2089,7 +2089,7 @@ SPL_METHOD(RegexIterator, accept) } zval_ptr_dtor(&intern->current.data); ALLOC_INIT_ZVAL(intern->current.data); - php_pcre_match_impl(intern->u.regex.pce, subject, subject_len, &zcount, + php_pcre_match_impl(intern->u.regex.pce, subject, subject_len, &zcount, intern->current.data, intern->u.regex.mode == REGIT_MODE_ALL_MATCHES, intern->u.regex.use_flags, intern->u.regex.preg_flags, 0 TSRMLS_CC); RETVAL_BOOL(Z_LVAL(zcount) > 0); break; @@ -2115,7 +2115,7 @@ SPL_METHOD(RegexIterator, accept) replacement = &tmp_replacement; } result = php_pcre_replace_impl(intern->u.regex.pce, subject, subject_len, replacement, 0, &result_len, -1, &count TSRMLS_CC); - + if (intern->u.regex.flags & REGIT_USE_KEY) { zval_ptr_dtor(&intern->current.key); MAKE_STD_ZVAL(intern->current.key); @@ -2163,9 +2163,9 @@ SPL_METHOD(RegexIterator, getMode) if (zend_parse_parameters_none() == FAILURE) { return; } - + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); - + RETURN_LONG(intern->u.regex.mode); } /* }}} */ @@ -2184,7 +2184,7 @@ SPL_METHOD(RegexIterator, setMode) zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "Illegal mode %ld", mode); return;/* NULL */ } - + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); intern->u.regex.mode = mode; @@ -2199,9 +2199,9 @@ SPL_METHOD(RegexIterator, getFlags) if (zend_parse_parameters_none() == FAILURE) { return; } - + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); - + RETURN_LONG(intern->u.regex.flags); } /* }}} */ @@ -2215,7 +2215,7 @@ SPL_METHOD(RegexIterator, setFlags) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &flags) == FAILURE) { return; } - + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); intern->u.regex.flags = flags; @@ -2226,11 +2226,11 @@ SPL_METHOD(RegexIterator, setFlags) SPL_METHOD(RegexIterator, getPregFlags) { spl_dual_it_object *intern; - + if (zend_parse_parameters_none() == FAILURE) { return; } - + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); if (intern->u.regex.use_flags) { @@ -2250,14 +2250,14 @@ SPL_METHOD(RegexIterator, setPregFlags) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &preg_flags) == FAILURE) { return; } - + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); intern->u.regex.preg_flags = preg_flags; intern->u.regex.use_flags = 1; } /* }}} */ -/* {{{ proto void RecursiveRegexIterator::__construct(RecursiveIterator it, string regex [, int mode [, int flags [, int preg_flags]]]) +/* {{{ proto void RecursiveRegexIterator::__construct(RecursiveIterator it, string regex [, int mode [, int flags [, int preg_flags]]]) Create an RecursiveRegexIterator from another recursive iterator and a regular expression */ SPL_METHOD(RecursiveRegexIterator, __construct) { @@ -2270,7 +2270,7 @@ SPL_METHOD(RecursiveRegexIterator, getChildren) { spl_dual_it_object *intern; zval *retval; - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -2361,7 +2361,7 @@ static void spl_dual_it_free_storage(void *_object TSRMLS_DC) if (object->inner.zobject) { zval_ptr_dtor(&object->inner.zobject); } - + if (object->dit_type == DIT_AppendIterator) { object->u.append.iterator->funcs->dtor(object->u.append.iterator TSRMLS_CC); if (object->u.append.zarrayit) { @@ -2424,7 +2424,7 @@ static zend_object_value spl_dual_it_new(zend_class_entry *class_type TSRMLS_DC) } /* }}} */ -ZEND_BEGIN_ARG_INFO(arginfo_filter_it___construct, 0) +ZEND_BEGIN_ARG_INFO(arginfo_filter_it___construct, 0) ZEND_ARG_OBJ_INFO(0, iterator, Iterator, 0) ZEND_END_ARG_INFO(); @@ -2440,7 +2440,7 @@ static const zend_function_entry spl_funcs_FilterIterator[] = { PHP_FE_END }; -ZEND_BEGIN_ARG_INFO(arginfo_callback_filter_it___construct, 0) +ZEND_BEGIN_ARG_INFO(arginfo_callback_filter_it___construct, 0) ZEND_ARG_OBJ_INFO(0, iterator, Iterator, 0) ZEND_ARG_INFO(0, callback) ZEND_END_ARG_INFO(); @@ -2451,7 +2451,7 @@ static const zend_function_entry spl_funcs_CallbackFilterIterator[] = { PHP_FE_END }; -ZEND_BEGIN_ARG_INFO(arginfo_recursive_callback_filter_it___construct, 0) +ZEND_BEGIN_ARG_INFO(arginfo_recursive_callback_filter_it___construct, 0) ZEND_ARG_OBJ_INFO(0, iterator, RecursiveIterator, 0) ZEND_ARG_INFO(0, callback) ZEND_END_ARG_INFO(); @@ -2463,7 +2463,7 @@ static const zend_function_entry spl_funcs_RecursiveCallbackFilterIterator[] = { PHP_FE_END }; -ZEND_BEGIN_ARG_INFO(arginfo_parent_it___construct, 0) +ZEND_BEGIN_ARG_INFO(arginfo_parent_it___construct, 0) ZEND_ARG_OBJ_INFO(0, iterator, RecursiveIterator, 0) ZEND_END_ARG_INFO(); @@ -2481,7 +2481,7 @@ static const zend_function_entry spl_funcs_ParentIterator[] = { }; #if HAVE_PCRE || HAVE_BUNDLED_PCRE -ZEND_BEGIN_ARG_INFO_EX(arginfo_regex_it___construct, 0, 0, 2) +ZEND_BEGIN_ARG_INFO_EX(arginfo_regex_it___construct, 0, 0, 2) ZEND_ARG_OBJ_INFO(0, iterator, Iterator, 0) ZEND_ARG_INFO(0, regex) ZEND_ARG_INFO(0, mode) @@ -2489,15 +2489,15 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_regex_it___construct, 0, 0, 2) ZEND_ARG_INFO(0, preg_flags) ZEND_END_ARG_INFO(); -ZEND_BEGIN_ARG_INFO_EX(arginfo_regex_it_set_mode, 0, 0, 1) +ZEND_BEGIN_ARG_INFO_EX(arginfo_regex_it_set_mode, 0, 0, 1) ZEND_ARG_INFO(0, mode) ZEND_END_ARG_INFO(); -ZEND_BEGIN_ARG_INFO_EX(arginfo_regex_it_set_flags, 0, 0, 1) +ZEND_BEGIN_ARG_INFO_EX(arginfo_regex_it_set_flags, 0, 0, 1) ZEND_ARG_INFO(0, flags) ZEND_END_ARG_INFO(); -ZEND_BEGIN_ARG_INFO_EX(arginfo_regex_it_set_preg_flags, 0, 0, 1) +ZEND_BEGIN_ARG_INFO_EX(arginfo_regex_it_set_preg_flags, 0, 0, 1) ZEND_ARG_INFO(0, preg_flags) ZEND_END_ARG_INFO(); @@ -2514,7 +2514,7 @@ static const zend_function_entry spl_funcs_RegexIterator[] = { PHP_FE_END }; -ZEND_BEGIN_ARG_INFO_EX(arginfo_rec_regex_it___construct, 0, 0, 2) +ZEND_BEGIN_ARG_INFO_EX(arginfo_rec_regex_it___construct, 0, 0, 2) ZEND_ARG_OBJ_INFO(0, iterator, RecursiveIterator, 0) ZEND_ARG_INFO(0, regex) ZEND_ARG_INFO(0, mode) @@ -2588,7 +2588,7 @@ SPL_METHOD(LimitIterator, __construct) spl_dual_it_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, spl_ce_LimitIterator, zend_ce_iterator, DIT_LimitIterator); } /* }}} */ -/* {{{ proto void LimitIterator::rewind() +/* {{{ proto void LimitIterator::rewind() Rewind the iterator to the specified starting offset */ SPL_METHOD(LimitIterator, rewind) { @@ -2650,7 +2650,7 @@ SPL_METHOD(LimitIterator, getPosition) RETURN_LONG(intern->current.pos); } /* }}} */ -ZEND_BEGIN_ARG_INFO(arginfo_seekable_it_seek, 0) +ZEND_BEGIN_ARG_INFO(arginfo_seekable_it_seek, 0) ZEND_ARG_INFO(0, position) ZEND_END_ARG_INFO(); @@ -2659,13 +2659,13 @@ static const zend_function_entry spl_funcs_SeekableIterator[] = { PHP_FE_END }; -ZEND_BEGIN_ARG_INFO_EX(arginfo_limit_it___construct, 0, 0, 1) +ZEND_BEGIN_ARG_INFO_EX(arginfo_limit_it___construct, 0, 0, 1) ZEND_ARG_OBJ_INFO(0, iterator, Iterator, 0) ZEND_ARG_INFO(0, offset) ZEND_ARG_INFO(0, count) ZEND_END_ARG_INFO(); -ZEND_BEGIN_ARG_INFO(arginfo_limit_it_seek, 0) +ZEND_BEGIN_ARG_INFO(arginfo_limit_it_seek, 0) ZEND_ARG_INFO(0, position) ZEND_END_ARG_INFO(); @@ -2700,7 +2700,7 @@ static inline void spl_caching_it_next(spl_dual_it_object *intern TSRMLS_DC) if (intern->u.caching.flags & CIT_FULL_CACHE) { zval *zcacheval; zval *key = intern->current.key; - + MAKE_STD_ZVAL(zcacheval); ZVAL_ZVAL(zcacheval, intern->current.data, 1, 0); @@ -2771,7 +2771,7 @@ static inline void spl_caching_it_next(spl_dual_it_object *intern TSRMLS_DC) zval_copy_ctor(intern->u.caching.zstr); } } - spl_dual_it_next(intern, 0 TSRMLS_CC); + spl_dual_it_next(intern, 0 TSRMLS_CC); } else { intern->u.caching.flags &= ~CIT_VALID; } @@ -2796,7 +2796,7 @@ SPL_METHOD(CachingIterator, __construct) SPL_METHOD(CachingIterator, rewind) { spl_dual_it_object *intern; - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -2811,7 +2811,7 @@ SPL_METHOD(CachingIterator, rewind) SPL_METHOD(CachingIterator, valid) { spl_dual_it_object *intern; - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -2826,7 +2826,7 @@ SPL_METHOD(CachingIterator, valid) SPL_METHOD(CachingIterator, next) { spl_dual_it_object *intern; - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -2841,7 +2841,7 @@ SPL_METHOD(CachingIterator, next) SPL_METHOD(CachingIterator, hasNext) { spl_dual_it_object *intern; - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -2864,10 +2864,16 @@ SPL_METHOD(CachingIterator, __toString) return; } if (intern->u.caching.flags & CIT_TOSTRING_USE_KEY) { + if (!intern->current.key) { + RETURN_EMPTY_STRING(); + } MAKE_COPY_ZVAL(&intern->current.key, return_value); convert_to_string(return_value); return; } else if (intern->u.caching.flags & CIT_TOSTRING_USE_CURRENT) { + if (!intern->current.data) { + RETURN_EMPTY_STRING(); + } MAKE_COPY_ZVAL(&intern->current.data, return_value); convert_to_string(return_value); return; @@ -2875,7 +2881,7 @@ SPL_METHOD(CachingIterator, __toString) if (intern->u.caching.zstr) { RETURN_STRINGL(Z_STRVAL_P(intern->u.caching.zstr), Z_STRLEN_P(intern->u.caching.zstr), 1); } else { - RETURN_NULL(); + RETURN_EMPTY_STRING(); } } /* }}} */ @@ -2928,7 +2934,7 @@ SPL_METHOD(CachingIterator, offsetGet) zend_error(E_NOTICE, "Undefined index: %s", arKey); return; } - + RETURN_ZVAL(*value, 1, 0); } /* }}} */ @@ -2963,14 +2969,14 @@ SPL_METHOD(CachingIterator, offsetExists) spl_dual_it_object *intern; char *arKey; uint nKeyLength; - + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); if (!(intern->u.caching.flags & CIT_FULL_CACHE)) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "%s does not use a full cache (see CachingIterator::__construct)", Z_OBJCE_P(getThis())->name); return; } - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arKey, &nKeyLength) == FAILURE) { return; } @@ -2984,11 +2990,11 @@ SPL_METHOD(CachingIterator, offsetExists) SPL_METHOD(CachingIterator, getCache) { spl_dual_it_object *intern; - + if (zend_parse_parameters_none() == FAILURE) { return; } - + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); if (!(intern->u.caching.flags & CIT_FULL_CACHE)) { @@ -3009,7 +3015,7 @@ SPL_METHOD(CachingIterator, getFlags) if (zend_parse_parameters_none() == FAILURE) { return; } - + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); RETURN_LONG(intern->u.caching.flags); @@ -3058,7 +3064,7 @@ SPL_METHOD(CachingIterator, count) if (zend_parse_parameters_none() == FAILURE) { return; } - + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); if (!(intern->u.caching.flags & CIT_FULL_CACHE)) { @@ -3070,12 +3076,12 @@ SPL_METHOD(CachingIterator, count) } /* }}} */ -ZEND_BEGIN_ARG_INFO_EX(arginfo_caching_it___construct, 0, 0, 1) +ZEND_BEGIN_ARG_INFO_EX(arginfo_caching_it___construct, 0, 0, 1) ZEND_ARG_OBJ_INFO(0, iterator, Iterator, 0) ZEND_ARG_INFO(0, flags) ZEND_END_ARG_INFO(); -ZEND_BEGIN_ARG_INFO(arginfo_caching_it_setFlags, 0) +ZEND_BEGIN_ARG_INFO(arginfo_caching_it_setFlags, 0) ZEND_ARG_INFO(0, flags) ZEND_END_ARG_INFO(); @@ -3125,7 +3131,7 @@ SPL_METHOD(RecursiveCachingIterator, hasChildren) if (zend_parse_parameters_none() == FAILURE) { return; } - + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); RETURN_BOOL(intern->u.caching.zchildren); @@ -3136,7 +3142,7 @@ SPL_METHOD(RecursiveCachingIterator, hasChildren) SPL_METHOD(RecursiveCachingIterator, getChildren) { spl_dual_it_object *intern; - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -3150,7 +3156,7 @@ SPL_METHOD(RecursiveCachingIterator, getChildren) } } /* }}} */ -ZEND_BEGIN_ARG_INFO_EX(arginfo_caching_rec_it___construct, 0, ZEND_RETURN_VALUE, 1) +ZEND_BEGIN_ARG_INFO_EX(arginfo_caching_rec_it___construct, 0, ZEND_RETURN_VALUE, 1) ZEND_ARG_OBJ_INFO(0, iterator, Iterator, 0) ZEND_ARG_INFO(0, flags) ZEND_END_ARG_INFO(); @@ -3169,7 +3175,7 @@ SPL_METHOD(IteratorIterator, __construct) spl_dual_it_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, spl_ce_IteratorIterator, zend_ce_traversable, DIT_IteratorIterator); } /* }}} */ -ZEND_BEGIN_ARG_INFO(arginfo_iterator_it___construct, 0) +ZEND_BEGIN_ARG_INFO(arginfo_iterator_it___construct, 0) ZEND_ARG_OBJ_INFO(0, iterator, Traversable, 0) ZEND_END_ARG_INFO(); @@ -3206,7 +3212,7 @@ SPL_METHOD(NoRewindIterator, rewind) SPL_METHOD(NoRewindIterator, valid) { spl_dual_it_object *intern; - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -3220,7 +3226,7 @@ SPL_METHOD(NoRewindIterator, valid) SPL_METHOD(NoRewindIterator, key) { spl_dual_it_object *intern; - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -3240,7 +3246,7 @@ SPL_METHOD(NoRewindIterator, current) { spl_dual_it_object *intern; zval **data; - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -3257,7 +3263,7 @@ SPL_METHOD(NoRewindIterator, current) SPL_METHOD(NoRewindIterator, next) { spl_dual_it_object *intern; - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -3266,7 +3272,7 @@ SPL_METHOD(NoRewindIterator, next) intern->inner.iterator->funcs->move_forward(intern->inner.iterator TSRMLS_CC); } /* }}} */ -ZEND_BEGIN_ARG_INFO(arginfo_norewind_it___construct, 0) +ZEND_BEGIN_ARG_INFO(arginfo_norewind_it___construct, 0) ZEND_ARG_OBJ_INFO(0, iterator, Iterator, 0) ZEND_END_ARG_INFO(); @@ -3293,7 +3299,7 @@ SPL_METHOD(InfiniteIterator, __construct) SPL_METHOD(InfiniteIterator, next) { spl_dual_it_object *intern; - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -3460,13 +3466,13 @@ SPL_METHOD(AppendIterator, append) SPL_METHOD(AppendIterator, rewind) { spl_dual_it_object *intern; - + if (zend_parse_parameters_none() == FAILURE) { return; } SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); - + intern->u.append.iterator->funcs->rewind(intern->u.append.iterator TSRMLS_CC); if (spl_append_it_next_iterator(intern TSRMLS_CC) == SUCCESS) { spl_append_it_fetch(intern TSRMLS_CC); @@ -3482,7 +3488,7 @@ SPL_METHOD(AppendIterator, valid) if (zend_parse_parameters_none() == FAILURE) { return; } - + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); RETURN_BOOL(intern->current.data); @@ -3493,13 +3499,13 @@ SPL_METHOD(AppendIterator, valid) SPL_METHOD(AppendIterator, next) { spl_dual_it_object *intern; - + if (zend_parse_parameters_none() == FAILURE) { return; } SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); - + spl_append_it_next(intern TSRMLS_CC); } /* }}} */ @@ -3508,7 +3514,7 @@ SPL_METHOD(AppendIterator, next) SPL_METHOD(AppendIterator, getIteratorIndex) { spl_dual_it_object *intern; - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -3524,7 +3530,7 @@ SPL_METHOD(AppendIterator, getIteratorIndex) SPL_METHOD(AppendIterator, getArrayIterator) { spl_dual_it_object *intern; - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -3534,7 +3540,7 @@ SPL_METHOD(AppendIterator, getArrayIterator) RETURN_ZVAL(intern->u.append.zarrayit, 1, 0); } /* }}} */ -ZEND_BEGIN_ARG_INFO(arginfo_append_it_append, 0) +ZEND_BEGIN_ARG_INFO(arginfo_append_it_append, 0) ZEND_ARG_OBJ_INFO(0, iterator, Iterator, 0) ZEND_END_ARG_INFO(); @@ -3637,7 +3643,7 @@ static int spl_iterator_to_values_apply(zend_object_iterator *iter, void *puser } /* }}} */ -/* {{{ proto array iterator_to_array(Traversable it [, bool use_keys = true]) +/* {{{ proto array iterator_to_array(Traversable it [, bool use_keys = true]) Copy the iterator into an array */ PHP_FUNCTION(iterator_to_array) { @@ -3663,7 +3669,7 @@ static int spl_iterator_count_apply(zend_object_iterator *iter, void *puser TSRM } /* }}} */ -/* {{{ proto int iterator_count(Traversable it) +/* {{{ proto int iterator_count(Traversable it) Count the elements in an iterator */ PHP_FUNCTION(iterator_count) { @@ -3673,7 +3679,7 @@ PHP_FUNCTION(iterator_count) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &obj, zend_ce_traversable) == FAILURE) { RETURN_FALSE; } - + if (spl_iterator_apply(obj, spl_iterator_count_apply, (void*)&count TSRMLS_CC) == SUCCESS) { RETURN_LONG(count); } @@ -3756,7 +3762,7 @@ PHP_MINIT_FUNCTION(spl_iterators) spl_handlers_dual_it.get_method = spl_dual_it_get_method; /*spl_handlers_dual_it.call_method = spl_dual_it_call_method;*/ spl_handlers_dual_it.clone_obj = NULL; - + spl_ce_RecursiveIteratorIterator->get_iterator = spl_recursive_it_get_iterator; spl_ce_RecursiveIteratorIterator->iterator_funcs.funcs = &spl_recursive_it_iterator_funcs; @@ -3796,16 +3802,16 @@ PHP_MINIT_FUNCTION(spl_iterators) REGISTER_SPL_IMPLEMENTS(CachingIterator, ArrayAccess); REGISTER_SPL_IMPLEMENTS(CachingIterator, Countable); - REGISTER_SPL_CLASS_CONST_LONG(CachingIterator, "CALL_TOSTRING", CIT_CALL_TOSTRING); - REGISTER_SPL_CLASS_CONST_LONG(CachingIterator, "CATCH_GET_CHILD", CIT_CATCH_GET_CHILD); + REGISTER_SPL_CLASS_CONST_LONG(CachingIterator, "CALL_TOSTRING", CIT_CALL_TOSTRING); + REGISTER_SPL_CLASS_CONST_LONG(CachingIterator, "CATCH_GET_CHILD", CIT_CATCH_GET_CHILD); REGISTER_SPL_CLASS_CONST_LONG(CachingIterator, "TOSTRING_USE_KEY", CIT_TOSTRING_USE_KEY); REGISTER_SPL_CLASS_CONST_LONG(CachingIterator, "TOSTRING_USE_CURRENT", CIT_TOSTRING_USE_CURRENT); REGISTER_SPL_CLASS_CONST_LONG(CachingIterator, "TOSTRING_USE_INNER", CIT_TOSTRING_USE_INNER); - REGISTER_SPL_CLASS_CONST_LONG(CachingIterator, "FULL_CACHE", CIT_FULL_CACHE); + REGISTER_SPL_CLASS_CONST_LONG(CachingIterator, "FULL_CACHE", CIT_FULL_CACHE); REGISTER_SPL_SUB_CLASS_EX(RecursiveCachingIterator, CachingIterator, spl_dual_it_new, spl_funcs_RecursiveCachingIterator); REGISTER_SPL_IMPLEMENTS(RecursiveCachingIterator, RecursiveIterator); - + REGISTER_SPL_SUB_CLASS_EX(NoRewindIterator, IteratorIterator, spl_dual_it_new, spl_funcs_NoRewindIterator); REGISTER_SPL_SUB_CLASS_EX(AppendIterator, IteratorIterator, spl_dual_it_new, spl_funcs_AppendIterator); diff --git a/ext/spl/tests/bug73073.phpt b/ext/spl/tests/bug73073.phpt new file mode 100644 index 0000000000..218a28eb70 --- /dev/null +++ b/ext/spl/tests/bug73073.phpt @@ -0,0 +1,9 @@ +--TEST-- +Bug #73073: CachingIterator null dereference when convert to string +--FILE-- + +--EXPECT-- +string(0) "" diff --git a/ext/spl/tests/spl_cachingiterator___toString_basic.phpt b/ext/spl/tests/spl_cachingiterator___toString_basic.phpt index 0395b3794d..57ca5152ed 100644 --- a/ext/spl/tests/spl_cachingiterator___toString_basic.phpt +++ b/ext/spl/tests/spl_cachingiterator___toString_basic.phpt @@ -13,4 +13,4 @@ $ci->__toString() // if conversion to string is done by echo, for example, an ex ); ?> --EXPECTF-- -NULL +string(0) "" diff --git a/ext/standard/math.c b/ext/standard/math.c index 5ffeff7a18..bb64425ee3 100644 --- a/ext/standard/math.c +++ b/ext/standard/math.c @@ -144,7 +144,7 @@ PHPAPI double _php_math_round(double value, int places, int mode) { if (!php_math_is_finite(value)) { return value; } - + places = places < INT_MIN+1 ? INT_MIN+1 : places; precision_places = 14 - php_intlog10abs(value); @@ -187,7 +187,7 @@ PHPAPI double _php_math_round(double value, int places, int mode) { /* round the temp value */ tmp_value = php_round_helper(tmp_value, mode); - + /* see if it makes sense to use simple division to round the value */ if (abs(places) < 23) { if (places > 0) { @@ -280,15 +280,15 @@ static double php_expm1(double x) /* {{{ proto int abs(int number) Return the absolute value of the number */ -PHP_FUNCTION(abs) +PHP_FUNCTION(abs) { zval **value; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &value) == FAILURE) { return; } convert_scalar_to_number_ex(value); - + if (Z_TYPE_PP(value) == IS_DOUBLE) { RETURN_DOUBLE(fabs(Z_DVAL_PP(value))); } else if (Z_TYPE_PP(value) == IS_LONG) { @@ -300,14 +300,14 @@ PHP_FUNCTION(abs) } RETURN_FALSE; } -/* }}} */ +/* }}} */ /* {{{ proto float ceil(float number) Returns the next highest integer value of the number */ -PHP_FUNCTION(ceil) +PHP_FUNCTION(ceil) { zval **value; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &value) == FAILURE) { return; } @@ -328,7 +328,7 @@ PHP_FUNCTION(ceil) PHP_FUNCTION(floor) { zval **value; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &value) == FAILURE) { return; } @@ -353,7 +353,7 @@ PHP_FUNCTION(round) long precision = 0; long mode = PHP_ROUND_HALF_UP; double return_val; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|ll", &value, &precision, &mode) == FAILURE) { return; } @@ -410,7 +410,7 @@ PHP_FUNCTION(sin) PHP_FUNCTION(cos) { double num; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &num) == FAILURE) { return; } @@ -540,7 +540,7 @@ PHP_FUNCTION(asinh) PHP_FUNCTION(acosh) { double num; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &num) == FAILURE) { return; } @@ -639,7 +639,7 @@ PHP_FUNCTION(exp) /* {{{ proto float expm1(float number) Returns exp(number) - 1, computed in a way that accurate even when the value of number is close to zero */ /* - WARNING: this function is expermental: it could change its name or + WARNING: this function is expermental: it could change its name or disappear in the next version of PHP! */ PHP_FUNCTION(expm1) @@ -654,9 +654,9 @@ PHP_FUNCTION(expm1) /* }}} */ /* {{{ proto float log1p(float number) - Returns log(1 + number), computed in a way that accurate even when the value of number is close to zero */ + Returns log(1 + number), computed in a way that accurate even when the value of number is close to zero */ /* - WARNING: this function is expermental: it could change its name or + WARNING: this function is expermental: it could change its name or disappear in the next version of PHP! */ PHP_FUNCTION(log1p) @@ -675,7 +675,7 @@ PHP_FUNCTION(log1p) PHP_FUNCTION(log) { double num, base = 0; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d|d", &num, &base) == FAILURE) { return; } @@ -683,7 +683,7 @@ PHP_FUNCTION(log) RETURN_DOUBLE(log(num)); } if (base <= 0.0) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "base must be greater than 0"); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "base must be greater than 0"); RETURN_FALSE; } if (base == 1) { @@ -721,7 +721,7 @@ PHP_FUNCTION(sqrt) /* }}} */ /* {{{ proto float hypot(float num1, float num2) - Returns sqrt(num1*num1 + num2*num2) */ + Returns sqrt(num1*num1 + num2*num2) */ PHP_FUNCTION(hypot) { double num1, num2; @@ -783,12 +783,12 @@ PHPAPI long _php_math_basetolong(zval *arg, int base) for (i = Z_STRLEN_P(arg); i > 0; i--) { c = *s++; - + digit = (c >= '0' && c <= '9') ? c - '0' : (c >= 'A' && c <= 'Z') ? c - 'A' + 10 : (c >= 'a' && c <= 'z') ? c - 'a' + 10 : base; - + if (digit >= base) { continue; } @@ -832,23 +832,23 @@ PHPAPI int _php_math_basetozval(zval *arg, int base, zval *ret) cutoff = LONG_MAX / base; cutlim = LONG_MAX % base; - + for (i = Z_STRLEN_P(arg); i > 0; i--) { c = *s++; /* might not work for EBCDIC */ - if (c >= '0' && c <= '9') + if (c >= '0' && c <= '9') c -= '0'; - else if (c >= 'A' && c <= 'Z') + else if (c >= 'A' && c <= 'Z') c -= 'A' - 10; - else if (c >= 'a' && c <= 'z') + else if (c >= 'a' && c <= 'z') c -= 'a' - 10; else continue; if (c >= base) continue; - + switch (mode) { case 0: /* Integer */ if (num < cutoff || (num == cutoff && c <= cutlim)) { @@ -861,7 +861,7 @@ PHPAPI int _php_math_basetozval(zval *arg, int base, zval *ret) /* fall-through */ case 1: /* Float */ fnum = fnum * base + c; - } + } } if (mode == 1) { @@ -937,9 +937,9 @@ PHPAPI char * _php_math_zvaltobase(zval *arg, int base TSRMLS_DC) return estrndup(ptr, end - ptr); } - + return _php_math_longtobase(arg, base); -} +} /* }}} */ /* {{{ proto int bindec(string binary_number) @@ -947,7 +947,7 @@ PHPAPI char * _php_math_zvaltobase(zval *arg, int base TSRMLS_DC) PHP_FUNCTION(bindec) { zval **arg; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &arg) == FAILURE) { return; } @@ -963,7 +963,7 @@ PHP_FUNCTION(bindec) PHP_FUNCTION(hexdec) { zval **arg; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &arg) == FAILURE) { return; } @@ -979,7 +979,7 @@ PHP_FUNCTION(hexdec) PHP_FUNCTION(octdec) { zval **arg; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &arg) == FAILURE) { return; } @@ -1050,7 +1050,7 @@ PHP_FUNCTION(base_convert) return; } convert_to_string_ex(number); - + if (frombase < 2 || frombase > 36) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid `from base' (%ld)", frombase); RETURN_FALSE; @@ -1065,10 +1065,10 @@ PHP_FUNCTION(base_convert) } result = _php_math_zvaltobase(&temp, tobase TSRMLS_CC); RETVAL_STRING(result, 0); -} +} /* }}} */ -/* {{{ _php_math_number_format +/* {{{ _php_math_number_format */ PHPAPI char *_php_math_number_format(double d, int dec, char dec_point, char thousand_sep) { @@ -1077,13 +1077,13 @@ PHPAPI char *_php_math_number_format(double d, int dec, char dec_point, char tho static char *_php_math_number_format_ex_len(double d, int dec, char *dec_point, size_t dec_point_len, char *thousand_sep, size_t thousand_sep_len, - int *result_len) + size_t *result_len) { char *tmpbuf = NULL, *resbuf; char *s, *t; /* source, target */ char *dp; - int integral; - int tmplen, reslen=0; + size_t integral; + size_t tmplen, reslen=0; int count=0; int is_negative=0; @@ -1122,15 +1122,23 @@ static char *_php_math_number_format_ex_len(double d, int dec, char *dec_point, /* allow for thousand separators */ if (thousand_sep) { + if (integral + thousand_sep_len * ((integral-1) / 3) < integral) { + /* overflow */ + zend_error(E_ERROR, "String overflow"); + } integral += thousand_sep_len * ((integral-1) / 3); } - + reslen = integral; - + if (dec) { reslen += dec; if (dec_point) { + if (reslen + dec_point < dec_point) { + /* overflow */ + zend_error(E_ERROR, "String overflow"); + } reslen += dec_point_len; } } @@ -1156,7 +1164,7 @@ static char *_php_math_number_format_ex_len(double d, int dec, char *dec_point, while (topad--) { *t-- = '0'; } - + if (dp) { s -= declen + 1; /* +1 to skip the point */ t -= declen; @@ -1188,7 +1196,7 @@ static char *_php_math_number_format_ex_len(double d, int dec, char *dec_point, } efree(tmpbuf); - + if (result_len) { *result_len = reslen; } @@ -1213,17 +1221,21 @@ PHP_FUNCTION(number_format) char *thousand_sep = NULL, *dec_point = NULL; char thousand_sep_chr = ',', dec_point_chr = '.'; int thousand_sep_len = 0, dec_point_len = 0; - + char *formatted; + size_t formatted_len; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d|ls!s!", &num, &dec, &dec_point, &dec_point_len, &thousand_sep, &thousand_sep_len) == FAILURE) { return; } switch(ZEND_NUM_ARGS()) { case 1: - RETURN_STRING(_php_math_number_format(num, 0, dec_point_chr, thousand_sep_chr), 0); + formatted = _php_math_number_format(num, 0, dec_point_chr, thousand_sep_chr); + formatted_len = strlen(formatted); break; case 2: - RETURN_STRING(_php_math_number_format(num, dec, dec_point_chr, thousand_sep_chr), 0); + formatted = _php_math_number_format(num, dec, dec_point_chr, thousand_sep_chr); + formatted_len = strlen(formatted); break; case 4: if (dec_point == NULL) { @@ -1236,15 +1248,15 @@ PHP_FUNCTION(number_format) thousand_sep_len = 1; } - Z_TYPE_P(return_value) = IS_STRING; - Z_STRVAL_P(return_value) = _php_math_number_format_ex_len(num, dec, + formatted = _php_math_number_format_ex_len(num, dec, dec_point, dec_point_len, thousand_sep, thousand_sep_len, - &Z_STRLEN_P(return_value)); + &formatted_len); break; default: WRONG_PARAM_COUNT; - break; + return; } + RETVAL_STRINGL_CHECK(formatted, formatted_len, 0); } /* }}} */ diff --git a/ext/standard/tests/serialize/bug69793.phpt b/ext/standard/tests/serialize/bug69793.phpt index b5784b89eb..ea1f0d4d9e 100644 --- a/ext/standard/tests/serialize/bug69793.phpt +++ b/ext/standard/tests/serialize/bug69793.phpt @@ -8,8 +8,6 @@ var_dump($e.""); ?> --EXPECTF-- Notice: Undefined property: Exception::$file in %s%ebug69793.php on line %d - -Notice: Undefined property: Exception::$previous in %s%ebug69793.php on line %d string(53) "exception 'Exception' in :1337 Stack trace: #0 {main}" diff --git a/main/fopen_wrappers.c b/main/fopen_wrappers.c index 74a493b2bf..af9c558b04 100644 --- a/main/fopen_wrappers.c +++ b/main/fopen_wrappers.c @@ -211,7 +211,7 @@ PHPAPI int php_check_specific_open_basedir(const char *basedir, const char *path if (path_len > 1 && path_tmp[path_len - 2] == ':') { if (path_len != 3) { return -1; - } + } /* this is c:\ */ path_tmp[path_len] = '\0'; } else { @@ -401,7 +401,7 @@ PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle TSRMLS_DC) spprintf(&filename, 0, "%s%c%s%c%s", pw->pw_dir, PHP_DIR_SEPARATOR, PG(user_dir), PHP_DIR_SEPARATOR, s + 1); /* Safe */ } else { filename = SG(request_info).path_translated; - } + } #if defined(ZTS) && defined(HAVE_GETPWNAM_R) && defined(_SC_GETPW_R_SIZE_MAX) efree(pwbuf); #endif @@ -494,8 +494,8 @@ PHPAPI char *php_resolve_path(const char *filename, int filename_length, const c return NULL; } - if ((*filename == '.' && - (IS_SLASH(filename[1]) || + if ((*filename == '.' && + (IS_SLASH(filename[1]) || ((filename[1] == '.') && IS_SLASH(filename[2])))) || IS_ABSOLUTE_PATH(filename, filename_length) || !path || @@ -522,7 +522,7 @@ PHPAPI char *php_resolve_path(const char *filename, int filename_length, const c } end = strchr(p, DEFAULT_DIR_SEPARATOR); if (end) { - if ((end-ptr) + 1 + filename_length + 1 >= MAXPATHLEN) { + if (filename_length > (MAXPATHLEN - 2) || (end-ptr) > MAXPATHLEN || (end-ptr) + 1 + (size_t)filename_length + 1 >= MAXPATHLEN) { ptr = end + 1; continue; } @@ -531,9 +531,9 @@ PHPAPI char *php_resolve_path(const char *filename, int filename_length, const c memcpy(trypath+(end-ptr)+1, filename, filename_length+1); ptr = end+1; } else { - int len = strlen(ptr); + size_t len = strlen(ptr); - if (len + 1 + filename_length + 1 >= MAXPATHLEN) { + if (filename_length > (MAXPATHLEN - 2) || len > MAXPATHLEN || (size_t)len + 1 + (size_t)filename_length + 1 >= MAXPATHLEN) { break; } memcpy(trypath, ptr, len); @@ -571,6 +571,7 @@ PHPAPI char *php_resolve_path(const char *filename, int filename_length, const c while ((--exec_fname_length >= 0) && !IS_SLASH(exec_fname[exec_fname_length])); if (exec_fname && exec_fname[0] != '[' && exec_fname_length > 0 && + filename_length < (MAXPATHLEN - 2) && exec_fname_length + 1 + filename_length + 1 < MAXPATHLEN) { memcpy(trypath, exec_fname, exec_fname_length + 1); memcpy(trypath+exec_fname_length + 1, filename, filename_length+1); -- cgit v1.2.1