diff options
author | Stanley Sufficool <ssufficool@php.net> | 2013-07-14 11:10:36 -0700 |
---|---|---|
committer | Stanley Sufficool <ssufficool@php.net> | 2013-07-14 11:10:36 -0700 |
commit | 6e32a871a4a08c4c95ff61fb2be0d3f158882aea (patch) | |
tree | 805ef320254a391d5d03d1a3617c1b23042d7f2a | |
parent | 598e2690b81a145589f6dfe06f77d9e3b66a7853 (diff) | |
parent | e2e002d4ea7618039cabe925133760966c70b2a7 (diff) | |
download | php-git-6e32a871a4a08c4c95ff61fb2be0d3f158882aea.tar.gz |
Merge branch 'PHP-5.3' of https://git.php.net/push/php-src into PHP-5.3
* 'PHP-5.3' of https://git.php.net/push/php-src: (23 commits)
Merge PHP 5.3.27 NEWS
add test for bug #65236
truncate results at depth of 255 to prevent corruption
fix assembly of safe_address() for x86 and x86_64
Add bison 2.6.4 to the list of supported versions
Update git rules (5.5 is stable, 5.3 sec only)
This will be PHP 5.3.28
Fixed bug #63186 (compile failure on netbsd)
ensure the error_reporting level to get expected notice
fixed tests
missing tests for bug #53437
missing colon
Backported the fix for bug #53437
Fixed test script
Fixed bug #64997 (Segfault while using RecursiveIteratorIterator on 64-bits systems)
Fixed bug #64966 (segfault in zend_do_fcall_common_helper_SPEC)
Fixed bug #64934 Apache2 TS crash with get_browser()
Add NEWS for PHP 5.3.26
Fixed bug #64960 (Segfault in gc_zval_possible_root)
fix CVE-2013-2110 - use correct formula to calculate string size
...
42 files changed, 1262 insertions, 122 deletions
@@ -1,6 +1,18 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -?? ??? 2013, PHP 5.3.27 +?? ??? 2013, PHP 5.3.28 + +11 Jul 2013, PHP 5.3.27 + +- Core: + . Fixed bug #64966 (segfault in zend_do_fcall_common_helper_SPEC). (Laruence) + . Fixed bug #64960 (Segfault in gc_zval_possible_root). (Laruence) + . Fixed bug #64934 (Apache2 TS crash with get_browser()). (Anatol) + . Fixed bug #63186 (compile failure on netbsd). (Matteo) + +- DateTime: + . Fixed bug #53437 (Crash when using unserialized DatePeriod instance). + (Gustavo, Derick, Anatol) - PDO_firebird: . Fixed bug #64037 (Firebird return wrong value for numeric field). @@ -11,9 +23,21 @@ PHP NEWS - PDO_pgsql: . Fixed bug #64949 (Buffer overflow in _pdo_pgsql_error). (Remi) -?? ??? 2013, PHP 5.3.26 +- pgsql: + . Fixed bug #64609 (pg_convert enum type support). (Matteo) -### DO NOT ADD ENTRIES HERE, ADD THEM ABOVE FOR 5.3.27 ### +- SPL: + . Fixed bug #64997 (Segfault while using RecursiveIteratorIterator on + 64-bits systems). (Laruence) + +- XML: + . Fixed bug #65236 (heap corruption in xml parser). (Rob) + +06 Jun 2013, PHP 5.3.26 + +- Core: + . Fixed bug #64879 (Heap based buffer overflow in quoted_printable_encode, + CVE 2013-2110). (Stas) - Calendar: . Fixed bug #64895 (Integer overflow in SndToJewish). (Remi) diff --git a/README.GIT-RULES b/README.GIT-RULES index 289a4e743f..6e90aa97b6 100644 --- a/README.GIT-RULES +++ b/README.GIT-RULES @@ -45,14 +45,17 @@ Currently we have the following branches in use:: master The active development branch. - PHP-5.4 Is used to release the PHP 5.4.x series. It still allows for - larger enhancements. + PHP-5.5 Is used to release the PHP 5.5.x series. This is a current + stable version and is open for bugfixes only. - PHP-5.3 Is used to release the PHP 5.3.x series. This is current + PHP-5.4 Is used to release the PHP 5.4.x series. This is a current stable version and is open for bugfixes only. - PHP-5.2 Is used to release the PHP 5.2.x series. It is closed for - changes now. + PHP-5.3 Is used to release the PHP 5.3.x series. This is currently + in extended support and open forsecurity fixes only. Triaged + via security@php.net + + PHP-5.2 This branch is closed. PHP-5.1 This branch is closed. diff --git a/Zend/acinclude.m4 b/Zend/acinclude.m4 index 136d2d8bef..77430aba79 100644 --- a/Zend/acinclude.m4 +++ b/Zend/acinclude.m4 @@ -4,7 +4,7 @@ dnl This file contains local autoconf functions. AC_DEFUN([LIBZEND_BISON_CHECK],[ # we only support certain bison versions - bison_version_list="1.28 1.35 1.75 1.875 2.0 2.1 2.2 2.3 2.4 2.4.1 2.4.2 2.4.3 2.5 2.5.1 2.6 2.6.1 2.6.2" + bison_version_list="1.28 1.35 1.75 1.875 2.0 2.1 2.2 2.3 2.4 2.4.1 2.4.2 2.4.3 2.5 2.5.1 2.6 2.6.1 2.6.2 2.6.4" # for standalone build of Zend Engine test -z "$SED" && SED=sed diff --git a/Zend/tests/bug64960.phpt b/Zend/tests/bug64960.phpt new file mode 100644 index 0000000000..b31cca3dc6 --- /dev/null +++ b/Zend/tests/bug64960.phpt @@ -0,0 +1,40 @@ +--TEST-- +Bug #64960 (Segfault in gc_zval_possible_root) +--FILE-- +<?php +// this makes ob_end_clean raise an error +ob_end_flush(); + +class ExceptionHandler { + public function __invoke (Exception $e) + { + // this triggers the custom error handler + ob_end_clean(); + } +} + +// this must be a class, closure does not trigger segfault +set_exception_handler(new ExceptionHandler()); + +// exception must be throwed from error handler. +set_error_handler(function() +{ + $e = new Exception; + $e->_trace = debug_backtrace(); + + throw $e; +}); + +// trigger error handler +$a['waa']; +?> +--EXPECTF-- +Notice: ob_end_flush(): failed to delete and flush buffer. No buffer to delete or flush in %sbug64960.php on line 3 + +Fatal error: Uncaught exception 'Exception' in %sbug64960.php:19 +Stack trace: +#0 [internal function]: {closure}(8, 'ob_end_clean():...', '%s', 9, Array) +#1 %sbug64960.php(9): ob_end_clean() +#2 [internal function]: ExceptionHandler->__invoke(Object(Exception)) +#3 {main} + thrown in %sbug64960.php on line 19 diff --git a/Zend/tests/bug64966.phpt b/Zend/tests/bug64966.phpt new file mode 100644 index 0000000000..c1cdbbf812 --- /dev/null +++ b/Zend/tests/bug64966.phpt @@ -0,0 +1,30 @@ +--TEST-- +Bug #64966 (segfault in zend_do_fcall_common_helper_SPEC) +--FILE-- +<?php +error_reporting(E_ALL); +set_error_handler(function($error) { throw new Exception(); }, E_RECOVERABLE_ERROR); + +function test($func) { + $a = $func(""); + return true; +} +class A { + public function b() { + test("strlen"); + test("iterator_apply"); + } +} + +$a = new A(); +$a->b(); +?> +--EXPECTF-- +Fatal error: Uncaught exception 'Exception' in %sbug64966.php:3 +Stack trace: +#0 [internal function]: {closure}(4096, 'Argument 1 pass...', '%s', 6, Array) +#1 %sbug64966.php(6): iterator_apply('') +#2 %sbug64966.php(12): test('iterator_apply') +#3 %sbug64966.php(17): A->b() +#4 {main} + thrown in %sbug64966.php on line 3 diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index 02e84ee1e6..e86b3e7c58 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -2386,7 +2386,7 @@ static inline size_t safe_address(size_t nmemb, size_t size, size_t offset) size_t res = nmemb; unsigned long overflow = 0; - __asm__ ("mull %3\n\taddl %4,%0\n\tadcl %1,%1" + __asm__ ("mull %3\n\taddl %4,%0\n\tadcl $0,%1" : "=&a"(res), "=&d" (overflow) : "%0"(res), "rm"(size), @@ -2406,7 +2406,7 @@ static inline size_t safe_address(size_t nmemb, size_t size, size_t offset) size_t res = nmemb; unsigned long overflow = 0; - __asm__ ("mulq %3\n\taddq %4,%0\n\tadcq %1,%1" + __asm__ ("mulq %3\n\taddq %4,%0\n\tadcq $0,%1" : "=&a"(res), "=&d" (overflow) : "%0"(res), "rm"(size), diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 97818895ef..687520d1a4 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -263,15 +263,13 @@ void shutdown_executor(TSRMLS_D) /* {{{ */ if (EG(user_error_handler)) { zeh = EG(user_error_handler); EG(user_error_handler) = NULL; - zval_dtor(zeh); - FREE_ZVAL(zeh); + zval_ptr_dtor(&zeh); } if (EG(user_exception_handler)) { zeh = EG(user_exception_handler); EG(user_exception_handler) = NULL; - zval_dtor(zeh); - FREE_ZVAL(zeh); + zval_ptr_dtor(&zeh); } zend_stack_destroy(&EG(user_error_handlers_error_reporting)); diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 02566f365d..d471f399e0 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -2327,6 +2327,8 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY) if (!RETURN_VALUE_USED(opline)) { zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr); } + } else if (RETURN_VALUE_USED(opline)) { + EX_T(opline->result.u.var).var.ptr = NULL; } } else if (EX(function_state).function->type == ZEND_USER_FUNCTION) { EX(original_return_value) = EG(return_value_ptr_ptr); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index f6220b0f53..993b822aa7 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -327,6 +327,8 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR if (!RETURN_VALUE_USED(opline)) { zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr); } + } else if (RETURN_VALUE_USED(opline)) { + EX_T(opline->result.u.var).var.ptr = NULL; } } else if (EX(function_state).function->type == ZEND_USER_FUNCTION) { EX(original_return_value) = EG(return_value_ptr_ptr); diff --git a/configure.in b/configure.in index 0d9eff8339..8a0aa45a9d 100644 --- a/configure.in +++ b/configure.in @@ -41,7 +41,7 @@ AC_CONFIG_HEADER(main/php_config.h) PHP_MAJOR_VERSION=5 PHP_MINOR_VERSION=3 -PHP_RELEASE_VERSION=27 +PHP_RELEASE_VERSION=28 PHP_EXTRA_VERSION="-dev" PHP_VERSION="$PHP_MAJOR_VERSION.$PHP_MINOR_VERSION.$PHP_RELEASE_VERSION$PHP_EXTRA_VERSION" PHP_VERSION_ID=`expr [$]PHP_MAJOR_VERSION \* 10000 + [$]PHP_MINOR_VERSION \* 100 + [$]PHP_RELEASE_VERSION` diff --git a/ext/date/php_date.c b/ext/date/php_date.c index e27be7d81e..75bdf33121 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -39,6 +39,20 @@ static __inline __int64_t php_date_llabs( __int64_t i ) { return i >= 0 ? i : -i static inline long long php_date_llabs( long long i ) { return i >= 0 ? i : -i; } #endif +#ifdef PHP_WIN32 +#define DATE_I64_BUF_LEN 65 +# define DATE_I64A(i, s, len) _i64toa_s(i, s, len, 10) +# define DATE_A64I(i, s) i = _atoi64(s) +#else +#define DATE_I64_BUF_LEN 65 +# define DATE_I64A(i, s, len) \ + do { \ + int st = snprintf(s, len, "%lld", i); \ + s[st] = '\0'; \ + } while (0); +# define DATE_A64I(i, s) i = atoll(s) +#endif + /* {{{ arginfo */ ZEND_BEGIN_ARG_INFO_EX(arginfo_date, 0, 0, 1) ZEND_ARG_INFO(0, format) @@ -472,6 +486,8 @@ const zend_function_entry date_funcs_interval[] = { const zend_function_entry date_funcs_period[] = { PHP_ME(DatePeriod, __construct, arginfo_date_period_construct, ZEND_ACC_CTOR|ZEND_ACC_PUBLIC) + PHP_ME(DatePeriod, __wakeup, NULL, ZEND_ACC_PUBLIC) + PHP_ME(DatePeriod, __set_state, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) PHP_FE_END }; @@ -565,9 +581,12 @@ static zend_object_value date_object_clone_period(zval *this_ptr TSRMLS_DC); static int date_object_compare_date(zval *d1, zval *d2 TSRMLS_DC); static HashTable *date_object_get_properties(zval *object TSRMLS_DC); static HashTable *date_object_get_properties_interval(zval *object TSRMLS_DC); +static HashTable *date_object_get_properties_period(zval *object TSRMLS_DC); zval *date_interval_read_property(zval *object, zval *member, int type TSRMLS_DC); void date_interval_write_property(zval *object, zval *member, zval *value TSRMLS_DC); +static zval *date_period_read_property(zval *object, zval *member, int type TSRMLS_DC); +static void date_period_write_property(zval *object, zval *member, zval *value TSRMLS_DC); /* {{{ Module struct */ zend_module_entry date_module_entry = { @@ -2015,6 +2034,10 @@ static void date_register_classes(TSRMLS_D) zend_class_implements(date_ce_period TSRMLS_CC, 1, zend_ce_traversable); memcpy(&date_object_handlers_period, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); date_object_handlers_period.clone_obj = date_object_clone_period; + date_object_handlers_period.get_properties = date_object_get_properties_period; + date_object_handlers_period.get_property_ptr_ptr = NULL; + date_object_handlers_period.read_property = date_period_read_property; + date_object_handlers_period.write_property = date_period_write_property; #define REGISTER_PERIOD_CLASS_CONST_STRING(const_name, value) \ zend_declare_class_constant_long(date_ce_period, const_name, sizeof(const_name)-1, value TSRMLS_CC); @@ -2250,7 +2273,6 @@ static HashTable *date_object_get_properties_interval(zval *object TSRMLS_DC) zval *zv; php_interval_obj *intervalobj; - intervalobj = (php_interval_obj *) zend_object_store_get_object(object TSRMLS_CC); props = zend_std_get_properties(object TSRMLS_CC); @@ -2261,7 +2283,7 @@ static HashTable *date_object_get_properties_interval(zval *object TSRMLS_DC) #define PHP_DATE_INTERVAL_ADD_PROPERTY(n,f) \ MAKE_STD_ZVAL(zv); \ - ZVAL_LONG(zv, intervalobj->diff->f); \ + ZVAL_LONG(zv, (long)intervalobj->diff->f); \ zend_hash_update(props, n, strlen(n) + 1, &zv, sizeof(zval), NULL); PHP_DATE_INTERVAL_ADD_PROPERTY("y", y); @@ -2270,6 +2292,9 @@ static HashTable *date_object_get_properties_interval(zval *object TSRMLS_DC) PHP_DATE_INTERVAL_ADD_PROPERTY("h", h); PHP_DATE_INTERVAL_ADD_PROPERTY("i", i); PHP_DATE_INTERVAL_ADD_PROPERTY("s", s); + PHP_DATE_INTERVAL_ADD_PROPERTY("weekday", weekday); + PHP_DATE_INTERVAL_ADD_PROPERTY("weekday_behavior", weekday_behavior); + PHP_DATE_INTERVAL_ADD_PROPERTY("first_last_day_of", first_last_day_of); PHP_DATE_INTERVAL_ADD_PROPERTY("invert", invert); if (intervalobj->diff->days != -99999) { PHP_DATE_INTERVAL_ADD_PROPERTY("days", days); @@ -2278,6 +2303,10 @@ static HashTable *date_object_get_properties_interval(zval *object TSRMLS_DC) ZVAL_FALSE(zv); zend_hash_update(props, "days", 5, &zv, sizeof(zval), NULL); } + PHP_DATE_INTERVAL_ADD_PROPERTY("special_type", special.type); + PHP_DATE_INTERVAL_ADD_PROPERTY("special_amount", special.amount); + PHP_DATE_INTERVAL_ADD_PROPERTY("have_weekday_relative", have_weekday_relative); + PHP_DATE_INTERVAL_ADD_PROPERTY("have_special_relative", have_special_relative); return props; } @@ -2380,6 +2409,7 @@ PHPAPI zval *php_date_instantiate(zend_class_entry *pce, zval *object TSRMLS_DC) object_init_ex(object, pce); Z_SET_REFCOUNT_P(object, 1); Z_UNSET_ISREF_P(object); + return object; } @@ -3649,30 +3679,48 @@ PHP_METHOD(DateInterval, __construct) } /* }}} */ -static long php_date_long_from_hash_element(HashTable *myht, char *element, size_t size) -{ - zval **z_arg = NULL; - - if (zend_hash_find(myht, element, size + 1, (void**) &z_arg) == SUCCESS) { - convert_to_long(*z_arg); - return Z_LVAL_PP(z_arg); - } else { - return -1; - } -} static int php_date_interval_initialize_from_hash(zval **return_value, php_interval_obj **intobj, HashTable *myht TSRMLS_DC) { (*intobj)->diff = timelib_rel_time_ctor(); - (*intobj)->diff->y = php_date_long_from_hash_element(myht, "y", 1); - (*intobj)->diff->m = php_date_long_from_hash_element(myht, "m", 1); - (*intobj)->diff->d = php_date_long_from_hash_element(myht, "d", 1); - (*intobj)->diff->h = php_date_long_from_hash_element(myht, "h", 1); - (*intobj)->diff->i = php_date_long_from_hash_element(myht, "i", 1); - (*intobj)->diff->s = php_date_long_from_hash_element(myht, "s", 1); - (*intobj)->diff->invert = php_date_long_from_hash_element(myht, "invert", 6); - (*intobj)->diff->days = php_date_long_from_hash_element(myht, "days", 4); +#define PHP_DATE_INTERVAL_READ_PROPERTY(element, member, itype, def) \ + do { \ + zval **z_arg = NULL; \ + if (zend_hash_find(myht, element, strlen(element) + 1, (void**) &z_arg) == SUCCESS) { \ + convert_to_long(*z_arg); \ + (*intobj)->diff->member = (itype)Z_LVAL_PP(z_arg); \ + } else { \ + (*intobj)->diff->member = (itype)def; \ + } \ + } while (0); + +#define PHP_DATE_INTERVAL_READ_PROPERTY_I64(element, member) \ + do { \ + zval **z_arg = NULL; \ + if (zend_hash_find(myht, element, strlen(element) + 1, (void**) &z_arg) == SUCCESS) { \ + convert_to_string(*z_arg); \ + DATE_A64I((*intobj)->diff->member, Z_STRVAL_PP(z_arg)); \ + } else { \ + (*intobj)->diff->member = -1LL; \ + } \ + } while (0); + + PHP_DATE_INTERVAL_READ_PROPERTY("y", y, timelib_sll, -1) + PHP_DATE_INTERVAL_READ_PROPERTY("m", m, timelib_sll, -1) + PHP_DATE_INTERVAL_READ_PROPERTY("d", d, timelib_sll, -1) + PHP_DATE_INTERVAL_READ_PROPERTY("h", h, timelib_sll, -1) + PHP_DATE_INTERVAL_READ_PROPERTY("i", i, timelib_sll, -1) + PHP_DATE_INTERVAL_READ_PROPERTY("s", s, timelib_sll, -1) + PHP_DATE_INTERVAL_READ_PROPERTY("weekday", weekday, int, -1) + PHP_DATE_INTERVAL_READ_PROPERTY("weekday_behavior", weekday_behavior, int, -1) + PHP_DATE_INTERVAL_READ_PROPERTY("first_last_day_of", first_last_day_of, int, -1) + PHP_DATE_INTERVAL_READ_PROPERTY("invert", invert, int, 0); + PHP_DATE_INTERVAL_READ_PROPERTY_I64("days", days); + PHP_DATE_INTERVAL_READ_PROPERTY("special_type", special.type, unsigned int, 0); + PHP_DATE_INTERVAL_READ_PROPERTY_I64("special_amount", special.amount); + PHP_DATE_INTERVAL_READ_PROPERTY("have_weekday_relative", have_weekday_relative, unsigned int, 0); + PHP_DATE_INTERVAL_READ_PROPERTY("have_special_relative", have_special_relative, unsigned int, 0); (*intobj)->initialized = 1; return 0; @@ -4276,6 +4324,223 @@ PHP_FUNCTION(date_sun_info) timelib_time_dtor(t2); } /* }}} */ + + +static HashTable *date_object_get_properties_period(zval *object TSRMLS_DC) +{ + HashTable *props; + zval *zv; + php_period_obj *period_obj; + + period_obj = zend_object_store_get_object(object TSRMLS_CC); + + props = zend_std_get_properties(object TSRMLS_CC); + + if (!period_obj->start) { + return props; + } + + MAKE_STD_ZVAL(zv); + if (period_obj->start) { + php_date_obj *date_obj; + object_init_ex(zv, date_ce_date); + date_obj = zend_object_store_get_object(zv TSRMLS_CC); + date_obj->time = timelib_time_clone(period_obj->start); + } else { + ZVAL_NULL(zv); + } + zend_hash_update(props, "start", sizeof("start"), &zv, sizeof(zv), NULL); + + MAKE_STD_ZVAL(zv); + if (period_obj->current) { + php_date_obj *date_obj; + object_init_ex(zv, date_ce_date); + date_obj = zend_object_store_get_object(zv TSRMLS_CC); + date_obj->time = timelib_time_clone(period_obj->current); + } else { + ZVAL_NULL(zv); + } + zend_hash_update(props, "current", sizeof("current"), &zv, sizeof(zv), NULL); + + MAKE_STD_ZVAL(zv); + if (period_obj->end) { + php_date_obj *date_obj; + object_init_ex(zv, date_ce_date); + date_obj = zend_object_store_get_object(zv TSRMLS_CC); + date_obj->time = timelib_time_clone(period_obj->end); + } else { + ZVAL_NULL(zv); + } + zend_hash_update(props, "end", sizeof("end"), &zv, sizeof(zv), NULL); + + MAKE_STD_ZVAL(zv); + if (period_obj->interval) { + php_interval_obj *interval_obj; + object_init_ex(zv, date_ce_interval); + interval_obj = zend_object_store_get_object(zv TSRMLS_CC); + interval_obj->diff = timelib_rel_time_clone(period_obj->interval); + interval_obj->initialized = 1; + } else { + ZVAL_NULL(zv); + } + zend_hash_update(props, "interval", sizeof("interval"), &zv, sizeof(zv), NULL); + + /* converted to larger type (int->long); must check when unserializing */ + MAKE_STD_ZVAL(zv); + ZVAL_LONG(zv, (long) period_obj->recurrences); + zend_hash_update(props, "recurrences", sizeof("recurrences"), &zv, sizeof(zv), NULL); + + MAKE_STD_ZVAL(zv); + ZVAL_BOOL(zv, period_obj->include_start_date); + zend_hash_update(props, "include_start_date", sizeof("include_start_date"), &zv, sizeof(zv), NULL); + + return props; +} + +static int php_date_period_initialize_from_hash(php_period_obj *period_obj, HashTable *myht TSRMLS_DC) +{ + zval **ht_entry; + + /* this function does no rollback on error */ + + if (zend_hash_find(myht, "start", sizeof("start"), (void**) &ht_entry) == SUCCESS) { + if (Z_TYPE_PP(ht_entry) == IS_OBJECT && Z_OBJCE_PP(ht_entry) == date_ce_date) { + php_date_obj *date_obj; + date_obj = zend_object_store_get_object(*ht_entry TSRMLS_CC); + period_obj->start = timelib_time_clone(date_obj->time); + } else if (Z_TYPE_PP(ht_entry) != IS_NULL) { + return 0; + } + } else { + return 0; + } + + if (zend_hash_find(myht, "end", sizeof("end"), (void**) &ht_entry) == SUCCESS) { + if (Z_TYPE_PP(ht_entry) == IS_OBJECT && Z_OBJCE_PP(ht_entry) == date_ce_date) { + php_date_obj *date_obj; + date_obj = zend_object_store_get_object(*ht_entry TSRMLS_CC); + period_obj->end = timelib_time_clone(date_obj->time); + } else if (Z_TYPE_PP(ht_entry) != IS_NULL) { + return 0; + } + } else { + return 0; + } + + if (zend_hash_find(myht, "current", sizeof("current"), (void**) &ht_entry) == SUCCESS) { + if (Z_TYPE_PP(ht_entry) == IS_OBJECT && Z_OBJCE_PP(ht_entry) == date_ce_date) { + php_date_obj *date_obj; + date_obj = zend_object_store_get_object(*ht_entry TSRMLS_CC); + period_obj->current = timelib_time_clone(date_obj->time); + } else if (Z_TYPE_PP(ht_entry) != IS_NULL) { + return 0; + } + } else { + return 0; + } + + if (zend_hash_find(myht, "interval", sizeof("interval"), (void**) &ht_entry) == SUCCESS) { + if (Z_TYPE_PP(ht_entry) == IS_OBJECT && Z_OBJCE_PP(ht_entry) == date_ce_interval) { + php_interval_obj *interval_obj; + interval_obj = zend_object_store_get_object(*ht_entry TSRMLS_CC); + period_obj->interval = timelib_rel_time_clone(interval_obj->diff); + } else { /* interval is required */ + return 0; + } + } else { + return 0; + } + + if (zend_hash_find(myht, "recurrences", sizeof("recurrences"), (void**) &ht_entry) == SUCCESS && + Z_TYPE_PP(ht_entry) == IS_LONG && Z_LVAL_PP(ht_entry) >= 0 && Z_LVAL_PP(ht_entry) <= INT_MAX) { + period_obj->recurrences = Z_LVAL_PP(ht_entry); + } else { + return 0; + } + + if (zend_hash_find(myht, "include_start_date", sizeof("include_start_date"), (void**) &ht_entry) == SUCCESS && + Z_TYPE_PP(ht_entry) == IS_BOOL) { + period_obj->include_start_date = Z_BVAL_PP(ht_entry); + } else { + return 0; + } + + period_obj->initialized = 1; + + return 1; +} + +/* {{{ proto DatePeriod::__set_state() +*/ +PHP_METHOD(DatePeriod, __set_state) +{ + php_period_obj *period_obj; + zval *array; + HashTable *myht; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == FAILURE) { + RETURN_FALSE; + } + + myht = Z_ARRVAL_P(array); + + object_init_ex(return_value, date_ce_period); + period_obj = zend_object_store_get_object(return_value TSRMLS_CC); + if (!php_date_period_initialize_from_hash(period_obj, myht TSRMLS_CC)) { + php_error(E_ERROR, "Invalid serialization data for DatePeriod object"); + } +} +/* }}} */ + +/* {{{ proto DatePeriod::__wakeup() +*/ +PHP_METHOD(DatePeriod, __wakeup) +{ + zval *object = getThis(); + php_period_obj *period_obj; + HashTable *myht; + + period_obj = zend_object_store_get_object(object TSRMLS_CC); + + myht = Z_OBJPROP_P(object); + + if (!php_date_period_initialize_from_hash(period_obj, myht TSRMLS_CC)) { + php_error(E_ERROR, "Invalid serialization data for DatePeriod object"); + } +} +/* }}} */ + +/* {{{ date_period_read_property */ +static zval *date_period_read_property(zval *object, zval *member, int type TSRMLS_DC) +{ + zval *zv; + if (type != BP_VAR_IS && type != BP_VAR_R) { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Retrieval of DatePeriod properties for modification is unsupported"); + } + + Z_OBJPROP_P(object); /* build properties hash table */ + + zv = std_object_handlers.read_property(object, member, type TSRMLS_CC); + if (Z_TYPE_P(zv) == IS_OBJECT && Z_OBJ_HANDLER_P(zv, clone_obj)) { + /* defensive copy */ + zend_object_value zov = Z_OBJ_HANDLER_P(zv, clone_obj)(zv TSRMLS_CC); + MAKE_STD_ZVAL(zv); + Z_TYPE_P(zv) = IS_OBJECT; + Z_OBJVAL_P(zv) = zov; + } + + return zv; +} +/* }}} */ + +/* {{{ date_period_write_property */ +static void date_period_write_property(zval *object, zval *member, zval *value TSRMLS_DC) +{ + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Writing to DatePeriod properties is unsupported"); +} +/* }}} */ + + /* * Local variables: * tab-width: 4 diff --git a/ext/date/php_date.h b/ext/date/php_date.h index a86d6c7e70..16837df2a9 100644 --- a/ext/date/php_date.h +++ b/ext/date/php_date.h @@ -88,6 +88,8 @@ PHP_FUNCTION(date_interval_format); PHP_FUNCTION(date_interval_create_from_date_string); PHP_METHOD(DatePeriod, __construct); +PHP_METHOD(DatePeriod, __wakeup); +PHP_METHOD(DatePeriod, __set_state); /* Options and Configuration */ PHP_FUNCTION(date_default_timezone_set); diff --git a/ext/date/tests/bug45682.phpt b/ext/date/tests/bug45682.phpt index d8bbfc5a04..ea8fa94706 100644 --- a/ext/date/tests/bug45682.phpt +++ b/ext/date/tests/bug45682.phpt @@ -11,8 +11,8 @@ $other = new DateTime("31-July-2008"); $diff = date_diff($date, $other); var_dump($diff); ---EXPECT-- -object(DateInterval)#3 (8) { +--EXPECTF-- +object(DateInterval)#%d (15) { ["y"]=> int(0) ["m"]=> @@ -25,8 +25,22 @@ object(DateInterval)#3 (8) { int(0) ["s"]=> int(0) + ["weekday"]=> + int(0) + ["weekday_behavior"]=> + int(0) + ["first_last_day_of"]=> + int(0) ["invert"]=> int(0) ["days"]=> int(3) + ["special_type"]=> + int(0) + ["special_amount"]=> + int(0) + ["have_weekday_relative"]=> + int(0) + ["have_special_relative"]=> + int(0) } diff --git a/ext/date/tests/bug48678.phpt b/ext/date/tests/bug48678.phpt index e2cb724f76..253cb84ce6 100644 --- a/ext/date/tests/bug48678.phpt +++ b/ext/date/tests/bug48678.phpt @@ -15,8 +15,15 @@ DateInterval Object [h] => 12 [i] => 30 [s] => 5 + [weekday] => 0 + [weekday_behavior] => 0 + [first_last_day_of] => 0 [invert] => 0 - [days] =>%s + [days] => + [special_type] => 0 + [special_amount] => 0 + [have_weekday_relative] => 0 + [have_special_relative] => 0 ) DateInterval Object ( @@ -26,6 +33,13 @@ DateInterval Object [h] => 12 [i] => 30 [s] => 5 + [weekday] => 0 + [weekday_behavior] => 0 + [first_last_day_of] => 0 [invert] => 0 - [days] =>%s + [days] => 0 + [special_type] => 0 + [special_amount] => 0 + [have_weekday_relative] => 0 + [have_special_relative] => 0 ) diff --git a/ext/date/tests/bug49081.phpt b/ext/date/tests/bug49081.phpt index f4f02903d1..31f7351481 100644 --- a/ext/date/tests/bug49081.phpt +++ b/ext/date/tests/bug49081.phpt @@ -17,6 +17,13 @@ DateInterval Object [h] => 4 [i] => 0 [s] => 0 + [weekday] => 0 + [weekday_behavior] => 0 + [first_last_day_of] => 0 [invert] => 0 [days] => 30 + [special_type] => 0 + [special_amount] => 0 + [have_weekday_relative] => 0 + [have_special_relative] => 0 ) diff --git a/ext/date/tests/bug49778.phpt b/ext/date/tests/bug49778.phpt index 67c8e27f91..2062d69168 100644 --- a/ext/date/tests/bug49778.phpt +++ b/ext/date/tests/bug49778.phpt @@ -8,7 +8,7 @@ echo $i->format("%d"), "\n"; echo $i->format("%a"), "\n"; ?> --EXPECT-- -object(DateInterval)#1 (8) { +object(DateInterval)#1 (15) { ["y"]=> int(0) ["m"]=> @@ -21,10 +21,24 @@ object(DateInterval)#1 (8) { int(0) ["s"]=> int(0) + ["weekday"]=> + int(0) + ["weekday_behavior"]=> + int(0) + ["first_last_day_of"]=> + int(0) ["invert"]=> int(0) ["days"]=> bool(false) + ["special_type"]=> + int(0) + ["special_amount"]=> + int(0) + ["have_weekday_relative"]=> + int(0) + ["have_special_relative"]=> + int(0) } 7 (unknown) diff --git a/ext/date/tests/bug52113.phpt b/ext/date/tests/bug52113.phpt index a7d9339d13..f4730c6a44 100644 --- a/ext/date/tests/bug52113.phpt +++ b/ext/date/tests/bug52113.phpt @@ -32,7 +32,7 @@ var_dump($unser, $p); ?> --EXPECT-- -object(DateInterval)#3 (8) { +object(DateInterval)#3 (15) { ["y"]=> int(0) ["m"]=> @@ -45,12 +45,26 @@ object(DateInterval)#3 (8) { int(0) ["s"]=> int(0) + ["weekday"]=> + int(0) + ["weekday_behavior"]=> + int(0) + ["first_last_day_of"]=> + int(0) ["invert"]=> int(0) ["days"]=> int(0) + ["special_type"]=> + int(0) + ["special_amount"]=> + int(0) + ["have_weekday_relative"]=> + int(0) + ["have_special_relative"]=> + int(0) } -string(128) "O:12:"DateInterval":8:{s:1:"y";i:0;s:1:"m";i:0;s:1:"d";i:0;s:1:"h";i:4;s:1:"i";i:0;s:1:"s";i:0;s:6:"invert";i:0;s:4:"days";i:0;}" +string(320) "O:12:"DateInterval":15:{s:1:"y";i:0;s:1:"m";i:0;s:1:"d";i:0;s:1:"h";i:4;s:1:"i";i:0;s:1:"s";i:0;s:7:"weekday";i:0;s:16:"weekday_behavior";i:0;s:17:"first_last_day_of";i:0;s:6:"invert";i:0;s:4:"days";i:0;s:12:"special_type";i:0;s:14:"special_amount";i:0;s:21:"have_weekday_relative";i:0;s:21:"have_special_relative";i:0;}" DateInterval::__set_state(array( 'y' => 0, 'm' => 0, @@ -58,9 +72,16 @@ DateInterval::__set_state(array( 'h' => 4, 'i' => 0, 's' => 0, + 'weekday' => 0, + 'weekday_behavior' => 0, + 'first_last_day_of' => 0, 'invert' => 0, 'days' => 0, -))object(DateInterval)#5 (8) { + 'special_type' => 0, + 'special_amount' => 0, + 'have_weekday_relative' => 0, + 'have_special_relative' => 0, +))object(DateInterval)#5 (15) { ["y"]=> int(0) ["m"]=> @@ -73,14 +94,78 @@ DateInterval::__set_state(array( int(0) ["s"]=> int(0) + ["weekday"]=> + int(0) + ["weekday_behavior"]=> + int(0) + ["first_last_day_of"]=> + int(0) ["invert"]=> int(0) ["days"]=> int(0) + ["special_type"]=> + int(0) + ["special_amount"]=> + int(0) + ["have_weekday_relative"]=> + int(0) + ["have_special_relative"]=> + int(0) } -object(DatePeriod)#6 (0) { +object(DatePeriod)#6 (6) { + ["start"]=> + object(DateTime)#4 (3) { + ["date"]=> + string(19) "2003-01-02 08:00:00" + ["timezone_type"]=> + int(3) + ["timezone"]=> + string(3) "UTC" + } + ["current"]=> + NULL + ["end"]=> + NULL + ["interval"]=> + object(DateInterval)#7 (15) { + ["y"]=> + int(0) + ["m"]=> + int(0) + ["d"]=> + int(0) + ["h"]=> + int(4) + ["i"]=> + int(0) + ["s"]=> + int(0) + ["weekday"]=> + int(0) + ["weekday_behavior"]=> + int(0) + ["first_last_day_of"]=> + int(0) + ["invert"]=> + int(0) + ["days"]=> + int(0) + ["special_type"]=> + int(0) + ["special_amount"]=> + int(0) + ["have_weekday_relative"]=> + int(0) + ["have_special_relative"]=> + int(0) + } + ["recurrences"]=> + int(3) + ["include_start_date"]=> + bool(true) } -object(DateInterval)#4 (8) { +object(DateInterval)#8 (15) { ["y"]=> int(7) ["m"]=> @@ -93,10 +178,74 @@ object(DateInterval)#4 (8) { int(3) ["s"]=> int(2) + ["weekday"]=> + int(-1) + ["weekday_behavior"]=> + int(-1) + ["first_last_day_of"]=> + int(-1) ["invert"]=> int(1) ["days"]=> int(2400) + ["special_type"]=> + int(0) + ["special_amount"]=> + int(-1) + ["have_weekday_relative"]=> + int(0) + ["have_special_relative"]=> + int(0) } -object(DatePeriod)#7 (0) { +object(DatePeriod)#9 (6) { + ["start"]=> + object(DateTime)#6 (3) { + ["date"]=> + string(19) "2003-01-02 08:00:00" + ["timezone_type"]=> + int(3) + ["timezone"]=> + string(3) "UTC" + } + ["current"]=> + NULL + ["end"]=> + NULL + ["interval"]=> + object(DateInterval)#7 (15) { + ["y"]=> + int(0) + ["m"]=> + int(0) + ["d"]=> + int(0) + ["h"]=> + int(4) + ["i"]=> + int(0) + ["s"]=> + int(0) + ["weekday"]=> + int(0) + ["weekday_behavior"]=> + int(0) + ["first_last_day_of"]=> + int(0) + ["invert"]=> + int(0) + ["days"]=> + int(0) + ["special_type"]=> + int(0) + ["special_amount"]=> + int(0) + ["have_weekday_relative"]=> + int(0) + ["have_special_relative"]=> + int(0) + } + ["recurrences"]=> + int(3) + ["include_start_date"]=> + bool(true) } diff --git a/ext/date/tests/bug52738.phpt b/ext/date/tests/bug52738.phpt index fc1b6029e9..ea219f7c7c 100644 --- a/ext/date/tests/bug52738.phpt +++ b/ext/date/tests/bug52738.phpt @@ -27,6 +27,13 @@ di Object [h] => 0 [i] => 0 [s] => 0 + [weekday] => 0 + [weekday_behavior] => 0 + [first_last_day_of] => 0 [invert] => 0 [days] => + [special_type] => 0 + [special_amount] => 0 + [have_weekday_relative] => 0 + [have_special_relative] => 0 ) diff --git a/ext/date/tests/bug52808.phpt b/ext/date/tests/bug52808.phpt index e031ac6ee3..1f0fc84cd7 100644 --- a/ext/date/tests/bug52808.phpt +++ b/ext/date/tests/bug52808.phpt @@ -25,7 +25,7 @@ foreach($intervals as $iv) { echo "==DONE==\n"; ?> --EXPECTF-- -object(DateInterval)#%d (8) { +object(DateInterval)#%d (15) { ["y"]=> int(1) ["m"]=> @@ -38,12 +38,26 @@ object(DateInterval)#%d (8) { int(30) ["s"]=> int(0) + ["weekday"]=> + int(0) + ["weekday_behavior"]=> + int(0) + ["first_last_day_of"]=> + int(0) ["invert"]=> int(1) ["days"]=> int(437) + ["special_type"]=> + int(0) + ["special_amount"]=> + int(0) + ["have_weekday_relative"]=> + int(0) + ["have_special_relative"]=> + int(0) } -object(DateInterval)#%d (8) { +object(DateInterval)#%d (15) { ["y"]=> int(0) ["m"]=> @@ -56,12 +70,26 @@ object(DateInterval)#%d (8) { int(30) ["s"]=> int(0) + ["weekday"]=> + int(0) + ["weekday_behavior"]=> + int(0) + ["first_last_day_of"]=> + int(0) ["invert"]=> int(0) ["days"]=> int(294) + ["special_type"]=> + int(0) + ["special_amount"]=> + int(0) + ["have_weekday_relative"]=> + int(0) + ["have_special_relative"]=> + int(0) } -object(DateInterval)#%d (8) { +object(DateInterval)#%d (15) { ["y"]=> int(0) ["m"]=> @@ -74,10 +102,24 @@ object(DateInterval)#%d (8) { int(30) ["s"]=> int(0) + ["weekday"]=> + int(0) + ["weekday_behavior"]=> + int(0) + ["first_last_day_of"]=> + int(0) ["invert"]=> int(0) ["days"]=> int(294) + ["special_type"]=> + int(0) + ["special_amount"]=> + int(0) + ["have_weekday_relative"]=> + int(0) + ["have_special_relative"]=> + int(0) } DateInterval::__construct(): Failed to parse interval (2007-05-11T15:30:00Z/) DateInterval::__construct(): Failed to parse interval (2007-05-11T15:30:00Z) diff --git a/ext/date/tests/bug53437.phpt b/ext/date/tests/bug53437.phpt index f089866538..2ea091453f 100644 --- a/ext/date/tests/bug53437.phpt +++ b/ext/date/tests/bug53437.phpt @@ -1,7 +1,5 @@ --TEST-- -Bug #53437 (Crash when using unserialized DatePeriod instance) ---XFAIL-- -Bug #53437 Not fixed yet +Bug #53437 (Crash when using unserialized DatePeriod instance), variation 1 --FILE-- <?php $dp = new DatePeriod(new DateTime('2010-01-01 UTC'), new DateInterval('P1D'), 2); @@ -20,9 +18,137 @@ $dpu = unserialize($ser); // $dpu has invalid values??? var_dump($dpu); echo "Unserialized:\r\n"; -// ???which leads to CRASH: foreach($dpu as $dt) { echo $dt->format('Y-m-d H:i:s')."\r\n"; } ?> +==DONE== --EXPECT-- +Original: +2010-01-01 00:00:00 +2010-01-02 00:00:00 +2010-01-03 00:00:00 + +object(DatePeriod)#1 (6) { + ["start"]=> + object(DateTime)#2 (3) { + ["date"]=> + string(19) "2010-01-01 00:00:00" + ["timezone_type"]=> + int(3) + ["timezone"]=> + string(3) "UTC" + } + ["current"]=> + object(DateTime)#4 (3) { + ["date"]=> + string(19) "2010-01-04 00:00:00" + ["timezone_type"]=> + int(3) + ["timezone"]=> + string(3) "UTC" + } + ["end"]=> + NULL + ["interval"]=> + object(DateInterval)#5 (15) { + ["y"]=> + int(0) + ["m"]=> + int(0) + ["d"]=> + int(1) + ["h"]=> + int(0) + ["i"]=> + int(0) + ["s"]=> + int(0) + ["weekday"]=> + int(0) + ["weekday_behavior"]=> + int(0) + ["first_last_day_of"]=> + int(0) + ["invert"]=> + int(0) + ["days"]=> + bool(false) + ["special_type"]=> + int(0) + ["special_amount"]=> + int(0) + ["have_weekday_relative"]=> + int(0) + ["have_special_relative"]=> + int(0) + } + ["recurrences"]=> + int(3) + ["include_start_date"]=> + bool(true) +} +object(DatePeriod)#5 (6) { + ["start"]=> + object(DateTime)#10 (3) { + ["date"]=> + string(19) "2010-01-01 00:00:00" + ["timezone_type"]=> + int(3) + ["timezone"]=> + string(3) "UTC" + } + ["current"]=> + object(DateTime)#7 (3) { + ["date"]=> + string(19) "2010-01-04 00:00:00" + ["timezone_type"]=> + int(3) + ["timezone"]=> + string(3) "UTC" + } + ["end"]=> + NULL + ["interval"]=> + object(DateInterval)#8 (15) { + ["y"]=> + int(0) + ["m"]=> + int(0) + ["d"]=> + int(1) + ["h"]=> + int(0) + ["i"]=> + int(0) + ["s"]=> + int(0) + ["weekday"]=> + int(0) + ["weekday_behavior"]=> + int(0) + ["first_last_day_of"]=> + int(0) + ["invert"]=> + int(0) + ["days"]=> + int(0) + ["special_type"]=> + int(0) + ["special_amount"]=> + int(0) + ["have_weekday_relative"]=> + int(0) + ["have_special_relative"]=> + int(0) + } + ["recurrences"]=> + int(3) + ["include_start_date"]=> + bool(true) +} +Unserialized: +2010-01-01 00:00:00 +2010-01-02 00:00:00 +2010-01-03 00:00:00 +==DONE== diff --git a/ext/date/tests/bug53437_var1.phpt b/ext/date/tests/bug53437_var1.phpt new file mode 100644 index 0000000000..f1f9843d5e --- /dev/null +++ b/ext/date/tests/bug53437_var1.phpt @@ -0,0 +1,13 @@ +--TEST-- +Bug #53437 (Crash when using unserialized DatePeriod instance), variation 2 +--FILE-- +<?php +$s = 'O:10:"DatePeriod":0:{}'; + +$dp = unserialize($s); + +var_dump($dp); +?> +==DONE== +--EXPECTF-- +Fatal error: Invalid serialization data for DatePeriod object in %sbug53437_var1.php on line %d diff --git a/ext/date/tests/bug53437_var2.phpt b/ext/date/tests/bug53437_var2.phpt new file mode 100644 index 0000000000..50aebda57c --- /dev/null +++ b/ext/date/tests/bug53437_var2.phpt @@ -0,0 +1,80 @@ +--TEST-- +Bug #53437 DateInterval basic serialization +--FILE-- +<?php +$di0 = new DateInterval('P2Y4DT6H8M'); + +$s = serialize($di0); + +$di1 = unserialize($s); + +var_dump($di0, $di1); + +?> +==DONE== +--EXPECT-- +object(DateInterval)#1 (15) { + ["y"]=> + int(2) + ["m"]=> + int(0) + ["d"]=> + int(4) + ["h"]=> + int(6) + ["i"]=> + int(8) + ["s"]=> + int(0) + ["weekday"]=> + int(0) + ["weekday_behavior"]=> + int(0) + ["first_last_day_of"]=> + int(0) + ["invert"]=> + int(0) + ["days"]=> + bool(false) + ["special_type"]=> + int(0) + ["special_amount"]=> + int(0) + ["have_weekday_relative"]=> + int(0) + ["have_special_relative"]=> + int(0) +} +object(DateInterval)#2 (15) { + ["y"]=> + int(2) + ["m"]=> + int(0) + ["d"]=> + int(4) + ["h"]=> + int(6) + ["i"]=> + int(8) + ["s"]=> + int(0) + ["weekday"]=> + int(0) + ["weekday_behavior"]=> + int(0) + ["first_last_day_of"]=> + int(0) + ["invert"]=> + int(0) + ["days"]=> + int(0) + ["special_type"]=> + int(0) + ["special_amount"]=> + int(0) + ["have_weekday_relative"]=> + int(0) + ["have_special_relative"]=> + int(0) +} +==DONE== diff --git a/ext/date/tests/bug53437_var3.phpt b/ext/date/tests/bug53437_var3.phpt new file mode 100644 index 0000000000..82b90f559b --- /dev/null +++ b/ext/date/tests/bug53437_var3.phpt @@ -0,0 +1,47 @@ +--TEST-- +Bug #53437 DateInterval unserialize bad data, 32 bit +--SKIPIF-- +<?php if (PHP_INT_SIZE != 4) { die('skip 32 bit only'); } ?> +--FILE-- +<?php +$s = 'O:12:"DateInterval":15:{s:1:"y";s:1:"2";s:1:"m";s:1:"0";s:1:"d";s:3:"bla";s:1:"h";s:1:"6";s:1:"i";s:1:"8";s:1:"s";s:1:"0";s:7:"weekday";i:10;s:16:"weekday_behavior";i:10;s:17:"first_last_day_of";i:0;s:6:"invert";i:0;s:4:"days";s:4:"aoeu";s:12:"special_type";i:0;s:14:"special_amount";s:21:"234523452345234532455";s:21:"have_weekday_relative";i:21474836489;s:21:"have_special_relative";s:3:"bla";}'; + +$di = unserialize($s); +var_dump($di); + +?> +==DONE== +--EXPECTF-- +object(DateInterval)#%d (15) { + ["y"]=> + int(2) + ["m"]=> + int(0) + ["d"]=> + int(0) + ["h"]=> + int(6) + ["i"]=> + int(8) + ["s"]=> + int(0) + ["weekday"]=> + int(10) + ["weekday_behavior"]=> + int(10) + ["first_last_day_of"]=> + int(0) + ["invert"]=> + int(0) + ["days"]=> + int(0) + ["special_type"]=> + int(0) + ["special_amount"]=> + int(-1) + ["have_weekday_relative"]=> + int(9) + ["have_special_relative"]=> + int(0) +} +==DONE== diff --git a/ext/date/tests/bug53437_var4.phpt b/ext/date/tests/bug53437_var4.phpt new file mode 100644 index 0000000000..88fd81c9db --- /dev/null +++ b/ext/date/tests/bug53437_var4.phpt @@ -0,0 +1,64 @@ +--TEST-- +Bug #53437 (Check that var_dump out is the same using the whole object or it's single properties), variation 4 +--INI-- +date.timezone = Europe/Berlin +--FILE-- +<?php +$dt = new DateTime('2009-10-11'); + +$df = $dt->diff(new DateTime('2009-10-13')); + +var_dump($df, + $df->y, + $df->m, + $df->d, + $df->h, + $df->i, + $df->s, + $df->invert, + $df->days); + +?> +==DONE== +--EXPECTF-- +object(DateInterval)#%d (15) { + ["y"]=> + int(0) + ["m"]=> + int(0) + ["d"]=> + int(2) + ["h"]=> + int(0) + ["i"]=> + int(0) + ["s"]=> + int(0) + ["weekday"]=> + int(0) + ["weekday_behavior"]=> + int(0) + ["first_last_day_of"]=> + int(0) + ["invert"]=> + int(0) + ["days"]=> + int(2) + ["special_type"]=> + int(0) + ["special_amount"]=> + int(0) + ["have_weekday_relative"]=> + int(0) + ["have_special_relative"]=> + int(0) +} +int(0) +int(0) +int(2) +int(0) +int(0) +int(0) +int(0) +int(2) +==DONE== diff --git a/ext/date/tests/bug53437_var5.phpt b/ext/date/tests/bug53437_var5.phpt new file mode 100644 index 0000000000..e95fcdae96 --- /dev/null +++ b/ext/date/tests/bug53437_var5.phpt @@ -0,0 +1,47 @@ +--TEST-- +Bug #53437 DateInterval unserialize bad data, 64 bit +--SKIPIF-- +<?php if (PHP_INT_SIZE != 8) { die('skip true 64 bit only'); } ?> +--FILE-- +<?php +$s = 'O:12:"DateInterval":15:{s:1:"y";s:1:"2";s:1:"m";s:1:"0";s:1:"d";s:3:"bla";s:1:"h";s:1:"6";s:1:"i";s:1:"8";s:1:"s";s:1:"0";s:7:"weekday";i:10;s:16:"weekday_behavior";i:10;s:17:"first_last_day_of";i:0;s:6:"invert";i:0;s:4:"days";s:4:"aoeu";s:12:"special_type";i:0;s:14:"special_amount";s:21:"234523452345234532455";s:21:"have_weekday_relative";i:21474836489;s:21:"have_special_relative";s:3:"bla";}'; + +$di = unserialize($s); +var_dump($di); + +?> +==DONE== +--EXPECTF-- +object(DateInterval)#%d (15) { + ["y"]=> + int(2) + ["m"]=> + int(0) + ["d"]=> + int(0) + ["h"]=> + int(6) + ["i"]=> + int(8) + ["s"]=> + int(0) + ["weekday"]=> + int(10) + ["weekday_behavior"]=> + int(10) + ["first_last_day_of"]=> + int(0) + ["invert"]=> + int(0) + ["days"]=> + int(0) + ["special_type"]=> + int(0) + ["special_amount"]=> + int(9223372036854775807) + ["have_weekday_relative"]=> + int(9) + ["have_special_relative"]=> + int(0) +} +==DONE== diff --git a/ext/date/tests/date_diff1.phpt b/ext/date/tests/date_diff1.phpt index cf32fcbf3b..a908cdba75 100644 --- a/ext/date/tests/date_diff1.phpt +++ b/ext/date/tests/date_diff1.phpt @@ -28,7 +28,7 @@ object(DateTime)#2 (3) { ["timezone"]=> string(3) "EDT" } -object(DateInterval)#3 (8) { +object(DateInterval)#3 (15) { ["y"]=> int(0) ["m"]=> @@ -41,8 +41,22 @@ object(DateInterval)#3 (8) { int(19) ["s"]=> int(40) + ["weekday"]=> + int(0) + ["weekday_behavior"]=> + int(0) + ["first_last_day_of"]=> + int(0) ["invert"]=> int(0) ["days"]=> int(33) + ["special_type"]=> + int(0) + ["special_amount"]=> + int(0) + ["have_weekday_relative"]=> + int(0) + ["have_special_relative"]=> + int(0) } diff --git a/ext/pdo_pgsql/tests/copy_from.phpt b/ext/pdo_pgsql/tests/copy_from.phpt index 2858905d0c..10967b0fe9 100644 --- a/ext/pdo_pgsql/tests/copy_from.phpt +++ b/ext/pdo_pgsql/tests/copy_from.phpt @@ -110,8 +110,10 @@ $db->rollback(); echo "Exception! at line ", $e->getLine(), "\n"; var_dump($e->getMessage()); } -if(isset($filename)) { - @unlink($filename); + +// Clean up +foreach (array($filename, $filenameWithDifferentNullValues, $filenameWithDifferentNullValuesAndSelectedFields) as $f) { + @unlink($f); } ?> --EXPECT-- @@ -383,4 +385,4 @@ array(6) { NULL } Testing pgsqlCopyFromFile() with error -bool(false)
\ No newline at end of file +bool(false) diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index a0faed1424..c5d9a4ab1c 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -4875,7 +4875,7 @@ PHP_PGSQL_API int php_pgsql_meta_data(PGconn *pg_link, const char *table_name, z } smart_str_appends(&querystr, - "SELECT a.attname, a.attnum, t.typname, a.attlen, a.attnotNULL, a.atthasdef, a.attndims " + "SELECT a.attname, a.attnum, t.typname, a.attlen, a.attnotnull, a.atthasdef, a.attndims, t.typtype = 'e' " "FROM pg_class as c, pg_attribute a, pg_type t, pg_namespace n " "WHERE a.attnum > 0 AND a.attrelid = c.oid AND c.relname = '"); tmp_name2 = php_addslashes(tmp_name2, strlen(tmp_name2), &new_len, 0 TSRMLS_CC); @@ -4921,6 +4921,12 @@ PHP_PGSQL_API int php_pgsql_meta_data(PGconn *pg_link, const char *table_name, z add_assoc_bool(elem, "has default", 0); } add_assoc_long(elem, "array dims", atoi(PQgetvalue(pg_result,i,6))); + if (!strcmp(PQgetvalue(pg_result,i,7), "t")) { + add_assoc_bool(elem, "is enum", 1); + } + else { + add_assoc_bool(elem, "is enum", 0); + } name = PQgetvalue(pg_result,i,0); add_assoc_zval(meta, name, elem); } @@ -4954,7 +4960,18 @@ PHP_FUNCTION(pg_meta_data) zval_dtor(return_value); /* destroy array */ RETURN_FALSE; } -} + else { + HashPosition pos; + zval **val; + + for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(return_value), &pos); + zend_hash_get_current_data_ex(Z_ARRVAL_P(return_value), (void **)&val, &pos) == SUCCESS; + zend_hash_move_forward_ex(Z_ARRVAL_P(return_value), &pos)) { + /* delete newly added entry, in order to keep BC */ + zend_hash_del_key_or_index(Z_ARRVAL_PP(val), "is enum", sizeof("is enum"), 0, HASH_DEL_KEY); + } + } +} /* }}} */ /* {{{ php_pgsql_get_data_type @@ -5136,8 +5153,9 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con char *field = NULL; uint field_len = -1; ulong num_idx = -1; - zval *meta, **def, **type, **not_null, **has_default, **val, *new_val; + zval *meta, **def, **type, **not_null, **has_default, **is_enum, **val, *new_val; int new_len, key_type, err = 0, skip_field; + php_pgsql_data_type data_type; assert(pg_link != NULL); assert(Z_TYPE_P(values) == IS_ARRAY); @@ -5188,17 +5206,30 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Detected broken meta data. Missing 'has default'"); err = 1; } + if (!err && zend_hash_find(Z_ARRVAL_PP(def), "is enum", sizeof("is enum"), (void **)&is_enum) == FAILURE) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Detected broken meta data. Missing 'is enum'"); + err = 1; + } if (!err && (Z_TYPE_PP(val) == IS_ARRAY || Z_TYPE_PP(val) == IS_OBJECT || Z_TYPE_PP(val) == IS_CONSTANT_ARRAY)) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects scaler values as field values"); + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects scalar values as field values"); err = 1; } if (err) { break; /* break out for() */ } ALLOC_INIT_ZVAL(new_val); - switch(php_pgsql_get_data_type(Z_STRVAL_PP(type), Z_STRLEN_PP(type))) + + if (Z_BVAL_PP(is_enum)) { + /* enums need to be treated like strings */ + data_type = PG_TEXT; + } + else { + data_type = php_pgsql_get_data_type(Z_STRVAL_PP(type), Z_STRLEN_PP(type)); + } + + switch(data_type) { case PG_BOOL: switch (Z_TYPE_PP(val)) { diff --git a/ext/pgsql/tests/10pg_convert_85.phpt b/ext/pgsql/tests/10pg_convert_85.phpt index 4f1c92bf1a..8b1cc8f538 100644 --- a/ext/pgsql/tests/10pg_convert_85.phpt +++ b/ext/pgsql/tests/10pg_convert_85.phpt @@ -12,6 +12,7 @@ error_reporting(E_ALL); include 'config.inc'; $db = pg_connect($conn_str); +pg_query($db, "SET standard_conforming_strings = 0"); $fields = array('num'=>'1234', 'str'=>'AAA', 'bin'=>'BBB'); $converted = pg_convert($db, $table_name, $fields); diff --git a/ext/pgsql/tests/12pg_insert_85.phpt b/ext/pgsql/tests/12pg_insert_85.phpt index a85dea0363..5fbbe4b7af 100644 --- a/ext/pgsql/tests/12pg_insert_85.phpt +++ b/ext/pgsql/tests/12pg_insert_85.phpt @@ -12,6 +12,8 @@ error_reporting(E_ALL); include 'config.inc'; $db = pg_connect($conn_str); +pg_query($db, "SET standard_conforming_strings = 0"); + $fields = array('num'=>'1234', 'str'=>'AAA', 'bin'=>'BBB'); pg_insert($db, $table_name, $fields) or print "Error in test 1\n"; diff --git a/ext/pgsql/tests/14pg_update_85.phpt b/ext/pgsql/tests/14pg_update_85.phpt index f1c77eac1d..06ca8c3de9 100644 --- a/ext/pgsql/tests/14pg_update_85.phpt +++ b/ext/pgsql/tests/14pg_update_85.phpt @@ -12,6 +12,8 @@ error_reporting(E_ALL); include 'config.inc'; $db = pg_connect($conn_str); +pg_query($db, "SET standard_conforming_strings = 0"); + $fields = array('num'=>'1234', 'str'=>'ABC', 'bin'=>'XYZ'); $ids = array('num'=>'1234'); diff --git a/ext/pgsql/tests/18pg_escape_bytea.phpt b/ext/pgsql/tests/18pg_escape_bytea.phpt index 43f98c4467..5f52a17d97 100644 --- a/ext/pgsql/tests/18pg_escape_bytea.phpt +++ b/ext/pgsql/tests/18pg_escape_bytea.phpt @@ -8,10 +8,11 @@ PostgreSQL pg_escape_bytea() functions include('config.inc'); +$db = pg_connect($conn_str); + $image = file_get_contents(dirname(__FILE__) . '/php.gif'); $esc_image = pg_escape_bytea($image); -$db = pg_connect($conn_str); pg_query($db, 'INSERT INTO '.$table_name.' (num, bin) VALUES (9876, \''.$esc_image.'\');'); $result = pg_query($db, 'SELECT * FROM '.$table_name.' WHERE num = 9876'); $rows = pg_fetch_all($result); diff --git a/ext/pgsql/tests/bug64609.phpt b/ext/pgsql/tests/bug64609.phpt new file mode 100644 index 0000000000..0df63012da --- /dev/null +++ b/ext/pgsql/tests/bug64609.phpt @@ -0,0 +1,30 @@ +--TEST-- +Bug #64609 (pg_convert enum type support) +--SKIPIF-- +<?php +include("skipif.inc"); +skip_server_version('8.3', '<'); +?> +--FILE-- +<?php +error_reporting(E_ALL); + +include 'config.inc'; + +$db = pg_connect($conn_str); +pg_query("BEGIN"); +pg_query("CREATE TYPE t_enum AS ENUM ('ok', 'ko')"); +pg_query("CREATE TABLE test_enum (a t_enum)"); + +$fields = array('a' => 'ok'); +$converted = pg_convert($db, 'test_enum', $fields); + +pg_query("ROLLBACK"); + +var_dump($converted); +?> +--EXPECT-- +array(1) { + ["a"]=> + string(4) "'ok'" +} diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c index 91f7c8eb7b..cd0af8fbc5 100644 --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@ -1025,12 +1025,12 @@ static void spl_recursive_tree_iterator_get_entry(spl_recursive_it_object * obje zend_replace_error_handling(EH_THROW, spl_ce_UnexpectedValueException, &error_handling TSRMLS_CC); if (data && *data) { RETVAL_ZVAL(*data, 1, 0); - } - if (Z_TYPE_P(return_value) == IS_ARRAY) { - zval_dtor(return_value); - ZVAL_STRINGL(return_value, "Array", sizeof("Array")-1, 1); - } else { - convert_to_string(return_value); + if (Z_TYPE_P(return_value) == IS_ARRAY) { + zval_dtor(return_value); + ZVAL_STRINGL(return_value, "Array", sizeof("Array")-1, 1); + } else { + convert_to_string(return_value); + } } zend_restore_error_handling(&error_handling TSRMLS_CC); } @@ -1131,8 +1131,15 @@ SPL_METHOD(RecursiveTreeIterator, current) } } + INIT_ZVAL(prefix); + INIT_ZVAL(entry); spl_recursive_tree_iterator_get_prefix(object, &prefix TSRMLS_CC); spl_recursive_tree_iterator_get_entry(object, &entry TSRMLS_CC); + if (Z_TYPE(entry) != IS_STRING) { + zval_dtor(&prefix); + zval_dtor(&entry); + RETURN_NULL(); + } spl_recursive_tree_iterator_get_postfix(object, &postfix TSRMLS_CC); str_len = Z_STRLEN(prefix) + Z_STRLEN(entry) + Z_STRLEN(postfix); diff --git a/ext/standard/browscap.c b/ext/standard/browscap.c index 60949fc352..343ad2051c 100644 --- a/ext/standard/browscap.c +++ b/ext/standard/browscap.c @@ -451,6 +451,19 @@ static int browser_reg_compare(zval **browser TSRMLS_DC, int num_args, va_list a } /* }}} */ +static void browscap_zval_copy_ctor(zval **p) /* {{{ */ +{ + zval *new; + + ALLOC_ZVAL(new); + *new = **p; + + zval_copy_ctor(new); + + INIT_PZVAL(new); + *p = new; +} /* }}} */ + /* {{{ proto mixed get_browser([string browser_name [, bool return_array]]) Get information about the capabilities of a browser. If browser_name is omitted or null, HTTP_USER_AGENT is used. Returns an object by default; if return_array is true, returns an array. */ PHP_FUNCTION(get_browser) @@ -511,11 +524,11 @@ PHP_FUNCTION(get_browser) if (return_array) { array_init(return_value); - zend_hash_copy(Z_ARRVAL_P(return_value), Z_ARRVAL_PP(agent), (copy_ctor_func_t) zval_add_ref, (void *) &tmp_copy, sizeof(zval *)); + zend_hash_copy(Z_ARRVAL_P(return_value), Z_ARRVAL_PP(agent), (copy_ctor_func_t) browscap_zval_copy_ctor, (void *) &tmp_copy, sizeof(zval *)); } else { object_init(return_value); - zend_hash_copy(Z_OBJPROP_P(return_value), Z_ARRVAL_PP(agent), (copy_ctor_func_t) zval_add_ref, (void *) &tmp_copy, sizeof(zval *)); + zend_hash_copy(Z_OBJPROP_P(return_value), Z_ARRVAL_PP(agent), (copy_ctor_func_t) browscap_zval_copy_ctor, (void *) &tmp_copy, sizeof(zval *)); } while (zend_hash_find(Z_ARRVAL_PP(agent), "parent", sizeof("parent"), (void **) &z_agent_name) == SUCCESS) { @@ -524,10 +537,10 @@ PHP_FUNCTION(get_browser) } if (return_array) { - zend_hash_merge(Z_ARRVAL_P(return_value), Z_ARRVAL_PP(agent), (copy_ctor_func_t) zval_add_ref, (void *) &tmp_copy, sizeof(zval *), 0); + zend_hash_merge(Z_ARRVAL_P(return_value), Z_ARRVAL_PP(agent), (copy_ctor_func_t) browscap_zval_copy_ctor, (void *) &tmp_copy, sizeof(zval *), 0); } else { - zend_hash_merge(Z_OBJPROP_P(return_value), Z_ARRVAL_PP(agent), (copy_ctor_func_t) zval_add_ref, (void *) &tmp_copy, sizeof(zval *), 0); + zend_hash_merge(Z_OBJPROP_P(return_value), Z_ARRVAL_PP(agent), (copy_ctor_func_t) browscap_zval_copy_ctor, (void *) &tmp_copy, sizeof(zval *), 0); } } diff --git a/ext/standard/quot_print.c b/ext/standard/quot_print.c index 280b86a9a2..6627858989 100644 --- a/ext/standard/quot_print.c +++ b/ext/standard/quot_print.c @@ -151,7 +151,7 @@ PHPAPI unsigned char *php_quot_print_encode(const unsigned char *str, size_t len unsigned char c, *ret, *d; char *hex = "0123456789ABCDEF"; - ret = safe_emalloc(1, 3 * length + 3 * (((3 * length)/PHP_QPRINT_MAXL) + 1), 0); + ret = safe_emalloc(3, length + (((3 * length)/(PHP_QPRINT_MAXL-9)) + 1), 1); d = ret; while (length--) { diff --git a/ext/standard/tests/array/bug31158.phpt b/ext/standard/tests/array/bug31158.phpt index e672a10b28..da7a9ec907 100644 --- a/ext/standard/tests/array/bug31158.phpt +++ b/ext/standard/tests/array/bug31158.phpt @@ -1,5 +1,7 @@ --TEST-- Bug #31158 (array_splice on $GLOBALS crashes) +--INI-- +error_reporting = E_ALL --FILE-- <?php function __(){ diff --git a/ext/standard/tests/strings/bug64879.phpt b/ext/standard/tests/strings/bug64879.phpt new file mode 100644 index 0000000000..1df90c6d85 --- /dev/null +++ b/ext/standard/tests/strings/bug64879.phpt @@ -0,0 +1,12 @@ +--TEST-- +Bug #64879: quoted_printable_encode() wrong size calculation (CVE-2013-2110) +--FILE-- +<?php + +quoted_printable_encode(str_repeat("\xf4", 1000)); +quoted_printable_encode(str_repeat("\xf4", 100000)); + +echo "Done\n"; +?> +--EXPECTF-- +Done diff --git a/ext/xml/tests/bug65236.phpt b/ext/xml/tests/bug65236.phpt new file mode 100644 index 0000000000..67b26d663f --- /dev/null +++ b/ext/xml/tests/bug65236.phpt @@ -0,0 +1,15 @@ +--TEST-- +Bug #65236 (heap corruption in xml parser) +--SKIPIF-- +<?php +require_once("skipif.inc"); +?> +--FILE-- +<?php +xml_parse_into_struct(xml_parser_create_ns(), str_repeat("<blah>", 1000), $a); + +echo "Done\n"; +?> +--EXPECTF-- +Warning: xml_parse_into_struct(): Maximum depth exceeded - Results truncated in %s on line %d +Done diff --git a/ext/xml/xml.c b/ext/xml/xml.c index 1f0480b6c7..9f0bc30d98 100644 --- a/ext/xml/xml.c +++ b/ext/xml/xml.c @@ -427,7 +427,7 @@ static void xml_parser_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) } if (parser->ltags) { int inx; - for (inx = 0; inx < parser->level; inx++) + for (inx = 0; ((inx < parser->level) && (inx < XML_MAXLEVEL)); inx++) efree(parser->ltags[ inx ]); efree(parser->ltags); } @@ -905,45 +905,50 @@ void _xml_startElementHandler(void *userData, const XML_Char *name, const XML_Ch } if (parser->data) { - zval *tag, *atr; - int atcnt = 0; + if (parser->level <= XML_MAXLEVEL) { + zval *tag, *atr; + int atcnt = 0; - MAKE_STD_ZVAL(tag); - MAKE_STD_ZVAL(atr); + MAKE_STD_ZVAL(tag); + MAKE_STD_ZVAL(atr); - array_init(tag); - array_init(atr); + array_init(tag); + array_init(atr); - _xml_add_to_info(parser,((char *) tag_name) + parser->toffset); + _xml_add_to_info(parser,((char *) tag_name) + parser->toffset); - add_assoc_string(tag,"tag",((char *) tag_name) + parser->toffset,1); /* cast to avoid gcc-warning */ - add_assoc_string(tag,"type","open",1); - add_assoc_long(tag,"level",parser->level); + add_assoc_string(tag,"tag",((char *) tag_name) + parser->toffset,1); /* cast to avoid gcc-warning */ + add_assoc_string(tag,"type","open",1); + add_assoc_long(tag,"level",parser->level); - parser->ltags[parser->level-1] = estrdup(tag_name); - parser->lastwasopen = 1; + parser->ltags[parser->level-1] = estrdup(tag_name); + parser->lastwasopen = 1; - attributes = (const XML_Char **) attrs; + attributes = (const XML_Char **) attrs; - while (attributes && *attributes) { - att = _xml_decode_tag(parser, attributes[0]); - val = xml_utf8_decode(attributes[1], strlen(attributes[1]), &val_len, parser->target_encoding); - - add_assoc_stringl(atr,att,val,val_len,0); + while (attributes && *attributes) { + att = _xml_decode_tag(parser, attributes[0]); + val = xml_utf8_decode(attributes[1], strlen(attributes[1]), &val_len, parser->target_encoding); - atcnt++; - attributes += 2; + add_assoc_stringl(atr,att,val,val_len,0); - efree(att); - } + atcnt++; + attributes += 2; - if (atcnt) { - zend_hash_add(Z_ARRVAL_P(tag),"attributes",sizeof("attributes"),&atr,sizeof(zval*),NULL); - } else { - zval_ptr_dtor(&atr); - } + efree(att); + } + + if (atcnt) { + zend_hash_add(Z_ARRVAL_P(tag),"attributes",sizeof("attributes"),&atr,sizeof(zval*),NULL); + } else { + zval_ptr_dtor(&atr); + } - zend_hash_next_index_insert(Z_ARRVAL_P(parser->data),&tag,sizeof(zval*),(void *) &parser->ctag); + zend_hash_next_index_insert(Z_ARRVAL_P(parser->data),&tag,sizeof(zval*),(void *) &parser->ctag); + } else if (parser->level == (XML_MAXLEVEL + 1)) { + TSRMLS_FETCH(); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Maximum depth exceeded - Results truncated"); + } } efree(tag_name); @@ -995,7 +1000,7 @@ void _xml_endElementHandler(void *userData, const XML_Char *name) efree(tag_name); - if (parser->ltags) { + if ((parser->ltags) && (parser->level <= XML_MAXLEVEL)) { efree(parser->ltags[parser->level-1]); } @@ -1079,18 +1084,23 @@ void _xml_characterDataHandler(void *userData, const XML_Char *s, int len) } } - MAKE_STD_ZVAL(tag); - - array_init(tag); - - _xml_add_to_info(parser,parser->ltags[parser->level-1] + parser->toffset); + if (parser->level <= XML_MAXLEVEL) { + MAKE_STD_ZVAL(tag); - add_assoc_string(tag,"tag",parser->ltags[parser->level-1] + parser->toffset,1); - add_assoc_string(tag,"value",decoded_value,0); - add_assoc_string(tag,"type","cdata",1); - add_assoc_long(tag,"level",parser->level); + array_init(tag); - zend_hash_next_index_insert(Z_ARRVAL_P(parser->data),&tag,sizeof(zval*),NULL); + _xml_add_to_info(parser,parser->ltags[parser->level-1] + parser->toffset); + + add_assoc_string(tag,"tag",parser->ltags[parser->level-1] + parser->toffset,1); + add_assoc_string(tag,"value",decoded_value,0); + add_assoc_string(tag,"type","cdata",1); + add_assoc_long(tag,"level",parser->level); + + zend_hash_next_index_insert(Z_ARRVAL_P(parser->data),&tag,sizeof(zval*),NULL); + } else if (parser->level == (XML_MAXLEVEL + 1)) { + TSRMLS_FETCH(); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Maximum depth exceeded - Results truncated"); + } } } else { efree(decoded_value); diff --git a/main/php_version.h b/main/php_version.h index 1903611f29..bddf0bc12f 100644 --- a/main/php_version.h +++ b/main/php_version.h @@ -2,7 +2,7 @@ /* edit configure.in to change version number */ #define PHP_MAJOR_VERSION 5 #define PHP_MINOR_VERSION 3 -#define PHP_RELEASE_VERSION 27 +#define PHP_RELEASE_VERSION 28 #define PHP_EXTRA_VERSION "-dev" -#define PHP_VERSION "5.3.27-dev" -#define PHP_VERSION_ID 50327 +#define PHP_VERSION "5.3.28-dev" +#define PHP_VERSION_ID 50328 diff --git a/main/streams/cast.c b/main/streams/cast.c index 4063930436..6f79a24e30 100644 --- a/main/streams/cast.c +++ b/main/streams/cast.c @@ -31,10 +31,18 @@ /* Under BSD, emulate fopencookie using funopen */ #if defined(HAVE_FUNOPEN) && !defined(HAVE_FOPENCOOKIE) + +/* NetBSD 6.0+ uses off_t instead of fpos_t in funopen */ +# if defined(__NetBSD__) && (__NetBSD_Version__ > 600000000) +# define PHP_FPOS_T off_t +# else +# define PHP_FPOS_T fpos_t +# endif + typedef struct { int (*reader)(void *, char *, int); int (*writer)(void *, const char *, int); - fpos_t (*seeker)(void *, fpos_t, int); + PHP_FPOS_T (*seeker)(void *, PHP_FPOS_T, int); int (*closer)(void *); } COOKIE_IO_FUNCTIONS_T; @@ -68,11 +76,11 @@ static int stream_cookie_writer(void *cookie, const char *buffer, int size) return php_stream_write((php_stream *)cookie, (char *)buffer, size); } -static fpos_t stream_cookie_seeker(void *cookie, off_t position, int whence) +static PHP_FPOS_T stream_cookie_seeker(void *cookie, off_t position, int whence) { TSRMLS_FETCH(); - return (fpos_t)php_stream_seek((php_stream *)cookie, position, whence); + return (PHP_FPOS_T)php_stream_seek((php_stream *)cookie, position, whence); } static int stream_cookie_closer(void *cookie) |