diff options
author | Keyur Govande <keyur@php.net> | 2013-03-11 00:05:49 +0000 |
---|---|---|
committer | Keyur Govande <keyur@php.net> | 2013-03-11 00:05:49 +0000 |
commit | cdacda720c8c23aaa378d99dd17c95269c2e0ca8 (patch) | |
tree | 2883a427e2c5f47c168bfe10b71569a0237a3b69 | |
parent | 5543035a705ce29ed24d3f0729988122c1d469a6 (diff) | |
parent | 9490118fdb66eb6148dc74b24399eb72dc55aec1 (diff) | |
download | php-git-cdacda720c8c23aaa378d99dd17c95269c2e0ca8.tar.gz |
Merge branch 'PHP-5.5' of https://git.php.net/push/php-src into PHP-5.5
* 'PHP-5.5' of https://git.php.net/push/php-src:
Fix tests after laruence unserialize change
Fix get_property_ptr_ptr declaration in simplexml
Update NEWS
Fixed confused exception message while user threw exception
Fixed bug #64354 (Unserialize array of objects whose class can't be autoloaded fail)
Fix date
use NEWS only
Fixed bug #61025 (__invoke() visibility not honored)
-rw-r--r-- | NEWS | 5 | ||||
-rw-r--r-- | NEWS-5.5 | 344 | ||||
-rw-r--r-- | Zend/tests/bug61025.phpt | 27 | ||||
-rw-r--r-- | Zend/tests/bug64354.phpt | 24 | ||||
-rw-r--r-- | Zend/tests/generators/errors/serialize_unserialize_error.phpt | 2 | ||||
-rw-r--r-- | Zend/zend_closures.c | 1 | ||||
-rw-r--r-- | Zend/zend_closures.h | 2 | ||||
-rw-r--r-- | Zend/zend_compile.c | 8 | ||||
-rw-r--r-- | Zend/zend_compile.h | 1 | ||||
-rw-r--r-- | Zend/zend_interfaces.c | 2 | ||||
-rw-r--r-- | ext/simplexml/simplexml.c | 2 | ||||
-rw-r--r-- | ext/standard/tests/serialize/bug64354_1.phpt | 25 | ||||
-rw-r--r-- | ext/standard/tests/serialize/bug64354_2.phpt | 24 | ||||
-rw-r--r-- | ext/standard/tests/serialize/bug64354_3.phpt | 29 | ||||
-rw-r--r-- | ext/standard/var.c | 22 | ||||
-rw-r--r-- | ext/standard/var_unserializer.c | 90 | ||||
-rw-r--r-- | ext/standard/var_unserializer.re | 28 |
17 files changed, 250 insertions, 386 deletions
@@ -2,10 +2,15 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 20??, PHP 5.5.0 Beta 1 +- Core: + . Fixed bug #64354 (Unserialize array of objects whose class can't + be autoloaded fail). (Laruence) + 07 Mar 2013, PHP 5.5.0 Alpha 6 - Core: + . Fixed bug #61025 (__invoke() visibility not honored). (Laruence) . Fixed bug #49348 (Uninitialized ++$foo->bar; does not cause a notice). (Stas) diff --git a/NEWS-5.5 b/NEWS-5.5 deleted file mode 100644 index a5b11c0d32..0000000000 --- a/NEWS-5.5 +++ /dev/null @@ -1,344 +0,0 @@ -PHP NEWS -||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -?? ??? 201?, PHP 5.5.0 Beta 1 - -- Core: - . Fixed bug #49348 (Uninitialized ++$foo->bar; does not cause a notice). - (Stas) - -- Sockets: - . Fixed bug #64287 (sendmsg/recvmsg shutdown handler causes segfault). - (Gustavo) - -- PCRE: - . Merged PCRE 8.32. (Anatol) - -21 Feb 2013, PHP 5.5.0 Alpha 5 - -- Core: - . Implemented FR #64175 (Added HTTP codes as of RFC 6585). (Jonh Wendell) - . Fixed bug #64135 (Exceptions from set_error_handler are not always - propagated). (Laruence) - . Fixed bug #63830 (Segfault on undefined function call in nested generator). - (Nikita Popov) - . Fixed bug #60833 (self, parent, static behave inconsistently - case-sensitive). (Stas, mario at include-once dot org) - . Implemented FR #60524 (specify temp dir by php.ini). (ALeX Kazik). - . Fixed bug #64142 (dval to lval different behavior on ppc64). (Remi) - . Added ARMv7/v8 versions of various Zend arithmetic functions that are - implemented using inline assembler (Ard Biesheuvel) - . Fix undefined behavior when converting double variables to integers. - The double is now always rounded towards zero, the remainder of its division - by 2^32 or 2^64 (depending on sizeof(long)) is calculated and it's made - signed assuming a two's complement representation. (Gustavo) - -- CLI server: - . Fixed bug #64128 (buit-in web server is broken on ppc64). (Remi) - -- cURL: - . Implemented FR #46439 - added CURLFile for safer file uploads. - (Stas) - -- Intl: - . Cherry-picked UConverter wrapper, which had accidentaly been committed only - to master. - -- mysqli - . Added mysqli_begin_transaction()/mysqli::begin_transaction(). Implemented - all options, per MySQL 5.6, which can be used with START TRANSACTION, COMMIT - and ROLLBACK through options to mysqli_commit()/mysqli_rollback() and their - respective OO counterparts. They work in libmysql and mysqlnd mode. (Andrey) - . Added mysqli_savepoint(), mysqli_release_savepoint(). (Andrey) - -- mysqlnd - . Add new begin_transaction() call to the connection object. Implemented all - options, per MySQL 5.6, which can be used with START TRANSACTION, COMMIT - and ROLLBACK. (Andrey) - . Added mysqlnd_savepoint(), mysqlnd_release_savepoint(). (Andrey) - -- Sockets: - . Added recvmsg() and sendmsg() wrappers. (Gustavo) - See https://wiki.php.net/rfc/sendrecvmsg - -- Filter: - . Implemented FR #49180 - added MAC address validation. (Martin) - -- Phar: - . Fixed timestamp update on Phar contents modification. (Dmitry) - -- SPL: - . Fixed bug #64264 (SPLFixedArray toArray problem). (Laruence) - . Fixed bug #64228 (RecursiveDirectoryIterator always assumes SKIP_DOTS). - (patch by kriss@krizalys.com, Laruence) - . Fixed bug #64106 (Segfault on SplFixedArray[][x] = y when extended). - (Nikita Popov) - . Fixed bug #52861 (unset fails with ArrayObject and deep arrays). - (Mike Willbanks) - -- SNMP: - . Fixed bug #64124 (IPv6 malformed). (Boris Lytochkin) - -24 Jan 2013, PHP 5.5.0 Alpha 4 - -- Core: - . Fixed bug #63980 (object members get trimmed by zero bytes). (Laruence) - . Implemented RFC for Class Name Resolution As Scalar Via "class" Keyword. - (Ralph Schindler, Nikita Popov, Lars) - -- DateTime - . Added DateTimeImmutable - a variant of DateTime that only returns the - modified state instead of changing itself. (Derick) - -- FPM: - . Fixed bug #63999 (php with fpm fails to build on Solaris 10 or 11). (Adam) - -- pgsql: - . Bug #46408: Locale number format settings can cause pg_query_params to - break with numerics. (asmecher, Lars) - -- dba: - . Bug #62489: dba_insert not working as expected. - (marc-bennewitz at arcor dot de, Lars) - -- Reflection: - . Fixed bug #64007 (There is an ability to create instance of Generator by - hand). (Laruence) - -10 Jan 2013, PHP 5.5.0 Alpha 3 - -- General improvements: - . Fixed bug #63874 (Segfault if php_strip_whitespace has heredoc). (Pierrick) - . Fixed bug #63822 (Crash when using closures with ArrayAccess). - (Nikita Popov) - . Add Generator::throw() method. (Nikita Popov) - . Bug #23955: allow specifying Max-Age attribute in setcookie() (narfbg, Lars) - . Bug #52126: timestamp for mail.log (Martin Jansen, Lars) - -- mysqlnd - . Fixed return value of mysqli_stmt_affected_rows() in the time after - prepare() and before execute(). (Andrey) - -- cURL: - . Added new functions curl_escape, curl_multi_setopt, curl_multi_strerror - curl_pause, curl_reset, curl_share_close, curl_share_init, - curl_share_setopt curl_strerror and curl_unescape. (Pierrick) - . Addes new curl options CURLOPT_TELNETOPTIONS, CURLOPT_GSSAPI_DELEGATION, - CURLOPT_ACCEPTTIMEOUT_MS, CURLOPT_SSL_OPTIONS, CURLOPT_TCP_KEEPALIVE, - CURLOPT_TCP_KEEPIDLE and CURLOPT_TCP_KEEPINTVL. (Pierrick) - -18 Dec 2012, PHP 5.5.0 Alpha 2 - -- General improvements: - . Added systemtap support by enabling systemtap compatible dtrace probes on - linux. (David Soria Parra) - . Added support for using empty() on the result of function calls and - other expressions (https://wiki.php.net/rfc/empty_isset_exprs). - (Nikita Popov) - . Optimized access to temporary and compiled VM variables. 8% less memory - reads. (Dmitry) - . The VM stacks for passing function arguments and syntaticaly nested calls - were merged into a single stack. The stack size needed for op_array - execution is calculated at compile time and preallocated at once. As result - all the stack push operatins don't require checks for stack overflow - any more. (Dmitry) - -- MySQL - . This extension is now deprecated, and deprecation warnings will be generated - when connections are established to databases via mysql_connect(), - mysql_pconnect(), or through implicit connection: use MySQLi or PDO_MySQL - instead (https://wiki.php.net/rfc/mysql_deprecation). (Adam) - -- Fileinfo: - . Fixed bug #63590 (Different results in TS and NTS under Windows). - (Anatoliy) - -- Apache2 Handler SAPI: - . Enabled Apache 2.4 configure option for Windows (Pierre, Anatoliy) - -13 Nov 2012, PHP 5.5.0 Alpha 1 - -- General improvements: - . Added generators and coroutines (https://wiki.php.net/rfc/generators). - (Nikita Popov) - . Added "finally" keyword (https://wiki.php.net/rfc/finally). (Laruence) - . Add simplified password hashing API - (https://wiki.php.net/rfc/password_hash). (Anthony Ferrara) - . Added support for list in foreach (https://wiki.php.net/rfc/foreachlist). - (Laruence) - . Added support for using empty() on the result of function calls and - other expressions (https://wiki.php.net/rfc/empty_isset_exprs). - (Nikita Popov) - . Added support for constant array/string dereferencing. (Laruence) - . Improve set_exception_handler while doing reset.(Laruence) - . Remove php_logo_guid(), php_egg_logo_guid(), php_real_logo_guid(), - zend_logo_guid(). (Adnrew Faulds) - . Drop Windows XP and 2003 support. (Pierre) - -- Calendar: - . Fixed bug #54254 (cal_from_jd returns month = 6 when there is only one Adar) - (Stas, Eitan Mosenkis) - -- Core: - . Added boolval(). (Jille Timmermans) - . Added "Z" option to pack/unpack. (Gustavo) - . Implemented FR #60738 (Allow 'set_error_handler' to handle NULL). - (Laruence, Nikita Popov) - . Added optional second argument for assert() to specify custom message. Patch - by Lonny Kapelushnik (lonny@lonnylot.com). (Lars) - . Fixed bug #18556 (Engine uses locale rules to handle class names). (Stas) - . Fixed bug #61681 (Malformed grammar). (Nikita Popov, Etienne, Laruence) - . Fixed bug #61038 (unpack("a5", "str\0\0") does not work as expected). - (srgoogleguy, Gustavo) - . Return previous handler when passing NULL to set_error_handler and - set_exception_handler. (Nikita Popov) - -- cURL: - . Added support for CURLOPT_FTP_RESPONSE_TIMEOUT, CURLOPT_APPEND, - CURLOPT_DIRLISTONLY, CURLOPT_NEW_DIRECTORY_PERMS, CURLOPT_NEW_FILE_PERMS, - CURLOPT_NETRC_FILE, CURLOPT_PREQUOTE, CURLOPT_KRBLEVEL, CURLOPT_MAXFILESIZE, - CURLOPT_FTP_ACCOUNT, CURLOPT_COOKIELIST, CURLOPT_IGNORE_CONTENT_LENGTH, - CURLOPT_CONNECT_ONLY, CURLOPT_LOCALPORT, CURLOPT_LOCALPORTRANGE, - CURLOPT_FTP_ALTERNATIVE_TO_USER, CURLOPT_SSL_SESSIONID_CACHE, - CURLOPT_FTP_SSL_CCC, CURLOPT_HTTP_CONTENT_DECODING, - CURLOPT_HTTP_TRANSFER_DECODING, CURLOPT_PROXY_TRANSFER_MODE, - CURLOPT_ADDRESS_SCOPE, CURLOPT_CRLFILE, CURLOPT_ISSUERCERT, - CURLOPT_USERNAME, CURLOPT_PASSWORD, CURLOPT_PROXYUSERNAME, - CURLOPT_PROXYPASSWORD, CURLOPT_NOPROXY, CURLOPT_SOCKS5_GSSAPI_NEC, - CURLOPT_SOCKS5_GSSAPI_SERVICE, CURLOPT_TFTP_BLKSIZE, - CURLOPT_SSH_KNOWNHOSTS, CURLOPT_FTP_USE_PRET, CURLOPT_MAIL_FROM, - CURLOPT_MAIL_RCPT, CURLOPT_RTSP_CLIENT_CSEQ, CURLOPT_RTSP_SERVER_CSEQ, - CURLOPT_RTSP_SESSION_ID, CURLOPT_RTSP_STREAM_URI, CURLOPT_RTSP_TRANSPORT, - CURLOPT_RTSP_REQUEST, CURLOPT_RESOLVE, CURLOPT_ACCEPT_ENCODING, - CURLOPT_TRANSFER_ENCODING, CURLOPT_DNS_SERVERS and CURLOPT_USE_SSL. - (Pierrick) - . Fixed bug #55635 (CURLOPT_BINARYTRANSFER no longer used. The constant - still exists for backward compatibility but is doing nothing). (Pierrick) - . Fixed bug #54995 (Missing CURLINFO_RESPONSE_CODE support). (Pierrick) - -- Datetime - . Fixed bug #61642 (modify("+5 weekdays") returns Sunday). - (Dmitri Iouchtchenko) - -- Hash - . Added support for PBKDF2 via hash_pbkdf2(). (Anthony Ferrara) - -- Intl - . The intl extension now requires ICU 4.0+. - . Added intl.use_exceptions INI directive, which controls what happens when - global errors are set together with intl.error_level. (Gustavo) - . MessageFormatter::format() and related functions now accepted named - arguments and mixed numeric/named arguments in ICU 4.8+. (Gustavo) - . MessageFormatter::format() and related functions now don't error out when - an insufficient argument count is provided. Instead, the placeholders will - remain unsubstituted. (Gustavo) - . MessageFormatter::parse() and MessageFormat::format() (and their static - equivalents) don't throw away better than second precision in the arguments. - (Gustavo) - . IntlDateFormatter::__construct and datefmt_create() now accept for the - $timezone argument time zone identifiers, IntlTimeZone objects, DateTimeZone - objects and NULL. (Gustavo) - . IntlDateFormatter::__construct and datefmt_create() no longer accept invalid - timezone identifiers or empty strings. (Gustavo) - . The default time zone used in IntlDateFormatter::__construct and - datefmt_create() (when the corresponding argument is not passed or NULL is - passed) is now the one given by date_default_timezone_get(), not the - default ICU time zone. (Gustavo) - . The time zone passed to the IntlDateFormatter is ignored if it is NULL and - if the calendar passed is an IntlCalendar object -- in this case, the - IntlCalendar's time zone will be used instead. Otherwise, the time zone - specified in the $timezone argument is used instead. This does not affect - old code, as IntlCalendar was introduced in this version. (Gustavo) - . IntlDateFormatter::__construct and datefmt_create() now accept for the - $calendar argument also IntlCalendar objects. (Gustavo) - . IntlDateFormatter::getCalendar() and datefmt_get_calendar() return false - if the IntlDateFormatter was set up with an IntlCalendar instead of the - constants IntlDateFormatter::GREGORIAN/TRADITIONAL. IntlCalendar did not - exist before this version. (Gustavo) - . IntlDateFormatter::setCalendar() and datefmt_set_calendar() now also accept - an IntlCalendar object, in which case its time zone is taken. Passing a - constant is still allowed, and still keeps the time zone. (Gustavo) - . IntlDateFormatter::setTimeZoneID() and datefmt_set_timezone_id() are - deprecated. Use IntlDateFormatter::setTimeZone() or datefmt_set_timezone() - instead. (Gustavo) - . IntlDateFormatter::format() and datefmt_format() now also accept an - IntlCalendar object for formatting. (Gustavo) - . Added the classes: IntlCalendar, IntlGregorianCalendar, IntlTimeZone, - IntlBreakIterator, IntlRuleBasedBreakIterator and - IntlCodePointBreakIterator. (Gustavo) - . Added the functions: intlcal_get_keyword_values_for_locale(), - intlcal_get_now(), intlcal_get_available_locales(), intlcal_get(), - intlcal_get_time(), intlcal_set_time(), intlcal_add(), - intlcal_set_time_zone(), intlcal_after(), intlcal_before(), intlcal_set(), - intlcal_roll(), intlcal_clear(), intlcal_field_difference(), - intlcal_get_actual_maximum(), intlcal_get_actual_minimum(), - intlcal_get_day_of_week_type(), intlcal_get_first_day_of_week(), - intlcal_get_greatest_minimum(), intlcal_get_least_maximum(), - intlcal_get_locale(), intlcal_get_maximum(), - intlcal_get_minimal_days_in_first_week(), intlcal_get_minimum(), - intlcal_get_time_zone(), intlcal_get_type(), - intlcal_get_weekend_transition(), intlcal_in_daylight_time(), - intlcal_is_equivalent_to(), intlcal_is_lenient(), intlcal_is_set(), - intlcal_is_weekend(), intlcal_set_first_day_of_week(), - intlcal_set_lenient(), intlcal_equals(), - intlcal_get_repeated_wall_time_option(), - intlcal_get_skipped_wall_time_option(), - intlcal_set_repeated_wall_time_option(), - intlcal_set_skipped_wall_time_option(), intlcal_from_date_time(), - intlcal_to_date_time(), intlcal_get_error_code(), - intlcal_get_error_message(), intlgregcal_create_instance(), - intlgregcal_set_gregorian_change(), intlgregcal_get_gregorian_change() and - intlgregcal_is_leap_year(). (Gustavo) - . Added the functions: intltz_create_time_zone(), intltz_create_default(), - intltz_get_id(), intltz_get_gmt(), intltz_get_unknown(), - intltz_create_enumeration(), intltz_count_equivalent_ids(), - intltz_create_time_zone_id_enumeration(), intltz_get_canonical_id(), - intltz_get_region(), intltz_get_tz_data_version(), - intltz_get_equivalent_id(), intltz_use_daylight_time(), intltz_get_offset(), - intltz_get_raw_offset(), intltz_has_same_rules(), intltz_get_display_name(), - intltz_get_dst_savings(), intltz_from_date_time_zone(), - intltz_to_date_time_zone(), intltz_get_error_code(), - intltz_get_error_message(). (Gustavo) - . Added the methods: IntlDateFormatter::formatObject(), - IntlDateFormatter::getCalendarObject(), IntlDateFormatter::getTimeZone(), - IntlDateFormatter::setTimeZone(). (Gustavo) - . Added the functions: datefmt_format_object(), datefmt_get_calendar_object(), - datefmt_get_timezone(), datefmt_set_timezone(), - datefmt_get_calendar_object(), intlcal_create_instance(). (Gustavo) - -- MCrypt - . mcrypt_ecb(), mcrypt_cbc(), mcrypt_cfb() and mcrypt_ofb() now throw - E_DEPRECATED. (GoogleGuy) - -- MySQLi - . Dropped support for LOAD DATA LOCAL INFILE handlers when using libmysql. - Known for stability problems. (Andrey) - . Added support for SHA256 authentication available with MySQL 5.6.6+. - (Andrey) - -- PCRE: - . Deprecated the /e modifier - (https://wiki.php.net/rfc/remove_preg_replace_eval_modifier). (Nikita Popov) - . Fixed bug #63284 (Upgrade PCRE to 8.31). (Anatoliy) - -- pgsql - . Added pg_escape_literal() and pg_escape_identifier() (Yasuo) - -- SPL - . Fix bug #60560 (SplFixedArray un-/serialize, getSize(), count() return 0, - keys are strings). (Adam) - -- Tokenizer: - . Fixed bug #60097 (token_get_all fails to lex nested heredoc). (Nikita Popov) - -- Zip: - . Upgraded libzip to 0.10.1 (Anatoliy) - -- Fileinfo: - . Fixed bug #63248 (Load multiple magic files from a directory under Windows). - (Anatoliy) - -- General improvements: - . Implemented FR #46487 (Dereferencing process-handles no longer waits on - those processes). (Jille Timmermans) - -<<< NOTE: Insert NEWS from last stable release here prior to actual release! >>> diff --git a/Zend/tests/bug61025.phpt b/Zend/tests/bug61025.phpt new file mode 100644 index 0000000000..0709c28fbc --- /dev/null +++ b/Zend/tests/bug61025.phpt @@ -0,0 +1,27 @@ +--TEST-- +Bug #61025 (__invoke() visibility not honored) +--FILE-- +<?php + +Interface InvokeAble { + static function __invoke(); +} + +class Bar { + private function __invoke() { + return __CLASS__; + } +} + +$b = new Bar; +echo $b(); + +echo $b->__invoke(); + +?> +--EXPECTF-- +Warning: The magic method __invoke() must have public visibility and cannot be static in %sbug61025.php on line %d + +Warning: The magic method __invoke() must have public visibility and cannot be static in %sbug61025.php on line %d +Bar +Fatal error: Call to private method Bar::__invoke() from context '' in %sbug61025.php on line %d diff --git a/Zend/tests/bug64354.phpt b/Zend/tests/bug64354.phpt new file mode 100644 index 0000000000..03a4b80b4b --- /dev/null +++ b/Zend/tests/bug64354.phpt @@ -0,0 +1,24 @@ +--TEST-- +Bug #64354 (Unserialize array of objects whose class can't be autoloaded fail) +--FILE-- +<?php +class B implements Serializable { + public function serialize() { + throw new Exception("serialize"); + return NULL; + } + + public function unserialize($data) { + } +} + +$data = array(new B); + +try { + serialize($data); +} catch (Exception $e) { + var_dump($e->getMessage()); +} +?> +--EXPECTF-- +string(9) "serialize" diff --git a/Zend/tests/generators/errors/serialize_unserialize_error.phpt b/Zend/tests/generators/errors/serialize_unserialize_error.phpt index a8470b0a63..aa2d4693f7 100644 --- a/Zend/tests/generators/errors/serialize_unserialize_error.phpt +++ b/Zend/tests/generators/errors/serialize_unserialize_error.phpt @@ -38,8 +38,6 @@ Stack trace: #1 %s(%d): unserialize('O:9:"Generator"...') #2 {main} - -Notice: unserialize(): Error at offset 19 of 20 bytes in %s on line %d exception 'Exception' with message 'Unserialization of 'Generator' is not allowed' in %s:%d Stack trace: #0 %s(%d): unserialize('C:9:"Generator"...') diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index 0de9283337..5faefbd224 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -291,7 +291,6 @@ static zend_object_value zend_closure_clone(zval *zobject TSRMLS_DC) /* {{{ */ } /* }}} */ - int zend_closure_get_closure(zval *obj, zend_class_entry **ce_ptr, zend_function **fptr_ptr, zval **zobj_ptr TSRMLS_DC) /* {{{ */ { zend_closure *closure; diff --git a/Zend/zend_closures.h b/Zend/zend_closures.h index c41cf47560..9d50641d21 100644 --- a/Zend/zend_closures.h +++ b/Zend/zend_closures.h @@ -24,8 +24,6 @@ BEGIN_EXTERN_C() -#define ZEND_INVOKE_FUNC_NAME "__invoke" - void zend_register_closure_ce(TSRMLS_D); extern ZEND_API zend_class_entry *zend_ce_closure; diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index e45419d3f0..aa1df99ea9 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1621,6 +1621,10 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) { zend_error(E_WARNING, "The magic method __toString() must have public visibility and cannot be static"); } + } else if ((name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1))) { + if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) { + zend_error(E_WARNING, "The magic method __invoke() must have public visibility and cannot be static"); + } } } else { char *class_lcname; @@ -1677,6 +1681,10 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n zend_error(E_WARNING, "The magic method __toString() must have public visibility and cannot be static"); } CG(active_class_entry)->__tostring = (zend_function *) CG(active_op_array); + } else if ((name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1))) { + if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) { + zend_error(E_WARNING, "The magic method __invoke() must have public visibility and cannot be static"); + } } else if (!(fn_flags & ZEND_ACC_STATIC)) { CG(active_op_array)->fn_flags |= ZEND_ACC_ALLOW_STATIC; } diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 8042dd54ee..2295cffab9 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -856,6 +856,7 @@ END_EXTERN_C() #define ZEND_CALLSTATIC_FUNC_NAME "__callstatic" #define ZEND_TOSTRING_FUNC_NAME "__tostring" #define ZEND_AUTOLOAD_FUNC_NAME "__autoload" +#define ZEND_INVOKE_FUNC_NAME "__invoke" /* The following constants may be combined in CG(compiler_options) * to change the default compiler behavior */ diff --git a/Zend/zend_interfaces.c b/Zend/zend_interfaces.c index 384b66da4b..e2e81ed326 100644 --- a/Zend/zend_interfaces.c +++ b/Zend/zend_interfaces.c @@ -452,7 +452,7 @@ ZEND_API int zend_user_serialize(zval *object, unsigned char **buffer, zend_uint zval_ptr_dtor(&retval); } - if (result == FAILURE) { + if (result == FAILURE && !EG(exception)) { zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "%s::serialize() must return a string or NULL", ce->name); } return result; diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c index 692516840b..baae3842c2 100644 --- a/ext/simplexml/simplexml.c +++ b/ext/simplexml/simplexml.c @@ -694,7 +694,7 @@ static void sxe_dimension_write(zval *object, zval *offset, zval *value TSRMLS_D } /* }}} */ -static zval** sxe_property_get_adr(zval *object, zval *member, const zend_literal *key TSRMLS_DC) /* {{{ */ +static zval** sxe_property_get_adr(zval *object, zval *member, int fetch_type, const zend_literal *key TSRMLS_DC) /* {{{ */ { php_sxe_object *sxe; xmlNodePtr node; diff --git a/ext/standard/tests/serialize/bug64354_1.phpt b/ext/standard/tests/serialize/bug64354_1.phpt new file mode 100644 index 0000000000..e85749bcbe --- /dev/null +++ b/ext/standard/tests/serialize/bug64354_1.phpt @@ -0,0 +1,25 @@ +--TEST-- +Bug #64354 (Unserialize array of objects whose class can't be autoloaded fail) +--FILE-- +<?php +spl_autoload_register( + function($class) { + throw new Exception("Failed"); + } +); + +try { + var_dump(unserialize('O:1:"A":0:{}')); +} catch (Exception $e) { + var_dump($e->getMessage()); +} + +try { + var_dump(unserialize('a:2:{i:0;O:1:"A":0:{}i:1;O:1:"A":0:{}}')); +} catch (Exception $e) { + var_dump($e->getMessage()); +} +?> +--EXPECTF-- +string(6) "Failed" +string(6) "Failed" diff --git a/ext/standard/tests/serialize/bug64354_2.phpt b/ext/standard/tests/serialize/bug64354_2.phpt new file mode 100644 index 0000000000..41a455b54a --- /dev/null +++ b/ext/standard/tests/serialize/bug64354_2.phpt @@ -0,0 +1,24 @@ +--TEST-- +Bug #64354 (Unserialize array of objects whose class can't be autoloaded fail) +--FILE-- +<?php +class A { + public function __wakeup() { + throw new Exception("Failed"); + } +} + +spl_autoload_register( + function($class) { + throw new Exception("Failed"); + } +); + +try { + var_dump(unserialize('a:2:{i:0;O:1:"A":0:{}i:1;O:1:"B":0:{}}')); +} catch (Exception $e) { + var_dump($e->getMessage()); +} +?> +--EXPECTF-- +string(6) "Failed" diff --git a/ext/standard/tests/serialize/bug64354_3.phpt b/ext/standard/tests/serialize/bug64354_3.phpt new file mode 100644 index 0000000000..3ce61152d6 --- /dev/null +++ b/ext/standard/tests/serialize/bug64354_3.phpt @@ -0,0 +1,29 @@ +--TEST-- +Bug #64354 (Unserialize array of objects whose class can't be autoloaded fail) +--FILE-- +<?php +class A { + public function __sleep() { + throw new Exception("Failed"); + } +} + +class B implements Serializable { + public function serialize() { + return NULL; + } + + public function unserialize($data) { + } +} + +$data = array(new A, new B); + +try { + serialize($data); +} catch (Exception $e) { + var_dump($e->getMessage()); +} +?> +--EXPECTF-- +string(6) "Failed" diff --git a/ext/standard/var.c b/ext/standard/var.c index b13edf6615..f76a14cfa6 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -714,6 +714,10 @@ static void php_var_serialize_intern(smart_str *buf, zval *struc, HashTable *var ulong *var_already; HashTable *myht; + if (EG(exception)) { + return; + } + if (var_hash && php_add_var_hash(var_hash, struc, (void *) &var_already TSRMLS_CC) == FAILURE) { if (Z_ISREF_P(struc)) { smart_str_appendl(buf, "R:", 2); @@ -800,8 +804,15 @@ static void php_var_serialize_intern(smart_str *buf, zval *struc, HashTable *var BG(serialize_lock)++; res = call_user_function_ex(CG(function_table), &struc, &fname, &retval_ptr, 0, 0, 1, NULL TSRMLS_CC); BG(serialize_lock)--; + + if (EG(exception)) { + if (retval_ptr) { + zval_ptr_dtor(&retval_ptr); + } + return; + } - if (res == SUCCESS && !EG(exception)) { + if (res == SUCCESS) { if (retval_ptr) { if (HASH_OF(retval_ptr)) { php_var_serialize_class(buf, struc, retval_ptr, var_hash TSRMLS_CC); @@ -921,6 +932,11 @@ PHP_FUNCTION(serialize) php_var_serialize(&buf, struc, &var_hash TSRMLS_CC); PHP_VAR_SERIALIZE_DESTROY(var_hash); + if (EG(exception)) { + smart_str_free(&buf); + RETURN_FALSE; + } + if (buf.c) { RETURN_STRINGL(buf.c, buf.len, 0); } else { @@ -951,7 +967,9 @@ PHP_FUNCTION(unserialize) if (!php_var_unserialize(&return_value, &p, p + buf_len, &var_hash TSRMLS_CC)) { PHP_VAR_UNSERIALIZE_DESTROY(var_hash); zval_dtor(return_value); - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Error at offset %ld of %d bytes", (long)((char*)p - buf), buf_len); + if (!EG(exception)) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Error at offset %ld of %d bytes", (long)((char*)p - buf), buf_len); + } RETURN_FALSE; } PHP_VAR_UNSERIALIZE_DESTROY(var_hash); diff --git a/ext/standard/var_unserializer.c b/ext/standard/var_unserializer.c index 3730ff8e81..ddf43b02cf 100644 --- a/ext/standard/var_unserializer.c +++ b/ext/standard/var_unserializer.c @@ -1,4 +1,4 @@ -/* Generated by re2c 0.13.5 on Mon Jan 21 11:41:53 2013 */ +/* Generated by re2c 0.13.5 */ #line 1 "ext/standard/var_unserializer.re" /* +----------------------------------------------------------------------+ @@ -396,8 +396,13 @@ static inline int object_common2(UNSERIALIZE_PARAMETER, long elements) BG(serialize_lock)--; } - if (retval_ptr) + if (retval_ptr) { zval_ptr_dtor(&retval_ptr); + } + + if (EG(exception)) { + return 0; + } return finish_nested_data(UNSERIALIZE_PASSTHRU); @@ -427,7 +432,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER) -#line 431 "ext/standard/var_unserializer.c" +#line 436 "ext/standard/var_unserializer.c" { YYCTYPE yych; static const unsigned char yybm[] = { @@ -487,9 +492,9 @@ yy2: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy95; yy3: -#line 759 "ext/standard/var_unserializer.re" +#line 785 "ext/standard/var_unserializer.re" { return 0; } -#line 493 "ext/standard/var_unserializer.c" +#line 498 "ext/standard/var_unserializer.c" yy4: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy89; @@ -532,13 +537,13 @@ yy13: goto yy3; yy14: ++YYCURSOR; -#line 753 "ext/standard/var_unserializer.re" +#line 779 "ext/standard/var_unserializer.re" { /* this is the case where we have less data than planned */ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unexpected end of serialized data"); return 0; /* not sure if it should be 0 or 1 here? */ } -#line 542 "ext/standard/var_unserializer.c" +#line 547 "ext/standard/var_unserializer.c" yy16: yych = *++YYCURSOR; goto yy3; @@ -568,7 +573,7 @@ yy20: yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; -#line 630 "ext/standard/var_unserializer.re" +#line 635 "ext/standard/var_unserializer.re" { size_t len, len2, len3, maxlen; long elements; @@ -623,10 +628,19 @@ yy20: BG(serialize_lock) = 1; if (zend_lookup_class(class_name, len2, &pce TSRMLS_CC) == SUCCESS) { BG(serialize_lock) = 0; + if (EG(exception)) { + efree(class_name); + return 0; + } ce = *pce; break; } BG(serialize_lock) = 0; + + if (EG(exception)) { + efree(class_name); + return 0; + } /* Check for unserialize callback */ if ((PG(unserialize_callback_func) == NULL) || (PG(unserialize_callback_func)[0] == '\0')) { @@ -644,6 +658,12 @@ yy20: BG(serialize_lock) = 1; if (call_user_function_ex(CG(function_table), NULL, user_func, &retval_ptr, 1, args, 0, NULL TSRMLS_CC) != SUCCESS) { BG(serialize_lock) = 0; + if (EG(exception)) { + efree(class_name); + zval_ptr_dtor(&user_func); + zval_ptr_dtor(&arg_func_name); + return 0; + } php_error_docref(NULL TSRMLS_CC, E_WARNING, "defined (%s) but not found", user_func->value.str.val); incomplete_class = 1; ce = PHP_IC_ENTRY; @@ -655,6 +675,12 @@ yy20: if (retval_ptr) { zval_ptr_dtor(&retval_ptr); } + if (EG(exception)) { + efree(class_name); + zval_ptr_dtor(&user_func); + zval_ptr_dtor(&arg_func_name); + return 0; + } /* The callback function may have defined the class */ if (zend_lookup_class(class_name, len2, &pce TSRMLS_CC) == SUCCESS) { @@ -691,7 +717,7 @@ yy20: return object_common2(UNSERIALIZE_PASSTHRU, elements); } -#line 695 "ext/standard/var_unserializer.c" +#line 721 "ext/standard/var_unserializer.c" yy25: yych = *++YYCURSOR; if (yych <= ',') { @@ -716,7 +742,7 @@ yy27: yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; -#line 622 "ext/standard/var_unserializer.re" +#line 627 "ext/standard/var_unserializer.re" { INIT_PZVAL(*rval); @@ -724,7 +750,7 @@ yy27: return object_common2(UNSERIALIZE_PASSTHRU, object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR)); } -#line 728 "ext/standard/var_unserializer.c" +#line 754 "ext/standard/var_unserializer.c" yy32: yych = *++YYCURSOR; if (yych == '+') goto yy33; @@ -745,7 +771,7 @@ yy34: yych = *++YYCURSOR; if (yych != '{') goto yy18; ++YYCURSOR; -#line 602 "ext/standard/var_unserializer.re" +#line 607 "ext/standard/var_unserializer.re" { long elements = parse_iv(start + 2); /* use iv() not uiv() in order to check data range */ @@ -765,7 +791,7 @@ yy34: return finish_nested_data(UNSERIALIZE_PASSTHRU); } -#line 769 "ext/standard/var_unserializer.c" +#line 795 "ext/standard/var_unserializer.c" yy39: yych = *++YYCURSOR; if (yych == '+') goto yy40; @@ -786,7 +812,7 @@ yy41: yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; -#line 573 "ext/standard/var_unserializer.re" +#line 578 "ext/standard/var_unserializer.re" { size_t len, maxlen; char *str; @@ -815,7 +841,7 @@ yy41: ZVAL_STRINGL(*rval, str, len, 0); return 1; } -#line 819 "ext/standard/var_unserializer.c" +#line 845 "ext/standard/var_unserializer.c" yy46: yych = *++YYCURSOR; if (yych == '+') goto yy47; @@ -836,7 +862,7 @@ yy48: yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; -#line 545 "ext/standard/var_unserializer.re" +#line 550 "ext/standard/var_unserializer.re" { size_t len, maxlen; char *str; @@ -864,7 +890,7 @@ yy48: ZVAL_STRINGL(*rval, str, len, 1); return 1; } -#line 868 "ext/standard/var_unserializer.c" +#line 894 "ext/standard/var_unserializer.c" yy53: yych = *++YYCURSOR; if (yych <= '/') { @@ -952,7 +978,7 @@ yy61: } yy63: ++YYCURSOR; -#line 535 "ext/standard/var_unserializer.re" +#line 540 "ext/standard/var_unserializer.re" { #if SIZEOF_LONG == 4 use_double: @@ -962,7 +988,7 @@ use_double: ZVAL_DOUBLE(*rval, zend_strtod((const char *)start + 2, NULL)); return 1; } -#line 966 "ext/standard/var_unserializer.c" +#line 992 "ext/standard/var_unserializer.c" yy65: yych = *++YYCURSOR; if (yych <= ',') { @@ -1021,7 +1047,7 @@ yy73: yych = *++YYCURSOR; if (yych != ';') goto yy18; ++YYCURSOR; -#line 520 "ext/standard/var_unserializer.re" +#line 525 "ext/standard/var_unserializer.re" { *p = YYCURSOR; INIT_PZVAL(*rval); @@ -1036,7 +1062,7 @@ yy73: return 1; } -#line 1040 "ext/standard/var_unserializer.c" +#line 1066 "ext/standard/var_unserializer.c" yy76: yych = *++YYCURSOR; if (yych == 'N') goto yy73; @@ -1063,7 +1089,7 @@ yy79: if (yych <= '9') goto yy79; if (yych != ';') goto yy18; ++YYCURSOR; -#line 493 "ext/standard/var_unserializer.re" +#line 498 "ext/standard/var_unserializer.re" { #if SIZEOF_LONG == 4 int digits = YYCURSOR - start - 3; @@ -1090,7 +1116,7 @@ yy79: ZVAL_LONG(*rval, parse_iv(start + 2)); return 1; } -#line 1094 "ext/standard/var_unserializer.c" +#line 1120 "ext/standard/var_unserializer.c" yy83: yych = *++YYCURSOR; if (yych <= '/') goto yy18; @@ -1098,24 +1124,24 @@ yy83: yych = *++YYCURSOR; if (yych != ';') goto yy18; ++YYCURSOR; -#line 486 "ext/standard/var_unserializer.re" +#line 491 "ext/standard/var_unserializer.re" { *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_BOOL(*rval, parse_iv(start + 2)); return 1; } -#line 1109 "ext/standard/var_unserializer.c" +#line 1135 "ext/standard/var_unserializer.c" yy87: ++YYCURSOR; -#line 479 "ext/standard/var_unserializer.re" +#line 484 "ext/standard/var_unserializer.re" { *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_NULL(*rval); return 1; } -#line 1119 "ext/standard/var_unserializer.c" +#line 1145 "ext/standard/var_unserializer.c" yy89: yych = *++YYCURSOR; if (yych <= ',') { @@ -1138,7 +1164,7 @@ yy91: if (yych <= '9') goto yy91; if (yych != ';') goto yy18; ++YYCURSOR; -#line 456 "ext/standard/var_unserializer.re" +#line 461 "ext/standard/var_unserializer.re" { long id; @@ -1161,7 +1187,7 @@ yy91: return 1; } -#line 1165 "ext/standard/var_unserializer.c" +#line 1191 "ext/standard/var_unserializer.c" yy95: yych = *++YYCURSOR; if (yych <= ',') { @@ -1184,7 +1210,7 @@ yy97: if (yych <= '9') goto yy97; if (yych != ';') goto yy18; ++YYCURSOR; -#line 435 "ext/standard/var_unserializer.re" +#line 440 "ext/standard/var_unserializer.re" { long id; @@ -1205,9 +1231,9 @@ yy97: return 1; } -#line 1209 "ext/standard/var_unserializer.c" +#line 1235 "ext/standard/var_unserializer.c" } -#line 761 "ext/standard/var_unserializer.re" +#line 787 "ext/standard/var_unserializer.re" return 0; diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re index 204995783f..4d99cbfd78 100644 --- a/ext/standard/var_unserializer.re +++ b/ext/standard/var_unserializer.re @@ -400,8 +400,13 @@ static inline int object_common2(UNSERIALIZE_PARAMETER, long elements) BG(serialize_lock)--; } - if (retval_ptr) + if (retval_ptr) { zval_ptr_dtor(&retval_ptr); + } + + if (EG(exception)) { + return 0; + } return finish_nested_data(UNSERIALIZE_PASSTHRU); @@ -681,10 +686,19 @@ object ":" uiv ":" ["] { BG(serialize_lock) = 1; if (zend_lookup_class(class_name, len2, &pce TSRMLS_CC) == SUCCESS) { BG(serialize_lock) = 0; + if (EG(exception)) { + efree(class_name); + return 0; + } ce = *pce; break; } BG(serialize_lock) = 0; + + if (EG(exception)) { + efree(class_name); + return 0; + } /* Check for unserialize callback */ if ((PG(unserialize_callback_func) == NULL) || (PG(unserialize_callback_func)[0] == '\0')) { @@ -702,6 +716,12 @@ object ":" uiv ":" ["] { BG(serialize_lock) = 1; if (call_user_function_ex(CG(function_table), NULL, user_func, &retval_ptr, 1, args, 0, NULL TSRMLS_CC) != SUCCESS) { BG(serialize_lock) = 0; + if (EG(exception)) { + efree(class_name); + zval_ptr_dtor(&user_func); + zval_ptr_dtor(&arg_func_name); + return 0; + } php_error_docref(NULL TSRMLS_CC, E_WARNING, "defined (%s) but not found", user_func->value.str.val); incomplete_class = 1; ce = PHP_IC_ENTRY; @@ -713,6 +733,12 @@ object ":" uiv ":" ["] { if (retval_ptr) { zval_ptr_dtor(&retval_ptr); } + if (EG(exception)) { + efree(class_name); + zval_ptr_dtor(&user_func); + zval_ptr_dtor(&arg_func_name); + return 0; + } /* The callback function may have defined the class */ if (zend_lookup_class(class_name, len2, &pce TSRMLS_CC) == SUCCESS) { |