diff --git a/CODING_STANDARDS b/CODING_STANDARDS index 16ec36b681307..5fd3f9f35a19d 100644 --- a/CODING_STANDARDS +++ b/CODING_STANDARDS @@ -59,8 +59,8 @@ Exceptions: you're calling. 7. When commenting out code using a #if statement, do NOT use 0 only. Instead - use "_0". For example, #if FOO_0, where FOO is your - svn user foo. This allows easier tracking of why code was commented out, + use "_0". For example, #if FOO_0, where FOO is your + git user foo. This allows easier tracking of why code was commented out, especially in bundled libraries. 8. Do not define functions that are not available. For instance, if a @@ -151,7 +151,7 @@ Naming Conventions 7. Classes should be given descriptive names. Avoid using abbreviations where possible. Each word in the class name should start with a capital letter, - without underscore delimiters (CampelCaps starting with a capital letter). + without underscore delimiters (CamelCaps starting with a capital letter). The class name should be prefixed with the name of the 'parent set' (e.g. the name of the extension):: diff --git a/NEWS b/NEWS index 540f896fe4c68..a1fa83c231709 100644 --- a/NEWS +++ b/NEWS @@ -1,56 +1,10 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -?? ??? 201?, PHP 5.6.0 +?? ??? 20??, PHP 5.7.0 -- Core: - . Improved IS_VAR operands fetching. (Laruence, Dmitry) - . Implemented internal operator overloading - (RFC: https://wiki.php.net/rfc/operator_overloading_gmp). (Nikita) - . Made calls from incompatible context issue an E_DEPRECATED warning instead - of E_STRICT (phase 1 of RFC: https://wiki.php.net/rfc/incompat_ctx). - (Gustavo) - . Uploads equal or greater than 2GB in size are now accepted. - (Ralf Lang, Mike) - . Reduced POST data memory usage by 200-300%. Removed INI setting - always_populate_raw_post_data and the $HTTP_RAW_POST_DATA global - variable. (Mike) - -- cURL: - . Implemented FR #65646 (re-enable CURLOPT_FOLLOWLOCATION with open_basedir - or safe_mode). (Adam) - -- GMP: - . Moved GMP to use object as the underlying structure and implemented various - improvements based on this. - (RFC: https://wiki.php.net/rfc/operator_overloading_gmp). (Nikita) - -- mysqlnd: - . Disabled flag for SP OUT variables for 5.5+ servers as they are not natively - supported by the overlying APIs. (Andrey) - -- OPcache: - . Added an optimization pass to convert FCALL_BY_NAME into DO_FCALL. - (Laruence, Dmitry) - . Added an optimization pass to merged identical constants (and related - cache_slots) in op_array->literals table. (Laruence, Dmitry) - . Added script level constant replacement optimization pass. (Dmitry) - -- PDO_pgsql: - . Fixed Bug #42614 (PDO_pgsql: add pg_get_notify support). (Matteo) - . Fixed Bug #63657 (pgsqlCopyFromFile, pgsqlCopyToArray use Postgres < 7.3 - syntax). (Matteo) - -- Session: - . Fixed Bug #65315 (session.hash_function silently fallback to default md5) - (Yasuo) - . Implemented Request #54649 (Create session_serializer_name()). (Yasuo) - . Implemented Request #17860 (Session write short circuit). (Yasuo) - . Implemented Request #20421 (session_abort() and session_reset() function). - (Yasuo) - . Implemented Request #11100 (session_gc() function). (Yasuo) - -- Standard: - . Implemented FR #65634 (HTTP wrapper is very slow with protocol_version - 1.1). (Adam) +- DBA: + . Fixed bug #62490 (dba_delete returns true on missing item (inifile)). (Mike) +- XSL: + . Fixed bug #64776 (The XSLT extension is not thread safe). (Mike) <<< NOTE: Insert NEWS from last stable release here prior to actual release! >>> diff --git a/README.EXT_SKEL b/README.EXT_SKEL index b0db843a42ba0..d44fcc5c6a92c 100644 --- a/README.EXT_SKEL +++ b/README.EXT_SKEL @@ -31,6 +31,11 @@ HOW TO USE IT ./buildconf; ./configure --enable-module_name; make + The definition of PHP_MODULE_NAME_VERSION will be present in the + php_module_name.h and injected into the zend_module_entry definition. This + is required by the PECL website for the version string conformity checks + against package.xml + But if you already have planned the overall scheme of your module, what functions it will contain, their return types and the arguments they take (a very good idea) and don't want to bother yourself with creating function diff --git a/README.GIT-RULES b/README.GIT-RULES index 6e90aa97b6ff4..3df9d17bcda21 100644 --- a/README.GIT-RULES +++ b/README.GIT-RULES @@ -69,9 +69,11 @@ The next few rules are more of a technical nature:: branches) an empty merge should be done. 2. All news updates intended for public viewing, such as new features, - bug fixes, improvements, etc., should go into the NEWS file of the - *first* to be released version with the given change. In other words - any NEWS file change only needs to done in one branch. + bug fixes, improvements, etc., should go into the NEWS file of *any + stable release* version with the given change. In other words, + news about a bug fix which went into PHP-5.4, PHP-5.5 and master + should be noted in both PHP-5.4/NEWS and PHP-5.5/NEWS but + not master, which is not a public released version yet. 3. Do not commit multiple file and dump all messages in one commit. If you modified several unrelated files, commit each group separately and diff --git a/README.RELEASE_PROCESS b/README.RELEASE_PROCESS index 06f4724f7a0a5..a0c34f8f7aa5b 100644 --- a/README.RELEASE_PROCESS +++ b/README.RELEASE_PROCESS @@ -8,15 +8,16 @@ General notes and tips 1. Do not release on Fridays, Saturdays or Sundays because the sysadmins can not upgrade stuff then. -2. Package the day before a release. So if the release is to be on Thursday, -package on Wednesday. +2. Package two days before a release. So if the release is to be on Thursday, +package on Tuesday. Think about timezones as well. 3. Ensure that Windows builds will work before packaging -4. Follow all steps to the letter. When unclear ask previous RM's (Derick/Ilia) -before proceeding. Ideally make sure that for the first releases one of the -previous RM's is around to answer questions. For the steps related to the -php/QA/bug websites try to have someone from the webmaster team (Bjori) on hand. +4. Follow all steps to the letter. When unclear ask previous RM's (David/Julien/ +Johannes/Stas/Derick/Ilia) before proceeding. Ideally make sure that for the +first releases one of the previous RM's is around to answer questions. For the +steps related to the php/QA/bug websites try to have someone from the webmaster +team (Bjori) on hand. 5. Verify the tags to be extra sure everything was tagged properly. @@ -50,37 +51,47 @@ Rolling a non stable release (alpha/beta/RC) 2. run the "scripts/dev/credits" script in php-src and commit the changes in the credits files in ext/standard. -3. Checkout the release branch for this release (e.g., PHP-5.4.2). +3. Checkout the release branch for this release (e.g., PHP-5.4.2) from the main branch. 4. Bump the version numbers in ``main/php_version.h``, ``configure.in`` and possibly ``NEWS``. -Do not use abbreviations for alpha and beta. +Do not use abbreviations for alpha and beta. Do not use dashes, you should +``#define PHP_VERSION "5.4.22RC1"`` and not ``#define PHP_VERSION "5.4.22-RC1"`` -5. Commit these changes to the branch with ``git commit -a``. +5. Compile and make test, with and without ZTS, using the right Bison version +(for example, for 5.5, Bison 2.4.1 is used) -6. Tag the repository with the version, e.g.: +6. Check ./sapi/cli/php -v output for version matching. + +7. If all is right, commit the changes to the release branch with ``git commit -a``. + +8. Tag the repository release branch with the version, e.g.: ``git tag -u YOURKEYID php-5.4.2RC2`` -7. Push the changes to the main repo: +9. Bump the version numbers in ``main/php_version.h``, ``configure.in`` and ``NEWS`` +in the *main* branch (PHP-5.4 for example) to prepare for the **next** version. +F.e. if the RC is "5.4.1RC1" then the new one should be "5.4.2-dev" - regardless if we get +a new RC or not. This is to make sure ``version_compare()`` can correctly work. +Commit the changes to the main branch. + +10. Push the changes to the main repo, the tag, the main branch and the release branch : ``git push --tags origin HEAD`` +``git push origin {main branch}`` +``git push origin {release branch}`` -8. run: ``./makedist 5.4.2RC2``, this will export the tree, create configure -and build three tarballs (gz,bz2 and xz). Make sure you use the same GNU Bison -version as snaps. Recent bison version are known to break ZTS. +11. run: ``PHPROOT=. ./makedist 5.4.2RC2``, this will export the tree, create configure +and build three tarballs (gz, bz2 and xz). -9. Copy those three tarballs to www.php.net, in your homedir there should be a +12. Copy those tarballs (scp, rsync) to downloads.php.net, in your homedir there should be a directory "downloads/". Copy them into there, so that the system can generate -MD5 sums. If you do not have this directory, talk to Derick. +MD5 sums. If you do not have this directory, talk to Derick or Dan. -10. Now the RC can be found on http://downloads.php.net/yourname, +13. Now the RC can be found on http://downloads.php.net/yourname, f.e. http://downloads.php.net/derick/ -11. Once the release has been tagged, contact the PHP Windows development team +14. Once the release has been tagged, contact the PHP Windows development team (internals-win@lists.php.net) so that Windows binaries can be created. Once those are made, they should be placed into the same directory as the source snapshots. -12. Notify the documentation team if documentations for new features are -not yet available but a stable release is imminent. - Getting the non stable release (alpha/beta/RC) announced -------------------------------------------------------- @@ -109,9 +120,9 @@ Derick) run the following commands for you: Note: Remember to update the MD5 checksum information. -4. Update ``php.git/include/version.inc`` (x=major version number) +4. Update ``web/php.git/include/version.inc`` (x=major version number) - a. ``$PHP_x_RC`` = "5.4.0RC1" + a. ``$PHP_x_RC`` = "5.4.0RC1" (should be set to "false" before) b. ``$PHP_x_RC_DATE`` = "06 September 2007" @@ -122,70 +133,61 @@ Derick) run the following commands for you: 6. For the first RC, write the doc team (phpdoc@lists.php.net) about updating the INSTALL and win32/install.txt files which are generated from the PHP manual sources. -7. Publish the announce on www.php.net as well (for all releases, alpha, RCs or other) - Rolling a stable release ------------------------ -1. Check windows snapshot builder logs (http://snaps.php.net/win32/snapshot-STABLE.log f.e.) - -2. Bump the version numbers in ``main/php_version.h``, ``configure.in`` and possibly ``NEWS``. +1. Checkout your release branch, you should have created when releasing previous RC +and bump the version numbers in ``main/php_version.h``, ``configure.in`` and possibly ``NEWS``. -3. **Merge** all related sections in NEWS (f.e. merge the 5.4.1RC1 and 5.4.0 sections) +2. If a CVE commit needs to be merged to the release, then have it commited to +the base branches and merged upwards as usual (f.e commit the CVE fix to 5.3, +merge to 5.4, 5.5 etc...). Then you can cherry-pick it in your release branch. +Don't forget to update NEWS manually in an extra commit then. -4. Commit those changes +3. Commit those changes -5. run the "scripts/dev/credits" script in php-src and commit the changes in the +4. run the "scripts/dev/credits" script in php-src and commit the changes in the credits files in ext/standard. -6. tag the repository with the version f.e. "``git tag -s php-5.4.1``" -(of course, you need to change that to the version you're rolling an RC for). -When making 5.X release, you need to tag the Zend directory separately!! +5. Compile and make test, with and without ZTS, using the right Bison version +(for example, for 5.5, Bison 2.4.1 is used) -7. Bump up the version numbers in ``main/php_version.h``, ``configure.in`` and -possibly ``NEWS`` again, to the **next** version. F.e. if the release candidate -was "5.4.1RC1" then the new one should be "5.4.1RC2-dev" - regardless if we get -a new RC or not. This is to make sure ``version_compare()`` can correctly work. +6. Check ./sapi/cli/php -v output for version matching. -8. Commit those changes +7. tag the repository with the version f.e. "``git tag -s php-5.4.1``" -9. Log in onto the snaps box and go into the correct tree (f.e. the PHP-5.4 -branch if you're rolling 5.5.x releases). +8. Push the tag f.e. "``git push origin php-5.4.1``" -10. You do not have to update the tree, but of course you can with "``git pull -origin ``". +9. run: ``PHPROOT=. ./makedist php 5.4.1``, this will export the tag, create configure +and build three tarballs (gz, bz2 and xz). +Check if the pear files are updated (phar). -11. run: ``./makedist php 5.4.1``, this will export the tree, create configure -and build two tarballs (one gz and one bz2). +10. Generate the GPG signature files for the archives. + ``gpg -u YOUREMAIL --armor --detach-sign php-X.Y.Z.tar.xxx`` -12. Commit those two tarballs to web/php-distributions.git, then update the git - submodule reference in web/php.git: - git submodule init; +11. Commit and push all the tarballs and signature files to web/php-distributions.git, + then update the git submodule reference in web/php.git: + ``git submodule init; git submodule update; cd distributions; git pull origin master; cd ..; git commit distributions; - git push; - -13. Once the release has been tagged, contact the PHP Windows development team -(internals-win@lists.php.net) so that Windows binaries can be created. Once -those are made, they should be committed to SVN too. + git push;`` +This is to fetch the last commit id from php-distributions.git and commit this +last commit id to web/php.git, then, mirrors will now sync -14. Check if the pear files are updated (phar for 5.1+ or run pear/make-pear-bundle.php with 4.4) - -15. When making a final release, also remind the PHP Windows development team -(internals-win@lists.php.net) to prepare the installer packages for Win32. - -16. Make sure proper documentation exists for all new features/changes. -Coordinate the release with the PHP Documentation team. +12. Once the release has been tagged, contact the PHP Windows development team +(internals-win@lists.php.net) so that Windows binaries can be created. Getting the stable release announced ------------------------------------ 1. Run the bumpRelease script for phpweb on your local checkout - a. ``php bin/bumpRelease 5`` (or ``php bin/bumpRelease 4`` for PHP4) + a. ``php bin/bumpRelease 5`` to create the release file (releases/x_y_z.php) + The release announcement file should list in detail security fixes and + changes in behavior (whether due to a bug fix or not). b. In case multiple PHP minor versions are in active development you have to manually copy the old information to include/releases.inc @@ -205,7 +207,13 @@ Getting the stable release announced f. if the windows builds aren't ready yet prefix the "windows" key with a dot (".windows") -3. Update the ChangeLog file for the given major version +3. Update phpweb/include/releases.php with the old release info + (updates the download archives) + +4. Update php-qa/include/release-qa.php and add the next version as an QARELEASE + (prepare for next RC) + +5. Update the ChangeLog file for the given major version f.e. ``ChangeLog-5.php`` from the NEWS file a. go over the list and put every element on one line @@ -225,19 +233,10 @@ f.e. ``ChangeLog-5.php`` from the NEWS file IV. ``s/Fixed PECL bug #\([0-9]\+\)//`` V. ``s/FR #\([0-9]\+\)/FR /`` + + e. You may want to try php-web/bin/news2html to automate this task -4. ``cp releases/5_4_0.php releases/5_4_1.php`` - -5. ``git add releases/5_4_1.php`` - -6. Update the ``releases/*.php`` file with relevant data. The release -announcement file should list in detail: - - a. security fixes, - - b. changes in behavior (whether due to a bug fix or not) - -7. Add a short notice to phpweb stating that there is a new release, and +6. Add a short notice to phpweb stating that there is a new release, and highlight the major important things (security fixes) and when it is important to upgrade. @@ -245,7 +244,11 @@ to upgrade. b. Add the content for the news entry -8. Commit all the changes. +7. **Check mirrors have been synced before announcing or pushing news** + Try, f.e. http://www.php.net/get/php-5.5.1.tar.bz2/from/a/mirror + Try several mirrors, mirrors may update slowly (may take an hour) + +8. Commit all the changes to their respective git repos 9. Wait an hour or two, then send a mail to php-announce@lists.php.net, php-general@lists.php.net and internals@lists.php.net with a text similar to diff --git a/README.SELF-CONTAINED-EXTENSIONS b/README.SELF-CONTAINED-EXTENSIONS index e6a375331b4a5..5287230e1aea0 100644 --- a/README.SELF-CONTAINED-EXTENSIONS +++ b/README.SELF-CONTAINED-EXTENSIONS @@ -153,3 +153,18 @@ ADDING SHARED MODULE SUPPORT TO A MODULE #ifdef COMPILE_DL_FOO ZEND_GET_MODULE(foo) #endif + +PECL SITE CONFORMITY + + If you plan to release an extension to the PECL website, there are several + points to be regarded. + + 1. Add LICENSE or COPYING to the package.xml + + 2. The following should be defined in one of the extension header files + + #define PHP_FOO_VERSION "1.2.3" + + This macros has to be used within your foo_module_entry to indicate the + extension version. + diff --git a/README.md b/README.md index 51973854db86f..09e70e6a39f99 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ See https://wiki.php.net/rfc and https://wiki.php.net/rfc/voting for more information on the process. Bug fixes **do not** require an RFC, but require a bugtracker ticket. Always -open a ticket at http://bugs.php.net and reference the bug id using #NNNNNN. +open a ticket at https://bugs.php.net and reference the bug id using #NNNNNN. Fix #55371: get_magic_quotes_gpc() throws deprecation warning @@ -28,3 +28,12 @@ open a ticket at http://bugs.php.net and reference the bug id using #NNNNNN. We do not merge pull requests directly on github. All PRs will be pulled and pushed through http://git.php.net. + + +Guidelines for contributors +=========================== +- [CODING_STANDARDS](/CODING_STANDARDS) +- [README.GIT-RULES](/README.GIT-RULES) +- [README.MAILINGLIST_RULES](/README.MAILINGLIST_RULES) +- [README.RELEASE_PROCESS](/README.RELEASE_PROCESS) + diff --git a/TSRM/Makefile.am b/TSRM/Makefile.am index 91e585b65c89a..e232381a019e1 100644 --- a/TSRM/Makefile.am +++ b/TSRM/Makefile.am @@ -1,6 +1,6 @@ ## process this file with automake to produce Makefile.am AUTOMAKE_OPTIONS=foreign noinst_LTLIBRARIES=libtsrm.la -libtsrm_la_SOURCES = TSRM.c tsrm_strtok_r.c tsrm_virtual_cwd.c +libtsrm_la_SOURCES = TSRM.c tsrm_strtok_r.c depend: diff --git a/TSRM/TSRM.dsp b/TSRM/TSRM.dsp index 1a5693f5a23c4..6c3e8bfb8bede 100644 --- a/TSRM/TSRM.dsp +++ b/TSRM/TSRM.dsp @@ -143,10 +143,6 @@ SOURCE=.\tsrm_strtok_r.c # End Source File # Begin Source File -SOURCE=.\tsrm_virtual_cwd.c -# End Source File -# Begin Source File - SOURCE=.\tsrm_win32.c # End Source File # End Group diff --git a/TSRM/config.w32 b/TSRM/config.w32 index 5498f8e7bd3ec..91b4eead2a07d 100644 --- a/TSRM/config.w32 +++ b/TSRM/config.w32 @@ -1,5 +1,5 @@ // vim:ft=javascript // $Id$ -ADD_SOURCES("TSRM", "TSRM.c tsrm_strtok_r.c tsrm_virtual_cwd.c tsrm_win32.c"); +ADD_SOURCES("TSRM", "TSRM.c tsrm_strtok_r.c tsrm_win32.c"); diff --git a/TSRM/tsrm_win32.c b/TSRM/tsrm_win32.c index 2ec97be0116bc..7b9ebc3061b34 100644 --- a/TSRM/tsrm_win32.c +++ b/TSRM/tsrm_win32.c @@ -32,7 +32,7 @@ #ifdef TSRM_WIN32 #include #include "tsrm_win32.h" -#include "tsrm_virtual_cwd.h" +#include "zend_virtual_cwd.h" #ifdef ZTS static ts_rsrc_id win32_globals_id; diff --git a/UPGRADING b/UPGRADING index f5e7cd0bbdbb9..f5e36fefc8482 100755 --- a/UPGRADING +++ b/UPGRADING @@ -20,23 +20,14 @@ PHP X.Y UPGRADE NOTES 1. Backward Incompatible Changes ======================================== -- Core: - Removed $HTTP_RAW_POST_DATA global variable. Restore backwards compatibility - by: - +- DBA + . dba_delete() now returns false if the key was not found for the inifile + handler, too. ======================================== 2. New Features ======================================== -- Core: - The php://input stream is now re-usable and can be used concurrently with - enable_post_data_reading=0. ======================================== 2. Changes in SAPI modules @@ -47,17 +38,11 @@ PHP X.Y UPGRADE NOTES 3. Deprecated Functionality ======================================== -- Incompatible context calls: - Instance calls from an incompatible context are now deprecated and issue - E_DEPRECATED instead of E_STRICT. See https://wiki.php.net/rfc/incompat_ctx ======================================== 4. Changed Functions ======================================== -- cURL: - CURLOPT_SAFE_UPLOAD is now turned on by default and uploads with @file - do not work unless it is explicitly set to false. ======================================== 5. New Functions @@ -78,21 +63,6 @@ PHP X.Y UPGRADE NOTES 8. Other Changes to Extensions ======================================== -- GMP: - The GMP extension now uses objects as the underlying data structure, rather - than resources. GMP instances now support dumping, serialization, cloning, - casts to primitive types and have overloaded operators. - (RFC: https://wiki.php.net/rfc/operator_overloading_gmp) - -- OCI8: - - Added Implicit Result Set support for Oracle Database 12c with a - new oci_get_implicit_resultset() function. - - Using 'oci_execute($s, OCI_NO_AUTO_COMMIT)' for a SELECT no longer - unnecessarily initiates an internal ROLLBACK during connection - close. - - Added DTrace probes enabled with PHP's generic --enable-dtrace - - The oci_internal_debug() function is now a no-op. - - The phpinfo() output format for OCI8 has changed. ======================================== 9. New Global Constants @@ -103,16 +73,8 @@ PHP X.Y UPGRADE NOTES 10. Changes to INI File Handling ======================================== -- Core: - Removed always_populate_raw_post_data. ======================================== 11. Other Changes ======================================== -- File upload: - Uploads equal or greater than 2GB in size are now accepted. - -- HTTP stream wrapper: - HTTP 1.1 requests now include a Connection: close header unless explicitly - overridden by setting a Connection header via the header context option. diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index 90202f00f03ca..97b281a93ed64 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -6,6 +6,7 @@ UPGRADE NOTES - PHP X.Y a. Addition of do_operation and compare object handlers b. return_value_ptr now always available, RETVAL_ZVAL_FAST macros c. POST data handling + d. Arginfo changes 2. Build system changes a. Unix build system changes @@ -16,67 +17,11 @@ UPGRADE NOTES - PHP X.Y 1. Internal API changes ======================== - a. Addition of do_operation and compare object handlers - - Two new object handlers have been added: - - do_operation: - typedef int (*zend_object_do_operation_t)( - zend_uchar opcode, zval *result, zval *op1, zval *op2 TSRMLS_DC - ); - - compare: - typedef int (*zend_object_compare_zvals_t)( - zval *result, zval *op1, zval *op2 TSRMLS_DC - ); - - The first handler is used to overload arithmetic operations. The first - argument specifies the opcode of the operator, result is the target zval, - op1 the first operand and op2 the second operand. For unary operations - op2 is NULL. If the handler returns FAILURE PHP falls back to the default - behavior for the operation. - - The second handler is used to perform comparison operations with - non-objects. The value written into result must be an IS_LONG with value - -1 (smaller), 0 (equal) or 1 (greater). The return value is a SUCCESS/FAILURE - return code. The difference between this handler and compare_objects is - that it will be triggered for comparisons with non-objects and objects of - different types. It takes precedence over compare_objects. - - Further docs in the RFC: https://wiki.php.net/rfc/operator_overloading_gmp - - b. return_value_ptr now always available, RETVAL_ZVAL_FAST macros + a. zend_set_memory_limit() now takes the TSRMLS_CC macro as its last argument - The return_value_ptr argument to internal functions is now always set. - Previously it was only available for functions returning by-reference. - return_value_ptr can now be used to return zvals without copying them. - For this purpose two new macros are provided: - - RETVAL_ZVAL_FAST(zv); /* analog to RETVAL_ZVAL(zv, 1, 0) */ - RETURN_ZVAL_FAST(zv); /* analog to RETURN_ZVAL(zv, 1, 0) */ - - The macros behave similarly to the non-FAST variants with copy=1 and - dtor=0, but will try to return the zval without making a copy by utilizing - return_value_ptr. - - c. POST data handling - - The sapi_request_info's members post_data, post_data_len and raw_post_data as - well as raw_post_data_len have been replaced with a temp PHP stream - request_body. - - The recommended way to access raw POST data is to open and use a php://input - stream wrapper. It is safe to be used concurrently and more than once. ======================== 2. Build system changes ======================== - a. Unix build system changes - - The bison version check is now a blacklist instead of a whitelist. - - The bison binary can be specified through the YACC environment/configure - variable. Previously `bison` was assumed to be in $PATH. - - b. Windows build system changes - - diff --git a/Zend/Makefile.am b/Zend/Makefile.am index 6417f3eb141ed..d9ce4c61ba51c 100644 --- a/Zend/Makefile.am +++ b/Zend/Makefile.am @@ -18,7 +18,7 @@ libZend_la_SOURCES=\ zend_default_classes.c \ zend_iterators.c zend_interfaces.c zend_exceptions.c \ zend_strtod.c zend_closures.c zend_float.c zend_string.c zend_signal.c \ - zend_generators.c + zend_generators.c zend_virtual_cwd.c zend_ast.c libZend_la_LDFLAGS = libZend_la_LIBADD = @ZEND_EXTRA_LIBS@ diff --git a/Zend/RFCs/003.txt b/Zend/RFCs/003.txt index 30fb4cec4912f..ac042183d426c 100644 --- a/Zend/RFCs/003.txt +++ b/Zend/RFCs/003.txt @@ -9,11 +9,11 @@ Modified: 2001-09-17 1. Background/Need ================== -Many internal function of PHP will reject parameters because of their +Many internal functions of PHP will reject parameters because of their type (the array and variable function come to mind). For userland this is not an easy task as there is no uniform way to do it. An addition to the engine for requiring loose types would allow -delevopers to know that the data passed to their functions is of the +developers to know that the data passed to their functions are of the correct type and reduce the need for duplicating the same code in every function to check for the type of data. @@ -57,7 +57,7 @@ function foo (array $var){ =========== Mis-matches in type should be reported as fatal errors and should halt -the execution of a script as that function can not be run and code +the execution of a script as that function cannot be run and code following could not reliably run. diff --git a/Zend/Zend.dsp b/Zend/Zend.dsp index 23ebd4532b5e7..d8bb03b9e86ea 100644 --- a/Zend/Zend.dsp +++ b/Zend/Zend.dsp @@ -119,6 +119,10 @@ SOURCE=.\zend_API.c # End Source File # Begin Source File +SOURCE=.\zend_ast.c +# End Source File +# Begin Source File + SOURCE=.\zend_builtin_functions.c # End Source File # Begin Source File @@ -429,6 +433,10 @@ SOURCE=.\zend_ts_hash.h SOURCE=.\zend_variables.h # End Source File +# Begin Source File + +SOURCE=.\zend_virtual_cwd.c +# End Source File # End Group # Begin Group "Parsers" diff --git a/Zend/ZendTS.dsp b/Zend/ZendTS.dsp index 3be2c58bed6fa..5dfa24d5b98f4 100644 --- a/Zend/ZendTS.dsp +++ b/Zend/ZendTS.dsp @@ -140,6 +140,10 @@ SOURCE=.\zend_alloc.c # End Source File # Begin Source File +SOURCE=.\zend_ast.c +# End Source File +# Begin Source File + SOURCE=.\zend_API.c # End Source File # Begin Source File diff --git a/Zend/tests/arg_unpack/basic.phpt b/Zend/tests/arg_unpack/basic.phpt new file mode 100644 index 0000000000000..9c0365586aec7 --- /dev/null +++ b/Zend/tests/arg_unpack/basic.phpt @@ -0,0 +1,114 @@ +--TEST-- +Basic argument unpacking +--FILE-- + +--EXPECT-- +array(0) { +} +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +array(0) { +} +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +array(6) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + [5]=> + int(6) +} +array(6) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + [5]=> + int(6) +} +int(1) +int(2) +NULL +int(1) +int(2) +int(3) +int(1) +int(2) +int(3) diff --git a/Zend/tests/arg_unpack/by_ref.phpt b/Zend/tests/arg_unpack/by_ref.phpt new file mode 100644 index 0000000000000..0619a3bab8d66 --- /dev/null +++ b/Zend/tests/arg_unpack/by_ref.phpt @@ -0,0 +1,149 @@ +--TEST-- +Argument unpacking with by-ref arguments +--FILE-- + +--EXPECTF-- +array(3) { + [0]=> + int(2) + [1]=> + int(3) + [2]=> + int(4) +} +array(2) { + [0]=> + int(2) + [1]=> + int(3) +} +int(4) +array(2) { + [0]=> + int(5) + [1]=> + int(6) +} +array(4) { + [0]=> + int(1) + [1]=> + int(3) + [2]=> + int(3) + [3]=> + int(5) +} +array(0) { +} +int(0) +int(1) +int(0) +int(1) +array(1) { + [0]=> + int(1) +} +int(1) +int(1) +int(1) +int(1) +array(2) { + [0]=> + int(1) + [1]=> + int(3) +} +int(1) +int(2) +int(1) +int(1) +array(3) { + [0]=> + int(1) + [1]=> + int(3) + [2]=> + int(3) +} +int(2) +int(2) +int(1) +int(1) + +Notice: Undefined index: a in %s on line %d + +Notice: Undefined index: c in %s on line %d +array(2) { + ["b"]=> + int(1) + ["d"]=> + int(1) +} + +Notice: Undefined index: b in %s on line %d + +Notice: Undefined index: d in %s on line %d +array(2) { + ["a"]=> + int(1) + ["c"]=> + int(1) +} diff --git a/Zend/tests/arg_unpack/dynamic.phpt b/Zend/tests/arg_unpack/dynamic.phpt new file mode 100644 index 0000000000000..efed84da78152 --- /dev/null +++ b/Zend/tests/arg_unpack/dynamic.phpt @@ -0,0 +1,37 @@ +--TEST-- +Unpack arguments for dynamic call +--FILE-- + +--EXPECT-- +array(0) { +} +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +array(5) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) +} diff --git a/Zend/tests/arg_unpack/internal.phpt b/Zend/tests/arg_unpack/internal.phpt new file mode 100644 index 0000000000000..adc985d94068c --- /dev/null +++ b/Zend/tests/arg_unpack/internal.phpt @@ -0,0 +1,43 @@ +--TEST-- +Argument unpacking with internal functions +--FILE-- + +--EXPECT-- +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(4) + [2]=> + int(7) + } + [1]=> + array(3) { + [0]=> + int(2) + [1]=> + int(5) + [2]=> + int(8) + } + [2]=> + array(3) { + [0]=> + int(3) + [1]=> + int(6) + [2]=> + int(9) + } +} diff --git a/Zend/tests/arg_unpack/invalid_type.phpt b/Zend/tests/arg_unpack/invalid_type.phpt new file mode 100644 index 0000000000000..3efffebc76528 --- /dev/null +++ b/Zend/tests/arg_unpack/invalid_type.phpt @@ -0,0 +1,59 @@ +--TEST-- +Only arrays and Traversables can be unpacked +--FILE-- + +--EXPECTF-- +Warning: Only arrays and Traversables can be unpacked in %s on line %d +array(0) { +} + +Warning: Only arrays and Traversables can be unpacked in %s on line %d +array(0) { +} + +Warning: Only arrays and Traversables can be unpacked in %s on line %d +array(0) { +} + +Warning: Only arrays and Traversables can be unpacked in %s on line %d +array(5) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) +} + +Warning: Only arrays and Traversables can be unpacked in %s on line %d + +Warning: Only arrays and Traversables can be unpacked in %s on line %d +array(5) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) +} diff --git a/Zend/tests/arg_unpack/method.phpt b/Zend/tests/arg_unpack/method.phpt new file mode 100644 index 0000000000000..d6a6e4712b8bd --- /dev/null +++ b/Zend/tests/arg_unpack/method.phpt @@ -0,0 +1,45 @@ +--TEST-- +Unpack arguments for method calls +--FILE-- +test(...[1, 2], 3, 4, ...[], 5); +Foo::test2(1, 2, ...[3, 4], ...[], 5); + +?> +--EXPECT-- +array(5) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) +} +array(5) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) +} diff --git a/Zend/tests/arg_unpack/new.phpt b/Zend/tests/arg_unpack/new.phpt new file mode 100644 index 0000000000000..3cf224f288f9c --- /dev/null +++ b/Zend/tests/arg_unpack/new.phpt @@ -0,0 +1,39 @@ +--TEST-- +Unpack arguments for new expression +--FILE-- + +--EXPECT-- +array(0) { +} +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +array(5) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) +} diff --git a/Zend/tests/arg_unpack/string_keys.phpt b/Zend/tests/arg_unpack/string_keys.phpt new file mode 100644 index 0000000000000..443a8829413dd --- /dev/null +++ b/Zend/tests/arg_unpack/string_keys.phpt @@ -0,0 +1,20 @@ +--TEST-- +Argument unpacking does not work with string keys (forward compatibility for named args) +--FILE-- + 3, 4]); +var_dump(...new ArrayIterator([1, 2, "foo" => 3, 4])); + +?> +--EXPECTF-- +string(36) "Cannot unpack array with string keys" +int(1) +int(2) +string(42) "Cannot unpack Traversable with string keys" +int(1) +int(2) diff --git a/Zend/tests/arg_unpack/traversable_throwing_exception.phpt b/Zend/tests/arg_unpack/traversable_throwing_exception.phpt new file mode 100644 index 0000000000000..8ddc24dc74304 --- /dev/null +++ b/Zend/tests/arg_unpack/traversable_throwing_exception.phpt @@ -0,0 +1,33 @@ +--TEST-- +Traversables that throw exceptions are properly handled during argument unpack +--FILE-- +getMessage()); } + +try { + test(1, 2, ...gen(), 3, 4); +} catch (Exception $e) { var_dump($e->getMessage()); } + +?> +--EXPECT-- +string(11) "getIterator" +string(3) "gen" diff --git a/Zend/tests/arg_unpack/traversable_with_by_ref_parameters.phpt b/Zend/tests/arg_unpack/traversable_with_by_ref_parameters.phpt new file mode 100644 index 0000000000000..e862341652f71 --- /dev/null +++ b/Zend/tests/arg_unpack/traversable_with_by_ref_parameters.phpt @@ -0,0 +1,34 @@ +--TEST-- +Traversables cannot be unpacked into by-reference parameters +--FILE-- + +--EXPECTF-- +int(42) +int(42) + +Warning: Cannot pass by-reference argument 4 of test() by unpacking a Traversable, passing by-value instead in %s on line %d + +Warning: Cannot pass by-reference argument 4 of test() by unpacking a Traversable, passing by-value instead in %s on line %d + +Warning: Cannot pass by-reference argument 4 of test() by unpacking a Traversable, passing by-value instead in %s on line %d diff --git a/Zend/tests/bug41421.phpt b/Zend/tests/bug41421.phpt index f10db10980397..f39fb15ddad78 100644 --- a/Zend/tests/bug41421.phpt +++ b/Zend/tests/bug41421.phpt @@ -24,6 +24,6 @@ Warning: feof(): wrapper::stream_eof is not implemented! Assuming EOF in %s on l Fatal error: Uncaught exception 'Exception' in %s:%d Stack trace: #0 [internal function]: wrapper->stream_eof() -#1 %s(%d): feof(Resource id #6) +#1 %s(%d): feof(Resource id #%d) #2 {main} thrown in %s on line %d diff --git a/Zend/tests/bug64979.phpt b/Zend/tests/bug64979.phpt index 09de555546420..5bc8e5a6ab2a4 100644 --- a/Zend/tests/bug64979.phpt +++ b/Zend/tests/bug64979.phpt @@ -1,15 +1,13 @@ --TEST-- -Bug #64578 (Closures with static variables can be generators) ---XFAIL-- -Bug #64979 not fixed yet. +Bug #64979 (Wrong behavior of static variables in closure generators) --FILE-- diff --git a/Zend/tests/bug65322.phpt b/Zend/tests/bug65322.phpt new file mode 100644 index 0000000000000..aab163d915e11 --- /dev/null +++ b/Zend/tests/bug65322.phpt @@ -0,0 +1,22 @@ +--TEST-- +Bug #65322: compile time errors won't trigger auto loading +--FILE-- + +--EXPECTF-- +string(50) "Redefining already defined constructor for class A" +string(%d) "%s(%d) : eval()'d code" +string(1) "B" diff --git a/Zend/tests/bug65784.phpt b/Zend/tests/bug65784.phpt new file mode 100644 index 0000000000000..29f086b5e34bf --- /dev/null +++ b/Zend/tests/bug65784.phpt @@ -0,0 +1,60 @@ +--TEST-- +Fixed Bug #65784 (Segfault with finally) +--FILE-- +getMessage()); + } while ($e = $e->getPrevious()); +} + +function foo2() { + try { + try { + throw new Exception("catched"); + return true; + } finally { + try { + throw new Exception("catched"); + } catch (Exception $e) { + } + } + } catch (Exception $e) { + } +} + +$foo = foo2(); +var_dump($foo); + +function foo3() { + try { + throw new Exception("not catched"); + return true; + } finally { + try { + throw new NotExists(); + } catch (Exception $e) { + } + } +} + +$bar = foo3(); +--EXPECTF-- +string(9) "not catch" +NULL + +Fatal error: Class 'NotExists' not found in %sbug65784.php on line %d diff --git a/Zend/tests/bug65911.phpt b/Zend/tests/bug65911.phpt new file mode 100644 index 0000000000000..b9f37b7bd6a45 --- /dev/null +++ b/Zend/tests/bug65911.phpt @@ -0,0 +1,20 @@ +--TEST-- +Bug #65911 (scope resolution operator - strange behavior with $this) +--FILE-- +foo = 'bar'; + echo A::$this->foo; // should not output 'bar' + } +} + +$obj = new B(); +$obj->go(); +?> +--EXPECTF-- +Fatal error: Access to undeclared static property: A::$this in %s on line %d diff --git a/Zend/tests/bug65969.phpt b/Zend/tests/bug65969.phpt new file mode 100644 index 0000000000000..d5128322aedf2 --- /dev/null +++ b/Zend/tests/bug65969.phpt @@ -0,0 +1,10 @@ +--TEST-- +Bug #65969 (Chain assignment with T_LIST failure) +--FILE-- +prop = [1,2]; +var_dump($a,$b); +--EXPECT-- +int(1) +int(2) diff --git a/Zend/tests/bug66218.phpt b/Zend/tests/bug66218.phpt new file mode 100644 index 0000000000000..af7a5ab1d0bf5 --- /dev/null +++ b/Zend/tests/bug66218.phpt @@ -0,0 +1,21 @@ +--TEST-- +Bug #66218 zend_register_functions breaks reflection +--SKIPIF-- + +--FILE-- + +Done +--EXPECTF-- +dl Ok +Done diff --git a/Zend/tests/bug66252.phpt b/Zend/tests/bug66252.phpt new file mode 100644 index 0000000000000..e692a8e706dee --- /dev/null +++ b/Zend/tests/bug66252.phpt @@ -0,0 +1,14 @@ +--TEST-- +Bug #66252 (Problems in AST evaluation invalidating valid parent:: reference) +--FILE-- +bar; +?> +--EXPECTF-- +3 diff --git a/Zend/tests/class_properties_static.phpt b/Zend/tests/class_properties_static.phpt new file mode 100644 index 0000000000000..9a56466340c11 --- /dev/null +++ b/Zend/tests/class_properties_static.phpt @@ -0,0 +1,20 @@ +--TEST-- +Static Class Property Expressions +--FILE-- +b1, + $f->b2, + $f->b3 +); +?> +--EXPECT-- +int(2) +int(4) +string(13) "foo bar baz" diff --git a/Zend/tests/closure_018.phpt b/Zend/tests/closure_018.phpt index d98c78aeacec8..2dcf15c6aa161 100644 --- a/Zend/tests/closure_018.phpt +++ b/Zend/tests/closure_018.phpt @@ -21,8 +21,11 @@ var_dump($x = $test->test($y)); var_dump($y, $x); ?> ---EXPECT-- +--EXPECTF-- +Notice: Only variable references should be returned by reference in %sclosure_018.php on line 7 int(4) + +Notice: Only variable references should be returned by reference in %sclosure_018.php on line 7 int(16) int(16) int(16) diff --git a/Zend/tests/closure_019.phpt b/Zend/tests/closure_019.phpt index 0c4c34e163c50..57aa2dec17cf7 100644 --- a/Zend/tests/closure_019.phpt +++ b/Zend/tests/closure_019.phpt @@ -20,7 +20,10 @@ test(); ?> --EXPECTF-- +Notice: Only variable references should be returned by reference in %sclosure_019.php on line 4 int(9) + +Notice: Only variable references should be returned by reference in %sclosure_019.php on line 4 int(81) Fatal error: Cannot pass parameter 1 by reference in %s on line %d diff --git a/Zend/tests/constant_expressions.phpt b/Zend/tests/constant_expressions.phpt new file mode 100644 index 0000000000000..7dea0d83f7403 --- /dev/null +++ b/Zend/tests/constant_expressions.phpt @@ -0,0 +1,91 @@ +--TEST-- +Constant Expressions +--FILE-- + 0; +const T_20 = 1 >= 0; +const T_21 = 1 === 1; +const T_22 = 1 !== 1; +const T_23 = 0 != "0"; +const T_24 = 1 == "1"; + +// Test order of operations +const T_25 = 1 + 2 * 3; + +// Test for memory leaks +const T_26 = "1" + 2 + "3"; + +var_dump(T_1); +var_dump(T_2); +var_dump(T_3); +var_dump(T_4); +var_dump(T_5); +var_dump(T_6); +var_dump(T_7); +var_dump(T_8); +var_dump(T_9); +var_dump(T_10); +var_dump(T_11); +var_dump(T_12); +var_dump(T_13); +var_dump(T_14); +var_dump(T_15); +var_dump(T_16); +var_dump(T_17); +var_dump(T_18); +var_dump(T_19); +var_dump(T_20); +var_dump(T_21); +var_dump(T_22); +var_dump(T_23); +var_dump(T_24); +var_dump(T_25); +var_dump(T_26); +?> +--EXPECT-- +int(2) +float(0.5) +float(3) +string(6) "foobar" +float(6) +string(6) "foo234" +int(8) +string(21) "This is a test string" +int(0) +int(2) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(true) +bool(true) +bool(true) +bool(false) +bool(false) +bool(true) +int(7) +int(6) diff --git a/Zend/tests/constant_expressions_classes.phpt b/Zend/tests/constant_expressions_classes.phpt new file mode 100644 index 0000000000000..6298ff66d6379 --- /dev/null +++ b/Zend/tests/constant_expressions_classes.phpt @@ -0,0 +1,43 @@ +--TEST-- +Constant scalar expressions with autoloading and classes +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=-1 +--SKIPIF-- + +--FILE-- + 'class A { const HW = "this is A"; }', + 'B'=> 'class B extends A { const HW = parent::HW." extended by B"; }', + 'space1\C' => 'namespace space1; class C { const HW = "this is space1\C"; }', + 'D' => 'class D { const HW = \space1\C::HW." extented by D"; }', + 'trE' => 'trait trE { public static function getHW() { return parent::HW; } }', + 'E' => 'class E extends B { use trE; }', + 'F' => 'class F { const XX = "this is F"; }', + 'G' => 'class G extends F { const XX = parent::XX." extended by G"; public static function get_me($x = "got ".self::XX) { return $x; } }', +]; + +spl_autoload_register(function ($class) use ($classlist) { + if (isset($classlist[$class])) { + eval($classlist[$class]); + } else { + die("Cannot autoload $class\n"); + } +}); + +printf("B::HW = %s\n", B::HW); +printf("D::HW = %s\n", D::HW); + +printf("E::getHW() = %s\n", E::getHW()); +printf("G::get_me() = %s\n", G::get_me()); + +?> +--EXPECT-- +B::HW = this is A extended by B +D::HW = this is space1\C extented by D +E::getHW() = this is A extended by B +G::get_me() = got this is F extended by G diff --git a/Zend/tests/constant_expressions_dynamic.phpt b/Zend/tests/constant_expressions_dynamic.phpt new file mode 100644 index 0000000000000..21c9216cc1927 --- /dev/null +++ b/Zend/tests/constant_expressions_dynamic.phpt @@ -0,0 +1,11 @@ +--TEST-- +Dynamic Constant Expressions +--FILE-- + +--EXPECTF-- +3 diff --git a/Zend/tests/errmsg_045.phpt b/Zend/tests/errmsg_045.phpt new file mode 100644 index 0000000000000..b27f67ade4caa --- /dev/null +++ b/Zend/tests/errmsg_045.phpt @@ -0,0 +1,18 @@ +--TEST-- +Error message in error handler during compilation +--FILE-- + +--EXPECTF-- +string(50) "Redefining already defined constructor for class A" +string(%d) "%s(%d) : eval()'d code" + +Notice: Undefined variable: undefined in %s on line %d diff --git a/Zend/tests/finally_goto_001.phpt b/Zend/tests/finally_goto_001.phpt new file mode 100644 index 0000000000000..990f78d4c7434 --- /dev/null +++ b/Zend/tests/finally_goto_001.phpt @@ -0,0 +1,14 @@ +--TEST-- +jmp into a finally block 01 +--FILE-- + +--EXPECTF-- +Fatal error: jump into a finally block is disallowed in %sfinally_goto_001.php on line %d diff --git a/Zend/tests/finally_goto_002.phpt b/Zend/tests/finally_goto_002.phpt new file mode 100644 index 0000000000000..a6bd9e307f556 --- /dev/null +++ b/Zend/tests/finally_goto_002.phpt @@ -0,0 +1,14 @@ +--TEST-- +jmp into a finally block 02 +--FILE-- + +--EXPECTF-- +Fatal error: jump into a finally block is disallowed in %sfinally_goto_002.php on line %d diff --git a/Zend/tests/finally_goto_003.phpt b/Zend/tests/finally_goto_003.phpt new file mode 100644 index 0000000000000..8529ff786579f --- /dev/null +++ b/Zend/tests/finally_goto_003.phpt @@ -0,0 +1,15 @@ +--TEST-- +jmp into a finally block 03 +--FILE-- + +--EXPECTF-- +okey diff --git a/Zend/tests/finally_goto_004.phpt b/Zend/tests/finally_goto_004.phpt new file mode 100644 index 0000000000000..d88ceedf52748 --- /dev/null +++ b/Zend/tests/finally_goto_004.phpt @@ -0,0 +1,14 @@ +--TEST-- +jmp into a finally block 03 +--FILE-- + +--EXPECTF-- +Fatal error: jump into a finally block is disallowed in %sfinally_goto_004.php on line %d diff --git a/Zend/tests/function_arguments_003.phpt b/Zend/tests/function_arguments_003.phpt new file mode 100644 index 0000000000000..b882476d1d906 --- /dev/null +++ b/Zend/tests/function_arguments_003.phpt @@ -0,0 +1,17 @@ +--TEST-- +Function Argument Parsing #003 +--FILE-- + +--EXPECT-- +int(2) +int(4) +string(6) "foobar" +int(100) diff --git a/Zend/tests/generators/bug66041.phpt b/Zend/tests/generators/bug66041.phpt new file mode 100644 index 0000000000000..d94422413496a --- /dev/null +++ b/Zend/tests/generators/bug66041.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #66041: list() fails to unpack yielded ArrayAccess object +--FILE-- +send($fixedArray); +?> +--EXPECT-- +string(11) "the element" diff --git a/Zend/tests/generators/throw_caught.phpt b/Zend/tests/generators/throw_caught.phpt index 0c3f8e9b2daae..c5e9d81ebcc80 100644 --- a/Zend/tests/generators/throw_caught.phpt +++ b/Zend/tests/generators/throw_caught.phpt @@ -4,6 +4,7 @@ Generator::throw() where the exception is caught in the generator throw(new RuntimeException('Test'))); ?> --EXPECTF-- +before yield exception 'RuntimeException' with message 'Test' in %s:%d Stack trace: #0 {main} diff --git a/Zend/tests/generators/throw_rethrow.phpt b/Zend/tests/generators/throw_rethrow.phpt index 267f5f0db86ec..65044ee3f3049 100644 --- a/Zend/tests/generators/throw_rethrow.phpt +++ b/Zend/tests/generators/throw_rethrow.phpt @@ -4,6 +4,7 @@ Generator::throw() where the generator throws a different exception throw(new RuntimeException('throw'))); ?> --EXPECTF-- +before yield Caught: exception 'RuntimeException' with message 'throw' in %s:%d Stack trace: #0 {main} diff --git a/Zend/tests/static_variable.phpt b/Zend/tests/static_variable.phpt new file mode 100644 index 0000000000000..62ca565ffe693 --- /dev/null +++ b/Zend/tests/static_variable.phpt @@ -0,0 +1,29 @@ +--TEST-- +Static Variable Expressions +--FILE-- + 1 + 1, baz * 2 => 1 << 2]; + static $c = [1 => bar, 3 => baz]; + var_dump($a, $b, $c); +} + +foo(); +?> +--EXPECT-- +int(2) +array(2) { + [2]=> + int(2) + [6]=> + int(4) +} +array(2) { + [1]=> + int(2) + [3]=> + int(3) +} diff --git a/Zend/tests/use_const/alias.phpt b/Zend/tests/use_const/alias.phpt new file mode 100644 index 0000000000000..f179393006bef --- /dev/null +++ b/Zend/tests/use_const/alias.phpt @@ -0,0 +1,26 @@ +--TEST-- +aliasing imported constants to resolve naming conflicts +--FILE-- + +--EXPECT-- +int(42) +int(43) +Done diff --git a/Zend/tests/use_const/basic.phpt b/Zend/tests/use_const/basic.phpt new file mode 100644 index 0000000000000..6eaed7f27d379 --- /dev/null +++ b/Zend/tests/use_const/basic.phpt @@ -0,0 +1,22 @@ +--TEST-- +import namespaced constant +--FILE-- + +--EXPECT-- +int(42) +int(43) +Done diff --git a/Zend/tests/use_const/case_sensivity.phpt b/Zend/tests/use_const/case_sensivity.phpt new file mode 100644 index 0000000000000..1977daa93bb9a --- /dev/null +++ b/Zend/tests/use_const/case_sensivity.phpt @@ -0,0 +1,12 @@ +--TEST-- +importing const with same name but different case +--FILE-- + +--EXPECT-- diff --git a/Zend/tests/use_const/conflicting_use.phpt b/Zend/tests/use_const/conflicting_use.phpt new file mode 100644 index 0000000000000..3b3c4b3262e79 --- /dev/null +++ b/Zend/tests/use_const/conflicting_use.phpt @@ -0,0 +1,21 @@ +--TEST-- +use const statements with conflicting names +--FILE-- + +--EXPECTF-- +Fatal error: Cannot use const bar\baz as baz because the name is already in use in %s on line %d diff --git a/Zend/tests/use_const/conflicting_use_alias.phpt b/Zend/tests/use_const/conflicting_use_alias.phpt new file mode 100644 index 0000000000000..8b563a4ca975e --- /dev/null +++ b/Zend/tests/use_const/conflicting_use_alias.phpt @@ -0,0 +1,18 @@ +--TEST-- +use and use const with the same alias +--FILE-- + +--EXPECT-- +string(3) "foo" diff --git a/Zend/tests/use_const/define_imported.phpt b/Zend/tests/use_const/define_imported.phpt new file mode 100644 index 0000000000000..5eb44be64a058 --- /dev/null +++ b/Zend/tests/use_const/define_imported.phpt @@ -0,0 +1,14 @@ +--TEST-- +defining const with same name as imported should fail +--FILE-- + +--EXPECTF-- +Fatal error: Cannot declare const bar because the name is already in use in %s on line %d diff --git a/Zend/tests/use_const/define_imported_before.phpt b/Zend/tests/use_const/define_imported_before.phpt new file mode 100644 index 0000000000000..f674ce81e8ec2 --- /dev/null +++ b/Zend/tests/use_const/define_imported_before.phpt @@ -0,0 +1,18 @@ +--TEST-- +using const with same name as defined should fail +--FILE-- + +--EXPECTF-- +Fatal error: Cannot use const foo\bar as bar because the name is already in use in %s on line %d diff --git a/Zend/tests/use_const/includes/foo_bar.php b/Zend/tests/use_const/includes/foo_bar.php new file mode 100644 index 0000000000000..90ed451f364d0 --- /dev/null +++ b/Zend/tests/use_const/includes/foo_bar.php @@ -0,0 +1,5 @@ + +--EXPECTF-- +Notice: Use of undefined constant baz - assumed 'baz' in %s on line %d +string(3) "baz" diff --git a/Zend/tests/use_const/self_parent.phpt b/Zend/tests/use_const/self_parent.phpt new file mode 100644 index 0000000000000..b71f2ecc81fee --- /dev/null +++ b/Zend/tests/use_const/self_parent.phpt @@ -0,0 +1,12 @@ +--TEST-- +Allow self and parent in use const statement +--FILE-- + +--EXPECT-- diff --git a/Zend/tests/use_const/shadow_core.phpt b/Zend/tests/use_const/shadow_core.phpt new file mode 100644 index 0000000000000..7d8bcbd1892f4 --- /dev/null +++ b/Zend/tests/use_const/shadow_core.phpt @@ -0,0 +1,16 @@ +--TEST-- +shadowing a global core constant with a local version +--FILE-- + +--EXPECTF-- +int(42) +Done diff --git a/Zend/tests/use_const/shadow_global.phpt b/Zend/tests/use_const/shadow_global.phpt new file mode 100644 index 0000000000000..930cc9f0b8778 --- /dev/null +++ b/Zend/tests/use_const/shadow_global.phpt @@ -0,0 +1,25 @@ +--TEST-- +shadowing a global constant with a local version +--FILE-- + +--EXPECT-- +string(10) "global bar" +string(9) "local bar" +Done diff --git a/Zend/tests/use_function/alias.phpt b/Zend/tests/use_function/alias.phpt new file mode 100644 index 0000000000000..5f7e97fff87f0 --- /dev/null +++ b/Zend/tests/use_function/alias.phpt @@ -0,0 +1,30 @@ +--TEST-- +aliasing imported functions to resolve naming conflicts +--FILE-- + +--EXPECT-- +string(7) "foo.baz" +string(7) "bar.baz" +Done diff --git a/Zend/tests/use_function/basic.phpt b/Zend/tests/use_function/basic.phpt new file mode 100644 index 0000000000000..513a96620c17b --- /dev/null +++ b/Zend/tests/use_function/basic.phpt @@ -0,0 +1,26 @@ +--TEST-- +import namespaced function +--FILE-- + +--EXPECT-- +string(11) "foo.bar.baz" +string(11) "foo.bar.baz" +Done diff --git a/Zend/tests/use_function/case_insensivity.phpt b/Zend/tests/use_function/case_insensivity.phpt new file mode 100644 index 0000000000000..ba6e3a7e4b1b5 --- /dev/null +++ b/Zend/tests/use_function/case_insensivity.phpt @@ -0,0 +1,13 @@ +--TEST-- +importing function with same name but different case should fail +--FILE-- + +--EXPECTF-- +Fatal error: Cannot use function foo\BAR as BAR because the name is already in use in %s on line %d diff --git a/Zend/tests/use_function/conditional_function_declaration.phpt b/Zend/tests/use_function/conditional_function_declaration.phpt new file mode 100644 index 0000000000000..ccfb96103a6b6 --- /dev/null +++ b/Zend/tests/use_function/conditional_function_declaration.phpt @@ -0,0 +1,17 @@ +--TEST-- +function that is conditionally defined at runtime should not cause compiler error +--FILE-- + +--EXPECT-- +Done diff --git a/Zend/tests/use_function/conflicting_use.phpt b/Zend/tests/use_function/conflicting_use.phpt new file mode 100644 index 0000000000000..0221fbdebb38a --- /dev/null +++ b/Zend/tests/use_function/conflicting_use.phpt @@ -0,0 +1,25 @@ +--TEST-- +use function statements with conflicting names +--FILE-- + +--EXPECTF-- +Fatal error: Cannot use function bar\baz as baz because the name is already in use in %s on line %d diff --git a/Zend/tests/use_function/conflicting_use_alias.phpt b/Zend/tests/use_function/conflicting_use_alias.phpt new file mode 100644 index 0000000000000..2870512014de0 --- /dev/null +++ b/Zend/tests/use_function/conflicting_use_alias.phpt @@ -0,0 +1,20 @@ +--TEST-- +use and use function with the same alias +--FILE-- + +--EXPECT-- +string(3) "foo" diff --git a/Zend/tests/use_function/conflicting_use_const_alias.phpt b/Zend/tests/use_function/conflicting_use_const_alias.phpt new file mode 100644 index 0000000000000..2e0faf0da21a6 --- /dev/null +++ b/Zend/tests/use_function/conflicting_use_const_alias.phpt @@ -0,0 +1,23 @@ +--TEST-- +use const and use function with the same alias +--FILE-- + +--EXPECT-- +string(9) "foo.const" +string(12) "foo.function" diff --git a/Zend/tests/use_function/define_imported.phpt b/Zend/tests/use_function/define_imported.phpt new file mode 100644 index 0000000000000..c542a4d5494b9 --- /dev/null +++ b/Zend/tests/use_function/define_imported.phpt @@ -0,0 +1,14 @@ +--TEST-- +defining function with same name as imported should fail +--FILE-- + +--EXPECTF-- +Fatal error: Cannot declare function bar because the name is already in use in %s on line %d diff --git a/Zend/tests/use_function/define_imported_before.phpt b/Zend/tests/use_function/define_imported_before.phpt new file mode 100644 index 0000000000000..91974e0783d15 --- /dev/null +++ b/Zend/tests/use_function/define_imported_before.phpt @@ -0,0 +1,18 @@ +--TEST-- +using function with same name as defined should fail +--FILE-- + +--EXPECTF-- +Fatal error: Cannot use function foo\bar as bar because the name is already in use in %s on line %d diff --git a/Zend/tests/use_function/ignore_constants.phpt b/Zend/tests/use_function/ignore_constants.phpt new file mode 100644 index 0000000000000..c50ff7357af17 --- /dev/null +++ b/Zend/tests/use_function/ignore_constants.phpt @@ -0,0 +1,23 @@ +--TEST-- +use function should ignore namespaced constants +--FILE-- + +--EXPECT-- +int(43) +Done diff --git a/Zend/tests/use_function/includes/foo_bar.php b/Zend/tests/use_function/includes/foo_bar.php new file mode 100644 index 0000000000000..6d2f8cab45fb4 --- /dev/null +++ b/Zend/tests/use_function/includes/foo_bar.php @@ -0,0 +1,7 @@ + +--EXPECTF-- +Fatal error: Call to undefined function foo\bar\baz() in %s on line %d diff --git a/Zend/tests/use_function/no_global_fallback2.phpt b/Zend/tests/use_function/no_global_fallback2.phpt new file mode 100644 index 0000000000000..5d012c10e5912 --- /dev/null +++ b/Zend/tests/use_function/no_global_fallback2.phpt @@ -0,0 +1,18 @@ +--TEST-- +non-existent imported functions should not be looked up in the global table +--FILE-- + +--EXPECTF-- +Fatal error: Call to undefined function bar\test() in %s on line %d diff --git a/Zend/tests/use_function/self_parent.phpt b/Zend/tests/use_function/self_parent.phpt new file mode 100644 index 0000000000000..f1e1fa84f1de1 --- /dev/null +++ b/Zend/tests/use_function/self_parent.phpt @@ -0,0 +1,12 @@ +--TEST-- +Allow self and parent in use function statement +--FILE-- + +--EXPECT-- diff --git a/Zend/tests/use_function/shadow_core.phpt b/Zend/tests/use_function/shadow_core.phpt new file mode 100644 index 0000000000000..8f92ff1e1be86 --- /dev/null +++ b/Zend/tests/use_function/shadow_core.phpt @@ -0,0 +1,16 @@ +--TEST-- +shadowing a global core function with a local version +--FILE-- + +--EXPECT-- +int(4) +Done diff --git a/Zend/tests/use_function/shadow_global.phpt b/Zend/tests/use_function/shadow_global.phpt new file mode 100644 index 0000000000000..791bcdf4d50d6 --- /dev/null +++ b/Zend/tests/use_function/shadow_global.phpt @@ -0,0 +1,25 @@ +--TEST-- +shadowing a global function with a local version +--FILE-- + +--EXPECT-- +string(10) "global bar" +string(9) "local bar" +Done diff --git a/Zend/tests/variadic/adding_additional_optional_parameter.phpt b/Zend/tests/variadic/adding_additional_optional_parameter.phpt new file mode 100644 index 0000000000000..b4e797803dcf2 --- /dev/null +++ b/Zend/tests/variadic/adding_additional_optional_parameter.phpt @@ -0,0 +1,17 @@ +--TEST-- +It's possible to add additional optional arguments with matching signature +--FILE-- + +===DONE=== +--EXPECT-- +===DONE=== diff --git a/Zend/tests/variadic/adding_additional_optional_parameter_error.phpt b/Zend/tests/variadic/adding_additional_optional_parameter_error.phpt new file mode 100644 index 0000000000000..2f31d47dc6969 --- /dev/null +++ b/Zend/tests/variadic/adding_additional_optional_parameter_error.phpt @@ -0,0 +1,16 @@ +--TEST-- +Additional optional parameters must have a matching prototype +--FILE-- + +--EXPECTF-- +Fatal error: Declaration of MySQL::query() must be compatible with DB::query($query, string ...$params) in %s on line %d diff --git a/Zend/tests/variadic/basic.phpt b/Zend/tests/variadic/basic.phpt new file mode 100644 index 0000000000000..810d4756aa087 --- /dev/null +++ b/Zend/tests/variadic/basic.phpt @@ -0,0 +1,57 @@ +--TEST-- +Basic variadic function +--FILE-- + +--EXPECT-- +array(0) { +} +array(1) { + [0]=> + int(1) +} +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +int(1) +int(2) +array(0) { +} +int(1) +int(2) +array(1) { + [0]=> + int(3) +} +int(1) +int(2) +array(3) { + [0]=> + int(3) + [1]=> + int(4) + [2]=> + int(5) +} diff --git a/Zend/tests/variadic/by_ref.phpt b/Zend/tests/variadic/by_ref.phpt new file mode 100644 index 0000000000000..e1635f4ecf20a --- /dev/null +++ b/Zend/tests/variadic/by_ref.phpt @@ -0,0 +1,24 @@ +--TEST-- +Variadic arguments with by-reference passing +--FILE-- + +--EXPECT-- +int(0) +int(0) +int(1) +int(2) diff --git a/Zend/tests/variadic/by_ref_error.phpt b/Zend/tests/variadic/by_ref_error.phpt new file mode 100644 index 0000000000000..7f21014146406 --- /dev/null +++ b/Zend/tests/variadic/by_ref_error.phpt @@ -0,0 +1,12 @@ +--TEST-- +By-ref variadics enforce the reference +--FILE-- + +--EXPECTF-- +Fatal error: Only variables can be passed by reference in %s on line %d diff --git a/Zend/tests/variadic/no_default_error.phpt b/Zend/tests/variadic/no_default_error.phpt new file mode 100644 index 0000000000000..427ebed0289a9 --- /dev/null +++ b/Zend/tests/variadic/no_default_error.phpt @@ -0,0 +1,10 @@ +--TEST-- +Variadic argument cannot have a default value +--FILE-- + +--EXPECTF-- +Fatal error: Variadic parameter cannot have a default value in %s on line %d diff --git a/Zend/tests/variadic/non_variadic_implements_variadic_error.phpt b/Zend/tests/variadic/non_variadic_implements_variadic_error.phpt new file mode 100644 index 0000000000000..f447837ca4afb --- /dev/null +++ b/Zend/tests/variadic/non_variadic_implements_variadic_error.phpt @@ -0,0 +1,16 @@ +--TEST-- +It's not possible to turn a variadic function into a non-variadic one +--FILE-- + +--EXPECTF-- +Fatal error: Declaration of MySQL::query() must be compatible with DB::query($query, ...$params) in %s on line %d diff --git a/Zend/tests/variadic/only_last_error.phpt b/Zend/tests/variadic/only_last_error.phpt new file mode 100644 index 0000000000000..ee6ff3f777c46 --- /dev/null +++ b/Zend/tests/variadic/only_last_error.phpt @@ -0,0 +1,10 @@ +--TEST-- +Only the last argument can be variadic +--FILE-- + +--EXPECTF-- +Fatal error: Only the last parameter can be variadic in %s on line %d diff --git a/Zend/tests/variadic/optional_params.phpt b/Zend/tests/variadic/optional_params.phpt new file mode 100644 index 0000000000000..ba965e538c4f9 --- /dev/null +++ b/Zend/tests/variadic/optional_params.phpt @@ -0,0 +1,49 @@ +--TEST-- +Optional parameter before variadic parameter +--FILE-- + +--EXPECT-- +int(1) +NULL +array(0) { +} +int(1) +int(2) +array(0) { +} +int(1) +int(2) +array(1) { + [0]=> + int(3) +} +int(1) +int(2) +array(2) { + [0]=> + int(3) + [1]=> + int(4) +} +int(1) +int(2) +array(3) { + [0]=> + int(3) + [1]=> + int(4) + [2]=> + int(5) +} diff --git a/Zend/tests/variadic/removing_parameter_error.phpt b/Zend/tests/variadic/removing_parameter_error.phpt new file mode 100644 index 0000000000000..a189e5cf094b7 --- /dev/null +++ b/Zend/tests/variadic/removing_parameter_error.phpt @@ -0,0 +1,20 @@ +--TEST-- +It's not possible to remove required parameter before a variadic parameter +--FILE-- + +--EXPECTF-- +Fatal error: Declaration of MySQL::query() must be compatible with DB::query($query, ...$params) in %s on line %d diff --git a/Zend/tests/variadic/typehint_error.phpt b/Zend/tests/variadic/typehint_error.phpt new file mode 100644 index 0000000000000..3006b999576c6 --- /dev/null +++ b/Zend/tests/variadic/typehint_error.phpt @@ -0,0 +1,36 @@ +--TEST-- +Variadic arguments enforce typehints +--FILE-- + +--EXPECTF-- +array(0) { +} +array(3) { + [0]=> + array(1) { + [0]=> + int(0) + } + [1]=> + array(1) { + [0]=> + int(1) + } + [2]=> + array(1) { + [0]=> + int(2) + } +} + +Catchable fatal error: Argument 3 passed to test() must be of the type array, integer given, called in %s on line %d diff --git a/Zend/tests/variadic/typehint_suppressed_error.phpt b/Zend/tests/variadic/typehint_suppressed_error.phpt new file mode 100644 index 0000000000000..5048e1c1bb5ab --- /dev/null +++ b/Zend/tests/variadic/typehint_suppressed_error.phpt @@ -0,0 +1,33 @@ +--TEST-- +Error suppression for typehints on variadic arguments works +--FILE-- + +--EXPECTF-- +string(%d) "Argument 3 passed to test() must be of the type array, integer given, called in %s on line %d and defined" +array(3) { + [0]=> + array(1) { + [0]=> + int(0) + } + [1]=> + array(1) { + [0]=> + int(1) + } + [2]=> + int(2) +} diff --git a/Zend/tests/variadic/variadic_changed_byref_error.phpt b/Zend/tests/variadic/variadic_changed_byref_error.phpt new file mode 100644 index 0000000000000..14fb6ae5eb0d9 --- /dev/null +++ b/Zend/tests/variadic/variadic_changed_byref_error.phpt @@ -0,0 +1,16 @@ +--TEST-- +Variadic arguments must have compatible passing modes +--FILE-- + +--EXPECTF-- +Fatal error: Declaration of MySQL::query() must be compatible with DB::query($query, &...$params) in %s on line %d diff --git a/Zend/tests/variadic/variadic_changed_typehint_error.phpt b/Zend/tests/variadic/variadic_changed_typehint_error.phpt new file mode 100644 index 0000000000000..00df33a0424a4 --- /dev/null +++ b/Zend/tests/variadic/variadic_changed_typehint_error.phpt @@ -0,0 +1,16 @@ +--TEST-- +Typehints for variadic arguments have to be compatible +--FILE-- + +--EXPECTF-- +Fatal error: Declaration of MySQL::query() must be compatible with DB::query($query, string ...$params) in %s on line %d diff --git a/Zend/tests/variadic/variadic_implements_non_variadic.phpt b/Zend/tests/variadic/variadic_implements_non_variadic.phpt new file mode 100644 index 0000000000000..a66ec280b8626 --- /dev/null +++ b/Zend/tests/variadic/variadic_implements_non_variadic.phpt @@ -0,0 +1,17 @@ +--TEST-- +A non-variadic function can be turned into a variadic one +--FILE-- + +===DONE=== +--EXPECT-- +===DONE=== diff --git a/Zend/zend.c b/Zend/zend.c index f9069c8e1b515..ad45028d4be85 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -30,6 +30,7 @@ #include "zend_ini.h" #include "zend_vm.h" #include "zend_dtrace.h" +#include "zend_virtual_cwd.h" #ifdef ZTS # define GLOBAL_FUNCTION_TABLE global_function_table @@ -55,7 +56,7 @@ ZEND_API FILE *(*zend_fopen)(const char *filename, char **opened_path TSRMLS_DC) ZEND_API int (*zend_stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC); ZEND_API void (*zend_block_interruptions)(void); ZEND_API void (*zend_unblock_interruptions)(void); -ZEND_API void (*zend_ticks_function)(int ticks); +ZEND_API void (*zend_ticks_function)(int ticks TSRMLS_DC); ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args); int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap); ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC); @@ -652,6 +653,8 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions TS start_memory_manager(TSRMLS_C); + virtual_cwd_startup(); /* Could use shutdown to free the main cwd but it would just slow it down for CGI */ + #if defined(__FreeBSD__) || defined(__DragonFly__) /* FreeBSD and DragonFly floating point precision fix */ fpsetmask(0); @@ -802,9 +805,14 @@ void zend_post_startup(TSRMLS_D) /* {{{ */ compiler_globals_ctor(compiler_globals, tsrm_ls); } free(EG(zend_constants)); + + virtual_cwd_deactivate(TSRMLS_C); + executor_globals_ctor(executor_globals, tsrm_ls); global_persistent_list = &EG(persistent_list); zend_copy_ini_directives(TSRMLS_C); +#else + virtual_cwd_deactivate(TSRMLS_C); #endif } /* }}} */ @@ -820,6 +828,9 @@ void zend_shutdown(TSRMLS_D) /* {{{ */ zend_destroy_rsrc_list(&EG(persistent_list) TSRMLS_CC); zend_destroy_modules(); + virtual_cwd_deactivate(TSRMLS_C); + virtual_cwd_shutdown(); + zend_hash_destroy(GLOBAL_FUNCTION_TABLE); zend_hash_destroy(GLOBAL_CLASS_TABLE); @@ -908,8 +919,11 @@ ZEND_API char *get_zend_version(void) /* {{{ */ } /* }}} */ -void zend_activate(TSRMLS_D) /* {{{ */ +ZEND_API void zend_activate(TSRMLS_D) /* {{{ */ { +#ifdef ZTS + virtual_cwd_activate(TSRMLS_C); +#endif gc_reset(TSRMLS_C); init_compiler(TSRMLS_C); init_executor(TSRMLS_C); @@ -925,7 +939,7 @@ void zend_call_destructors(TSRMLS_D) /* {{{ */ } /* }}} */ -void zend_deactivate(TSRMLS_D) /* {{{ */ +ZEND_API void zend_deactivate(TSRMLS_D) /* {{{ */ { /* we're no longer executing anything */ EG(opline_ptr) = NULL; @@ -1184,7 +1198,7 @@ ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */ * such scripts recursivly, but some CG() variables may be * inconsistent. */ - in_compilation = zend_is_compiling(TSRMLS_C); + in_compilation = CG(in_compilation); if (in_compilation) { saved_class_entry = CG(active_class_entry); CG(active_class_entry) = NULL; @@ -1196,6 +1210,7 @@ ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */ SAVE_STACK(declare_stack); SAVE_STACK(list_stack); SAVE_STACK(context_stack); + CG(in_compilation) = 0; } if (call_user_function_ex(CG(function_table), NULL, orig_user_error_handler, &retval, 5, params, 1, NULL TSRMLS_CC) == SUCCESS) { @@ -1220,6 +1235,7 @@ ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */ RESTORE_STACK(declare_stack); RESTORE_STACK(list_stack); RESTORE_STACK(context_stack); + CG(in_compilation) = 1; } if (!EG(user_error_handler)) { diff --git a/Zend/zend.h b/Zend/zend.h index acbb6acaf76ce..f60ef687f61cf 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -22,7 +22,7 @@ #ifndef ZEND_H #define ZEND_H -#define ZEND_VERSION "2.6.0-dev" +#define ZEND_VERSION "2.7.0-dev" #define ZEND_ENGINE_2 @@ -193,7 +193,7 @@ char *alloca (); #endif #define restrict __restrict__ -#if (HAVE_ALLOCA || (defined (__GNUC__) && __GNUC__ >= 2)) && !(defined(ZTS) && defined(ZEND_WIN32)) && !(defined(ZTS) && defined(NETWARE)) && !(defined(ZTS) && defined(HPUX)) && !defined(DARWIN) +#if (HAVE_ALLOCA || (defined (__GNUC__) && __GNUC__ >= 2)) && !(defined(ZTS) && defined(NETWARE)) && !(defined(ZTS) && defined(HPUX)) && !defined(DARWIN) # define ZEND_ALLOCA_MAX_SIZE (32 * 1024) # define ALLOCA_FLAG(name) \ zend_bool name; @@ -317,6 +317,7 @@ typedef struct _zend_object { } zend_object; #include "zend_object_handlers.h" +#include "zend_ast.h" typedef union _zvalue_value { long lval; /* long value */ @@ -327,6 +328,7 @@ typedef union _zvalue_value { } str; HashTable *ht; /* hash table value */ zend_object_value obj; + zend_ast *ast; } zvalue_value; struct _zval_struct { @@ -548,7 +550,7 @@ typedef struct _zend_utility_functions { void (*block_interruptions)(void); void (*unblock_interruptions)(void); int (*get_configuration_directive)(const char *name, uint name_length, zval *contents); - void (*ticks_function)(int ticks); + void (*ticks_function)(int ticks TSRMLS_DC); void (*on_timeout)(int seconds TSRMLS_DC); int (*stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC); int (*vspprintf_function)(char **pbuf, size_t max_len, const char *format, va_list ap); @@ -587,7 +589,8 @@ typedef int (*zend_write_func_t)(const char *str, uint str_length); #define IS_RESOURCE 7 #define IS_CONSTANT 8 #define IS_CONSTANT_ARRAY 9 -#define IS_CALLABLE 10 +#define IS_CONSTANT_AST 10 +#define IS_CALLABLE 11 /* Ugly hack to support constants as static array indices */ #define IS_CONSTANT_TYPE_MASK 0x00f @@ -597,6 +600,8 @@ typedef int (*zend_write_func_t)(const char *str, uint str_length); #define IS_LEXICAL_REF 0x040 #define IS_CONSTANT_IN_NAMESPACE 0x100 +#define IS_CONSTANT_TYPE(type) (((type) & IS_CONSTANT_TYPE_MASK) >= IS_CONSTANT && ((type) & IS_CONSTANT_TYPE_MASK) <= IS_CONSTANT_AST) + /* overloaded elements data types */ #define OE_IS_ARRAY (1<<0) #define OE_IS_OBJECT (1<<1) @@ -651,12 +656,14 @@ ZEND_API void zend_print_zval_r_ex(zend_write_func_t write_func, zval *expr, int ZEND_API void zend_output_debug_string(zend_bool trigger_break, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3); END_EXTERN_C() -void zend_activate(TSRMLS_D); -void zend_deactivate(TSRMLS_D); -void zend_call_destructors(TSRMLS_D); -void zend_activate_modules(TSRMLS_D); -void zend_deactivate_modules(TSRMLS_D); -void zend_post_deactivate_modules(TSRMLS_D); +BEGIN_EXTERN_C() +ZEND_API void zend_activate(TSRMLS_D); +ZEND_API void zend_deactivate(TSRMLS_D); +ZEND_API void zend_call_destructors(TSRMLS_D); +ZEND_API void zend_activate_modules(TSRMLS_D); +ZEND_API void zend_deactivate_modules(TSRMLS_D); +ZEND_API void zend_post_deactivate_modules(TSRMLS_D); +END_EXTERN_C() #if ZEND_DEBUG #define Z_DBG(expr) (expr) @@ -683,7 +690,7 @@ END_EXTERN_C() #define ZEND_WRITE_EX(str, str_len) write_func((str), (str_len)) #define ZEND_PUTS(str) zend_write((str), strlen((str))) #define ZEND_PUTS_EX(str) write_func((str), strlen((str))) -#define ZEND_PUTC(c) zend_write(&(c), 1), (c) +#define ZEND_PUTC(c) zend_write(&(c), 1) BEGIN_EXTERN_C() extern ZEND_API int (*zend_printf)(const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 1, 2); @@ -691,7 +698,7 @@ extern ZEND_API zend_write_func_t zend_write; extern ZEND_API FILE *(*zend_fopen)(const char *filename, char **opened_path TSRMLS_DC); extern ZEND_API void (*zend_block_interruptions)(void); extern ZEND_API void (*zend_unblock_interruptions)(void); -extern ZEND_API void (*zend_ticks_function)(int ticks); +extern ZEND_API void (*zend_ticks_function)(int ticks TSRMLS_DC); extern ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 4, 0); extern ZEND_API void (*zend_on_timeout)(int seconds TSRMLS_DC); extern ZEND_API int (*zend_stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC); diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 6241df1cad39b..3de56114387f1 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -1010,7 +1010,7 @@ ZEND_API int _array_init(zval *arg, uint size ZEND_FILE_LINE_DC) /* {{{ */ { ALLOC_HASHTABLE_REL(Z_ARRVAL_P(arg)); - _zend_hash_init(Z_ARRVAL_P(arg), size, NULL, ZVAL_PTR_DTOR, 0 ZEND_FILE_LINE_RELAY_CC); + _zend_hash_init(Z_ARRVAL_P(arg), size, ZVAL_PTR_DTOR, 0 ZEND_FILE_LINE_RELAY_CC); Z_TYPE_P(arg) = IS_ARRAY; return SUCCESS; } @@ -1053,8 +1053,7 @@ ZEND_API void zend_merge_properties(zval *obj, HashTable *properties, int destro static int zval_update_class_constant(zval **pp, int is_static, int offset TSRMLS_DC) /* {{{ */ { - if ((Z_TYPE_PP(pp) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT || - (Z_TYPE_PP(pp) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT_ARRAY) { + if (IS_CONSTANT_TYPE(Z_TYPE_PP(pp))) { zend_class_entry **scope = EG(in_execution)?&EG(scope):&CG(active_class_entry); if ((*scope)->parent) { @@ -1078,7 +1077,7 @@ static int zval_update_class_constant(zval **pp, int is_static, int offset TSRML } ce = ce->parent; } while (ce); - + } return zval_update_constant(pp, (void*)1 TSRMLS_CC); } @@ -1973,35 +1972,35 @@ ZEND_API void zend_check_magic_method_implementation(const zend_class_entry *ce, zend_str_tolower_copy(lcname, fptr->common.function_name, MIN(name_len, sizeof(lcname)-1)); lcname[sizeof(lcname)-1] = '\0'; /* zend_str_tolower_copy won't necessarily set the zero byte */ - if (name_len == sizeof(ZEND_DESTRUCTOR_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_DESTRUCTOR_FUNC_NAME, sizeof(ZEND_DESTRUCTOR_FUNC_NAME)) && fptr->common.num_args != 0) { + if (name_len == sizeof(ZEND_DESTRUCTOR_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_DESTRUCTOR_FUNC_NAME, sizeof(ZEND_DESTRUCTOR_FUNC_NAME) - 1) && fptr->common.num_args != 0) { zend_error(error_type, "Destructor %s::%s() cannot take arguments", ce->name, ZEND_DESTRUCTOR_FUNC_NAME); - } else if (name_len == sizeof(ZEND_CLONE_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_CLONE_FUNC_NAME, sizeof(ZEND_CLONE_FUNC_NAME)) && fptr->common.num_args != 0) { + } else if (name_len == sizeof(ZEND_CLONE_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_CLONE_FUNC_NAME, sizeof(ZEND_CLONE_FUNC_NAME) - 1) && fptr->common.num_args != 0) { zend_error(error_type, "Method %s::%s() cannot accept any arguments", ce->name, ZEND_CLONE_FUNC_NAME); - } else if (name_len == sizeof(ZEND_GET_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_GET_FUNC_NAME, sizeof(ZEND_GET_FUNC_NAME))) { + } else if (name_len == sizeof(ZEND_GET_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_GET_FUNC_NAME, sizeof(ZEND_GET_FUNC_NAME) - 1)) { if (fptr->common.num_args != 1) { zend_error(error_type, "Method %s::%s() must take exactly 1 argument", ce->name, ZEND_GET_FUNC_NAME); } else if (ARG_SHOULD_BE_SENT_BY_REF(fptr, 1)) { zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ce->name, ZEND_GET_FUNC_NAME); } - } else if (name_len == sizeof(ZEND_SET_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_SET_FUNC_NAME, sizeof(ZEND_SET_FUNC_NAME))) { + } else if (name_len == sizeof(ZEND_SET_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_SET_FUNC_NAME, sizeof(ZEND_SET_FUNC_NAME) - 1)) { if (fptr->common.num_args != 2) { zend_error(error_type, "Method %s::%s() must take exactly 2 arguments", ce->name, ZEND_SET_FUNC_NAME); } else if (ARG_SHOULD_BE_SENT_BY_REF(fptr, 1) || ARG_SHOULD_BE_SENT_BY_REF(fptr, 2)) { zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ce->name, ZEND_SET_FUNC_NAME); } - } else if (name_len == sizeof(ZEND_UNSET_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_UNSET_FUNC_NAME, sizeof(ZEND_UNSET_FUNC_NAME))) { + } else if (name_len == sizeof(ZEND_UNSET_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_UNSET_FUNC_NAME, sizeof(ZEND_UNSET_FUNC_NAME) - 1)) { if (fptr->common.num_args != 1) { zend_error(error_type, "Method %s::%s() must take exactly 1 argument", ce->name, ZEND_UNSET_FUNC_NAME); } else if (ARG_SHOULD_BE_SENT_BY_REF(fptr, 1)) { zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ce->name, ZEND_UNSET_FUNC_NAME); } - } else if (name_len == sizeof(ZEND_ISSET_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_ISSET_FUNC_NAME, sizeof(ZEND_ISSET_FUNC_NAME))) { + } else if (name_len == sizeof(ZEND_ISSET_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_ISSET_FUNC_NAME, sizeof(ZEND_ISSET_FUNC_NAME) - 1)) { if (fptr->common.num_args != 1) { zend_error(error_type, "Method %s::%s() must take exactly 1 argument", ce->name, ZEND_ISSET_FUNC_NAME); } else if (ARG_SHOULD_BE_SENT_BY_REF(fptr, 1)) { zend_error(error_type, "Method %s::%s() cannot take arguments by reference", ce->name, ZEND_ISSET_FUNC_NAME); } - } else if (name_len == sizeof(ZEND_CALL_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_CALL_FUNC_NAME, sizeof(ZEND_CALL_FUNC_NAME))) { + } else if (name_len == sizeof(ZEND_CALL_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_CALL_FUNC_NAME, sizeof(ZEND_CALL_FUNC_NAME) - 1)) { if (fptr->common.num_args != 2) { zend_error(error_type, "Method %s::%s() must take exactly 2 arguments", ce->name, ZEND_CALL_FUNC_NAME); } else if (ARG_SHOULD_BE_SENT_BY_REF(fptr, 1) || ARG_SHOULD_BE_SENT_BY_REF(fptr, 2)) { @@ -2090,16 +2089,12 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio } else { internal_function->required_num_args = info->required_num_args; } - if (info->pass_rest_by_reference) { - if (info->pass_rest_by_reference == ZEND_SEND_PREFER_REF) { - internal_function->fn_flags |= ZEND_ACC_PASS_REST_PREFER_REF; - } else { - internal_function->fn_flags |= ZEND_ACC_PASS_REST_BY_REFERENCE; - } - } if (info->return_reference) { internal_function->fn_flags |= ZEND_ACC_RETURN_REFERENCE; } + if (ptr->arg_info[ptr->num_args].is_variadic) { + internal_function->fn_flags |= ZEND_ACC_VARIADIC; + } } else { internal_function->arg_info = NULL; internal_function->num_args = 0; @@ -2142,6 +2137,19 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio str_efree(lowercase_name); break; } + + /* If types of arguments have to be checked */ + if (reg_function->common.arg_info && reg_function->common.num_args) { + int i; + for (i = 0; i < reg_function->common.num_args; i++) { + if (reg_function->common.arg_info[i].class_name || + reg_function->common.arg_info[i].type_hint) { + reg_function->common.fn_flags |= ZEND_ACC_HAS_TYPE_HINTS; + break; + } + } + } + if (scope) { /* Look for ctor, dtor, clone * If it's an old-style constructor, store it only if we don't have @@ -2149,28 +2157,28 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio */ if ((fname_len == class_name_len) && !ctor && !memcmp(lowercase_name, lc_class_name, class_name_len+1)) { ctor = reg_function; - } else if ((fname_len == sizeof(ZEND_CONSTRUCTOR_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME))) { + } else if ((fname_len == sizeof(ZEND_CONSTRUCTOR_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME) - 1)) { ctor = reg_function; - } else if ((fname_len == sizeof(ZEND_DESTRUCTOR_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_DESTRUCTOR_FUNC_NAME, sizeof(ZEND_DESTRUCTOR_FUNC_NAME))) { + } else if ((fname_len == sizeof(ZEND_DESTRUCTOR_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_DESTRUCTOR_FUNC_NAME, sizeof(ZEND_DESTRUCTOR_FUNC_NAME) - 1)) { dtor = reg_function; if (internal_function->num_args) { zend_error(error_type, "Destructor %s::%s() cannot take arguments", scope->name, ptr->fname); } - } else if ((fname_len == sizeof(ZEND_CLONE_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_CLONE_FUNC_NAME, sizeof(ZEND_CLONE_FUNC_NAME))) { + } else if ((fname_len == sizeof(ZEND_CLONE_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_CLONE_FUNC_NAME, sizeof(ZEND_CLONE_FUNC_NAME) - 1)) { clone = reg_function; - } else if ((fname_len == sizeof(ZEND_CALL_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_CALL_FUNC_NAME, sizeof(ZEND_CALL_FUNC_NAME))) { + } else if ((fname_len == sizeof(ZEND_CALL_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_CALL_FUNC_NAME, sizeof(ZEND_CALL_FUNC_NAME) - 1)) { __call = reg_function; - } else if ((fname_len == sizeof(ZEND_CALLSTATIC_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_CALLSTATIC_FUNC_NAME, sizeof(ZEND_CALLSTATIC_FUNC_NAME))) { + } else if ((fname_len == sizeof(ZEND_CALLSTATIC_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_CALLSTATIC_FUNC_NAME, sizeof(ZEND_CALLSTATIC_FUNC_NAME) - 1)) { __callstatic = reg_function; - } else if ((fname_len == sizeof(ZEND_TOSTRING_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_TOSTRING_FUNC_NAME, sizeof(ZEND_TOSTRING_FUNC_NAME))) { + } else if ((fname_len == sizeof(ZEND_TOSTRING_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_TOSTRING_FUNC_NAME, sizeof(ZEND_TOSTRING_FUNC_NAME) - 1)) { __tostring = reg_function; - } else if ((fname_len == sizeof(ZEND_GET_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_GET_FUNC_NAME, sizeof(ZEND_GET_FUNC_NAME))) { + } else if ((fname_len == sizeof(ZEND_GET_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_GET_FUNC_NAME, sizeof(ZEND_GET_FUNC_NAME) - 1)) { __get = reg_function; - } else if ((fname_len == sizeof(ZEND_SET_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_SET_FUNC_NAME, sizeof(ZEND_SET_FUNC_NAME))) { + } else if ((fname_len == sizeof(ZEND_SET_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_SET_FUNC_NAME, sizeof(ZEND_SET_FUNC_NAME) - 1)) { __set = reg_function; - } else if ((fname_len == sizeof(ZEND_UNSET_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_UNSET_FUNC_NAME, sizeof(ZEND_UNSET_FUNC_NAME))) { + } else if ((fname_len == sizeof(ZEND_UNSET_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_UNSET_FUNC_NAME, sizeof(ZEND_UNSET_FUNC_NAME) - 1)) { __unset = reg_function; - } else if ((fname_len == sizeof(ZEND_ISSET_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_ISSET_FUNC_NAME, sizeof(ZEND_ISSET_FUNC_NAME))) { + } else if ((fname_len == sizeof(ZEND_ISSET_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_ISSET_FUNC_NAME, sizeof(ZEND_ISSET_FUNC_NAME) - 1)) { __isset = reg_function; } else { reg_function = NULL; @@ -2305,10 +2313,8 @@ ZEND_API void zend_unregister_functions(const zend_function_entry *functions, in } /* }}} */ -ZEND_API int zend_startup_module(zend_module_entry *module) /* {{{ */ +ZEND_API int zend_startup_module(zend_module_entry *module TSRMLS_DC) /* {{{ */ { - TSRMLS_FETCH(); - if ((module = zend_register_internal_module(module TSRMLS_CC)) != NULL && zend_startup_module_ex(module TSRMLS_CC) == SUCCESS) { return SUCCESS; } @@ -2385,7 +2391,7 @@ void module_destructor(zend_module_entry *module) /* {{{ */ } /* }}} */ -void zend_activate_modules(TSRMLS_D) /* {{{ */ +ZEND_API void zend_activate_modules(TSRMLS_D) /* {{{ */ { zend_module_entry **p = module_request_startup_handlers; @@ -2414,7 +2420,7 @@ int module_registry_cleanup(zend_module_entry *module TSRMLS_DC) /* {{{ */ } /* }}} */ -void zend_deactivate_modules(TSRMLS_D) /* {{{ */ +ZEND_API void zend_deactivate_modules(TSRMLS_D) /* {{{ */ { EG(opline_ptr) = NULL; /* we're no longer executing anything */ @@ -2461,7 +2467,7 @@ static int exec_done_cb(zend_module_entry *module TSRMLS_DC) /* {{{ */ } /* }}} */ -void zend_post_deactivate_modules(TSRMLS_D) /* {{{ */ +ZEND_API void zend_post_deactivate_modules(TSRMLS_D) /* {{{ */ { if (EG(full_tables_cleanup)) { zend_hash_apply(&module_registry, (apply_func_t) exec_done_cb TSRMLS_CC); @@ -2822,7 +2828,7 @@ static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fca if (strict_class && fcc->calling_scope && mlen == sizeof(ZEND_CONSTRUCTOR_FUNC_NAME)-1 && - !memcmp(lmname, ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME))) { + !memcmp(lmname, ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME) - 1)) { fcc->function_handler = fcc->calling_scope->constructor; if (fcc->function_handler) { retval = 1; diff --git a/Zend/zend_API.h b/Zend/zend_API.h index 16e766d8a51ea..c426acf497400 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -98,16 +98,18 @@ typedef struct _zend_fcall_info_cache { #define ZEND_FE_END { NULL, NULL, NULL, 0, 0 } -#define ZEND_ARG_INFO(pass_by_ref, name) { #name, sizeof(#name)-1, NULL, 0, 0, 0, pass_by_ref}, -#define ZEND_ARG_PASS_INFO(pass_by_ref) { NULL, 0, NULL, 0, 0, 0, pass_by_ref}, -#define ZEND_ARG_OBJ_INFO(pass_by_ref, name, classname, allow_null) { #name, sizeof(#name)-1, #classname, sizeof(#classname)-1, IS_OBJECT, allow_null, pass_by_ref}, -#define ZEND_ARG_ARRAY_INFO(pass_by_ref, name, allow_null) { #name, sizeof(#name)-1, NULL, 0, IS_ARRAY, allow_null, pass_by_ref}, -#define ZEND_ARG_TYPE_INFO(pass_by_ref, name, type_hint, allow_null) { #name, sizeof(#name)-1, NULL, 0, type_hint, allow_null, pass_by_ref}, -#define ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, return_reference, required_num_args) \ +#define ZEND_ARG_INFO(pass_by_ref, name) { #name, sizeof(#name)-1, NULL, 0, 0, pass_by_ref, 0, 0 }, +#define ZEND_ARG_PASS_INFO(pass_by_ref) { NULL, 0, NULL, 0, 0, pass_by_ref, 0, 0 }, +#define ZEND_ARG_OBJ_INFO(pass_by_ref, name, classname, allow_null) { #name, sizeof(#name)-1, #classname, sizeof(#classname)-1, IS_OBJECT, pass_by_ref, allow_null, 0 }, +#define ZEND_ARG_ARRAY_INFO(pass_by_ref, name, allow_null) { #name, sizeof(#name)-1, NULL, 0, IS_ARRAY, pass_by_ref, allow_null, 0 }, +#define ZEND_ARG_TYPE_INFO(pass_by_ref, name, type_hint, allow_null) { #name, sizeof(#name)-1, NULL, 0, type_hint, pass_by_ref, allow_null, 0 }, +#define ZEND_ARG_VARIADIC_INFO(pass_by_ref, name) { #name, sizeof(#name)-1, NULL, 0, 0, pass_by_ref, 0, 1 }, + +#define ZEND_BEGIN_ARG_INFO_EX(name, _unused, return_reference, required_num_args) \ static const zend_arg_info name[] = { \ - { NULL, 0, NULL, required_num_args, 0, return_reference, pass_rest_by_reference}, -#define ZEND_BEGIN_ARG_INFO(name, pass_rest_by_reference) \ - ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, ZEND_RETURN_VALUE, -1) + { NULL, 0, NULL, required_num_args, 0, return_reference, 0, 0 }, +#define ZEND_BEGIN_ARG_INFO(name, _unused) \ + ZEND_BEGIN_ARG_INFO_EX(name, 0, ZEND_RETURN_VALUE, -1) #define ZEND_END_ARG_INFO() }; /* Name macros */ @@ -264,7 +266,7 @@ ZEND_API int zend_parse_parameter(int flags, int arg_num TSRMLS_DC, zval **arg, ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_function_entry *functions, HashTable *function_table, int type TSRMLS_DC); ZEND_API void zend_unregister_functions(const zend_function_entry *functions, int count, HashTable *function_table TSRMLS_DC); -ZEND_API int zend_startup_module(zend_module_entry *module_entry); +ZEND_API int zend_startup_module(zend_module_entry *module_entry TSRMLS_DC); ZEND_API zend_module_entry* zend_register_internal_module(zend_module_entry *module_entry TSRMLS_DC); ZEND_API zend_module_entry* zend_register_module_ex(zend_module_entry *module TSRMLS_DC); ZEND_API int zend_startup_module_ex(zend_module_entry *module TSRMLS_DC); diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index bf9d000437731..e9d8a1d83726e 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -2682,10 +2682,8 @@ ZEND_API char *zend_strndup(const char *s, uint length) } -ZEND_API int zend_set_memory_limit(size_t memory_limit) +ZEND_API int zend_set_memory_limit(size_t memory_limit TSRMLS_DC) { - TSRMLS_FETCH(); - AG(mm_heap)->limit = (memory_limit >= AG(mm_heap)->block_size) ? memory_limit : AG(mm_heap)->block_size; return SUCCESS; diff --git a/Zend/zend_alloc.h b/Zend/zend_alloc.h index 0b4e74d8971a2..020e37c972896 100644 --- a/Zend/zend_alloc.h +++ b/Zend/zend_alloc.h @@ -139,7 +139,7 @@ inline static void * __zend_realloc(void *p, size_t len) #define safe_estrdup(ptr) ((ptr)?(estrdup(ptr)):STR_EMPTY_ALLOC()) #define safe_estrndup(ptr, len) ((ptr)?(estrndup((ptr), (len))):STR_EMPTY_ALLOC()) -ZEND_API int zend_set_memory_limit(size_t memory_limit); +ZEND_API int zend_set_memory_limit(size_t memory_limit TSRMLS_DC); ZEND_API void start_memory_manager(TSRMLS_D); ZEND_API void shutdown_memory_manager(int silent, int full_shutdown TSRMLS_DC); diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c new file mode 100644 index 0000000000000..7a15762a105e6 --- /dev/null +++ b/Zend/zend_ast.c @@ -0,0 +1,329 @@ +/* + +----------------------------------------------------------------------+ + | Zend Engine | + +----------------------------------------------------------------------+ + | Copyright (c) 1998-2013 Zend Technologies Ltd. (http://www.zend.com) | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.00 of the Zend license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.zend.com/license/2_00.txt. | + | If you did not receive a copy of the Zend license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@zend.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Bob Weinand | + | Dmitry Stogov | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#include "zend_ast.h" +#include "zend_API.h" +#include "zend_operators.h" + +ZEND_API zend_ast *zend_ast_create_constant(zval *zv) +{ + zend_ast *ast = emalloc(sizeof(zend_ast) + sizeof(zval)); + ast->kind = ZEND_CONST; + ast->children = 0; + ast->u.val = (zval*)(ast + 1); + INIT_PZVAL_COPY(ast->u.val, zv); + return ast; +} + +ZEND_API zend_ast* zend_ast_create_unary(uint kind, zend_ast *op0) +{ + zend_ast *ast = emalloc(sizeof(zend_ast)); + ast->kind = kind; + ast->children = 1; + (&ast->u.child)[0] = op0; + return ast; +} + +ZEND_API zend_ast* zend_ast_create_binary(uint kind, zend_ast *op0, zend_ast *op1) +{ + zend_ast *ast = emalloc(sizeof(zend_ast) + sizeof(zend_ast*)); + ast->kind = kind; + ast->children = 2; + (&ast->u.child)[0] = op0; + (&ast->u.child)[1] = op1; + return ast; +} + +ZEND_API zend_ast* zend_ast_create_ternary(uint kind, zend_ast *op0, zend_ast *op1, zend_ast *op2) +{ + zend_ast *ast = emalloc(sizeof(zend_ast) + sizeof(zend_ast*) * 2); + ast->kind = kind; + ast->children = 3; + (&ast->u.child)[0] = op0; + (&ast->u.child)[1] = op1; + (&ast->u.child)[2] = op2; + return ast; +} + +ZEND_API int zend_ast_is_ct_constant(zend_ast *ast) +{ + int i; + + if (ast->kind == ZEND_CONST) { + return !IS_CONSTANT_TYPE(Z_TYPE_P(ast->u.val)); + } else { + for (i = 0; i < ast->children; i++) { + if ((&ast->u.child)[i]) { + if (!zend_ast_is_ct_constant((&ast->u.child)[i])) { + return 0; + } + } + } + return 1; + } +} + +ZEND_API void zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *scope TSRMLS_DC) +{ + zval op1, op2; + + switch (ast->kind) { + case ZEND_ADD: + zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); + zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); + add_function(result, &op1, &op2 TSRMLS_CC); + zval_dtor(&op1); + zval_dtor(&op2); + break; + case ZEND_SUB: + zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); + zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); + sub_function(result, &op1, &op2 TSRMLS_CC); + zval_dtor(&op1); + zval_dtor(&op2); + break; + case ZEND_MUL: + zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); + zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); + mul_function(result, &op1, &op2 TSRMLS_CC); + zval_dtor(&op1); + zval_dtor(&op2); + break; + case ZEND_DIV: + zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); + zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); + div_function(result, &op1, &op2 TSRMLS_CC); + zval_dtor(&op1); + zval_dtor(&op2); + break; + case ZEND_MOD: + zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); + zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); + mod_function(result, &op1, &op2 TSRMLS_CC); + zval_dtor(&op1); + zval_dtor(&op2); + break; + case ZEND_SL: + zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); + zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); + shift_left_function(result, &op1, &op2 TSRMLS_CC); + zval_dtor(&op1); + zval_dtor(&op2); + break; + case ZEND_SR: + zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); + zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); + shift_right_function(result, &op1, &op2 TSRMLS_CC); + zval_dtor(&op1); + zval_dtor(&op2); + break; + case ZEND_CONCAT: + zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); + zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); + concat_function(result, &op1, &op2 TSRMLS_CC); + zval_dtor(&op1); + zval_dtor(&op2); + break; + case ZEND_BW_OR: + zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); + zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); + bitwise_or_function(result, &op1, &op2 TSRMLS_CC); + zval_dtor(&op1); + zval_dtor(&op2); + break; + case ZEND_BW_AND: + zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); + zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); + bitwise_and_function(result, &op1, &op2 TSRMLS_CC); + zval_dtor(&op1); + zval_dtor(&op2); + break; + case ZEND_BW_XOR: + zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); + zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); + bitwise_xor_function(result, &op1, &op2 TSRMLS_CC); + zval_dtor(&op1); + zval_dtor(&op2); + break; + case ZEND_BW_NOT: + zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); + bitwise_not_function(result, &op1 TSRMLS_CC); + zval_dtor(&op1); + break; + case ZEND_BOOL_NOT: + zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); + boolean_not_function(result, &op1 TSRMLS_CC); + zval_dtor(&op1); + break; + case ZEND_BOOL_XOR: + zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); + zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); + boolean_xor_function(result, &op1, &op2 TSRMLS_CC); + zval_dtor(&op1); + zval_dtor(&op2); + break; + case ZEND_IS_IDENTICAL: + zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); + zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); + is_identical_function(result, &op1, &op2 TSRMLS_CC); + zval_dtor(&op1); + zval_dtor(&op2); + break; + case ZEND_IS_NOT_IDENTICAL: + zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); + zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); + is_not_identical_function(result, &op1, &op2 TSRMLS_CC); + zval_dtor(&op1); + zval_dtor(&op2); + break; + case ZEND_IS_EQUAL: + zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); + zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); + is_equal_function(result, &op1, &op2 TSRMLS_CC); + zval_dtor(&op1); + zval_dtor(&op2); + break; + case ZEND_IS_NOT_EQUAL: + zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); + zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); + is_not_equal_function(result, &op1, &op2 TSRMLS_CC); + zval_dtor(&op1); + zval_dtor(&op2); + break; + case ZEND_IS_SMALLER: + zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); + zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); + is_smaller_function(result, &op1, &op2 TSRMLS_CC); + zval_dtor(&op1); + zval_dtor(&op2); + break; + case ZEND_IS_SMALLER_OR_EQUAL: + zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); + zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); + is_smaller_or_equal_function(result, &op1, &op2 TSRMLS_CC); + zval_dtor(&op1); + zval_dtor(&op2); + break; + case ZEND_CONST: + *result = *ast->u.val; + zval_copy_ctor(result); + if (IS_CONSTANT_TYPE(Z_TYPE_P(result))) { + zval_update_constant_ex(&result, (void *) 1, scope TSRMLS_CC); + } + break; + case ZEND_BOOL_AND: + zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); + if (zend_is_true(&op1 TSRMLS_CC)) { + zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); + ZVAL_BOOL(result, zend_is_true(&op2 TSRMLS_CC)); + zval_dtor(&op2); + } else { + ZVAL_BOOL(result, 0); + } + zval_dtor(&op1); + break; + case ZEND_BOOL_OR: + zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); + if (zend_is_true(&op1 TSRMLS_CC)) { + ZVAL_BOOL(result, 1); + } else { + zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); + ZVAL_BOOL(result, zend_is_true(&op2 TSRMLS_CC)); + zval_dtor(&op2); + } + zval_dtor(&op1); + break; + case ZEND_SELECT: + zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); + if (zend_is_true(&op1 TSRMLS_CC)) { + if (!(&ast->u.child)[1]) { + *result = op1; + } else { + zend_ast_evaluate(result, (&ast->u.child)[1], scope TSRMLS_CC); + zval_dtor(&op1); + } + } else { + zend_ast_evaluate(result, (&ast->u.child)[2], scope TSRMLS_CC); + zval_dtor(&op1); + } + break; + case ZEND_UNARY_PLUS: + ZVAL_LONG(&op1, 0); + zend_ast_evaluate(&op2, (&ast->u.child)[0], scope TSRMLS_CC); + add_function(result, &op1, &op2 TSRMLS_CC); + zval_dtor(&op2); + break; + case ZEND_UNARY_MINUS: + ZVAL_LONG(&op1, 0); + zend_ast_evaluate(&op2, (&ast->u.child)[0], scope TSRMLS_CC); + sub_function(result, &op1, &op2 TSRMLS_CC); + zval_dtor(&op2); + break; + default: + zend_error(E_ERROR, "Unsupported constant expression"); + } +} + +ZEND_API zend_ast *zend_ast_copy(zend_ast *ast) +{ + if (ast == NULL) { + return NULL; + } else if (ast->kind == ZEND_CONST) { + zend_ast *copy = zend_ast_create_constant(ast->u.val); + zval_copy_ctor(copy->u.val); + return copy; + } else { + switch (ast->children) { + case 1: + return zend_ast_create_unary( + ast->kind, + zend_ast_copy((&ast->u.child)[0])); + case 2: + return zend_ast_create_binary( + ast->kind, + zend_ast_copy((&ast->u.child)[0]), + zend_ast_copy((&ast->u.child)[1])); + case 3: + return zend_ast_create_ternary( + ast->kind, + zend_ast_copy((&ast->u.child)[0]), + zend_ast_copy((&ast->u.child)[1]), + zend_ast_copy((&ast->u.child)[2])); + } + } + return NULL; +} + +ZEND_API void zend_ast_destroy(zend_ast *ast) +{ + int i; + + if (ast->kind == ZEND_CONST) { + zval_dtor(ast->u.val); + } else { + for (i = 0; i < ast->children; i++) { + if ((&ast->u.child)[i]) { + zend_ast_destroy((&ast->u.child)[i]); + } + } + } + efree(ast); +} diff --git a/Zend/zend_ast.h b/Zend/zend_ast.h new file mode 100644 index 0000000000000..49908cebbe1f6 --- /dev/null +++ b/Zend/zend_ast.h @@ -0,0 +1,61 @@ +/* + +----------------------------------------------------------------------+ + | Zend Engine | + +----------------------------------------------------------------------+ + | Copyright (c) 1998-2013 Zend Technologies Ltd. (http://www.zend.com) | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.00 of the Zend license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.zend.com/license/2_00.txt. | + | If you did not receive a copy of the Zend license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@zend.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Bob Weinand | + | Dmitry Stogov | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifndef ZEND_AST_H +#define ZEND_AST_H + +typedef struct _zend_ast zend_ast; + +#include "zend.h" + +typedef enum _zend_ast_kind { + /* first 256 kinds are reserved for opcodes */ + ZEND_CONST = 256, + ZEND_BOOL_AND, + ZEND_BOOL_OR, + ZEND_SELECT, + ZEND_UNARY_PLUS, + ZEND_UNARY_MINUS, +} zend_ast_kind; + +struct _zend_ast { + unsigned short kind; + unsigned short children; + union { + zval *val; + zend_ast *child; + } u; +}; + +ZEND_API zend_ast *zend_ast_create_constant(zval *zv); + +ZEND_API zend_ast *zend_ast_create_unary(uint kind, zend_ast *op0); +ZEND_API zend_ast *zend_ast_create_binary(uint kind, zend_ast *op0, zend_ast *op1); +ZEND_API zend_ast *zend_ast_create_ternary(uint kind, zend_ast *op0, zend_ast *op1, zend_ast *op2); + +ZEND_API int zend_ast_is_ct_constant(zend_ast *ast); + +ZEND_API void zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *scope TSRMLS_DC); + +ZEND_API zend_ast *zend_ast_copy(zend_ast *ast); +ZEND_API void zend_ast_destroy(zend_ast *ast); + +#endif diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index ed136f5e12917..0a478a7532912 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -435,9 +435,7 @@ ZEND_FUNCTION(func_get_arg) } arg = *(p-(arg_count-requested_offset)); - *return_value = *arg; - zval_copy_ctor(return_value); - INIT_PZVAL(return_value); + RETURN_ZVAL_FAST(arg); } /* }}} */ @@ -461,12 +459,17 @@ ZEND_FUNCTION(func_get_args) array_init_size(return_value, arg_count); for (i=0; ivalue.ht, &element, sizeof(zval *), NULL); } } @@ -606,9 +609,9 @@ ZEND_FUNCTION(each) Z_ADDREF_P(entry); /* add the key elements */ - switch (zend_hash_get_current_key_ex(target_hash, &string_key, &string_key_len, &num_key, 1, NULL)) { + switch (zend_hash_get_current_key_ex(target_hash, &string_key, &string_key_len, &num_key, 0, NULL)) { case HASH_KEY_IS_STRING: - add_get_index_stringl(return_value, 0, string_key, string_key_len-1, (void **) &inserted_pointer, 0); + add_get_index_stringl(return_value, 0, string_key, string_key_len-1, (void **) &inserted_pointer, !IS_INTERNED(string_key)); break; case HASH_KEY_IS_LONG: add_get_index_long(return_value, 0, num_key, (void **) &inserted_pointer); @@ -943,11 +946,11 @@ static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value /* this is necessary to make it able to work with default array * properties, returned to user */ - if (Z_TYPE_P(prop_copy) == IS_CONSTANT_ARRAY || (Z_TYPE_P(prop_copy) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) { + if (IS_CONSTANT_TYPE(Z_TYPE_P(prop_copy))) { zval_update_constant(&prop_copy, 0 TSRMLS_CC); } - add_assoc_zval(return_value, key, prop_copy); + zend_hash_update(Z_ARRVAL_P(return_value), key, key_len, &prop_copy, sizeof(zval*), NULL); } } /* }}} */ @@ -1017,7 +1020,14 @@ ZEND_FUNCTION(get_object_vars) zend_unmangle_property_name_ex(key, key_len - 1, &class_name, &prop_name, (int*) &prop_len); /* Not separating references */ Z_ADDREF_PP(value); - add_assoc_zval_ex(return_value, prop_name, prop_len + 1, *value); + if (IS_INTERNED(key) && prop_name != key) { + /* we can't use substring of interned string as a new key */ + char *tmp = estrndup(prop_name, prop_len); + add_assoc_zval_ex(return_value, tmp, prop_len + 1, *value); + efree(tmp); + } else { + add_assoc_zval_ex(return_value, prop_name, prop_len + 1, *value); + } } } zend_hash_move_forward_ex(properties, &pos); @@ -1473,6 +1483,7 @@ ZEND_FUNCTION(crash) ZEND_FUNCTION(get_included_files) { char *entry; + uint entry_len; if (zend_parse_parameters_none() == FAILURE) { return; @@ -1480,8 +1491,8 @@ ZEND_FUNCTION(get_included_files) array_init(return_value); zend_hash_internal_pointer_reset(&EG(included_files)); - while (zend_hash_get_current_key(&EG(included_files), &entry, NULL, 1) == HASH_KEY_IS_STRING) { - add_next_index_string(return_value, entry, 0); + while (zend_hash_get_current_key_ex(&EG(included_files), &entry, &entry_len, NULL, 0, NULL) == HASH_KEY_IS_STRING) { + add_next_index_stringl(return_value, entry, entry_len-1, !IS_INTERNED(entry)); zend_hash_move_forward(&EG(included_files)); } } @@ -2436,36 +2447,49 @@ ZEND_FUNCTION(extension_loaded) Returns an array with the names of functions belonging to the named extension */ ZEND_FUNCTION(get_extension_funcs) { - char *extension_name; - int extension_name_len; + char *extension_name, *lcname; + int extension_name_len, array; zend_module_entry *module; - const zend_function_entry *func; - + HashPosition iterator; + zend_function *zif; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &extension_name, &extension_name_len) == FAILURE) { return; } - if (strncasecmp(extension_name, "zend", sizeof("zend"))) { - char *lcname = zend_str_tolower_dup(extension_name, extension_name_len); - if (zend_hash_find(&module_registry, lcname, - extension_name_len+1, (void**)&module) == FAILURE) { - efree(lcname); - RETURN_FALSE; - } + lcname = zend_str_tolower_dup(extension_name, extension_name_len); + } else { + lcname = estrdup("core"); + } + if (zend_hash_find(&module_registry, lcname, + extension_name_len+1, (void**)&module) == FAILURE) { efree(lcname); + RETURN_FALSE; + } - if (!(func = module->functions)) { - RETURN_FALSE; - } + zend_hash_internal_pointer_reset_ex(CG(function_table), &iterator); + if (module->functions) { + /* avoid BC break, if functions list is empty, will return an empty array */ + array_init(return_value); + array = 1; } else { - func = builtin_functions; + array = 0; + } + while (zend_hash_get_current_data_ex(CG(function_table), (void **) &zif, &iterator) == SUCCESS) { + if (zif->common.type==ZEND_INTERNAL_FUNCTION + && zif->internal_function.module == module) { + if (!array) { + array_init(return_value); + array = 1; + } + add_next_index_string(return_value, zif->common.function_name, 1); + } + zend_hash_move_forward_ex(CG(function_table), &iterator); } - array_init(return_value); + efree(lcname); - while (func->fname) { - add_next_index_string(return_value, func->fname, 1); - func++; + if (!array) { + RETURN_FALSE; } } /* }}} */ diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 672f62b7eefa3..476711e9e3e8a 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -26,7 +26,7 @@ #include "zend_llist.h" #include "zend_API.h" #include "zend_exceptions.h" -#include "tsrm_virtual_cwd.h" +#include "zend_virtual_cwd.h" #include "zend_multibyte.h" #include "zend_language_scanner.h" @@ -197,6 +197,9 @@ void zend_init_compiler_data_structures(TSRMLS_D) /* {{{ */ CG(in_namespace) = 0; CG(has_bracketed_namespaces) = 0; CG(current_import) = NULL; + CG(current_import_function) = NULL; + CG(current_import_const) = NULL; + zend_hash_init(&CG(const_filenames), 0, NULL, NULL, 0); init_compiler_declarables(TSRMLS_C); zend_stack_init(&CG(context_stack)); @@ -235,6 +238,7 @@ void shutdown_compiler(TSRMLS_D) /* {{{ */ zend_stack_destroy(&CG(list_stack)); zend_hash_destroy(&CG(filenames_table)); zend_llist_destroy(&CG(open_files)); + zend_hash_destroy(&CG(const_filenames)); zend_stack_destroy(&CG(context_stack)); } /* }}} */ @@ -417,12 +421,16 @@ int zend_add_ns_func_name_literal(zend_op_array *op_array, const zval *zv TSRMLS lc_literal = zend_add_literal(CG(active_op_array), &c TSRMLS_CC); CALCULATE_LITERAL_HASH(lc_literal); - ns_separator = (const char*)zend_memrchr(Z_STRVAL_P(zv), '\\', Z_STRLEN_P(zv)) + 1; - lc_len = Z_STRLEN_P(zv) - (ns_separator - Z_STRVAL_P(zv)); - lc_name = zend_str_tolower_dup(ns_separator, lc_len); - ZVAL_STRINGL(&c, lc_name, lc_len, 0); - lc_literal = zend_add_literal(CG(active_op_array), &c TSRMLS_CC); - CALCULATE_LITERAL_HASH(lc_literal); + ns_separator = (const char*)zend_memrchr(Z_STRVAL_P(zv), '\\', Z_STRLEN_P(zv)); + + if (ns_separator != NULL) { + ns_separator += 1; + lc_len = Z_STRLEN_P(zv) - (ns_separator - Z_STRVAL_P(zv)); + lc_name = zend_str_tolower_dup(ns_separator, lc_len); + ZVAL_STRINGL(&c, lc_name, lc_len, 0); + lc_literal = zend_add_literal(CG(active_op_array), &c TSRMLS_CC); + CALCULATE_LITERAL_HASH(lc_literal); + } return ret; } @@ -659,7 +667,7 @@ void fetch_simple_variable_ex(znode *result, znode *varname, int bp, zend_uchar hash = str_hash(Z_STRVAL(varname->u.constant), Z_STRLEN(varname->u.constant)); if (!zend_is_auto_global_quick(Z_STRVAL(varname->u.constant), Z_STRLEN(varname->u.constant), hash TSRMLS_CC) && !(Z_STRLEN(varname->u.constant) == (sizeof("this")-1) && - !memcmp(Z_STRVAL(varname->u.constant), "this", sizeof("this"))) && + !memcmp(Z_STRVAL(varname->u.constant), "this", sizeof("this") - 1)) && (CG(active_op_array)->last == 0 || CG(active_op_array)->opcodes[CG(active_op_array)->last-1].opcode != ZEND_BEGIN_SILENCE)) { result->op_type = IS_CV; @@ -877,7 +885,7 @@ void zend_do_abstract_method(const znode *function_name, znode *modifiers, const if (Z_LVAL(modifiers->u.constant) & ZEND_ACC_ABSTRACT) { if(Z_LVAL(modifiers->u.constant) & ZEND_ACC_PRIVATE) { - zend_error(E_COMPILE_ERROR, "%s function %s::%s() cannot be declared private", method_type, CG(active_class_entry)->name, Z_STRVAL(function_name->u.constant)); + zend_error_noreturn(E_COMPILE_ERROR, "%s function %s::%s() cannot be declared private", method_type, CG(active_class_entry)->name, Z_STRVAL(function_name->u.constant)); } if (Z_LVAL(body->u.constant) == ZEND_ACC_ABSTRACT) { zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -887,11 +895,11 @@ void zend_do_abstract_method(const znode *function_name, znode *modifiers, const SET_UNUSED(opline->op2); } else { /* we had code in the function body */ - zend_error(E_COMPILE_ERROR, "%s function %s::%s() cannot contain body", method_type, CG(active_class_entry)->name, Z_STRVAL(function_name->u.constant)); + zend_error_noreturn(E_COMPILE_ERROR, "%s function %s::%s() cannot contain body", method_type, CG(active_class_entry)->name, Z_STRVAL(function_name->u.constant)); } } else { if (Z_LVAL(body->u.constant) == ZEND_ACC_ABSTRACT) { - zend_error(E_COMPILE_ERROR, "Non-abstract method %s::%s() must contain body", CG(active_class_entry)->name, Z_STRVAL(function_name->u.constant)); + zend_error_noreturn(E_COMPILE_ERROR, "Non-abstract method %s::%s() must contain body", CG(active_class_entry)->name, Z_STRVAL(function_name->u.constant)); } } } @@ -901,9 +909,10 @@ static zend_bool opline_is_fetch_this(const zend_op *opline TSRMLS_DC) /* {{{ */ { if ((opline->opcode == ZEND_FETCH_W) && (opline->op1_type == IS_CONST) && (Z_TYPE(CONSTANT(opline->op1.constant)) == IS_STRING) + && ((opline->extended_value & ZEND_FETCH_STATIC_MEMBER) != ZEND_FETCH_STATIC_MEMBER) && (Z_HASH_P(&CONSTANT(opline->op1.constant)) == THIS_HASHVAL) && (Z_STRLEN(CONSTANT(opline->op1.constant)) == (sizeof("this")-1)) - && !memcmp(Z_STRVAL(CONSTANT(opline->op1.constant)), "this", sizeof("this"))) { + && !memcmp(Z_STRVAL(CONSTANT(opline->op1.constant)), "this", sizeof("this") - 1)) { return 1; } else { return 0; @@ -950,7 +959,7 @@ void zend_do_assign(znode *result, znode *variable, znode *value TSRMLS_DC) /* { if (variable->op_type == IS_CV) { if (variable->u.op.var == CG(active_op_array)->this_var) { - zend_error(E_COMPILE_ERROR, "Cannot re-assign $this"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign $this"); } } else if (variable->op_type == IS_VAR) { int n = 0; @@ -996,7 +1005,7 @@ void zend_do_assign(znode *result, znode *variable, znode *value TSRMLS_DC) /* { GET_NODE(result, last_op->result); return; } else if (opline_is_fetch_this(last_op TSRMLS_CC)) { - zend_error(E_COMPILE_ERROR, "Cannot re-assign $this"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign $this"); } else { break; } @@ -1020,7 +1029,7 @@ void zend_do_assign_ref(znode *result, const znode *lvar, const znode *rvar TSRM if (lvar->op_type == IS_CV) { if (lvar->u.op.var == CG(active_op_array)->this_var) { - zend_error(E_COMPILE_ERROR, "Cannot re-assign $this"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign $this"); } } else if (lvar->op_type == IS_VAR) { int last_op_number = get_next_op_number(CG(active_op_array)); @@ -1028,7 +1037,7 @@ void zend_do_assign_ref(znode *result, const znode *lvar, const znode *rvar TSRM if (last_op_number > 0) { opline = &CG(active_op_array)->opcodes[last_op_number-1]; if (opline_is_fetch_this(opline TSRMLS_CC)) { - zend_error(E_COMPILE_ERROR, "Cannot re-assign $this"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign $this"); } } } @@ -1270,10 +1279,10 @@ void zend_check_writable_variable(const znode *variable) /* {{{ */ zend_uint type = variable->EA; if (type & ZEND_PARSED_METHOD_CALL) { - zend_error(E_COMPILE_ERROR, "Can't use method return value in write context"); + zend_error_noreturn(E_COMPILE_ERROR, "Can't use method return value in write context"); } if (type == ZEND_PARSED_FUNCTION_CALL) { - zend_error(E_COMPILE_ERROR, "Can't use function return value in write context"); + zend_error_noreturn(E_COMPILE_ERROR, "Can't use function return value in write context"); } } /* }}} */ @@ -1346,7 +1355,7 @@ void zend_do_end_variable_parse(znode *variable, int type, int arg_offset TSRMLS switch (type) { case BP_VAR_R: if (opline->opcode == ZEND_FETCH_DIM_W && opline->op2_type == IS_UNUSED) { - zend_error(E_COMPILE_ERROR, "Cannot use [] for reading"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use [] for reading"); } opline->opcode -= 3; break; @@ -1357,7 +1366,7 @@ void zend_do_end_variable_parse(znode *variable, int type, int arg_offset TSRMLS break; case BP_VAR_IS: if (opline->opcode == ZEND_FETCH_DIM_W && opline->op2_type == IS_UNUSED) { - zend_error(E_COMPILE_ERROR, "Cannot use [] for reading"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use [] for reading"); } opline->opcode += 6; /* 3+3 */ break; @@ -1367,7 +1376,7 @@ void zend_do_end_variable_parse(znode *variable, int type, int arg_offset TSRMLS break; case BP_VAR_UNSET: if (opline->opcode == ZEND_FETCH_DIM_W && opline->op2_type == IS_UNUSED) { - zend_error(E_COMPILE_ERROR, "Cannot use [] for unsetting"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use [] for unsetting"); } opline->opcode += 12; /* 3+3+3+3 */ break; @@ -1495,22 +1504,22 @@ int zend_do_verify_access_types(const znode *current_access_type, const znode *n { if ((Z_LVAL(current_access_type->u.constant) & ZEND_ACC_PPP_MASK) && (Z_LVAL(new_modifier->u.constant) & ZEND_ACC_PPP_MASK)) { - zend_error(E_COMPILE_ERROR, "Multiple access type modifiers are not allowed"); + zend_error_noreturn(E_COMPILE_ERROR, "Multiple access type modifiers are not allowed"); } if ((Z_LVAL(current_access_type->u.constant) & ZEND_ACC_ABSTRACT) && (Z_LVAL(new_modifier->u.constant) & ZEND_ACC_ABSTRACT)) { - zend_error(E_COMPILE_ERROR, "Multiple abstract modifiers are not allowed"); + zend_error_noreturn(E_COMPILE_ERROR, "Multiple abstract modifiers are not allowed"); } if ((Z_LVAL(current_access_type->u.constant) & ZEND_ACC_STATIC) && (Z_LVAL(new_modifier->u.constant) & ZEND_ACC_STATIC)) { - zend_error(E_COMPILE_ERROR, "Multiple static modifiers are not allowed"); + zend_error_noreturn(E_COMPILE_ERROR, "Multiple static modifiers are not allowed"); } if ((Z_LVAL(current_access_type->u.constant) & ZEND_ACC_FINAL) && (Z_LVAL(new_modifier->u.constant) & ZEND_ACC_FINAL)) { - zend_error(E_COMPILE_ERROR, "Multiple final modifiers are not allowed"); + zend_error_noreturn(E_COMPILE_ERROR, "Multiple final modifiers are not allowed"); } if (((Z_LVAL(current_access_type->u.constant) | Z_LVAL(new_modifier->u.constant)) & (ZEND_ACC_ABSTRACT | ZEND_ACC_FINAL)) == (ZEND_ACC_ABSTRACT | ZEND_ACC_FINAL)) { - zend_error(E_COMPILE_ERROR, "Cannot use the final modifier on an abstract class member"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use the final modifier on an abstract class member"); } return (Z_LVAL(current_access_type->u.constant) | Z_LVAL(new_modifier->u.constant)); } @@ -1530,7 +1539,7 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n if (is_method) { if (CG(active_class_entry)->ce_flags & ZEND_ACC_INTERFACE) { if ((Z_LVAL(fn_flags_znode->u.constant) & ~(ZEND_ACC_STATIC|ZEND_ACC_PUBLIC))) { - zend_error(E_COMPILE_ERROR, "Access type for interface method %s::%s() must be omitted", CG(active_class_entry)->name, Z_STRVAL(function_name->u.constant)); + zend_error_noreturn(E_COMPILE_ERROR, "Access type for interface method %s::%s() must be omitted", CG(active_class_entry)->name, Z_STRVAL(function_name->u.constant)); } Z_LVAL(fn_flags_znode->u.constant) |= ZEND_ACC_ABSTRACT; /* propagates to the rest of the parser */ } @@ -1566,7 +1575,7 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n lcname = zend_new_interned_string(zend_str_tolower_dup(name, name_len), name_len + 1, 1 TSRMLS_CC); hash = str_hash(lcname, name_len); if (zend_hash_quick_add(&CG(active_class_entry)->function_table, lcname, name_len+1, hash, &op_array, sizeof(zend_op_array), (void **) &CG(active_op_array)) == FAILURE) { - zend_error(E_COMPILE_ERROR, "Cannot redeclare %s::%s()", CG(active_class_entry)->name, name); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare %s::%s()", CG(active_class_entry)->name, name); } zend_stack_push(&CG(context_stack), (void *) &CG(context), sizeof(CG(context))); @@ -1683,6 +1692,7 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n } else { zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); zval key; + zval **ns_name; if (CG(current_namespace)) { /* Prefix function name with current namespace name */ @@ -1698,18 +1708,32 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n lcname = zend_str_tolower_dup(name, name_len); } + /* Function name must not conflict with import names */ + if (CG(current_import_function) && + zend_hash_find(CG(current_import_function), lcname, Z_STRLEN(function_name->u.constant)+1, (void**)&ns_name) == SUCCESS) { + + char *tmp = zend_str_tolower_dup(Z_STRVAL_PP(ns_name), Z_STRLEN_PP(ns_name)); + + if (Z_STRLEN_PP(ns_name) != Z_STRLEN(function_name->u.constant) || + memcmp(tmp, lcname, Z_STRLEN(function_name->u.constant))) { + zend_error(E_COMPILE_ERROR, "Cannot declare function %s because the name is already in use", Z_STRVAL(function_name->u.constant)); + } + efree(tmp); + } + opline->opcode = ZEND_DECLARE_FUNCTION; opline->op1_type = IS_CONST; build_runtime_defined_function_key(&key, lcname, name_len TSRMLS_CC); opline->op1.constant = zend_add_literal(CG(active_op_array), &key TSRMLS_CC); Z_HASH_P(&CONSTANT(opline->op1.constant)) = zend_hash_func(Z_STRVAL(CONSTANT(opline->op1.constant)), Z_STRLEN(CONSTANT(opline->op1.constant))); opline->op2_type = IS_CONST; - LITERAL_STRINGL(opline->op2, lcname, name_len, 0); + LITERAL_STRINGL(opline->op2, lcname, name_len, 1); CALCULATE_LITERAL_HASH(opline->op2.constant); opline->extended_value = ZEND_DECLARE_FUNCTION; zend_hash_quick_update(CG(function_table), Z_STRVAL(key), Z_STRLEN(key), Z_HASH_P(&CONSTANT(opline->op1.constant)), &op_array, sizeof(zend_op_array), (void **) &CG(active_op_array)); zend_stack_push(&CG(context_stack), (void *) &CG(context), sizeof(CG(context))); zend_init_compiler_context(TSRMLS_C); + str_efree(lcname); } if (CG(compiler_options) & ZEND_COMPILE_EXTENDED_INFO) { @@ -1737,7 +1761,6 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n zend_op dummy_opline; dummy_opline.result_type = IS_UNUSED; - dummy_opline.op1_type = IS_UNUSED; zend_stack_push(&CG(foreach_copy_stack), (void *) &dummy_opline, sizeof(zend_op)); } @@ -1808,7 +1831,7 @@ void zend_do_end_function_declaration(const znode *function_token TSRMLS_DC) /* zend_str_tolower_copy(lcname, CG(active_op_array)->function_name, MIN(name_len, sizeof(lcname)-1)); lcname[sizeof(lcname)-1] = '\0'; /* zend_str_tolower_copy won't necessarily set the zero byte */ if (name_len == sizeof(ZEND_AUTOLOAD_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_AUTOLOAD_FUNC_NAME, sizeof(ZEND_AUTOLOAD_FUNC_NAME)) && CG(active_op_array)->num_args != 1) { - zend_error(E_COMPILE_ERROR, "%s() must take exactly 1 argument", ZEND_AUTOLOAD_FUNC_NAME); + zend_error_noreturn(E_COMPILE_ERROR, "%s() must take exactly 1 argument", ZEND_AUTOLOAD_FUNC_NAME); } } @@ -1822,14 +1845,14 @@ void zend_do_end_function_declaration(const znode *function_token TSRMLS_DC) /* } /* }}} */ -void zend_do_receive_arg(zend_uchar op, znode *varname, const znode *offset, const znode *initialization, znode *class_type, zend_uchar pass_by_reference TSRMLS_DC) /* {{{ */ +void zend_do_receive_param(zend_uchar op, znode *varname, const znode *initialization, znode *class_type, zend_uchar pass_by_reference, zend_bool is_variadic TSRMLS_DC) /* {{{ */ { zend_op *opline; zend_arg_info *cur_arg_info; znode var; if (zend_is_auto_global(Z_STRVAL(varname->u.constant), Z_STRLEN(varname->u.constant) TSRMLS_CC)) { - zend_error(E_COMPILE_ERROR, "Cannot re-assign auto-global variable %s", Z_STRVAL(varname->u.constant)); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign auto-global variable %s", Z_STRVAL(varname->u.constant)); } else { var.op_type = IS_CV; var.u.op.var = lookup_cv(CG(active_op_array), Z_STRVAL(varname->u.constant), Z_STRLEN(varname->u.constant), 0 TSRMLS_CC); @@ -1840,30 +1863,47 @@ void zend_do_receive_arg(zend_uchar op, znode *varname, const znode *offset, con !memcmp(Z_STRVAL(varname->u.constant), "this", sizeof("this")-1)) { if (CG(active_op_array)->scope && (CG(active_op_array)->fn_flags & ZEND_ACC_STATIC) == 0) { - zend_error(E_COMPILE_ERROR, "Cannot re-assign $this"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign $this"); } CG(active_op_array)->this_var = var.u.op.var; } } + if (CG(active_op_array)->fn_flags & ZEND_ACC_VARIADIC) { + zend_error_noreturn(E_COMPILE_ERROR, "Only the last parameter can be variadic"); + } + + if (is_variadic) { + if (op == ZEND_RECV_INIT) { + zend_error_noreturn(E_COMPILE_ERROR, "Variadic parameter cannot have a default value"); + } + + op = ZEND_RECV_VARIADIC; + CG(active_op_array)->fn_flags |= ZEND_ACC_VARIADIC; + } + opline = get_next_op(CG(active_op_array) TSRMLS_CC); CG(active_op_array)->num_args++; opline->opcode = op; SET_NODE(opline->result, &var); - SET_NODE(opline->op1, offset); + opline->op1_type = IS_UNUSED; + opline->op1.num = CG(active_op_array)->num_args; if (op == ZEND_RECV_INIT) { SET_NODE(opline->op2, initialization); } else { - CG(active_op_array)->required_num_args = CG(active_op_array)->num_args; SET_UNUSED(opline->op2); + if (!is_variadic) { + CG(active_op_array)->required_num_args = CG(active_op_array)->num_args; + } } CG(active_op_array)->arg_info = erealloc(CG(active_op_array)->arg_info, sizeof(zend_arg_info)*(CG(active_op_array)->num_args)); cur_arg_info = &CG(active_op_array)->arg_info[CG(active_op_array)->num_args-1]; cur_arg_info->name = zend_new_interned_string(estrndup(Z_STRVAL(varname->u.constant), Z_STRLEN(varname->u.constant)), Z_STRLEN(varname->u.constant) + 1, 1 TSRMLS_CC); cur_arg_info->name_len = Z_STRLEN(varname->u.constant); cur_arg_info->type_hint = 0; - cur_arg_info->allow_null = 1; cur_arg_info->pass_by_reference = pass_by_reference; + cur_arg_info->allow_null = 1; + cur_arg_info->is_variadic = is_variadic; cur_arg_info->class_name = NULL; cur_arg_info->class_name_len = 0; @@ -1874,19 +1914,19 @@ void zend_do_receive_arg(zend_uchar op, znode *varname, const znode *offset, con if (class_type->u.constant.type == IS_ARRAY) { cur_arg_info->type_hint = IS_ARRAY; if (op == ZEND_RECV_INIT) { - if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL"))) { + if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL")) || Z_TYPE(initialization->u.constant) == IS_CONSTANT_AST) { cur_arg_info->allow_null = 1; } else if (Z_TYPE(initialization->u.constant) != IS_ARRAY && Z_TYPE(initialization->u.constant) != IS_CONSTANT_ARRAY) { - zend_error(E_COMPILE_ERROR, "Default value for parameters with array type hint can only be an array or NULL"); + zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters with array type hint can only be an array or NULL"); } } } else if (class_type->u.constant.type == IS_CALLABLE) { cur_arg_info->type_hint = IS_CALLABLE; if (op == ZEND_RECV_INIT) { - if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL"))) { + if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL")) || Z_TYPE(initialization->u.constant) == IS_CONSTANT_AST) { cur_arg_info->allow_null = 1; } else { - zend_error(E_COMPILE_ERROR, "Default value for parameters with callable type hint can only be NULL"); + zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters with callable type hint can only be NULL"); } } } else { @@ -1898,10 +1938,10 @@ void zend_do_receive_arg(zend_uchar op, znode *varname, const znode *offset, con cur_arg_info->class_name = Z_STRVAL(class_type->u.constant); cur_arg_info->class_name_len = Z_STRLEN(class_type->u.constant); if (op == ZEND_RECV_INIT) { - if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL"))) { + if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL")) || Z_TYPE(initialization->u.constant) == IS_CONSTANT_AST) { cur_arg_info->allow_null = 1; } else { - zend_error(E_COMPILE_ERROR, "Default value for parameters with a class type hint can only be NULL"); + zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters with a class type hint can only be NULL"); } } } @@ -1916,7 +1956,7 @@ int zend_do_begin_function_call(znode *function_name, zend_bool check_namespace char *lcname; char *is_compound = memchr(Z_STRVAL(function_name->u.constant), '\\', Z_STRLEN(function_name->u.constant)); - zend_resolve_non_class_name(function_name, check_namespace TSRMLS_CC); + zend_resolve_function_name(function_name, &check_namespace TSRMLS_CC); if (check_namespace && CG(current_namespace) && !is_compound) { /* We assume we call function from the current namespace @@ -1962,7 +2002,7 @@ void zend_do_begin_method_call(znode *left_bracket TSRMLS_DC) /* {{{ */ if ((last_op->op2_type == IS_CONST) && (Z_TYPE(CONSTANT(last_op->op2.constant)) == IS_STRING) && (Z_STRLEN(CONSTANT(last_op->op2.constant)) == sizeof(ZEND_CLONE_FUNC_NAME)-1) && !zend_binary_strcasecmp(Z_STRVAL(CONSTANT(last_op->op2.constant)), Z_STRLEN(CONSTANT(last_op->op2.constant)), ZEND_CLONE_FUNC_NAME, sizeof(ZEND_CLONE_FUNC_NAME)-1)) { - zend_error(E_COMPILE_ERROR, "Cannot call __clone() method on objects - use 'clone $obj' instead"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot call __clone() method on objects - use 'clone $obj' instead"); } if (last_op->opcode == ZEND_FETCH_OBJ_R) { @@ -1970,7 +2010,7 @@ void zend_do_begin_method_call(znode *left_bracket TSRMLS_DC) /* {{{ */ zval name; name = CONSTANT(last_op->op2.constant); if (Z_TYPE(name) != IS_STRING) { - zend_error(E_COMPILE_ERROR, "Method name must be a string"); + zend_error_noreturn(E_COMPILE_ERROR, "Method name must be a string"); } Z_STRVAL(name) = str_estrndup(Z_STRVAL(name), Z_STRLEN(name)); FREE_POLYMORPHIC_CACHE_SLOT(last_op->op2.constant); @@ -2053,12 +2093,12 @@ void zend_do_begin_dynamic_function_call(znode *function_name, int ns_call TSRML } /* }}} */ -void zend_resolve_non_class_name(znode *element_name, zend_bool check_namespace TSRMLS_DC) /* {{{ */ +void zend_resolve_non_class_name(znode *element_name, zend_bool *check_namespace, zend_bool case_sensitive, HashTable *current_import_sub TSRMLS_DC) /* {{{ */ { znode tmp; int len; zval **ns; - char *lcname, *compound = memchr(Z_STRVAL(element_name->u.constant), '\\', Z_STRLEN(element_name->u.constant)); + char *lookup_name, *compound = memchr(Z_STRVAL(element_name->u.constant), '\\', Z_STRLEN(element_name->u.constant)); if (Z_STRVAL(element_name->u.constant)[0] == '\\') { /* name starts with \ so it is known and unambiguos, nothing to do here but shorten it */ @@ -2067,15 +2107,35 @@ void zend_resolve_non_class_name(znode *element_name, zend_bool check_namespace return; } - if(!check_namespace) { + if(!*check_namespace) { return; } + if (current_import_sub) { + len = Z_STRLEN(element_name->u.constant)+1; + if (case_sensitive) { + lookup_name = estrndup(Z_STRVAL(element_name->u.constant), len); + } else { + lookup_name = zend_str_tolower_dup(Z_STRVAL(element_name->u.constant), len); + } + /* Check if function/const matches imported name */ + if (zend_hash_find(current_import_sub, lookup_name, len, (void**)&ns) == SUCCESS) { + zval_dtor(&element_name->u.constant); + element_name->u.constant = **ns; + zval_copy_ctor(&element_name->u.constant); + efree(lookup_name); + *check_namespace = 0; + return; + } + efree(lookup_name); + } + if (compound && CG(current_import)) { len = compound - Z_STRVAL(element_name->u.constant); - lcname = zend_str_tolower_dup(Z_STRVAL(element_name->u.constant), len); + /* namespace is always lowercase */ + lookup_name = zend_str_tolower_dup(Z_STRVAL(element_name->u.constant), len); /* Check if first part of compound name is an import name */ - if (zend_hash_find(CG(current_import), lcname, len+1, (void**)&ns) == SUCCESS) { + if (zend_hash_find(CG(current_import), lookup_name, len+1, (void**)&ns) == SUCCESS) { /* Substitute import name */ tmp.op_type = IS_CONST; tmp.u.constant = **ns; @@ -2085,10 +2145,11 @@ void zend_resolve_non_class_name(znode *element_name, zend_bool check_namespace memmove(Z_STRVAL(element_name->u.constant), Z_STRVAL(element_name->u.constant)+len, Z_STRLEN(element_name->u.constant)+1); zend_do_build_namespace_name(&tmp, &tmp, element_name TSRMLS_CC); *element_name = tmp; - efree(lcname); + efree(lookup_name); + *check_namespace = 0; return; } - efree(lcname); + efree(lookup_name); } if (CG(current_namespace)) { @@ -2104,6 +2165,18 @@ void zend_resolve_non_class_name(znode *element_name, zend_bool check_namespace } /* }}} */ +void zend_resolve_function_name(znode *element_name, zend_bool *check_namespace TSRMLS_DC) /* {{{ */ +{ + zend_resolve_non_class_name(element_name, check_namespace, 0, CG(current_import_function) TSRMLS_CC); +} +/* }}} */ + +void zend_resolve_const_name(znode *element_name, zend_bool *check_namespace TSRMLS_DC) /* {{{ */ +{ + zend_resolve_non_class_name(element_name, check_namespace, 1, CG(current_import_const) TSRMLS_CC); +} +/* }}} */ + void zend_do_resolve_class_name(znode *result, znode *class_name, int is_static TSRMLS_DC) /* {{{ */ { char *lcname; @@ -2115,7 +2188,7 @@ void zend_do_resolve_class_name(znode *result, znode *class_name, int is_static switch (lctype) { case ZEND_FETCH_CLASS_SELF: if (!CG(active_class_entry)) { - zend_error(E_COMPILE_ERROR, "Cannot access self::class when no class scope is active"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot access self::class when no class scope is active"); } zval_dtor(&class_name->u.constant); class_name->op_type = IS_CONST; @@ -2125,13 +2198,13 @@ void zend_do_resolve_class_name(znode *result, znode *class_name, int is_static case ZEND_FETCH_CLASS_STATIC: case ZEND_FETCH_CLASS_PARENT: if (is_static) { - zend_error(E_COMPILE_ERROR, + zend_error_noreturn(E_COMPILE_ERROR, "%s::class cannot be used for compile-time class name resolution", lctype == ZEND_FETCH_CLASS_STATIC ? "static" : "parent" ); } if (!CG(active_class_entry)) { - zend_error(E_COMPILE_ERROR, + zend_error_noreturn(E_COMPILE_ERROR, "Cannot access %s::class when no class scope is active", lctype == ZEND_FETCH_CLASS_STATIC ? "static" : "parent" ); @@ -2171,7 +2244,7 @@ void zend_resolve_class_name(znode *class_name TSRMLS_DC) /* {{{ */ Z_STRLEN(class_name->u.constant) + 1); if (ZEND_FETCH_CLASS_DEFAULT != zend_get_class_fetch_type(Z_STRVAL(class_name->u.constant), Z_STRLEN(class_name->u.constant))) { - zend_error(E_COMPILE_ERROR, "'\\%s' is an invalid class name", Z_STRVAL(class_name->u.constant)); + zend_error_noreturn(E_COMPILE_ERROR, "'\\%s' is an invalid class name", Z_STRVAL(class_name->u.constant)); } } else { if (CG(current_import)) { @@ -2279,7 +2352,7 @@ void zend_do_label(znode *label TSRMLS_DC) /* {{{ */ dest.opline_num = get_next_op_number(CG(active_op_array)); if (zend_hash_add(CG(context).labels, Z_STRVAL(label->u.constant), Z_STRLEN(label->u.constant) + 1, (void**)&dest, sizeof(zend_label), NULL) == FAILURE) { - zend_error(E_COMPILE_ERROR, "Label '%s' already defined", Z_STRVAL(label->u.constant)); + zend_error_noreturn(E_COMPILE_ERROR, "Label '%s' already defined", Z_STRVAL(label->u.constant)); } /* Done with label now */ @@ -2305,7 +2378,7 @@ void zend_resolve_goto_label(zend_op_array *op_array, zend_op *opline, int pass2 CG(in_compilation) = 1; CG(active_op_array) = op_array; CG(zend_lineno) = opline->lineno; - zend_error(E_COMPILE_ERROR, "'goto' to undefined label '%s'", Z_STRVAL_P(label)); + zend_error_noreturn(E_COMPILE_ERROR, "'goto' to undefined label '%s'", Z_STRVAL_P(label)); } else { /* Label is not defined. Delay to pass 2. */ INC_BPC(op_array); @@ -2326,7 +2399,7 @@ void zend_resolve_goto_label(zend_op_array *op_array, zend_op *opline, int pass2 CG(active_op_array) = op_array; CG(zend_lineno) = opline->lineno; } - zend_error(E_COMPILE_ERROR, "'goto' into loop or switch statement is disallowed"); + zend_error_noreturn(E_COMPILE_ERROR, "'goto' into loop or switch statement is disallowed"); } current = op_array->brk_cont_array[current].parent; } @@ -2413,7 +2486,7 @@ int zend_do_begin_class_member_function_call(znode *class_name, znode *method_na if (method_name->op_type == IS_CONST) { char *lcname; if (Z_TYPE(method_name->u.constant) != IS_STRING) { - zend_error(E_COMPILE_ERROR, "Method name must be a string"); + zend_error_noreturn(E_COMPILE_ERROR, "Method name must be a string"); } lcname = zend_str_tolower_dup(Z_STRVAL(method_name->u.constant), Z_STRLEN(method_name->u.constant)); if ((sizeof(ZEND_CONSTRUCTOR_FUNC_NAME)-1) == Z_STRLEN(method_name->u.constant) && @@ -2476,8 +2549,11 @@ void zend_do_end_function_call(znode *function_name, znode *result, const znode } opline = &CG(active_op_array)->opcodes[Z_LVAL(function_name->u.constant)]; } else { + zend_function **function_ptr_ptr; + zend_stack_top(&CG(function_call_stack), (void **) &function_ptr_ptr); + opline = get_next_op(CG(active_op_array) TSRMLS_CC); - if (!is_method && !is_dynamic_fcall && function_name->op_type==IS_CONST) { + if (*function_ptr_ptr) { opline->opcode = ZEND_DO_FCALL; SET_NODE(opline->op1, function_name); SET_UNUSED(opline->op2); @@ -2489,6 +2565,13 @@ void zend_do_end_function_call(znode *function_name, znode *result, const znode SET_UNUSED(opline->op1); SET_UNUSED(opline->op2); opline->op2.num = --CG(context).nested_calls; + + /* This would normally be a ZEND_DO_FCALL, but was forced to use + * ZEND_DO_FCALL_BY_NAME due to a ... argument. In this case we need to + * free the function_name */ + if (!is_method && !is_dynamic_fcall && function_name->op_type==IS_CONST) { + zval_dtor(&function_name->u.constant); + } } } @@ -2509,9 +2592,9 @@ void zend_do_end_function_call(znode *function_name, znode *result, const znode void zend_do_pass_param(znode *param, zend_uchar op, int offset TSRMLS_DC) /* {{{ */ { zend_op *opline; - int original_op=op; + int original_op = op; zend_function **function_ptr_ptr, *function_ptr; - int send_by_reference; + int send_by_reference = 0; int send_function = 0; zend_stack_top(&CG(function_call_stack), (void **) &function_ptr_ptr); @@ -2522,34 +2605,31 @@ void zend_do_pass_param(znode *param, zend_uchar op, int offset TSRMLS_DC) /* {{ function_ptr->common.function_name && function_ptr->common.type == ZEND_USER_FUNCTION && !ARG_SHOULD_BE_SENT_BY_REF(function_ptr, (zend_uint) offset)) { - zend_error(E_COMPILE_ERROR, + zend_error_noreturn(E_COMPILE_ERROR, "Call-time pass-by-reference has been removed; " "If you would like to pass argument by reference, modify the declaration of %s().", function_ptr->common.function_name); } else { - zend_error(E_COMPILE_ERROR, "Call-time pass-by-reference has been removed"); + zend_error_noreturn(E_COMPILE_ERROR, "Call-time pass-by-reference has been removed"); } return; } if (function_ptr) { if (ARG_MAY_BE_SENT_BY_REF(function_ptr, (zend_uint) offset)) { - if (param->op_type & (IS_VAR|IS_CV) && original_op != ZEND_SEND_VAL) { - send_by_reference = 1; - if (op == ZEND_SEND_VAR && zend_is_function_or_method_call(param)) { + if (op == ZEND_SEND_VAR && param->op_type & (IS_VAR|IS_CV)) { + send_by_reference = ZEND_ARG_SEND_BY_REF; + if (zend_is_function_or_method_call(param)) { /* Method call */ op = ZEND_SEND_VAR_NO_REF; send_function = ZEND_ARG_SEND_FUNCTION | ZEND_ARG_SEND_SILENT; } } else { op = ZEND_SEND_VAL; - send_by_reference = 0; } - } else { - send_by_reference = ARG_SHOULD_BE_SENT_BY_REF(function_ptr, (zend_uint) offset) ? ZEND_ARG_SEND_BY_REF : 0; + } else if (ARG_SHOULD_BE_SENT_BY_REF(function_ptr, (zend_uint) offset)) { + send_by_reference = ZEND_ARG_SEND_BY_REF; } - } else { - send_by_reference = 0; } if (op == ZEND_SEND_VAR && zend_is_function_or_method_call(param)) { @@ -2568,7 +2648,7 @@ void zend_do_pass_param(znode *param, zend_uchar op, int offset TSRMLS_DC) /* {{ op = ZEND_SEND_REF; break; default: - zend_error(E_COMPILE_ERROR, "Only variables can be passed by reference"); + zend_error_noreturn(E_COMPILE_ERROR, "Only variables can be passed by reference"); break; } } @@ -2617,6 +2697,39 @@ void zend_do_pass_param(znode *param, zend_uchar op, int offset TSRMLS_DC) /* {{ } /* }}} */ +void zend_do_unpack_params(znode *params, int offset TSRMLS_DC) /* {{{ */ +{ + zend_op *opline; + zend_function **function_ptr_ptr; + + zend_stack_top(&CG(function_call_stack), (void **) &function_ptr_ptr); + if (*function_ptr_ptr) { + /* If argument unpacking is used argument numbers and sending modes can no longer be + * computed at compile time, thus we need access to EX(call). In order to have it we + * retroactively emit a ZEND_INIT_FCALL_BY_NAME opcode. */ + zval func_name; + ZVAL_STRING(&func_name, (*function_ptr_ptr)->common.function_name, 1); + + opline = get_next_op(CG(active_op_array) TSRMLS_CC); + opline->opcode = ZEND_INIT_FCALL_BY_NAME; + opline->result.num = CG(context).nested_calls; + SET_UNUSED(opline->op1); + opline->op2_type = IS_CONST; + opline->op2.constant = zend_add_func_name_literal(CG(active_op_array), &func_name TSRMLS_CC); + GET_CACHE_SLOT(opline->op2.constant); + + ++CG(context).nested_calls; + *function_ptr_ptr = NULL; + } + + opline = get_next_op(CG(active_op_array) TSRMLS_CC); + opline->opcode = ZEND_SEND_UNPACK; + SET_NODE(opline->op1, params); + SET_UNUSED(opline->op2); + opline->op2.num = (zend_uint) offset; +} +/* }}} */ + static int generate_free_switch_expr(const zend_switch_entry *switch_entry TSRMLS_DC) /* {{{ */ { zend_op *opline; @@ -2630,7 +2743,7 @@ static int generate_free_switch_expr(const zend_switch_entry *switch_entry TSRML opline->opcode = (switch_entry->cond.op_type == IS_TMP_VAR) ? ZEND_FREE : ZEND_SWITCH_FREE; SET_NODE(opline->op1, &switch_entry->cond); SET_UNUSED(opline->op2); - opline->extended_value = 0; + return 0; } /* }}} */ @@ -2640,7 +2753,7 @@ static int generate_free_foreach_copy(const zend_op *foreach_copy TSRMLS_DC) /* zend_op *opline; /* If we reach the separator then stop applying the stack */ - if (foreach_copy->result_type == IS_UNUSED && foreach_copy->op1_type == IS_UNUSED) { + if (foreach_copy->result_type == IS_UNUSED) { return 1; } @@ -2649,16 +2762,6 @@ static int generate_free_foreach_copy(const zend_op *foreach_copy TSRMLS_DC) /* opline->opcode = (foreach_copy->result_type == IS_TMP_VAR) ? ZEND_FREE : ZEND_SWITCH_FREE; COPY_NODE(opline->op1, foreach_copy->result); SET_UNUSED(opline->op2); - opline->extended_value = 1; - - if (foreach_copy->op1_type != IS_UNUSED) { - opline = get_next_op(CG(active_op_array) TSRMLS_CC); - - opline->opcode = (foreach_copy->op1_type == IS_TMP_VAR) ? ZEND_FREE : ZEND_SWITCH_FREE; - COPY_NODE(opline->op1, foreach_copy->op1); - SET_UNUSED(opline->op2); - opline->extended_value = 0; - } return 0; } @@ -2710,7 +2813,9 @@ void zend_do_return(znode *expr, int do_end_vparse TSRMLS_DC) /* {{{ */ if (expr) { SET_NODE(opline->op1, expr); - if (do_end_vparse && zend_is_function_or_method_call(expr)) { + if (!do_end_vparse) { + opline->extended_value = ZEND_RETURNS_VALUE; + } else if (zend_is_function_or_method_call(expr)) { opline->extended_value = ZEND_RETURNS_FUNCTION; } } else { @@ -2727,7 +2832,7 @@ void zend_do_yield(znode *result, znode *value, const znode *key, zend_bool is_v zend_op *opline; if (!CG(active_op_array)->function_name) { - zend_error(E_COMPILE_ERROR, "The \"yield\" expression can only be used inside a function"); + zend_error_noreturn(E_COMPILE_ERROR, "The \"yield\" expression can only be used inside a function"); } CG(active_op_array)->fn_flags |= ZEND_ACC_GENERATOR; @@ -2760,7 +2865,7 @@ void zend_do_yield(znode *result, znode *value, const znode *key, zend_bool is_v SET_UNUSED(opline->op2); } - opline->result_type = IS_TMP_VAR; + opline->result_type = IS_VAR; opline->result.var = get_temporary_variable(CG(active_op_array)); GET_NODE(result, opline->result); } @@ -2867,7 +2972,7 @@ void zend_do_begin_catch(znode *catch_token, znode *class_name, znode *catch_var zend_resolve_class_name(class_name TSRMLS_CC); catch_class = *class_name; } else { - zend_error(E_COMPILE_ERROR, "Bad class name in the catch statement"); + zend_error_noreturn(E_COMPILE_ERROR, "Bad class name in the catch statement"); } catch_op_number = get_next_op_number(CG(active_op_array)); @@ -2916,7 +3021,7 @@ void zend_do_bind_catch(znode *try_token, znode *catch_token TSRMLS_DC) /* {{{ * void zend_do_end_finally(znode *try_token, znode* catch_token, znode *finally_token TSRMLS_DC) /* {{{ */ { if (catch_token->op_type == IS_UNUSED && finally_token->op_type == IS_UNUSED) { - zend_error(E_COMPILE_ERROR, "Cannot use try without catch or finally"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use try without catch or finally"); } if (finally_token->op_type != IS_UNUSED) { zend_op *opline; @@ -3083,7 +3188,7 @@ static void do_inherit_method(zend_function *function) /* {{{ */ static zend_bool zend_do_perform_implementation_check(const zend_function *fe, const zend_function *proto TSRMLS_DC) /* {{{ */ { - zend_uint i; + zend_uint i, num_args; /* If it's a user function then arg_info == NULL means we don't have any parameters but * we still need to do the arg number checks. We are only willing to ignore this for internal @@ -3113,48 +3218,66 @@ static zend_bool zend_do_perform_implementation_check(const zend_function *fe, c return 0; } - if (fe->common.type != ZEND_USER_FUNCTION - && (proto->common.fn_flags & ZEND_ACC_PASS_REST_BY_REFERENCE) != 0 - && (fe->common.fn_flags & ZEND_ACC_PASS_REST_BY_REFERENCE) == 0) { - return 0; - } - /* by-ref constraints on return values are covariant */ if ((proto->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) && !(fe->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { return 0; } - for (i=0; i < proto->common.num_args; i++) { - if (ZEND_LOG_XOR(fe->common.arg_info[i].class_name, proto->common.arg_info[i].class_name)) { + if ((proto->common.fn_flags & ZEND_ACC_VARIADIC) + && !(fe->common.fn_flags & ZEND_ACC_VARIADIC)) { + return 0; + } + + /* For variadic functions any additional (optional) arguments that were added must be + * checked against the signature of the variadic argument, so in this case we have to + * go through all the parameters of the function and not just those present in the + * prototype. */ + num_args = proto->common.num_args; + if ((fe->common.fn_flags & ZEND_ACC_VARIADIC) + && fe->common.num_args > proto->common.num_args) { + num_args = fe->common.num_args; + } + + for (i = 0; i < num_args; i++) { + zend_arg_info *fe_arg_info = &fe->common.arg_info[i]; + + zend_arg_info *proto_arg_info; + if (i < proto->common.num_args) { + proto_arg_info = &proto->common.arg_info[i]; + } else { + proto_arg_info = &proto->common.arg_info[proto->common.num_args-1]; + } + + if (ZEND_LOG_XOR(fe_arg_info->class_name, proto_arg_info->class_name)) { /* Only one has a type hint and the other one doesn't */ return 0; } - if (fe->common.arg_info[i].class_name) { + if (fe_arg_info->class_name) { const char *fe_class_name, *proto_class_name; zend_uint fe_class_name_len, proto_class_name_len; - if (!strcasecmp(fe->common.arg_info[i].class_name, "parent") && proto->common.scope) { + if (!strcasecmp(fe_arg_info->class_name, "parent") && proto->common.scope) { fe_class_name = proto->common.scope->name; fe_class_name_len = proto->common.scope->name_length; - } else if (!strcasecmp(fe->common.arg_info[i].class_name, "self") && fe->common.scope) { + } else if (!strcasecmp(fe_arg_info->class_name, "self") && fe->common.scope) { fe_class_name = fe->common.scope->name; fe_class_name_len = fe->common.scope->name_length; } else { - fe_class_name = fe->common.arg_info[i].class_name; - fe_class_name_len = fe->common.arg_info[i].class_name_len; + fe_class_name = fe_arg_info->class_name; + fe_class_name_len = fe_arg_info->class_name_len; } - if (!strcasecmp(proto->common.arg_info[i].class_name, "parent") && proto->common.scope && proto->common.scope->parent) { + if (!strcasecmp(proto_arg_info->class_name, "parent") && proto->common.scope && proto->common.scope->parent) { proto_class_name = proto->common.scope->parent->name; proto_class_name_len = proto->common.scope->parent->name_length; - } else if (!strcasecmp(proto->common.arg_info[i].class_name, "self") && proto->common.scope) { + } else if (!strcasecmp(proto_arg_info->class_name, "self") && proto->common.scope) { proto_class_name = proto->common.scope->name; proto_class_name_len = proto->common.scope->name_length; } else { - proto_class_name = proto->common.arg_info[i].class_name; - proto_class_name_len = proto->common.arg_info[i].class_name_len; + proto_class_name = proto_arg_info->class_name; + proto_class_name_len = proto_arg_info->class_name_len; } if (strcasecmp(fe_class_name, proto_class_name)!=0) { @@ -3181,24 +3304,17 @@ static zend_bool zend_do_perform_implementation_check(const zend_function *fe, c } } } - if (fe->common.arg_info[i].type_hint != proto->common.arg_info[i].type_hint) { + if (fe_arg_info->type_hint != proto_arg_info->type_hint) { /* Incompatible type hint */ return 0; } /* by-ref constraints on arguments are invariant */ - if (fe->common.arg_info[i].pass_by_reference != proto->common.arg_info[i].pass_by_reference) { + if (fe_arg_info->pass_by_reference != proto_arg_info->pass_by_reference) { return 0; } } - if (proto->common.fn_flags & ZEND_ACC_PASS_REST_BY_REFERENCE) { - for (i=proto->common.num_args; i < fe->common.num_args; i++) { - if (!fe->common.arg_info[i].pass_by_reference) { - return 0; - } - } - } return 1; } /* }}} */ @@ -3271,6 +3387,13 @@ static char * zend_get_function_declaration(zend_function *fptr TSRMLS_DC) /* {{ if (arg_info->pass_by_reference) { *(offset++) = '&'; } + + if (arg_info->is_variadic) { + *(offset++) = '.'; + *(offset++) = '.'; + *(offset++) = '.'; + } + *(offset++) = '$'; if (arg_info->name) { @@ -3286,7 +3409,7 @@ static char * zend_get_function_declaration(zend_function *fptr TSRMLS_DC) /* {{ idx /= 10; } while (idx > 0); } - if (i >= required) { + if (i >= required && !arg_info->is_variadic) { *(offset++) = ' '; *(offset++) = '='; *(offset++) = ' '; @@ -3381,14 +3504,14 @@ static void do_inheritance_check_on_method(zend_function *child, zend_function * && parent->common.fn_flags & ZEND_ACC_ABSTRACT && parent->common.scope != (child->common.prototype ? child->common.prototype->common.scope : child->common.scope) && child->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_IMPLEMENTED_ABSTRACT)) { - zend_error(E_COMPILE_ERROR, "Can't inherit abstract function %s::%s() (previously declared abstract in %s)", + zend_error_noreturn(E_COMPILE_ERROR, "Can't inherit abstract function %s::%s() (previously declared abstract in %s)", parent->common.scope->name, child->common.function_name, child->common.prototype ? child->common.prototype->common.scope->name : child->common.scope->name); } if (parent_flags & ZEND_ACC_FINAL) { - zend_error(E_COMPILE_ERROR, "Cannot override final method %s::%s()", ZEND_FN_SCOPE_NAME(parent), child->common.function_name); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot override final method %s::%s()", ZEND_FN_SCOPE_NAME(parent), child->common.function_name); } child_flags = child->common.fn_flags; @@ -3396,15 +3519,15 @@ static void do_inheritance_check_on_method(zend_function *child, zend_function * */ if ((child_flags & ZEND_ACC_STATIC) != (parent_flags & ZEND_ACC_STATIC)) { if (child->common.fn_flags & ZEND_ACC_STATIC) { - zend_error(E_COMPILE_ERROR, "Cannot make non static method %s::%s() static in class %s", ZEND_FN_SCOPE_NAME(parent), child->common.function_name, ZEND_FN_SCOPE_NAME(child)); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot make non static method %s::%s() static in class %s", ZEND_FN_SCOPE_NAME(parent), child->common.function_name, ZEND_FN_SCOPE_NAME(child)); } else { - zend_error(E_COMPILE_ERROR, "Cannot make static method %s::%s() non static in class %s", ZEND_FN_SCOPE_NAME(parent), child->common.function_name, ZEND_FN_SCOPE_NAME(child)); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot make static method %s::%s() non static in class %s", ZEND_FN_SCOPE_NAME(parent), child->common.function_name, ZEND_FN_SCOPE_NAME(child)); } } /* Disallow making an inherited method abstract. */ if ((child_flags & ZEND_ACC_ABSTRACT) && !(parent_flags & ZEND_ACC_ABSTRACT)) { - zend_error(E_COMPILE_ERROR, "Cannot make non abstract method %s::%s() abstract in class %s", ZEND_FN_SCOPE_NAME(parent), child->common.function_name, ZEND_FN_SCOPE_NAME(child)); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot make non abstract method %s::%s() abstract in class %s", ZEND_FN_SCOPE_NAME(parent), child->common.function_name, ZEND_FN_SCOPE_NAME(child)); } if (parent_flags & ZEND_ACC_CHANGED) { @@ -3413,7 +3536,7 @@ static void do_inheritance_check_on_method(zend_function *child, zend_function * /* Prevent derived classes from restricting access that was available in parent classes */ if ((child_flags & ZEND_ACC_PPP_MASK) > (parent_flags & ZEND_ACC_PPP_MASK)) { - zend_error(E_COMPILE_ERROR, "Access level to %s::%s() must be %s (as in class %s)%s", ZEND_FN_SCOPE_NAME(child), child->common.function_name, zend_visibility_string(parent_flags), ZEND_FN_SCOPE_NAME(parent), (parent_flags&ZEND_ACC_PUBLIC) ? "" : " or weaker"); + zend_error_noreturn(E_COMPILE_ERROR, "Access level to %s::%s() must be %s (as in class %s)%s", ZEND_FN_SCOPE_NAME(child), child->common.function_name, zend_visibility_string(parent_flags), ZEND_FN_SCOPE_NAME(parent), (parent_flags&ZEND_ACC_PUBLIC) ? "" : " or weaker"); } else if (((child_flags & ZEND_ACC_PPP_MASK) < (parent_flags & ZEND_ACC_PPP_MASK)) && ((parent_flags & ZEND_ACC_PPP_MASK) & ZEND_ACC_PRIVATE)) { child->common.fn_flags |= ZEND_ACC_CHANGED; @@ -3432,7 +3555,7 @@ static void do_inheritance_check_on_method(zend_function *child, zend_function * if (child->common.prototype && (child->common.prototype->common.fn_flags & ZEND_ACC_ABSTRACT)) { if (!zend_do_perform_implementation_check(child, child->common.prototype TSRMLS_CC)) { - zend_error(E_COMPILE_ERROR, "Declaration of %s::%s() must be compatible with %s", ZEND_FN_SCOPE_NAME(child), child->common.function_name, zend_get_function_declaration(child->common.prototype TSRMLS_CC)); + zend_error_noreturn(E_COMPILE_ERROR, "Declaration of %s::%s() must be compatible with %s", ZEND_FN_SCOPE_NAME(child), child->common.function_name, zend_get_function_declaration(child->common.prototype TSRMLS_CC)); } } else if (EG(error_reporting) & E_STRICT || EG(user_error_handler)) { /* Check E_STRICT (or custom error handler) before the check so that we save some time */ if (!zend_do_perform_implementation_check(child, parent TSRMLS_CC)) { @@ -3486,7 +3609,7 @@ static zend_bool do_inherit_property_access_check(HashTable *target_ht, zend_pro if (zend_hash_quick_find(&ce->properties_info, hash_key->arKey, hash_key->nKeyLength, hash_key->h, (void **) &child_info)==SUCCESS) { if ((parent_info->flags & ZEND_ACC_STATIC) != (child_info->flags & ZEND_ACC_STATIC)) { - zend_error(E_COMPILE_ERROR, "Cannot redeclare %s%s::$%s as %s%s::$%s", + zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare %s%s::$%s as %s%s::$%s", (parent_info->flags & ZEND_ACC_STATIC) ? "static " : "non static ", parent_ce->name, hash_key->arKey, (child_info->flags & ZEND_ACC_STATIC) ? "static " : "non static ", ce->name, hash_key->arKey); @@ -3497,7 +3620,7 @@ static zend_bool do_inherit_property_access_check(HashTable *target_ht, zend_pro } if ((child_info->flags & ZEND_ACC_PPP_MASK) > (parent_info->flags & ZEND_ACC_PPP_MASK)) { - zend_error(E_COMPILE_ERROR, "Access level to %s::$%s must be %s (as in class %s)%s", ce->name, hash_key->arKey, zend_visibility_string(parent_info->flags), parent_ce->name, (parent_info->flags&ZEND_ACC_PUBLIC) ? "" : " or weaker"); + zend_error_noreturn(E_COMPILE_ERROR, "Access level to %s::$%s must be %s (as in class %s)%s", ce->name, hash_key->arKey, zend_visibility_string(parent_info->flags), parent_ce->name, (parent_info->flags&ZEND_ACC_PUBLIC) ? "" : " or weaker"); } else if ((child_info->flags & ZEND_ACC_STATIC) == 0) { zval_ptr_dtor(&(ce->default_properties_table[parent_info->offset])); ce->default_properties_table[parent_info->offset] = ce->default_properties_table[child_info->offset]; @@ -3582,10 +3705,10 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent if ((ce->ce_flags & ZEND_ACC_INTERFACE) && !(parent_ce->ce_flags & ZEND_ACC_INTERFACE)) { - zend_error(E_COMPILE_ERROR, "Interface %s may not inherit from class (%s)", ce->name, parent_ce->name); + zend_error_noreturn(E_COMPILE_ERROR, "Interface %s may not inherit from class (%s)", ce->name, parent_ce->name); } if (parent_ce->ce_flags & ZEND_ACC_FINAL_CLASS) { - zend_error(E_COMPILE_ERROR, "Class %s may not inherit from final class (%s)", ce->name, parent_ce->name); + zend_error_noreturn(E_COMPILE_ERROR, "Class %s may not inherit from final class (%s)", ce->name, parent_ce->name); } ce->parent = parent_ce; @@ -3707,7 +3830,7 @@ static zend_bool do_inherit_constant_check(HashTable *child_constants_table, con if (zend_hash_quick_find(child_constants_table, hash_key->arKey, hash_key->nKeyLength, hash_key->h, (void**)&old_constant) == SUCCESS) { if (*old_constant != *parent_constant) { - zend_error(E_COMPILE_ERROR, "Cannot inherit previously-inherited or override constant %s from interface %s", hash_key->arKey, iface->name); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot inherit previously-inherited or override constant %s from interface %s", hash_key->arKey, iface->name); } return 0; } @@ -3739,7 +3862,7 @@ ZEND_API void zend_do_implement_interface(zend_class_entry *ce, zend_class_entry if (i < parent_iface_num) { ignore = 1; } else { - zend_error(E_COMPILE_ERROR, "Class %s cannot implement previously implemented interface %s", ce->name, iface->name); + zend_error_noreturn(E_COMPILE_ERROR, "Class %s cannot implement previously implemented interface %s", ce->name, iface->name); } } } @@ -3812,7 +3935,7 @@ static void zend_add_magic_methods(zend_class_entry* ce, const char* mname, uint ce->clone = fe; fe->common.fn_flags |= ZEND_ACC_CLONE; } else if (!strncmp(mname, ZEND_CONSTRUCTOR_FUNC_NAME, mname_len)) { if (ce->constructor) { - zend_error(E_COMPILE_ERROR, "%s has colliding constructor definitions coming from traits", ce->name); + zend_error_noreturn(E_COMPILE_ERROR, "%s has colliding constructor definitions coming from traits", ce->name); } ce->constructor = fe; fe->common.fn_flags |= ZEND_ACC_CTOR; } else if (!strncmp(mname, ZEND_DESTRUCTOR_FUNC_NAME, mname_len)) { @@ -3837,7 +3960,7 @@ static void zend_add_magic_methods(zend_class_entry* ce, const char* mname, uint lowercase_name = (char*)zend_new_interned_string(lowercase_name, ce->name_length + 1, 1 TSRMLS_CC); if (!memcmp(mname, lowercase_name, mname_len)) { if (ce->constructor) { - zend_error(E_COMPILE_ERROR, "%s has colliding constructor definitions coming from traits", ce->name); + zend_error_noreturn(E_COMPILE_ERROR, "%s has colliding constructor definitions coming from traits", ce->name); } ce->constructor = fe; fe->common.fn_flags |= ZEND_ACC_CTOR; @@ -3861,14 +3984,14 @@ static void zend_add_trait_method(zend_class_entry *ce, const char *name, const if (existing_fn->common.fn_flags & ZEND_ACC_ABSTRACT) { /* Make sure the trait method is compatible with previosly declared abstract method */ if (!zend_traits_method_compatibility_check(fn, existing_fn TSRMLS_CC)) { - zend_error(E_COMPILE_ERROR, "Declaration of %s must be compatible with %s", + zend_error_noreturn(E_COMPILE_ERROR, "Declaration of %s must be compatible with %s", zend_get_function_declaration(fn TSRMLS_CC), zend_get_function_declaration(existing_fn TSRMLS_CC)); } } else if (fn->common.fn_flags & ZEND_ACC_ABSTRACT) { /* Make sure the abstract declaration is compatible with previous declaration */ if (!zend_traits_method_compatibility_check(existing_fn, fn TSRMLS_CC)) { - zend_error(E_COMPILE_ERROR, "Declaration of %s must be compatible with %s", + zend_error_noreturn(E_COMPILE_ERROR, "Declaration of %s must be compatible with %s", zend_get_function_declaration(fn TSRMLS_CC), zend_get_function_declaration(existing_fn TSRMLS_CC)); } @@ -3884,25 +4007,25 @@ static void zend_add_trait_method(zend_class_entry *ce, const char *name, const } else if (existing_fn->common.fn_flags & ZEND_ACC_ABSTRACT) { /* Make sure the trait method is compatible with previosly declared abstract method */ if (!zend_traits_method_compatibility_check(fn, existing_fn TSRMLS_CC)) { - zend_error(E_COMPILE_ERROR, "Declaration of %s must be compatible with %s", + zend_error_noreturn(E_COMPILE_ERROR, "Declaration of %s must be compatible with %s", zend_get_function_declaration(fn TSRMLS_CC), zend_get_function_declaration(existing_fn TSRMLS_CC)); } } else if (fn->common.fn_flags & ZEND_ACC_ABSTRACT) { /* Make sure the abstract declaration is compatible with previous declaration */ if (!zend_traits_method_compatibility_check(existing_fn, fn TSRMLS_CC)) { - zend_error(E_COMPILE_ERROR, "Declaration of %s must be compatible with %s", + zend_error_noreturn(E_COMPILE_ERROR, "Declaration of %s must be compatible with %s", zend_get_function_declaration(fn TSRMLS_CC), zend_get_function_declaration(existing_fn TSRMLS_CC)); } return; } else if ((existing_fn->common.scope->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) { - /* two trais can't define the same non-abstract method */ + /* two traits can't define the same non-abstract method */ #if 1 - zend_error(E_COMPILE_ERROR, "Trait method %s has not been applied, because there are collisions with other trait methods on %s", + zend_error_noreturn(E_COMPILE_ERROR, "Trait method %s has not been applied, because there are collisions with other trait methods on %s", name, ce->name); -#else /* TODO: better errot message */ - zend_error(E_COMPILE_ERROR, "Trait method %s::%s has not been applied as %s::%s, because of collision with %s::%s", +#else /* TODO: better error message */ + zend_error_noreturn(E_COMPILE_ERROR, "Trait method %s::%s has not been applied as %s::%s, because of collision with %s::%s", fn->common.scope->name, fn->common.function_name, ce->name, name, existing_fn->common.scope->name, existing_fn->common.function_name); @@ -4026,7 +4149,7 @@ static void zend_check_trait_usage(zend_class_entry *ce, zend_class_entry *trait zend_uint i; if ((trait->ce_flags & ZEND_ACC_TRAIT) != ZEND_ACC_TRAIT) { - zend_error(E_COMPILE_ERROR, "Class %s is not a trait, Only traits may be used in 'as' and 'insteadof' statements", trait->name); + zend_error_noreturn(E_COMPILE_ERROR, "Class %s is not a trait, Only traits may be used in 'as' and 'insteadof' statements", trait->name); } for (i = 0; i < ce->num_traits; i++) { @@ -4034,7 +4157,7 @@ static void zend_check_trait_usage(zend_class_entry *ce, zend_class_entry *trait return; } } - zend_error(E_COMPILE_ERROR, "Required Trait %s wasn't added to %s", trait->name, ce->name); + zend_error_noreturn(E_COMPILE_ERROR, "Required Trait %s wasn't added to %s", trait->name, ce->name); } /* }}} */ @@ -4055,7 +4178,7 @@ static void zend_traits_init_trait_structures(zend_class_entry *ce TSRMLS_DC) /* cur_method_ref = cur_precedence->trait_method; if (!(cur_precedence->trait_method->ce = zend_fetch_class(cur_method_ref->class_name, cur_method_ref->cname_len, ZEND_FETCH_CLASS_TRAIT|ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC))) { - zend_error(E_COMPILE_ERROR, "Could not find trait %s", cur_method_ref->class_name); + zend_error_noreturn(E_COMPILE_ERROR, "Could not find trait %s", cur_method_ref->class_name); } zend_check_trait_usage(ce, cur_precedence->trait_method->ce TSRMLS_CC); @@ -4067,7 +4190,7 @@ static void zend_traits_init_trait_structures(zend_class_entry *ce TSRMLS_DC) /* cur_method_ref->mname_len + 1); efree(lcname); if (!method_exists) { - zend_error(E_COMPILE_ERROR, + zend_error_noreturn(E_COMPILE_ERROR, "A precedence rule was defined for %s::%s but this method does not exist", cur_method_ref->ce->name, cur_method_ref->method_name); @@ -4085,14 +4208,14 @@ static void zend_traits_init_trait_structures(zend_class_entry *ce TSRMLS_DC) /* zend_uint name_length = strlen(class_name); if (!(cur_precedence->exclude_from_classes[j] = zend_fetch_class(class_name, name_length, ZEND_FETCH_CLASS_TRAIT |ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC))) { - zend_error(E_COMPILE_ERROR, "Could not find trait %s", class_name); + zend_error_noreturn(E_COMPILE_ERROR, "Could not find trait %s", class_name); } zend_check_trait_usage(ce, cur_precedence->exclude_from_classes[j] TSRMLS_CC); /* make sure that the trait method is not from a class mentioned in exclude_from_classes, for consistency */ if (cur_precedence->trait_method->ce == cur_precedence->exclude_from_classes[i]) { - zend_error(E_COMPILE_ERROR, + zend_error_noreturn(E_COMPILE_ERROR, "Inconsistent insteadof definition. " "The method %s is to be used from %s, but %s is also on the exclude list", cur_method_ref->method_name, @@ -4115,7 +4238,7 @@ static void zend_traits_init_trait_structures(zend_class_entry *ce TSRMLS_DC) /* if (ce->trait_aliases[i]->trait_method->class_name) { cur_method_ref = ce->trait_aliases[i]->trait_method; if (!(cur_method_ref->ce = zend_fetch_class(cur_method_ref->class_name, cur_method_ref->cname_len, ZEND_FETCH_CLASS_TRAIT|ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC))) { - zend_error(E_COMPILE_ERROR, "Could not find trait %s", cur_method_ref->class_name); + zend_error_noreturn(E_COMPILE_ERROR, "Could not find trait %s", cur_method_ref->class_name); } zend_check_trait_usage(ce, cur_method_ref->ce TSRMLS_CC); @@ -4127,7 +4250,7 @@ static void zend_traits_init_trait_structures(zend_class_entry *ce TSRMLS_DC) /* efree(lcname); if (!method_exists) { - zend_error(E_COMPILE_ERROR, "An alias was defined for %s::%s but this method does not exist", cur_method_ref->ce->name, cur_method_ref->method_name); + zend_error_noreturn(E_COMPILE_ERROR, "An alias was defined for %s::%s but this method does not exist", cur_method_ref->ce->name, cur_method_ref->method_name); } } i++; @@ -4153,7 +4276,7 @@ static void zend_traits_compile_exclude_table(HashTable* exclude_table, zend_tra if (zend_hash_add(exclude_table, lcname, lcname_len, NULL, 0, NULL) == FAILURE) { efree(lcname); - zend_error(E_COMPILE_ERROR, "Failed to evaluate a trait precedence (%s). Method of trait %s was defined to be excluded multiple times", precedences[i]->trait_method->method_name, trait->name); + zend_error_noreturn(E_COMPILE_ERROR, "Failed to evaluate a trait precedence (%s). Method of trait %s was defined to be excluded multiple times", precedences[i]->trait_method->method_name, trait->name); } efree(lcname); } @@ -4278,7 +4401,7 @@ static void zend_do_traits_property_binding(zend_class_entry *ce TSRMLS_DC) /* { } if (not_compatible) { - zend_error(E_COMPILE_ERROR, + zend_error_noreturn(E_COMPILE_ERROR, "%s and %s define the same property ($%s) in the composition of %s. However, the definition differs and is considered incompatible. Class was composed", find_first_definition(ce, i, prop_name, prop_name_length, prop_hash, coliding_prop->ce)->name, property_info->ce->name, @@ -4327,7 +4450,7 @@ static void zend_do_check_for_inconsistent_traits_aliasing(zend_class_entry *ce if (!cur_alias->trait_method->ce) { if (cur_alias->alias) { /** Plain old inconsistency/typo/bug */ - zend_error(E_COMPILE_ERROR, + zend_error_noreturn(E_COMPILE_ERROR, "An alias (%s) was defined for method %s(), but this method does not exist", cur_alias->alias, cur_alias->trait_method->method_name); @@ -4346,12 +4469,12 @@ static void zend_do_check_for_inconsistent_traits_aliasing(zend_class_entry *ce lc_method_name, cur_alias->trait_method->mname_len+1)) { efree(lc_method_name); - zend_error(E_COMPILE_ERROR, + zend_error_noreturn(E_COMPILE_ERROR, "The modifiers for the trait alias %s() need to be changed in the same statment in which the alias is defined. Error", cur_alias->trait_method->method_name); } else { efree(lc_method_name); - zend_error(E_COMPILE_ERROR, + zend_error_noreturn(E_COMPILE_ERROR, "The modifiers of the trait method %s() are changed, but this method does not exist. Error", cur_alias->trait_method->method_name); @@ -4460,13 +4583,13 @@ void zend_add_trait_alias(znode *method_reference, znode *modifiers, znode *alia zend_trait_alias *trait_alias; if (Z_LVAL(modifiers->u.constant) == ZEND_ACC_STATIC) { - zend_error(E_COMPILE_ERROR, "Cannot use 'static' as method modifier"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use 'static' as method modifier"); return; } else if (Z_LVAL(modifiers->u.constant) == ZEND_ACC_ABSTRACT) { - zend_error(E_COMPILE_ERROR, "Cannot use 'abstract' as method modifier"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use 'abstract' as method modifier"); return; } else if (Z_LVAL(modifiers->u.constant) == ZEND_ACC_FINAL) { - zend_error(E_COMPILE_ERROR, "Cannot use 'final' as method modifier"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use 'final' as method modifier"); return; } @@ -4508,7 +4631,7 @@ ZEND_API zend_class_entry *do_bind_class(const zend_op_array* op_array, const ze op2 = opline->op2.zv; } if (zend_hash_quick_find(class_table, Z_STRVAL_P(op1), Z_STRLEN_P(op1), Z_HASH_P(op1), (void **) &pce)==FAILURE) { - zend_error(E_COMPILE_ERROR, "Internal Zend error - Missing class information for %s", Z_STRVAL_P(op1)); + zend_error_noreturn(E_COMPILE_ERROR, "Internal Zend error - Missing class information for %s", Z_STRVAL_P(op1)); return NULL; } else { ce = *pce; @@ -4522,7 +4645,7 @@ ZEND_API zend_class_entry *do_bind_class(const zend_op_array* op_array, const ze * so we shut up about it. This allows the if (!defined('FOO')) { return; } * approach to work. */ - zend_error(E_COMPILE_ERROR, "Cannot redeclare class %s", ce->name); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare class %s", ce->name); } return NULL; } else { @@ -4557,7 +4680,7 @@ ZEND_API zend_class_entry *do_bind_inherited_class(const zend_op_array *op_array * so we shut up about it. This allows the if (!defined('FOO')) { return; } * approach to work. */ - zend_error(E_COMPILE_ERROR, "Cannot redeclare class %s", Z_STRVAL_P(op2)); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare class %s", Z_STRVAL_P(op2)); } return NULL; } else { @@ -4565,9 +4688,9 @@ ZEND_API zend_class_entry *do_bind_inherited_class(const zend_op_array *op_array } if (parent_ce->ce_flags & ZEND_ACC_INTERFACE) { - zend_error(E_COMPILE_ERROR, "Class %s cannot extend from interface %s", ce->name, parent_ce->name); + zend_error_noreturn(E_COMPILE_ERROR, "Class %s cannot extend from interface %s", ce->name, parent_ce->name); } else if ((parent_ce->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) { - zend_error(E_COMPILE_ERROR, "Class %s cannot extend from trait %s", ce->name, parent_ce->name); + zend_error_noreturn(E_COMPILE_ERROR, "Class %s cannot extend from trait %s", ce->name, parent_ce->name); } zend_do_inheritance(ce, parent_ce TSRMLS_CC); @@ -4576,7 +4699,7 @@ ZEND_API zend_class_entry *do_bind_inherited_class(const zend_op_array *op_array /* Register the derived class */ if (zend_hash_quick_add(class_table, Z_STRVAL_P(op2), Z_STRLEN_P(op2)+1, Z_HASH_P(op2), pce, sizeof(zend_class_entry *), NULL)==FAILURE) { - zend_error(E_COMPILE_ERROR, "Cannot redeclare class %s", ce->name); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare class %s", ce->name); } return ce; } @@ -4645,7 +4768,7 @@ void zend_do_early_binding(TSRMLS_D) /* {{{ */ /* Classes with traits are handled exactly the same, no early-bind here */ return; default: - zend_error(E_COMPILE_ERROR, "Invalid binding type"); + zend_error_noreturn(E_COMPILE_ERROR, "Invalid binding type"); return; } @@ -4776,9 +4899,9 @@ void zend_do_brk_cont(zend_uchar op, const znode *expr TSRMLS_DC) /* {{{ */ SET_UNUSED(opline->op1); if (expr) { if (expr->op_type != IS_CONST) { - zend_error(E_COMPILE_ERROR, "'%s' operator with non-constant operand is no longer supported", op == ZEND_BRK ? "break" : "continue"); + zend_error_noreturn(E_COMPILE_ERROR, "'%s' operator with non-constant operand is no longer supported", op == ZEND_BRK ? "break" : "continue"); } else if (Z_TYPE(expr->u.constant) != IS_LONG || Z_LVAL(expr->u.constant) < 1) { - zend_error(E_COMPILE_ERROR, "'%s' operator accepts only positive numbers", op == ZEND_BRK ? "break" : "continue"); + zend_error_noreturn(E_COMPILE_ERROR, "'%s' operator accepts only positive numbers", op == ZEND_BRK ? "break" : "continue"); } SET_NODE(opline->op2, expr); } else { @@ -4937,7 +5060,7 @@ void zend_do_begin_class_declaration(const znode *class_token, znode *class_name zval **ns_name, key; if (CG(active_class_entry)) { - zend_error(E_COMPILE_ERROR, "Class declarations may not be nested"); + zend_error_noreturn(E_COMPILE_ERROR, "Class declarations may not be nested"); return; } @@ -4945,7 +5068,7 @@ void zend_do_begin_class_declaration(const znode *class_token, znode *class_name if (!(strcmp(lcname, "self") && strcmp(lcname, "parent"))) { efree(lcname); - zend_error(E_COMPILE_ERROR, "Cannot use '%s' as class name as it is reserved", Z_STRVAL(class_name->u.constant)); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use '%s' as class name as it is reserved", Z_STRVAL(class_name->u.constant)); } /* Class name must not conflict with import names */ @@ -4972,7 +5095,7 @@ void zend_do_begin_class_declaration(const znode *class_token, znode *class_name if (Z_STRLEN_PP(ns_name) != Z_STRLEN(class_name->u.constant) || memcmp(tmp, lcname, Z_STRLEN(class_name->u.constant))) { - zend_error(E_COMPILE_ERROR, "Cannot declare class %s because the name is already in use", Z_STRVAL(class_name->u.constant)); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare class %s because the name is already in use", Z_STRVAL(class_name->u.constant)); } efree(tmp); } @@ -4990,13 +5113,13 @@ void zend_do_begin_class_declaration(const znode *class_token, znode *class_name if (parent_class_name && parent_class_name->op_type != IS_UNUSED) { switch (parent_class_name->EA) { case ZEND_FETCH_CLASS_SELF: - zend_error(E_COMPILE_ERROR, "Cannot use 'self' as class name as it is reserved"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use 'self' as class name as it is reserved"); break; case ZEND_FETCH_CLASS_PARENT: - zend_error(E_COMPILE_ERROR, "Cannot use 'parent' as class name as it is reserved"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use 'parent' as class name as it is reserved"); break; case ZEND_FETCH_CLASS_STATIC: - zend_error(E_COMPILE_ERROR, "Cannot use 'static' as class name as it is reserved"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use 'static' as class name as it is reserved"); break; default: break; @@ -5015,7 +5138,7 @@ void zend_do_begin_class_declaration(const znode *class_token, znode *class_name if (doing_inheritance) { /* Make sure a trait does not try to extend a class */ if ((new_class_entry->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) { - zend_error(E_COMPILE_ERROR, "A trait (%s) cannot extend a class. Traits can only be composed from other traits with the 'use' keyword. Error", new_class_entry->name); + zend_error_noreturn(E_COMPILE_ERROR, "A trait (%s) cannot extend a class. Traits can only be composed from other traits with the 'use' keyword. Error", new_class_entry->name); } opline->extended_value = parent_class_name->u.op.var; @@ -5060,19 +5183,19 @@ void zend_do_end_class_declaration(const znode *class_token, const znode *parent if (ce->constructor) { ce->constructor->common.fn_flags |= ZEND_ACC_CTOR; if (ce->constructor->common.fn_flags & ZEND_ACC_STATIC) { - zend_error(E_COMPILE_ERROR, "Constructor %s::%s() cannot be static", ce->name, ce->constructor->common.function_name); + zend_error_noreturn(E_COMPILE_ERROR, "Constructor %s::%s() cannot be static", ce->name, ce->constructor->common.function_name); } } if (ce->destructor) { ce->destructor->common.fn_flags |= ZEND_ACC_DTOR; if (ce->destructor->common.fn_flags & ZEND_ACC_STATIC) { - zend_error(E_COMPILE_ERROR, "Destructor %s::%s() cannot be static", ce->name, ce->destructor->common.function_name); + zend_error_noreturn(E_COMPILE_ERROR, "Destructor %s::%s() cannot be static", ce->name, ce->destructor->common.function_name); } } if (ce->clone) { ce->clone->common.fn_flags |= ZEND_ACC_CLONE; if (ce->clone->common.fn_flags & ZEND_ACC_STATIC) { - zend_error(E_COMPILE_ERROR, "Clone method %s::%s() cannot be static", ce->name, ce->clone->common.function_name); + zend_error_noreturn(E_COMPILE_ERROR, "Clone method %s::%s() cannot be static", ce->name, ce->clone->common.function_name); } } @@ -5121,7 +5244,7 @@ void zend_do_implements_interface(znode *interface_name TSRMLS_DC) /* {{{ */ /* Traits can not implement interfaces */ if ((CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) { - zend_error(E_COMPILE_ERROR, "Cannot use '%s' as interface on '%s' since it is a Trait", + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use '%s' as interface on '%s' since it is a Trait", Z_STRVAL(interface_name->u.constant), CG(active_class_entry)->name); } @@ -5130,7 +5253,7 @@ void zend_do_implements_interface(znode *interface_name TSRMLS_DC) /* {{{ */ case ZEND_FETCH_CLASS_SELF: case ZEND_FETCH_CLASS_PARENT: case ZEND_FETCH_CLASS_STATIC: - zend_error(E_COMPILE_ERROR, "Cannot use '%s' as interface name as it is reserved", Z_STRVAL(interface_name->u.constant)); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use '%s' as interface name as it is reserved", Z_STRVAL(interface_name->u.constant)); break; default: break; @@ -5152,7 +5275,7 @@ void zend_do_use_trait(znode *trait_name TSRMLS_DC) /* {{{ */ zend_op *opline; if ((CG(active_class_entry)->ce_flags & ZEND_ACC_INTERFACE)) { - zend_error(E_COMPILE_ERROR, + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use traits inside of interfaces. %s is used in %s", Z_STRVAL(trait_name->u.constant), CG(active_class_entry)->name); } @@ -5162,7 +5285,7 @@ void zend_do_use_trait(znode *trait_name TSRMLS_DC) /* {{{ */ case ZEND_FETCH_CLASS_SELF: case ZEND_FETCH_CLASS_PARENT: case ZEND_FETCH_CLASS_STATIC: - zend_error(E_COMPILE_ERROR, "Cannot use '%s' as trait name as it is reserved", Z_STRVAL(trait_name->u.constant)); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use '%s' as trait name as it is reserved", Z_STRVAL(trait_name->u.constant)); break; default: break; @@ -5251,20 +5374,20 @@ void zend_do_declare_property(const znode *var_name, const znode *value, zend_ui int comment_len = 0; if (CG(active_class_entry)->ce_flags & ZEND_ACC_INTERFACE) { - zend_error(E_COMPILE_ERROR, "Interfaces may not include member variables"); + zend_error_noreturn(E_COMPILE_ERROR, "Interfaces may not include member variables"); } if (access_type & ZEND_ACC_ABSTRACT) { - zend_error(E_COMPILE_ERROR, "Properties cannot be declared abstract"); + zend_error_noreturn(E_COMPILE_ERROR, "Properties cannot be declared abstract"); } if (access_type & ZEND_ACC_FINAL) { - zend_error(E_COMPILE_ERROR, "Cannot declare property %s::$%s final, the final modifier is allowed only for methods and classes", + zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare property %s::$%s final, the final modifier is allowed only for methods and classes", CG(active_class_entry)->name, Z_STRVAL(var_name->u.constant)); } if (zend_hash_find(&CG(active_class_entry)->properties_info, Z_STRVAL(var_name->u.constant), Z_STRLEN(var_name->u.constant)+1, (void **) &existing_property_info)==SUCCESS) { - zend_error(E_COMPILE_ERROR, "Cannot redeclare %s::$%s", CG(active_class_entry)->name, Z_STRVAL(var_name->u.constant)); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare %s::$%s", CG(active_class_entry)->name, Z_STRVAL(var_name->u.constant)); } ALLOC_ZVAL(property); @@ -5294,11 +5417,11 @@ void zend_do_declare_class_constant(znode *var_name, const znode *value TSRMLS_D zend_ulong hash; if(Z_TYPE(value->u.constant) == IS_CONSTANT_ARRAY) { - zend_error(E_COMPILE_ERROR, "Arrays are not allowed in class constants"); + zend_error_noreturn(E_COMPILE_ERROR, "Arrays are not allowed in class constants"); return; } if ((CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) { - zend_error(E_COMPILE_ERROR, "Traits cannot have constants"); + zend_error_noreturn(E_COMPILE_ERROR, "Traits cannot have constants"); return; } @@ -5309,7 +5432,7 @@ void zend_do_declare_class_constant(znode *var_name, const znode *value TSRMLS_D hash = str_hash(cname, Z_STRLEN(var_name->u.constant)); if (zend_hash_quick_add(&CG(active_class_entry)->constants_table, cname, Z_STRLEN(var_name->u.constant)+1, hash, &property, sizeof(zval *), NULL) == FAILURE) { FREE_ZVAL(property); - zend_error(E_COMPILE_ERROR, "Cannot redefine class constant %s::%s", CG(active_class_entry)->name, Z_STRVAL(var_name->u.constant)); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot redefine class constant %s::%s", CG(active_class_entry)->name, Z_STRVAL(var_name->u.constant)); } FREE_PNODE(var_name); @@ -5403,7 +5526,7 @@ void zend_do_halt_compiler_register(TSRMLS_D) /* {{{ */ int len, clen; if (CG(has_bracketed_namespaces) && CG(in_namespace)) { - zend_error(E_COMPILE_ERROR, "__HALT_COMPILER() can only be used from the outermost scope"); + zend_error_noreturn(E_COMPILE_ERROR, "__HALT_COMPILER() can only be used from the outermost scope"); } cfilename = zend_get_compiled_filename(TSRMLS_C); @@ -5504,8 +5627,7 @@ static zend_constant* zend_get_ct_const(const zval *const_name, int all_internal if (all_internal_constants_substitution && (c->flags & CONST_PERSISTENT) && !(CG(compiler_options) & ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION) && - Z_TYPE(c->value) != IS_CONSTANT && - Z_TYPE(c->value) != IS_CONSTANT_ARRAY) { + !IS_CONSTANT_TYPE(Z_TYPE(c->value))) { return c; } return NULL; @@ -5592,7 +5714,7 @@ void zend_do_fetch_constant(znode *result, znode *constant_container, znode *con break; } - zend_resolve_non_class_name(constant_name, check_namespace TSRMLS_CC); + zend_resolve_const_name(constant_name, &check_namespace TSRMLS_CC); if(!compound) { fetch_type |= IS_CONSTANT_UNQUALIFIED; @@ -5604,7 +5726,7 @@ void zend_do_fetch_constant(znode *result, znode *constant_container, znode *con case ZEND_RT: compound = memchr(Z_STRVAL(constant_name->u.constant), '\\', Z_STRLEN(constant_name->u.constant)); - zend_resolve_non_class_name(constant_name, check_namespace TSRMLS_CC); + zend_resolve_const_name(constant_name, &check_namespace TSRMLS_CC); if(zend_constant_ct_subst(result, &constant_name->u.constant, 1 TSRMLS_CC)) { break; @@ -5747,7 +5869,7 @@ void zend_do_add_static_array_element(znode *result, znode *offset, const znode ALLOC_ZVAL(element); *element = expr->u.constant; if (offset) { - switch (offset->u.constant.type & IS_CONSTANT_TYPE_MASK) { + switch (Z_TYPE(offset->u.constant) & IS_CONSTANT_TYPE_MASK) { case IS_CONSTANT: /* Ugly hack to denote that this value has a constant index */ Z_TYPE_P(element) |= IS_CONSTANT_INDEX; @@ -5757,6 +5879,20 @@ void zend_do_add_static_array_element(znode *result, znode *offset, const znode zend_symtable_update(Z_ARRVAL(result->u.constant), Z_STRVAL(offset->u.constant), Z_STRLEN(offset->u.constant)+3, &element, sizeof(zval *), NULL); zval_dtor(&offset->u.constant); break; + case IS_CONSTANT_AST: { + /* Another ugly hack to store the data about the AST in the array */ + char* key; + int len = sizeof(zend_ast *); + Z_TYPE_P(element) |= IS_CONSTANT_INDEX; + + key = emalloc(len + 2); + *(zend_ast **)key = Z_AST(offset->u.constant); + key[len] = Z_TYPE(offset->u.constant); + key[len + 1] = 0; + zend_symtable_update(Z_ARRVAL(result->u.constant), key, len + 2, &element, sizeof(zval *), NULL); + efree(key); + break; + } case IS_STRING: zend_symtable_update(Z_ARRVAL(result->u.constant), Z_STRVAL(offset->u.constant), Z_STRLEN(offset->u.constant)+1, &element, sizeof(zval *), NULL); zval_dtor(&offset->u.constant); @@ -5979,7 +6115,7 @@ void zend_do_fetch_lexical_variable(znode *varname, zend_bool is_ref TSRMLS_DC) if (Z_STRLEN(varname->u.constant) == sizeof("this") - 1 && memcmp(Z_STRVAL(varname->u.constant), "this", sizeof("this") - 1) == 0) { - zend_error(E_COMPILE_ERROR, "Cannot use $this as lexical variable"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use $this as lexical variable"); return; } @@ -6123,7 +6259,7 @@ void zend_do_isset_or_isempty(int type, znode *result, znode *variable TSRMLS_DC /* empty(func()) can be transformed to !func() */ zend_do_unary_op(ZEND_BOOL_NOT, result, variable TSRMLS_CC); } else { - zend_error(E_COMPILE_ERROR, "Cannot use isset() on the result of a function call (you can use \"null !== func()\" instead)"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use isset() on the result of a function call (you can use \"null !== func()\" instead)"); } return; @@ -6171,7 +6307,7 @@ void zend_do_instanceof(znode *result, const znode *expr, const znode *class_zno } if (expr->op_type == IS_CONST) { - zend_error(E_COMPILE_ERROR, "instanceof expects an object instance, constant given"); + zend_error_noreturn(E_COMPILE_ERROR, "instanceof expects an object instance, constant given"); } opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -6190,7 +6326,6 @@ void zend_do_foreach_begin(znode *foreach_token, znode *open_brackets_token, zno { zend_op *opline; zend_bool is_variable; - zend_bool push_container = 0; zend_op dummy_opline; if (variable) { @@ -6202,14 +6337,6 @@ void zend_do_foreach_begin(znode *foreach_token, znode *open_brackets_token, zno /* save the location of FETCH_W instruction(s) */ open_brackets_token->u.op.opline_num = get_next_op_number(CG(active_op_array)); zend_do_end_variable_parse(array, BP_VAR_W, 0 TSRMLS_CC); - if (CG(active_op_array)->last > 0 && - CG(active_op_array)->opcodes[CG(active_op_array)->last-1].opcode == ZEND_FETCH_OBJ_W) { - /* Only lock the container if we are fetching from a real container and not $this */ - if (CG(active_op_array)->opcodes[CG(active_op_array)->last-1].op1_type == IS_VAR) { - CG(active_op_array)->opcodes[CG(active_op_array)->last-1].extended_value |= ZEND_FETCH_ADD_LOCK; - push_container = 1; - } - } } else { is_variable = 0; open_brackets_token->u.op.opline_num = get_next_op_number(CG(active_op_array)); @@ -6229,11 +6356,6 @@ void zend_do_foreach_begin(znode *foreach_token, znode *open_brackets_token, zno opline->extended_value = is_variable ? ZEND_FE_RESET_VARIABLE : 0; COPY_NODE(dummy_opline.result, opline->result); - if (push_container) { - COPY_NODE(dummy_opline.op1, CG(active_op_array)->opcodes[CG(active_op_array)->last-2].op1); - } else { - dummy_opline.op1_type = IS_UNUSED; - } zend_stack_push(&CG(foreach_copy_stack), (void *) &dummy_opline, sizeof(zend_op)); /* save the location of FE_FETCH */ @@ -6276,10 +6398,10 @@ void zend_do_foreach_cont(znode *foreach_token, const znode *open_brackets_token if ((key->op_type != IS_UNUSED)) { if (key->EA & ZEND_PARSED_REFERENCE_VARIABLE) { - zend_error(E_COMPILE_ERROR, "Key element cannot be a reference"); + zend_error_noreturn(E_COMPILE_ERROR, "Key element cannot be a reference"); } if (key->EA & ZEND_PARSED_LIST_EXPR) { - zend_error(E_COMPILE_ERROR, "Cannot use list as key element"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use list as key element"); } } @@ -6290,7 +6412,6 @@ void zend_do_foreach_cont(znode *foreach_token, const znode *open_brackets_token opline->extended_value |= ZEND_FE_FETCH_BYREF; CG(active_op_array)->opcodes[foreach_token->u.op.opline_num].extended_value |= ZEND_FE_RESET_REFERENCE; } else { - zend_op *foreach_copy; zend_op *fetch = &CG(active_op_array)->opcodes[foreach_token->u.op.opline_num]; zend_op *end = &CG(active_op_array)->opcodes[open_brackets_token->u.op.opline_num]; @@ -6299,7 +6420,7 @@ void zend_do_foreach_cont(znode *foreach_token, const znode *open_brackets_token while (fetch != end) { --fetch; if (fetch->opcode == ZEND_FETCH_DIM_W && fetch->op2_type == IS_UNUSED) { - zend_error(E_COMPILE_ERROR, "Cannot use [] for reading"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use [] for reading"); } if (fetch->opcode == ZEND_SEPARATE) { MAKE_NOP(fetch); @@ -6307,16 +6428,13 @@ void zend_do_foreach_cont(znode *foreach_token, const znode *open_brackets_token fetch->opcode -= 3; /* FETCH_W -> FETCH_R */ } } - /* prevent double SWITCH_FREE */ - zend_stack_top(&CG(foreach_copy_stack), (void **) &foreach_copy); - foreach_copy->op1_type = IS_UNUSED; } GET_NODE(&value_node, opline->result); if (value->EA & ZEND_PARSED_LIST_EXPR) { if (!CG(list_llist).head) { - zend_error(E_COMPILE_ERROR, "Cannot use empty list"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use empty list"); } zend_do_list_end(&dummy, &value_node TSRMLS_CC); zend_do_free(&dummy TSRMLS_CC); @@ -6384,7 +6502,7 @@ void zend_do_declare_stmt(znode *var, znode *val TSRMLS_DC) /* {{{ */ CG(declarables).ticks = val->u.constant; } else if (!zend_binary_strcasecmp(Z_STRVAL(var->u.constant), Z_STRLEN(var->u.constant), "encoding", sizeof("encoding")-1)) { if ((Z_TYPE(val->u.constant) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) { - zend_error(E_COMPILE_ERROR, "Cannot use constants as encoding"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use constants as encoding"); } /* @@ -6403,7 +6521,7 @@ void zend_do_declare_stmt(znode *var, znode *val TSRMLS_DC) /* {{{ */ } if (num > 0) { - zend_error(E_COMPILE_ERROR, "Encoding declaration pragma must be the very first statement in the script"); + zend_error_noreturn(E_COMPILE_ERROR, "Encoding declaration pragma must be the very first statement in the script"); } } @@ -6899,15 +7017,15 @@ void zend_do_begin_namespace(const znode *name, zend_bool with_bracket TSRMLS_DC if (CG(current_namespace)) { /* previous namespace declarations were unbracketed */ if (with_bracket) { - zend_error(E_COMPILE_ERROR, "Cannot mix bracketed namespace declarations with unbracketed namespace declarations"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot mix bracketed namespace declarations with unbracketed namespace declarations"); } } } else { /* previous namespace declarations were bracketed */ if (!with_bracket) { - zend_error(E_COMPILE_ERROR, "Cannot mix bracketed namespace declarations with unbracketed namespace declarations"); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot mix bracketed namespace declarations with unbracketed namespace declarations"); } else if (CG(current_namespace) || CG(in_namespace)) { - zend_error(E_COMPILE_ERROR, "Namespace declarations cannot be nested"); + zend_error_noreturn(E_COMPILE_ERROR, "Namespace declarations cannot be nested"); } } @@ -6920,7 +7038,7 @@ void zend_do_begin_namespace(const znode *name, zend_bool with_bracket TSRMLS_DC --num; } if (num > 0) { - zend_error(E_COMPILE_ERROR, "Namespace declaration statement has to be the very first statement in the script"); + zend_error_noreturn(E_COMPILE_ERROR, "Namespace declaration statement has to be the very first statement in the script"); } } @@ -6935,7 +7053,7 @@ void zend_do_begin_namespace(const znode *name, zend_bool with_bracket TSRMLS_DC !memcmp(lcname, "self", sizeof("self")-1)) || ((Z_STRLEN(name->u.constant) == sizeof("parent")-1) && !memcmp(lcname, "parent", sizeof("parent")-1))) { - zend_error(E_COMPILE_ERROR, "Cannot use '%s' as namespace name", Z_STRVAL(name->u.constant)); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use '%s' as namespace name", Z_STRVAL(name->u.constant)); } efree(lcname); @@ -6959,6 +7077,18 @@ void zend_do_begin_namespace(const znode *name, zend_bool with_bracket TSRMLS_DC CG(current_import) = NULL; } + if (CG(current_import_function)) { + zend_hash_destroy(CG(current_import_function)); + efree(CG(current_import_function)); + CG(current_import_function) = NULL; + } + + if (CG(current_import_const)) { + zend_hash_destroy(CG(current_import_const)); + efree(CG(current_import_const)); + CG(current_import_const) = NULL; + } + if (CG(doc_comment)) { efree(CG(doc_comment)); CG(doc_comment) = NULL; @@ -6979,8 +7109,8 @@ void zend_do_use(znode *ns_name, znode *new_name, int is_global TSRMLS_DC) /* {{ zend_hash_init(CG(current_import), 0, NULL, ZVAL_PTR_DTOR, 0); } - ALLOC_ZVAL(ns); - *ns = ns_name->u.constant; + MAKE_STD_ZVAL(ns); + ZVAL_ZVAL(ns, &ns_name->u.constant, 0, 0); if (new_name) { name = &new_name->u.constant; } else { @@ -6993,8 +7123,7 @@ void zend_do_use(znode *ns_name, znode *new_name, int is_global TSRMLS_DC) /* {{ if (p) { ZVAL_STRING(name, p+1, 1); } else { - *name = *ns; - zval_copy_ctor(name); + ZVAL_ZVAL(name, ns, 1, 0); warn = !is_global && !CG(current_namespace); } } @@ -7005,7 +7134,7 @@ void zend_do_use(znode *ns_name, znode *new_name, int is_global TSRMLS_DC) /* {{ !memcmp(lcname, "self", sizeof("self")-1)) || ((Z_STRLEN_P(name) == sizeof("parent")-1) && !memcmp(lcname, "parent", sizeof("parent")-1))) { - zend_error(E_COMPILE_ERROR, "Cannot use %s as %s because '%s' is a special class name", Z_STRVAL_P(ns), Z_STRVAL_P(name), Z_STRVAL_P(name)); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use %s as %s because '%s' is a special class name", Z_STRVAL_P(ns), Z_STRVAL_P(name), Z_STRVAL_P(name)); } if (CG(current_namespace)) { @@ -7020,7 +7149,7 @@ void zend_do_use(znode *ns_name, znode *new_name, int is_global TSRMLS_DC) /* {{ if (Z_STRLEN_P(ns) != Z_STRLEN_P(CG(current_namespace)) + 1 + Z_STRLEN_P(name) || memcmp(tmp2, c_ns_name, Z_STRLEN_P(ns))) { - zend_error(E_COMPILE_ERROR, "Cannot use %s as %s because the name is already in use", Z_STRVAL_P(ns), Z_STRVAL_P(name)); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use %s as %s because the name is already in use", Z_STRVAL_P(ns), Z_STRVAL_P(name)); } efree(tmp2); } @@ -7032,17 +7161,17 @@ void zend_do_use(znode *ns_name, znode *new_name, int is_global TSRMLS_DC) /* {{ if (Z_STRLEN_P(ns) != Z_STRLEN_P(name) || memcmp(c_tmp, lcname, Z_STRLEN_P(ns))) { - zend_error(E_COMPILE_ERROR, "Cannot use %s as %s because the name is already in use", Z_STRVAL_P(ns), Z_STRVAL_P(name)); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use %s as %s because the name is already in use", Z_STRVAL_P(ns), Z_STRVAL_P(name)); } efree(c_tmp); } if (zend_hash_add(CG(current_import), lcname, Z_STRLEN_P(name)+1, &ns, sizeof(zval*), NULL) != SUCCESS) { - zend_error(E_COMPILE_ERROR, "Cannot use %s as %s because the name is already in use", Z_STRVAL_P(ns), Z_STRVAL_P(name)); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot use %s as %s because the name is already in use", Z_STRVAL_P(ns), Z_STRVAL_P(name)); } if (warn) { if (!strcmp(Z_STRVAL_P(name), "strict")) { - zend_error(E_COMPILE_ERROR, "You seem to be trying to use a different language..."); + zend_error_noreturn(E_COMPILE_ERROR, "You seem to be trying to use a different language..."); } zend_error(E_WARNING, "The use statement with non-compound name '%s' has no effect", Z_STRVAL_P(name)); } @@ -7051,16 +7180,124 @@ void zend_do_use(znode *ns_name, znode *new_name, int is_global TSRMLS_DC) /* {{ } /* }}} */ +void zend_do_use_non_class(znode *ns_name, znode *new_name, int is_global, int is_function, zend_bool case_sensitive, HashTable *current_import_sub, HashTable *lookup_table TSRMLS_DC) /* {{{ */ +{ + char *lookup_name; + zval *name, *ns, tmp; + zend_bool warn = 0; + + MAKE_STD_ZVAL(ns); + ZVAL_ZVAL(ns, &ns_name->u.constant, 0, 0); + if (new_name) { + name = &new_name->u.constant; + } else { + const char *p; + + /* The form "use A\B" is eqivalent to "use A\B as B". + So we extract the last part of compound name to use as a new_name */ + name = &tmp; + p = zend_memrchr(Z_STRVAL_P(ns), '\\', Z_STRLEN_P(ns)); + if (p) { + ZVAL_STRING(name, p+1, 1); + } else { + ZVAL_ZVAL(name, ns, 1, 0); + warn = !is_global && !CG(current_namespace); + } + } + + if (case_sensitive) { + lookup_name = estrndup(Z_STRVAL_P(name), Z_STRLEN_P(name)); + } else { + lookup_name = zend_str_tolower_dup(Z_STRVAL_P(name), Z_STRLEN_P(name)); + } + + if (CG(current_namespace)) { + /* Prefix import name with current namespace name to avoid conflicts with functions/consts */ + char *c_ns_name = emalloc(Z_STRLEN_P(CG(current_namespace)) + 1 + Z_STRLEN_P(name) + 1); + + zend_str_tolower_copy(c_ns_name, Z_STRVAL_P(CG(current_namespace)), Z_STRLEN_P(CG(current_namespace))); + c_ns_name[Z_STRLEN_P(CG(current_namespace))] = '\\'; + memcpy(c_ns_name+Z_STRLEN_P(CG(current_namespace))+1, lookup_name, Z_STRLEN_P(name)+1); + if (zend_hash_exists(lookup_table, c_ns_name, Z_STRLEN_P(CG(current_namespace)) + 1 + Z_STRLEN_P(name)+1)) { + char *tmp2 = zend_str_tolower_dup(Z_STRVAL_P(ns), Z_STRLEN_P(ns)); + + if (Z_STRLEN_P(ns) != Z_STRLEN_P(CG(current_namespace)) + 1 + Z_STRLEN_P(name) || + memcmp(tmp2, c_ns_name, Z_STRLEN_P(ns))) { + zend_error(E_COMPILE_ERROR, "Cannot use %s %s as %s because the name is already in use", is_function ? "function" : "const", Z_STRVAL_P(ns), Z_STRVAL_P(name)); + } + efree(tmp2); + } + efree(c_ns_name); + } else if (is_function) { + zend_function *function; + + if (zend_hash_find(lookup_table, lookup_name, Z_STRLEN_P(name)+1, (void **) &function) == SUCCESS && function->type == ZEND_USER_FUNCTION && strcmp(function->op_array.filename, CG(compiled_filename)) == 0) { + char *c_tmp = zend_str_tolower_dup(Z_STRVAL_P(ns), Z_STRLEN_P(ns)); + + if (Z_STRLEN_P(ns) != Z_STRLEN_P(name) || + memcmp(c_tmp, lookup_name, Z_STRLEN_P(ns))) { + zend_error(E_COMPILE_ERROR, "Cannot use function %s as %s because the name is already in use", Z_STRVAL_P(ns), Z_STRVAL_P(name)); + } + efree(c_tmp); + } + } else { + const char *filename; + + if (zend_hash_find(lookup_table, lookup_name, Z_STRLEN_P(name)+1, (void **) &filename) == SUCCESS && strcmp(filename, CG(compiled_filename)) == 0) { + char *c_tmp = zend_str_tolower_dup(Z_STRVAL_P(ns), Z_STRLEN_P(ns)); + + if (Z_STRLEN_P(ns) != Z_STRLEN_P(name) || + memcmp(c_tmp, lookup_name, Z_STRLEN_P(ns))) { + zend_error(E_COMPILE_ERROR, "Cannot use const %s as %s because the name is already in use", Z_STRVAL_P(ns), Z_STRVAL_P(name)); + } + efree(c_tmp); + } + } + + if (zend_hash_add(current_import_sub, lookup_name, Z_STRLEN_P(name)+1, &ns, sizeof(zval*), NULL) != SUCCESS) { + zend_error(E_COMPILE_ERROR, "Cannot use %s %s as %s because the name is already in use", is_function ? "function" : "const", Z_STRVAL_P(ns), Z_STRVAL_P(name)); + } + if (warn) { + zend_error(E_WARNING, "The use %s statement with non-compound name '%s' has no effect", is_function ? "function" : "const", Z_STRVAL_P(name)); + } + efree(lookup_name); + zval_dtor(name); +} +/* }}} */ + +void zend_do_use_function(znode *ns_name, znode *new_name, int is_global TSRMLS_DC) /* {{{ */ +{ + if (!CG(current_import_function)) { + CG(current_import_function) = emalloc(sizeof(HashTable)); + zend_hash_init(CG(current_import_function), 0, NULL, ZVAL_PTR_DTOR, 0); + } + + zend_do_use_non_class(ns_name, new_name, is_global, 1, 0, CG(current_import_function), CG(function_table) TSRMLS_CC); +} +/* }}} */ + +void zend_do_use_const(znode *ns_name, znode *new_name, int is_global TSRMLS_DC) /* {{{ */ +{ + if (!CG(current_import_const)) { + CG(current_import_const) = emalloc(sizeof(HashTable)); + zend_hash_init(CG(current_import_const), 0, NULL, ZVAL_PTR_DTOR, 0); + } + + zend_do_use_non_class(ns_name, new_name, is_global, 0, 1, CG(current_import_const), &CG(const_filenames) TSRMLS_CC); +} +/* }}} */ + void zend_do_declare_constant(znode *name, znode *value TSRMLS_DC) /* {{{ */ { zend_op *opline; + zval **ns_name; if(Z_TYPE(value->u.constant) == IS_CONSTANT_ARRAY) { - zend_error(E_COMPILE_ERROR, "Arrays are not allowed as constants"); + zend_error_noreturn(E_COMPILE_ERROR, "Arrays are not allowed as constants"); } if (zend_get_ct_const(&name->u.constant, 0 TSRMLS_CC)) { - zend_error(E_COMPILE_ERROR, "Cannot redeclare constant '%s'", Z_STRVAL(name->u.constant)); + zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare constant '%s'", Z_STRVAL(name->u.constant)); } if (CG(current_namespace)) { @@ -7074,18 +7311,33 @@ void zend_do_declare_constant(znode *name, znode *value TSRMLS_DC) /* {{{ */ *name = tmp; } + /* Constant name must not conflict with import names */ + if (CG(current_import_const) && + zend_hash_find(CG(current_import_const), Z_STRVAL(name->u.constant), Z_STRLEN(name->u.constant)+1, (void**)&ns_name) == SUCCESS) { + + char *tmp = estrndup(Z_STRVAL_PP(ns_name), Z_STRLEN_PP(ns_name)); + + if (Z_STRLEN_PP(ns_name) != Z_STRLEN(name->u.constant) || + memcmp(tmp, Z_STRVAL(name->u.constant), Z_STRLEN(name->u.constant))) { + zend_error(E_COMPILE_ERROR, "Cannot declare const %s because the name is already in use", Z_STRVAL(name->u.constant)); + } + efree(tmp); + } + opline = get_next_op(CG(active_op_array) TSRMLS_CC); opline->opcode = ZEND_DECLARE_CONST; SET_UNUSED(opline->result); SET_NODE(opline->op1, name); SET_NODE(opline->op2, value); + + zend_hash_add(&CG(const_filenames), Z_STRVAL(name->u.constant), Z_STRLEN(name->u.constant)+1, CG(compiled_filename), strlen(CG(compiled_filename))+1, NULL); } /* }}} */ void zend_verify_namespace(TSRMLS_D) /* {{{ */ { if (CG(has_bracketed_namespaces) && !CG(in_namespace)) { - zend_error(E_COMPILE_ERROR, "No code may exist outside of namespace {}"); + zend_error_noreturn(E_COMPILE_ERROR, "No code may exist outside of namespace {}"); } } /* }}} */ @@ -7103,6 +7355,16 @@ void zend_do_end_namespace(TSRMLS_D) /* {{{ */ efree(CG(current_import)); CG(current_import) = NULL; } + if (CG(current_import_function)) { + zend_hash_destroy(CG(current_import_function)); + efree(CG(current_import_function)); + CG(current_import_function) = NULL; + } + if (CG(current_import_const)) { + zend_hash_destroy(CG(current_import_const)); + efree(CG(current_import_const)); + CG(current_import_const) = NULL; + } } /* }}} */ @@ -7113,6 +7375,21 @@ void zend_do_end_compilation(TSRMLS_D) /* {{{ */ } /* }}} */ +void zend_do_constant_expression(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ */ +{ + if (ast->kind == ZEND_CONST) { + result->u.constant = *ast->u.val; + efree(ast); + } else if (zend_ast_is_ct_constant(ast)) { + zend_ast_evaluate(&result->u.constant, ast, NULL TSRMLS_CC); + zend_ast_destroy(ast); + } else { + Z_TYPE(result->u.constant) = IS_CONSTANT_AST; + Z_AST(result->u.constant) = ast; + } +} +/* }}} */ + /* {{{ zend_dirname Returns directory name component of path */ ZEND_API size_t zend_dirname(char *path, size_t len) diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 61d11427a1e49..b969ae50d7614 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -23,6 +23,7 @@ #define ZEND_COMPILE_H #include "zend.h" +#include "zend_ast.h" #ifdef HAVE_STDARG_H # include @@ -74,7 +75,7 @@ typedef struct _zend_literal { #define Z_HASH_P(zv) \ (((zend_literal*)(zv))->hash_value) -typedef union _znode_op { +typedef union _znode_op { zend_uint constant; zend_uint var; zend_uint num; @@ -86,12 +87,13 @@ typedef union _znode_op { void *ptr; /* Used for passing pointers from the compile to execution phase, currently used for traits */ } znode_op; -typedef struct _znode { /* used only during compilation */ +typedef struct _znode { /* used only during compilation */ int op_type; union { znode_op op; zval constant; /* replaced by literal/zv */ zend_op_array *op_array; + zend_ast *ast; } u; zend_uint EA; /* extended attributes */ } znode; @@ -207,12 +209,14 @@ typedef struct _zend_try_catch_element { /* disable inline caching */ #define ZEND_ACC_NEVER_CACHE 0x400000 -#define ZEND_ACC_PASS_REST_BY_REFERENCE 0x1000000 -#define ZEND_ACC_PASS_REST_PREFER_REF 0x2000000 +#define ZEND_ACC_VARIADIC 0x1000000 #define ZEND_ACC_RETURN_REFERENCE 0x4000000 #define ZEND_ACC_DONE_PASS_TWO 0x8000000 +/* function has arguments with type hinting */ +#define ZEND_ACC_HAS_TYPE_HINTS 0x10000000 + char *zend_visibility_string(zend_uint fn_flags); @@ -234,12 +238,13 @@ typedef struct _zend_arg_info { const char *class_name; zend_uint class_name_len; zend_uchar type_hint; + zend_uchar pass_by_reference; zend_bool allow_null; - zend_bool pass_by_reference; + zend_bool is_variadic; } zend_arg_info; /* the following structure repeats the layout of zend_arg_info, - * but its fields have different meaning. It's used as the first element of + * but its fields have different meaning. It's used as the first element of * arg_info array to define properties of internal functions. */ typedef struct _zend_internal_function_info { @@ -249,7 +254,8 @@ typedef struct _zend_internal_function_info { zend_uint required_num_args; zend_uchar _type_hint; zend_bool return_reference; - zend_bool pass_rest_by_reference; + zend_bool _allow_null; + zend_bool _is_variadic; } zend_internal_function_info; typedef struct _zend_compiled_variable { @@ -261,7 +267,7 @@ typedef struct _zend_compiled_variable { struct _zend_op_array { /* Common elements */ zend_uchar type; - const char *function_name; + const char *function_name; zend_class_entry *scope; zend_uint fn_flags; union _zend_function *prototype; @@ -377,6 +383,7 @@ typedef struct _call_slot { zend_function *fbc; zval *object; zend_class_entry *called_scope; + zend_uint num_additional_args; zend_bool is_ctor_call; zend_bool is_ctor_result_used; } call_slot; @@ -395,6 +402,7 @@ struct _zend_execute_data { zend_class_entry *current_called_scope; zval *current_this; struct _zend_op *fast_ret; /* used by FAST_CALL/FAST_RET (finally keyword) */ + zval *delayed_exception; call_slot *call_slots; call_slot *call; }; @@ -437,7 +445,9 @@ ZEND_API char *zend_get_compiled_filename(TSRMLS_D); ZEND_API int zend_get_compiled_lineno(TSRMLS_D); ZEND_API size_t zend_get_scanned_file_offset(TSRMLS_D); -void zend_resolve_non_class_name(znode *element_name, zend_bool check_namespace TSRMLS_DC); +void zend_resolve_non_class_name(znode *element_name, zend_bool *check_namespace, zend_bool case_sensitive, HashTable *current_import_sub TSRMLS_DC); +void zend_resolve_function_name(znode *element_name, zend_bool *check_namespace TSRMLS_DC); +void zend_resolve_const_name(znode *element_name, zend_bool *check_namespace TSRMLS_DC); void zend_resolve_class_name(znode *class_name TSRMLS_DC); ZEND_API const char* zend_get_compiled_variable_name(const zend_op_array *op_array, zend_uint var, int* name_len); @@ -500,7 +510,7 @@ void zend_do_add_variable(znode *result, const znode *op1, const znode *op2 TSRM int zend_do_verify_access_types(const znode *current_access_type, const znode *new_modifier); void zend_do_begin_function_declaration(znode *function_token, znode *function_name, int is_method, int return_reference, znode *fn_flags_znode TSRMLS_DC); void zend_do_end_function_declaration(const znode *function_token TSRMLS_DC); -void zend_do_receive_arg(zend_uchar op, znode *varname, const znode *offset, const znode *initialization, znode *class_type, zend_bool pass_by_reference TSRMLS_DC); +void zend_do_receive_param(zend_uchar op, znode *varname, const znode *initialization, znode *class_type, zend_bool pass_by_reference, zend_bool is_variadic TSRMLS_DC); int zend_do_begin_function_call(znode *function_name, zend_bool check_namespace TSRMLS_DC); void zend_do_begin_method_call(znode *left_bracket TSRMLS_DC); void zend_do_clone(znode *result, const znode *expr TSRMLS_DC); @@ -545,6 +555,7 @@ void zend_do_early_binding(TSRMLS_D); ZEND_API void zend_do_delayed_early_binding(const zend_op_array *op_array TSRMLS_DC); void zend_do_pass_param(znode *param, zend_uchar op, int offset TSRMLS_DC); +void zend_do_unpack_params(znode *params, int offset TSRMLS_DC); void zend_do_boolean_or_begin(znode *expr1, znode *op_token TSRMLS_DC); @@ -636,7 +647,11 @@ void zend_do_begin_namespace(const znode *name, zend_bool with_brackets TSRMLS_D void zend_do_end_namespace(TSRMLS_D); void zend_verify_namespace(TSRMLS_D); void zend_do_use(znode *name, znode *new_name, int is_global TSRMLS_DC); +void zend_do_use_non_class(znode *ns_name, znode *new_name, int is_global, int is_function, zend_bool case_sensitive, HashTable *current_import_sub, HashTable *lookup_table TSRMLS_DC); +void zend_do_use_function(znode *name, znode *new_name, int is_global TSRMLS_DC); +void zend_do_use_const(znode *name, znode *new_name, int is_global TSRMLS_DC); void zend_do_end_compilation(TSRMLS_D); +void zend_do_constant_expression(znode *result, zend_ast *ast TSRMLS_DC); void zend_do_resolve_class_name(znode *result, znode *class_name, int is_static TSRMLS_DC); @@ -674,7 +689,7 @@ void zend_class_add_ref(zend_class_entry **ce); ZEND_API void zend_mangle_property_name(char **dest, int *dest_length, const char *src1, int src1_length, const char *src2, int src2_length, int internal); #define zend_unmangle_property_name(mangled_property, mangled_property_len, class_name, prop_name) \ - zend_unmangle_property_name_ex(mangled_property, mangled_property_len, class_name, prop_name, NULL) + zend_unmangle_property_name_ex(mangled_property, mangled_property_len, class_name, prop_name, NULL) ZEND_API int zend_unmangle_property_name_ex(const char *mangled_property, int mangled_property_len, const char **class_name, const char **prop_name, int *prop_len); #define ZEND_FUNCTION_DTOR (void (*)(void *)) zend_function_dtor @@ -817,21 +832,21 @@ int zend_add_literal(zend_op_array *op_array, const zval *zv TSRMLS_DC); #define ZEND_SEND_BY_REF 1 #define ZEND_SEND_PREFER_REF 2 -#define CHECK_ARG_SEND_TYPE(zf, arg_num, m1, m2) \ - ((zf) && \ - ((((zend_function*)(zf))->common.arg_info && \ - arg_num <= ((zend_function*)(zf))->common.num_args) ? \ - (((zend_function *)(zf))->common.arg_info[arg_num-1].pass_by_reference & (m1)) : \ - (((zend_function *)(zf))->common.fn_flags & (m2)))) +#define CHECK_ARG_SEND_TYPE(zf, arg_num, m) \ + ((zf)->common.arg_info && \ + (arg_num <= (zf)->common.num_args \ + ? ((zf)->common.arg_info[arg_num-1].pass_by_reference & (m)) \ + : ((zf)->common.fn_flags & ZEND_ACC_VARIADIC) \ + ? ((zf)->common.arg_info[(zf)->common.num_args-1].pass_by_reference & (m)) : 0)) #define ARG_MUST_BE_SENT_BY_REF(zf, arg_num) \ - CHECK_ARG_SEND_TYPE(zf, arg_num, ZEND_SEND_BY_REF, ZEND_ACC_PASS_REST_BY_REFERENCE) + CHECK_ARG_SEND_TYPE(zf, arg_num, ZEND_SEND_BY_REF) #define ARG_SHOULD_BE_SENT_BY_REF(zf, arg_num) \ - CHECK_ARG_SEND_TYPE(zf, arg_num, ZEND_SEND_BY_REF|ZEND_SEND_PREFER_REF, ZEND_ACC_PASS_REST_BY_REFERENCE|ZEND_ACC_PASS_REST_PREFER_REF) + CHECK_ARG_SEND_TYPE(zf, arg_num, ZEND_SEND_BY_REF|ZEND_SEND_PREFER_REF) #define ARG_MAY_BE_SENT_BY_REF(zf, arg_num) \ - CHECK_ARG_SEND_TYPE(zf, arg_num, ZEND_SEND_PREFER_REF, ZEND_ACC_PASS_REST_PREFER_REF) + CHECK_ARG_SEND_TYPE(zf, arg_num, ZEND_SEND_PREFER_REF) #define ZEND_RETURN_VAL 0 #define ZEND_RETURN_REF 1 @@ -839,6 +854,7 @@ int zend_add_literal(zend_op_array *op_array, const zval *zv TSRMLS_DC); #define ZEND_RETURNS_FUNCTION 1<<0 #define ZEND_RETURNS_NEW 1<<1 +#define ZEND_RETURNS_VALUE 1<<2 #define ZEND_FAST_RET_TO_CATCH 1 #define ZEND_FAST_RET_TO_FINALLY 2 diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index c79a55169c86e..777243221b466 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -40,7 +40,7 @@ #include "zend_dtrace.h" /* Virtual current working directory support */ -#include "tsrm_virtual_cwd.h" +#include "zend_virtual_cwd.h" #define _CONST_CODE 0 #define _TMP_CODE 1 @@ -79,7 +79,6 @@ static zend_always_inline void zend_pzval_unlock_func(zval *z, zend_free_op *sho if (unref && Z_ISREF_P(z) && Z_REFCOUNT_P(z) == 1) { Z_UNSET_ISREF_P(z); } - GC_ZVAL_CHECK_POSSIBLE_ROOT(z); } } @@ -95,6 +94,7 @@ static zend_always_inline void zend_pzval_unlock_free_func(zval *z TSRMLS_DC) #undef zval_ptr_dtor #define zval_ptr_dtor(pzv) i_zval_ptr_dtor(*(pzv) ZEND_FILE_LINE_CC TSRMLS_CC) +#define zval_ptr_dtor_nogc(pzv) i_zval_ptr_dtor_nogc(*(pzv) ZEND_FILE_LINE_CC TSRMLS_CC) #define PZVAL_UNLOCK(z, f) zend_pzval_unlock_func(z, f, 1 TSRMLS_CC) #define PZVAL_UNLOCK_EX(z, f, u) zend_pzval_unlock_func(z, f, u TSRMLS_CC) @@ -102,16 +102,14 @@ static zend_always_inline void zend_pzval_unlock_free_func(zval *z TSRMLS_DC) #define PZVAL_LOCK(z) Z_ADDREF_P((z)) #define SELECTIVE_PZVAL_LOCK(pzv, opline) if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(pzv); } -#define EXTRACT_ZVAL_PTR(t) do { \ - temp_variable *__t = (t); \ - if (__t->var.ptr_ptr) { \ - __t->var.ptr = *__t->var.ptr_ptr; \ - __t->var.ptr_ptr = &__t->var.ptr; \ - if (!PZVAL_IS_REF(__t->var.ptr) && \ - Z_REFCOUNT_P(__t->var.ptr) > 2) { \ - SEPARATE_ZVAL(__t->var.ptr_ptr); \ - } \ - } \ +#define EXTRACT_ZVAL_PTR(t) do { \ + temp_variable *__t = (t); \ + __t->var.ptr = *__t->var.ptr_ptr; \ + __t->var.ptr_ptr = &__t->var.ptr; \ + if (!PZVAL_IS_REF(__t->var.ptr) && \ + Z_REFCOUNT_P(__t->var.ptr) > 2) { \ + SEPARATE_ZVAL(__t->var.ptr_ptr); \ + } \ } while (0) #define AI_SET_PTR(t, val) do { \ @@ -125,18 +123,18 @@ static zend_always_inline void zend_pzval_unlock_free_func(zval *z TSRMLS_DC) if ((zend_uintptr_t)should_free.var & 1L) { \ zval_dtor((zval*)((zend_uintptr_t)should_free.var & ~1L)); \ } else { \ - zval_ptr_dtor(&should_free.var); \ + zval_ptr_dtor_nogc(&should_free.var); \ } \ } #define FREE_OP_IF_VAR(should_free) \ if (should_free.var != NULL && (((zend_uintptr_t)should_free.var & 1L) == 0)) { \ - zval_ptr_dtor(&should_free.var); \ + zval_ptr_dtor_nogc(&should_free.var); \ } #define FREE_OP_VAR_PTR(should_free) \ if (should_free.var) { \ - zval_ptr_dtor(&should_free.var); \ + zval_ptr_dtor_nogc(&should_free.var); \ } #define TMP_FREE(z) (zval*)(((zend_uintptr_t)(z)) | 1L) @@ -616,12 +614,17 @@ static inline int zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zva char *need_msg; zend_class_entry *ce; - if (!zf->common.arg_info - || arg_num>zf->common.num_args) { + if (!zf->common.arg_info) { return 1; } - cur_arg_info = &zf->common.arg_info[arg_num-1]; + if (arg_num <= zf->common.num_args) { + cur_arg_info = &zf->common.arg_info[arg_num-1]; + } else if (zf->common.fn_flags & ZEND_ACC_VARIADIC) { + cur_arg_info = &zf->common.arg_info[zf->common.num_args-1]; + } else { + return 1; + } if (cur_arg_info->class_name) { const char *class_name; @@ -1210,12 +1213,12 @@ static void zend_fetch_dimension_address(temp_variable *result, zval **container zend_error(E_NOTICE, "Indirect modification of overloaded element of %s has no effect", ce->name); } } - retval = &overloaded_result; + AI_SET_PTR(result, overloaded_result); + PZVAL_LOCK(overloaded_result); } else { - retval = &EG(error_zval_ptr); + result->var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); } - AI_SET_PTR(result, *retval); - PZVAL_LOCK(*retval); if (dim_type == IS_TMP_VAR) { zval_ptr_dtor(&dim); } @@ -1232,8 +1235,8 @@ static void zend_fetch_dimension_address(temp_variable *result, zval **container default: if (type == BP_VAR_UNSET) { zend_error(E_WARNING, "Cannot unset offset in a non-array variable"); - AI_SET_PTR(result, &EG(uninitialized_zval)); - PZVAL_LOCK(&EG(uninitialized_zval)); + result->var.ptr_ptr = &EG(uninitialized_zval_ptr); + PZVAL_LOCK(EG(uninitialized_zval_ptr)); } else { zend_error(E_WARNING, "Cannot use a scalar value as an array"); result->var.ptr_ptr = &EG(error_zval_ptr); @@ -1243,21 +1246,20 @@ static void zend_fetch_dimension_address(temp_variable *result, zval **container } } -static void zend_fetch_dimension_address_read(temp_variable *result, zval **container_ptr, zval *dim, int dim_type, int type TSRMLS_DC) +static void zend_fetch_dimension_address_read(temp_variable *result, zval *container, zval *dim, int dim_type, int type TSRMLS_DC) { - zval *container = *container_ptr; zval **retval; switch (Z_TYPE_P(container)) { case IS_ARRAY: retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, dim_type, type TSRMLS_CC); - AI_SET_PTR(result, *retval); + result->var.ptr = *retval; PZVAL_LOCK(*retval); return; case IS_NULL: - AI_SET_PTR(result, &EG(uninitialized_zval)); + result->var.ptr = &EG(uninitialized_zval); PZVAL_LOCK(&EG(uninitialized_zval)); return; @@ -1310,7 +1312,7 @@ static void zend_fetch_dimension_address_read(temp_variable *result, zval **cont Z_STRVAL_P(ptr)[1] = 0; Z_STRLEN_P(ptr) = 1; } - AI_SET_PTR(result, ptr); + result->var.ptr = ptr; return; } break; @@ -1328,12 +1330,14 @@ static void zend_fetch_dimension_address_read(temp_variable *result, zval **cont } overloaded_result = Z_OBJ_HT_P(container)->read_dimension(container, dim, type TSRMLS_CC); - if (overloaded_result) { - AI_SET_PTR(result, overloaded_result); - PZVAL_LOCK(overloaded_result); - } else if (result) { - AI_SET_PTR(result, &EG(uninitialized_zval)); - PZVAL_LOCK(&EG(uninitialized_zval)); + if (result) { + if (overloaded_result) { + result->var.ptr = overloaded_result; + PZVAL_LOCK(overloaded_result); + } else { + result->var.ptr = &EG(uninitialized_zval); + PZVAL_LOCK(&EG(uninitialized_zval)); + } } if (dim_type == IS_TMP_VAR) { zval_ptr_dtor(&dim); @@ -1342,7 +1346,7 @@ static void zend_fetch_dimension_address_read(temp_variable *result, zval **cont return; default: - AI_SET_PTR(result, &EG(uninitialized_zval)); + result->var.ptr = &EG(uninitialized_zval); PZVAL_LOCK(&EG(uninitialized_zval)); return; } @@ -1646,6 +1650,7 @@ static zend_always_inline zend_execute_data *i_create_execute_data_from_op_array EX(call) = NULL; EG(current_execute_data) = execute_data; EX(nested) = nested; + EX(delayed_exception) = NULL; if (!op_array->run_time_cache && op_array->last_cache_slot) { op_array->run_time_cache = ecalloc(op_array->last_cache_slot, sizeof(void*)); @@ -1673,12 +1678,19 @@ static zend_always_inline zend_execute_data *i_create_execute_data_from_op_array } /* }}} */ -zend_execute_data *zend_create_execute_data_from_op_array(zend_op_array *op_array, zend_bool nested TSRMLS_DC) /* {{{ */ +ZEND_API zend_execute_data *zend_create_execute_data_from_op_array(zend_op_array *op_array, zend_bool nested TSRMLS_DC) /* {{{ */ { return i_create_execute_data_from_op_array(op_array, nested TSRMLS_CC); } /* }}} */ +zend_always_inline zend_bool zend_is_by_ref_func_arg_fetch(zend_op *opline, call_slot *call TSRMLS_DC) /* {{{ */ +{ + zend_uint arg_num = (opline->extended_value & ZEND_FETCH_ARG_MASK) + call->num_additional_args; + return ARG_SHOULD_BE_SENT_BY_REF(call->fbc, arg_num); +} +/* }}} */ + #define ZEND_VM_NEXT_OPCODE() \ CHECK_SYMBOL_TABLES() \ ZEND_VM_INC_OPCODE(); \ diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index b68a82ef896e9..4802f0a19dde0 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -56,11 +56,11 @@ ZEND_API extern void (*zend_execute_internal)(zend_execute_data *execute_data_pt void init_executor(TSRMLS_D); void shutdown_executor(TSRMLS_D); void shutdown_destructors(TSRMLS_D); -zend_execute_data *zend_create_execute_data_from_op_array(zend_op_array *op_array, zend_bool nested TSRMLS_DC); +ZEND_API zend_execute_data *zend_create_execute_data_from_op_array(zend_op_array *op_array, zend_bool nested TSRMLS_DC); ZEND_API void zend_execute(zend_op_array *op_array TSRMLS_DC); ZEND_API void execute_ex(zend_execute_data *execute_data TSRMLS_DC); ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, struct _zend_fcall_info *fci, int return_value_used TSRMLS_DC); -ZEND_API int zend_is_true(zval *op); +ZEND_API int zend_is_true(zval *op TSRMLS_DC); ZEND_API int zend_lookup_class(const char *name, int name_length, zend_class_entry ***ce TSRMLS_DC); ZEND_API int zend_lookup_class_ex(const char *name, int name_length, const zend_literal *key, int use_autoload, zend_class_entry ***ce TSRMLS_DC); ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC); @@ -87,7 +87,21 @@ static zend_always_inline void i_zval_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC } } -static zend_always_inline int i_zend_is_true(zval *op) +static zend_always_inline void i_zval_ptr_dtor_nogc(zval *zval_ptr ZEND_FILE_LINE_DC TSRMLS_DC) +{ + if (!Z_DELREF_P(zval_ptr)) { + ZEND_ASSERT(zval_ptr != &EG(uninitialized_zval)); + GC_REMOVE_ZVAL_FROM_BUFFER(zval_ptr); + zval_dtor(zval_ptr); + efree_rel(zval_ptr); + } else { + if (Z_REFCOUNT_P(zval_ptr) == 1) { + Z_UNSET_ISREF_P(zval_ptr); + } + } +} + +static zend_always_inline int i_zend_is_true(zval *op TSRMLS_DC) { int result; @@ -116,8 +130,6 @@ static zend_always_inline int i_zend_is_true(zval *op) break; case IS_OBJECT: if(IS_ZEND_STD_OBJECT(*op)) { - TSRMLS_FETCH(); - if (Z_OBJ_HT_P(op)->cast_object) { zval tmp; if (Z_OBJ_HT_P(op)->cast_object(op, &tmp, IS_BOOL TSRMLS_CC) == SUCCESS) { diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 779e6d886fa4d..9c57300c84205 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -443,9 +443,9 @@ ZEND_API void _zval_internal_ptr_dtor(zval **zval_ptr ZEND_FILE_LINE_DC) /* {{{ } /* }}} */ -ZEND_API int zend_is_true(zval *op) /* {{{ */ +ZEND_API int zend_is_true(zval *op TSRMLS_DC) /* {{{ */ { - return i_zend_is_true(op); + return i_zend_is_true(op TSRMLS_CC); } /* }}} */ @@ -592,7 +592,10 @@ ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *sco zend_hash_move_forward(Z_ARRVAL_P(p)); continue; } - if (!zend_get_constant_ex(str_index, str_index_len - 3, &const_value, scope, str_index[str_index_len - 2] TSRMLS_CC)) { + if (str_index[str_index_len - 2] == IS_CONSTANT_AST) { + zend_ast_evaluate(&const_value, *(zend_ast **)str_index, scope TSRMLS_CC); + zend_ast_destroy(*(zend_ast **)str_index); + } else if (!zend_get_constant_ex(str_index, str_index_len - 3, &const_value, scope, str_index[str_index_len - 2] TSRMLS_CC)) { char *actual; const char *save = str_index; if ((colon = (char*)zend_memrchr(str_index, ':', str_index_len - 3))) { @@ -660,6 +663,15 @@ ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *sco } zend_hash_apply_with_argument(Z_ARRVAL_P(p), (apply_func_arg_t) zval_update_constant_inline_change, (void *) scope TSRMLS_CC); zend_hash_internal_pointer_reset(Z_ARRVAL_P(p)); + } else if (Z_TYPE_P(p) == IS_CONSTANT_AST) { + SEPARATE_ZVAL_IF_NOT_REF(pp); + p = *pp; + + zend_ast_evaluate(&const_value, Z_AST_P(p), scope TSRMLS_CC); + if (inline_change) { + zend_ast_destroy(Z_AST_P(p)); + } + ZVAL_COPY_VALUE(p, &const_value); } return 0; } @@ -1064,6 +1076,14 @@ ZEND_API int zend_lookup_class_ex(const char *name, int name_length, const zend_ return FAILURE; } + /* Verify class name before passing it to __autoload() */ + if (strspn(name, "0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377\\") != name_length) { + if (!key) { + free_alloca(lc_free, use_heap); + } + return FAILURE; + } + if (EG(in_autoload) == NULL) { ALLOC_HASHTABLE(EG(in_autoload)); zend_hash_init(EG(in_autoload), 0, NULL, NULL, 0); diff --git a/Zend/zend_extensions.c b/Zend/zend_extensions.c index 2dd7cd4c598c9..bc708f3843e04 100644 --- a/Zend/zend_extensions.c +++ b/Zend/zend_extensions.c @@ -24,7 +24,7 @@ ZEND_API zend_llist zend_extensions; static int last_resource_number; -int zend_load_extension(const char *path) +int zend_load_extension(const char *path TSRMLS_DC) { #if ZEND_EXTENSIONS_SUPPORT DL_HANDLE handle; @@ -107,7 +107,7 @@ int zend_load_extension(const char *path) return FAILURE; } - return zend_register_extension(new_extension, handle); + return zend_register_extension(new_extension, handle TSRMLS_CC); #else fprintf(stderr, "Extensions are not supported on this platform.\n"); /* See http://support.microsoft.com/kb/190351 */ @@ -119,7 +119,7 @@ int zend_load_extension(const char *path) } -int zend_register_extension(zend_extension *new_extension, DL_HANDLE handle) +int zend_register_extension(zend_extension *new_extension, DL_HANDLE handle TSRMLS_DC) { #if ZEND_EXTENSIONS_SUPPORT zend_extension extension; @@ -127,7 +127,7 @@ int zend_register_extension(zend_extension *new_extension, DL_HANDLE handle) extension = *new_extension; extension.handle = handle; - zend_extension_dispatch_message(ZEND_EXTMSG_NEW_EXTENSION, &extension); + zend_extension_dispatch_message(ZEND_EXTMSG_NEW_EXTENSION, &extension TSRMLS_CC); zend_llist_add_element(&zend_extensions, &extension); @@ -208,10 +208,8 @@ static void zend_extension_message_dispatcher(const zend_extension *extension, i } -ZEND_API void zend_extension_dispatch_message(int message, void *arg) +ZEND_API void zend_extension_dispatch_message(int message, void *arg TSRMLS_DC) { - TSRMLS_FETCH(); - zend_llist_apply_with_arguments(&zend_extensions, (llist_apply_with_args_func_t) zend_extension_message_dispatcher TSRMLS_CC, 2, message, arg); } diff --git a/Zend/zend_extensions.h b/Zend/zend_extensions.h index 83cad7f38d648..3ef28804e68e3 100644 --- a/Zend/zend_extensions.h +++ b/Zend/zend_extensions.h @@ -28,7 +28,7 @@ /* The first number is the engine version and the rest is the date. * This way engine 2/3 API no. is always greater than engine 1 API no.. */ -#define ZEND_EXTENSION_API_NO 220121212 +#define ZEND_EXTENSION_API_NO 220131218 typedef struct _zend_extension_version_info { int zend_extension_api_no; @@ -94,7 +94,7 @@ struct _zend_extension { BEGIN_EXTERN_C() ZEND_API int zend_get_resource_handle(zend_extension *extension); -ZEND_API void zend_extension_dispatch_message(int message, void *arg); +ZEND_API void zend_extension_dispatch_message(int message, void *arg TSRMLS_DC); END_EXTERN_C() #define ZEND_EXTMSG_NEW_EXTENSION 1 @@ -117,8 +117,8 @@ int zend_startup_extensions(void); void zend_shutdown_extensions(TSRMLS_D); BEGIN_EXTERN_C() -ZEND_API int zend_load_extension(const char *path); -ZEND_API int zend_register_extension(zend_extension *new_extension, DL_HANDLE handle); +ZEND_API int zend_load_extension(const char *path TSRMLS_DC); +ZEND_API int zend_register_extension(zend_extension *new_extension, DL_HANDLE handle TSRMLS_DC); ZEND_API zend_extension *zend_get_extension(const char *extension_name); END_EXTERN_C() diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c index c55dc67f1bbdf..e121e3c92a1fd 100644 --- a/Zend/zend_generators.c +++ b/Zend/zend_generators.c @@ -29,6 +29,73 @@ static zend_object_handlers zend_generator_handlers; static zend_object_value zend_generator_create(zend_class_entry *class_type TSRMLS_DC); +static void zend_generator_cleanup_unfinished_execution(zend_generator *generator TSRMLS_DC) /* {{{ */ +{ + zend_execute_data *execute_data = generator->execute_data; + zend_op_array *op_array = execute_data->op_array; + + if (generator->send_target) { + Z_DELREF_PP(generator->send_target); + generator->send_target = NULL; + } + + /* Manually free loop variables, as execution couldn't reach their + * SWITCH_FREE / FREE opcodes. */ + { + /* -1 required because we want the last run opcode, not the + * next to-be-run one. */ + zend_uint op_num = execute_data->opline - op_array->opcodes - 1; + + int i; + for (i = 0; i < op_array->last_brk_cont; ++i) { + zend_brk_cont_element *brk_cont = op_array->brk_cont_array + i; + + if (brk_cont->start < 0) { + continue; + } else if (brk_cont->start > op_num) { + break; + } else if (brk_cont->brk > op_num) { + zend_op *brk_opline = op_array->opcodes + brk_cont->brk; + + switch (brk_opline->opcode) { + case ZEND_SWITCH_FREE: + { + temp_variable *var = EX_TMP_VAR(execute_data, brk_opline->op1.var); + zval_ptr_dtor(&var->var.ptr); + } + break; + case ZEND_FREE: + { + temp_variable *var = EX_TMP_VAR(execute_data, brk_opline->op1.var); + zval_dtor(&var->tmp_var); + } + break; + } + } + } + } + + /* Clear any backed up stack arguments */ + { + void **ptr = generator->stack->top - 1; + void **end = zend_vm_stack_frame_base(execute_data); + + for (; ptr >= end; --ptr) { + zval_ptr_dtor((zval **) ptr); + } + } + + /* If yield was used as a function argument there may be active + * method calls those objects need to be freed */ + while (execute_data->call >= execute_data->call_slots) { + if (execute_data->call->object) { + zval_ptr_dtor(&execute_data->call->object); + } + execute_data->call--; + } +} +/* }}} */ + ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished_execution TSRMLS_DC) /* {{{ */ { if (generator->value) { @@ -61,65 +128,6 @@ ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished return; } - /* If the generator is closed before it can finish execution (reach - * a return statement) we have to free loop variables manually, as - * we don't know whether the SWITCH_FREE / FREE opcodes have run */ - if (!finished_execution) { - /* -1 required because we want the last run opcode, not the - * next to-be-run one. */ - zend_uint op_num = execute_data->opline - op_array->opcodes - 1; - - int i; - for (i = 0; i < op_array->last_brk_cont; ++i) { - zend_brk_cont_element *brk_cont = op_array->brk_cont_array + i; - - if (brk_cont->start < 0) { - continue; - } else if (brk_cont->start > op_num) { - break; - } else if (brk_cont->brk > op_num) { - zend_op *brk_opline = op_array->opcodes + brk_cont->brk; - - switch (brk_opline->opcode) { - case ZEND_SWITCH_FREE: - { - temp_variable *var = EX_TMP_VAR(execute_data, brk_opline->op1.var); - zval_ptr_dtor(&var->var.ptr); - } - break; - case ZEND_FREE: - { - temp_variable *var = EX_TMP_VAR(execute_data, brk_opline->op1.var); - zval_dtor(&var->tmp_var); - } - break; - } - } - } - } - - /* Clear any backed up stack arguments */ - if (generator->stack != EG(argument_stack)) { - void **ptr = generator->stack->top - 1; - void **end = zend_vm_stack_frame_base(execute_data); - - /* If the top stack element is the argument count, skip it */ - if (execute_data->function_state.arguments) { - ptr--; - } - - for (; ptr >= end; --ptr) { - zval_ptr_dtor((zval**) ptr); - } - } - - while (execute_data->call >= execute_data->call_slots) { - if (execute_data->call->object) { - zval_ptr_dtor(&execute_data->call->object); - } - execute_data->call--; - } - /* We have added an additional stack frame in prev_execute_data, so we * have to free it. It also contains the arguments passed to the * generator (for func_get_args) so those have to be freed too. */ @@ -138,6 +146,12 @@ ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished } } + /* Some cleanups are only necessary if the generator was closued + * before it could finish execution (reach a return statement). */ + if (!finished_execution) { + zend_generator_cleanup_unfinished_execution(generator TSRMLS_CC); + } + /* Free a clone of closure */ if (op_array->fn_flags & ZEND_ACC_CLOSURE) { destroy_op_array(op_array TSRMLS_CC); @@ -145,10 +159,6 @@ ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished } efree(generator->stack); - if (generator->stack == EG(argument_stack)) { - /* abnormal exit for running generator */ - EG(argument_stack) = NULL; - } generator->execute_data = NULL; } } @@ -226,6 +236,16 @@ static zend_object_value zend_generator_create(zend_class_entry *class_type TSRM } /* }}} */ +static void copy_closure_static_var(zval **var TSRMLS_DC, int num_args, va_list args, zend_hash_key *key) /* {{{ */ +{ + HashTable *target = va_arg(args, HashTable *); + + SEPARATE_ZVAL_TO_MAKE_IS_REF(var); + Z_ADDREF_PP(var); + zend_hash_quick_update(target, key->arKey, key->nKeyLength, key->h, var, sizeof(zval *), NULL); +} +/* }}} */ + /* Requires globals EG(scope), EG(current_scope), EG(This), * EG(active_symbol_table) and EG(current_execute_data). */ ZEND_API zval *zend_generator_create_zval(zend_op_array *op_array TSRMLS_DC) /* {{{ */ @@ -242,7 +262,23 @@ ZEND_API zval *zend_generator_create_zval(zend_op_array *op_array TSRMLS_DC) /* if (op_array->fn_flags & ZEND_ACC_CLOSURE) { zend_op_array *op_array_copy = (zend_op_array*)emalloc(sizeof(zend_op_array)); *op_array_copy = *op_array; - function_add_ref((zend_function *) op_array_copy); + + (*op_array->refcount)++; + op_array->run_time_cache = NULL; + if (op_array->static_variables) { + ALLOC_HASHTABLE(op_array_copy->static_variables); + zend_hash_init( + op_array_copy->static_variables, + zend_hash_num_elements(op_array->static_variables), + NULL, ZVAL_PTR_DTOR, 0 + ); + zend_hash_apply_with_arguments( + op_array->static_variables TSRMLS_CC, + (apply_func_args_t) copy_closure_static_var, + 1, op_array_copy->static_variables + ); + } + op_array = op_array_copy; } @@ -493,8 +529,12 @@ ZEND_METHOD(Generator, send) return; } - /* Put sent value into the TMP_VAR slot */ - MAKE_COPY_ZVAL(&value, &generator->send_target->tmp_var); + /* Put sent value in the target VAR slot, if it is used */ + if (generator->send_target) { + Z_DELREF_PP(generator->send_target); + Z_ADDREF_P(value); + *generator->send_target = value; + } zend_generator_resume(generator TSRMLS_CC); @@ -520,6 +560,8 @@ ZEND_METHOD(Generator, throw) generator = (zend_generator *) zend_object_store_get_object(getThis() TSRMLS_CC); + zend_generator_ensure_initialized(generator TSRMLS_CC); + if (generator->execute_data) { /* Throw the exception in the context of the generator */ zend_execute_data *current_execute_data = EG(current_execute_data); diff --git a/Zend/zend_generators.h b/Zend/zend_generators.h index bc125658ee74e..d5f61013155dc 100644 --- a/Zend/zend_generators.h +++ b/Zend/zend_generators.h @@ -49,7 +49,7 @@ typedef struct _zend_generator { /* Current key */ zval *key; /* Variable to put sent value into */ - temp_variable *send_target; + zval **send_target; /* Largest used integer key for auto-incrementing keys */ long largest_used_integer_key; diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index b9a5b39914a6c..27d471fa069a7 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -131,9 +131,13 @@ struct _zend_compiler_globals { zval *current_namespace; HashTable *current_import; + HashTable *current_import_function; + HashTable *current_import_const; zend_bool in_namespace; zend_bool has_bracketed_namespaces; + HashTable const_filenames; + zend_compiler_context context; zend_stack context_stack; diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c index ae7d8402f4bdd..e938d1d3d7fac 100644 --- a/Zend/zend_hash.c +++ b/Zend/zend_hash.c @@ -141,7 +141,7 @@ ZEND_API ulong zend_hash_func(const char *arKey, uint nKeyLength) static const Bucket *uninitialized_bucket = NULL; -ZEND_API int _zend_hash_init(HashTable *ht, uint nSize, hash_func_t pHashFunction, dtor_func_t pDestructor, zend_bool persistent ZEND_FILE_LINE_DC) +ZEND_API int _zend_hash_init(HashTable *ht, uint nSize, dtor_func_t pDestructor, zend_bool persistent ZEND_FILE_LINE_DC) { uint i = 3; @@ -172,9 +172,9 @@ ZEND_API int _zend_hash_init(HashTable *ht, uint nSize, hash_func_t pHashFunctio } -ZEND_API int _zend_hash_init_ex(HashTable *ht, uint nSize, hash_func_t pHashFunction, dtor_func_t pDestructor, zend_bool persistent, zend_bool bApplyProtection ZEND_FILE_LINE_DC) +ZEND_API int _zend_hash_init_ex(HashTable *ht, uint nSize, dtor_func_t pDestructor, zend_bool persistent, zend_bool bApplyProtection ZEND_FILE_LINE_DC) { - int retval = _zend_hash_init(ht, nSize, pHashFunction, pDestructor, persistent ZEND_FILE_LINE_CC); + int retval = _zend_hash_init(ht, nSize, pDestructor, persistent ZEND_FILE_LINE_CC); ht->bApplyProtection = bApplyProtection; return retval; @@ -199,12 +199,7 @@ ZEND_API int _zend_hash_add_or_update(HashTable *ht, const char *arKey, uint nKe IS_CONSISTENT(ht); - if (nKeyLength <= 0) { -#if ZEND_DEBUG - ZEND_PUTS("zend_hash_update: Can't put in empty key\n"); -#endif - return FAILURE; - } + ZEND_ASSERT(nKeyLength != 0); CHECK_INIT(ht); @@ -218,14 +213,8 @@ ZEND_API int _zend_hash_add_or_update(HashTable *ht, const char *arKey, uint nKe if (flag & HASH_ADD) { return FAILURE; } + ZEND_ASSERT(p->pData != pData); HANDLE_BLOCK_INTERRUPTIONS(); -#if ZEND_DEBUG - if (p->pData == pData) { - ZEND_PUTS("Fatal error in zend_hash_update: p->pData == pData\n"); - HANDLE_UNBLOCK_INTERRUPTIONS(); - return FAILURE; - } -#endif if (ht->pDestructor) { ht->pDestructor(p->pData); } @@ -275,9 +264,7 @@ ZEND_API int _zend_hash_quick_add_or_update(HashTable *ht, const char *arKey, ui IS_CONSISTENT(ht); - if (nKeyLength == 0) { - return zend_hash_index_update(ht, h, pData, nDataSize, pDest); - } + ZEND_ASSERT(nKeyLength != 0); CHECK_INIT(ht); nIndex = h & ht->nTableMask; @@ -289,14 +276,8 @@ ZEND_API int _zend_hash_quick_add_or_update(HashTable *ht, const char *arKey, ui if (flag & HASH_ADD) { return FAILURE; } + ZEND_ASSERT(p->pData != pData); HANDLE_BLOCK_INTERRUPTIONS(); -#if ZEND_DEBUG - if (p->pData == pData) { - ZEND_PUTS("Fatal error in zend_hash_update: p->pData == pData\n"); - HANDLE_UNBLOCK_INTERRUPTIONS(); - return FAILURE; - } -#endif if (ht->pDestructor) { ht->pDestructor(p->pData); } @@ -370,14 +351,8 @@ ZEND_API int _zend_hash_index_update_or_next_insert(HashTable *ht, ulong h, void if (flag & HASH_NEXT_INSERT || flag & HASH_ADD) { return FAILURE; } + ZEND_ASSERT(p->pData != pData); HANDLE_BLOCK_INTERRUPTIONS(); -#if ZEND_DEBUG - if (p->pData == pData) { - ZEND_PUTS("Fatal error in zend_hash_index_update: p->pData == pData\n"); - HANDLE_UNBLOCK_INTERRUPTIONS(); - return FAILURE; - } -#endif if (ht->pDestructor) { ht->pDestructor(p->pData); } @@ -876,12 +851,6 @@ ZEND_API void zend_hash_merge_ex(HashTable *target, HashTable *source, copy_ctor } -ZEND_API ulong zend_get_hash_value(const char *arKey, uint nKeyLength) -{ - return zend_inline_hash_func(arKey, nKeyLength); -} - - /* Returns SUCCESS if found and FAILURE if not. The pointer to the * data is returned in pData. The reason is that there's no reason * someone using the hash table might not want to have NULL data @@ -915,9 +884,7 @@ ZEND_API int zend_hash_quick_find(const HashTable *ht, const char *arKey, uint n uint nIndex; Bucket *p; - if (nKeyLength==0) { - return zend_hash_index_find(ht, h, pData); - } + ZEND_ASSERT(nKeyLength != 0); IS_CONSISTENT(ht); @@ -964,9 +931,7 @@ ZEND_API int zend_hash_quick_exists(const HashTable *ht, const char *arKey, uint uint nIndex; Bucket *p; - if (nKeyLength==0) { - return zend_hash_index_exists(ht, h); - } + ZEND_ASSERT(nKeyLength != 0); IS_CONSISTENT(ht); @@ -1158,7 +1123,7 @@ ZEND_API void zend_hash_get_current_key_zval_ex(const HashTable *ht, zval *key, Z_TYPE_P(key) = IS_NULL; } else if (p->nKeyLength) { Z_TYPE_P(key) = IS_STRING; - Z_STRVAL_P(key) = estrndup(p->arKey, p->nKeyLength - 1); + Z_STRVAL_P(key) = IS_INTERNED(p->arKey) ? (char*)p->arKey : estrndup(p->arKey, p->nKeyLength - 1); Z_STRLEN_P(key) = p->nKeyLength - 1; } else { Z_TYPE_P(key) = IS_LONG; diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h index 69732cd597531..c97412b46b6b5 100644 --- a/Zend/zend_hash.h +++ b/Zend/zend_hash.h @@ -97,12 +97,12 @@ typedef Bucket* HashPosition; BEGIN_EXTERN_C() /* startup/shutdown */ -ZEND_API int _zend_hash_init(HashTable *ht, uint nSize, hash_func_t pHashFunction, dtor_func_t pDestructor, zend_bool persistent ZEND_FILE_LINE_DC); -ZEND_API int _zend_hash_init_ex(HashTable *ht, uint nSize, hash_func_t pHashFunction, dtor_func_t pDestructor, zend_bool persistent, zend_bool bApplyProtection ZEND_FILE_LINE_DC); +ZEND_API int _zend_hash_init(HashTable *ht, uint nSize, dtor_func_t pDestructor, zend_bool persistent ZEND_FILE_LINE_DC); +ZEND_API int _zend_hash_init_ex(HashTable *ht, uint nSize, dtor_func_t pDestructor, zend_bool persistent, zend_bool bApplyProtection ZEND_FILE_LINE_DC); ZEND_API void zend_hash_destroy(HashTable *ht); ZEND_API void zend_hash_clean(HashTable *ht); -#define zend_hash_init(ht, nSize, pHashFunction, pDestructor, persistent) _zend_hash_init((ht), (nSize), (pHashFunction), (pDestructor), (persistent) ZEND_FILE_LINE_CC) -#define zend_hash_init_ex(ht, nSize, pHashFunction, pDestructor, persistent, bApplyProtection) _zend_hash_init_ex((ht), (nSize), (pHashFunction), (pDestructor), (persistent), (bApplyProtection) ZEND_FILE_LINE_CC) +#define zend_hash_init(ht, nSize, pHashFunction, pDestructor, persistent) _zend_hash_init((ht), (nSize), (pDestructor), (persistent) ZEND_FILE_LINE_CC) +#define zend_hash_init_ex(ht, nSize, pHashFunction, pDestructor, persistent, bApplyProtection) _zend_hash_init_ex((ht), (nSize), (pDestructor), (persistent), (bApplyProtection) ZEND_FILE_LINE_CC) /* additions/updates/changes */ ZEND_API int _zend_hash_add_or_update(HashTable *ht, const char *arKey, uint nKeyLength, void *pData, uint nDataSize, void **pDest, int flag ZEND_FILE_LINE_DC); @@ -157,8 +157,8 @@ ZEND_API int zend_hash_del_key_or_index(HashTable *ht, const char *arKey, uint n zend_hash_del_key_or_index(ht, arKey, nKeyLength, h, HASH_DEL_KEY_QUICK) #define zend_hash_index_del(ht, h) \ zend_hash_del_key_or_index(ht, NULL, 0, h, HASH_DEL_INDEX) - -ZEND_API ulong zend_get_hash_value(const char *arKey, uint nKeyLength); +#define zend_get_hash_value \ + zend_hash_func /* Data retreival */ ZEND_API int zend_hash_find(const HashTable *ht, const char *arKey, uint nKeyLength, void **pData); diff --git a/Zend/zend_indent.c b/Zend/zend_indent.c index fea78d9c57daf..42e4321b3db86 100644 --- a/Zend/zend_indent.c +++ b/Zend/zend_indent.c @@ -47,7 +47,7 @@ static void handle_whitespace(int *emit_whitespace) } -ZEND_API void zend_indent() +ZEND_API void zend_indent(TSRMLS_D) { zval token; int token_type; @@ -55,7 +55,6 @@ ZEND_API void zend_indent() int nest_level=0; int emit_whitespace[256]; int i; - TSRMLS_FETCH(); memset(emit_whitespace, 0, sizeof(int)*256); diff --git a/Zend/zend_indent.h b/Zend/zend_indent.h index bba02a738b3dc..f38e87eaefbe9 100644 --- a/Zend/zend_indent.h +++ b/Zend/zend_indent.h @@ -23,7 +23,7 @@ #define ZEND_INDENT_H BEGIN_EXTERN_C() -ZEND_API void zend_indent(void); +ZEND_API void zend_indent(TSRMLS_D); END_EXTERN_C() #endif /* ZEND_INDENT_H */ diff --git a/Zend/zend_ini_scanner.c b/Zend/zend_ini_scanner.c index 87ba664312712..a3ecdef4949ac 100644 --- a/Zend/zend_ini_scanner.c +++ b/Zend/zend_ini_scanner.c @@ -1,4663 +1,4663 @@ -/* Generated by re2c 0.13.5 */ -#line 1 "Zend/zend_ini_scanner.l" -/* - +----------------------------------------------------------------------+ - | Zend Engine | - +----------------------------------------------------------------------+ - | Copyright (c) 1998-2013 Zend Technologies Ltd. (http://www.zend.com) | - +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Zeev Suraski | - | Jani Taskinen | - | Marcus Boerger | - | Nuno Lopes | - | Scott MacVicar | - +----------------------------------------------------------------------+ -*/ - -/* $Id$ */ - -#include -#include "zend.h" -#include "zend_globals.h" -#include -#include "zend_ini_scanner.h" - -#if 0 -# define YYDEBUG(s, c) printf("state: %d char: %c\n", s, c) -#else -# define YYDEBUG(s, c) -#endif - -#include "zend_ini_scanner_defs.h" - -#define YYCTYPE unsigned char -/* allow the scanner to read one null byte after the end of the string (from ZEND_MMAP_AHEAD) - * so that if will be able to terminate to match the current token (e.g. non-enclosed string) */ -#define YYFILL(n) { if (YYCURSOR > YYLIMIT) return 0; } -#define YYCURSOR SCNG(yy_cursor) -#define YYLIMIT SCNG(yy_limit) -#define YYMARKER SCNG(yy_marker) - -#define YYGETCONDITION() SCNG(yy_state) -#define YYSETCONDITION(s) SCNG(yy_state) = s - -#define STATE(name) yyc##name - -/* emulate flex constructs */ -#define BEGIN(state) YYSETCONDITION(STATE(state)) -#define YYSTATE YYGETCONDITION() -#define yytext ((char*)SCNG(yy_text)) -#define yyleng SCNG(yy_leng) -#define yyless(x) do { YYCURSOR = (unsigned char*)yytext + x; \ - yyleng = (unsigned int)x; } while(0) - -/* #define yymore() goto yymore_restart */ - -/* perform sanity check. If this message is triggered you should - increase the ZEND_MMAP_AHEAD value in the zend_streams.h file */ -#define YYMAXFILL 6 -#if ZEND_MMAP_AHEAD < (YYMAXFILL + 1) -# error ZEND_MMAP_AHEAD should be greater than YYMAXFILL -#endif - - -/* How it works (for the core ini directives): - * =========================================== - * - * 1. Scanner scans file for tokens and passes them to parser. - * 2. Parser parses the tokens and passes the name/value pairs to the callback - * function which stores them in the configuration hash table. - * 3. Later REGISTER_INI_ENTRIES() is called which triggers the actual - * registering of ini entries and uses zend_get_configuration_directive() - * to fetch the previously stored name/value pair from configuration hash table - * and registers the static ini entries which match the name to the value - * into EG(ini_directives) hash table. - * 4. PATH section entries are used per-request from down to top, each overriding - * previous if one exists. zend_alter_ini_entry() is called for each entry. - * Settings in PATH section are ZEND_INI_SYSTEM accessible and thus mimics the - * php_admin_* directives used within Apache httpd.conf when PHP is compiled as - * module for Apache. - * 5. User defined ini files (like .htaccess for apache) are parsed for each request and - * stored in separate hash defined by SAPI. - */ - -/* TODO: (ordered by importance :-) - * =============================================================================== - * - * - Separate constant lookup totally from plain strings (using CONSTANT pattern) - * - Add #if .. #else .. #endif and ==, !=, <, > , <=, >= operators - * - Add #include "some.ini" - * - Allow variables to refer to options also when using parse_ini_file() - * - */ - -/* Globals Macros */ -#define SCNG INI_SCNG -#ifdef ZTS -ZEND_API ts_rsrc_id ini_scanner_globals_id; -#else -ZEND_API zend_ini_scanner_globals ini_scanner_globals; -#endif - -/* Eat leading whitespace */ -#define EAT_LEADING_WHITESPACE() \ - while (yytext[0]) { \ - if (yytext[0] == ' ' || yytext[0] == '\t') { \ - SCNG(yy_text)++; \ - yyleng--; \ - } else { \ - break; \ - } \ - } - -/* Eat trailing whitespace + extra char */ -#define EAT_TRAILING_WHITESPACE_EX(ch) \ - while (yyleng > 0 && ( \ - (ch != 'X' && yytext[yyleng - 1] == ch) || \ - yytext[yyleng - 1] == '\n' || \ - yytext[yyleng - 1] == '\r' || \ - yytext[yyleng - 1] == '\t' || \ - yytext[yyleng - 1] == ' ') \ - ) { \ - yyleng--; \ - } - -/* Eat trailing whitespace */ -#define EAT_TRAILING_WHITESPACE() EAT_TRAILING_WHITESPACE_EX('X') - -#define zend_ini_copy_value(retval, str, len) { \ - Z_STRVAL_P(retval) = zend_strndup(str, len); \ - Z_STRLEN_P(retval) = len; \ - Z_TYPE_P(retval) = IS_STRING; \ -} - -#define RETURN_TOKEN(type, str, len) { \ - zend_ini_copy_value(ini_lval, str, len); \ - return type; \ -} - -static void _yy_push_state(int new_state TSRMLS_DC) -{ - zend_stack_push(&SCNG(state_stack), (void *) &YYGETCONDITION(), sizeof(int)); - YYSETCONDITION(new_state); -} - -#define yy_push_state(state_and_tsrm) _yy_push_state(yyc##state_and_tsrm) - -static void yy_pop_state(TSRMLS_D) -{ - int *stack_state; - zend_stack_top(&SCNG(state_stack), (void **) &stack_state); - YYSETCONDITION(*stack_state); - zend_stack_del_top(&SCNG(state_stack)); -} - -static void yy_scan_buffer(char *str, unsigned int len TSRMLS_DC) -{ - YYCURSOR = (YYCTYPE*)str; - SCNG(yy_start) = YYCURSOR; - YYLIMIT = YYCURSOR + len; -} - -#define ini_filename SCNG(filename) - -/* {{{ init_ini_scanner() -*/ -static int init_ini_scanner(int scanner_mode, zend_file_handle *fh TSRMLS_DC) -{ - /* Sanity check */ - if (scanner_mode != ZEND_INI_SCANNER_NORMAL && scanner_mode != ZEND_INI_SCANNER_RAW) { - zend_error(E_WARNING, "Invalid scanner mode"); - return FAILURE; - } - - SCNG(lineno) = 1; - SCNG(scanner_mode) = scanner_mode; - SCNG(yy_in) = fh; - - if (fh != NULL) { - ini_filename = zend_strndup(fh->filename, strlen(fh->filename)); - } else { - ini_filename = NULL; - } - - zend_stack_init(&SCNG(state_stack)); - BEGIN(INITIAL); - - return SUCCESS; -} -/* }}} */ - -/* {{{ shutdown_ini_scanner() -*/ -void shutdown_ini_scanner(TSRMLS_D) -{ - zend_stack_destroy(&SCNG(state_stack)); - if (ini_filename) { - free(ini_filename); - } -} -/* }}} */ - -/* {{{ zend_ini_scanner_get_lineno() -*/ -int zend_ini_scanner_get_lineno(TSRMLS_D) -{ - return SCNG(lineno); -} -/* }}} */ - -/* {{{ zend_ini_scanner_get_filename() -*/ -char *zend_ini_scanner_get_filename(TSRMLS_D) -{ - return ini_filename ? ini_filename : "Unknown"; -} -/* }}} */ - -/* {{{ zend_ini_open_file_for_scanning() -*/ -int zend_ini_open_file_for_scanning(zend_file_handle *fh, int scanner_mode TSRMLS_DC) -{ - char *buf; - size_t size; - - if (zend_stream_fixup(fh, &buf, &size TSRMLS_CC) == FAILURE) { - return FAILURE; - } - - if (init_ini_scanner(scanner_mode, fh TSRMLS_CC) == FAILURE) { - zend_file_handle_dtor(fh TSRMLS_CC); - return FAILURE; - } - - yy_scan_buffer(buf, size TSRMLS_CC); - - return SUCCESS; -} -/* }}} */ - -/* {{{ zend_ini_prepare_string_for_scanning() -*/ -int zend_ini_prepare_string_for_scanning(char *str, int scanner_mode TSRMLS_DC) -{ - int len = strlen(str); - - if (init_ini_scanner(scanner_mode, NULL TSRMLS_CC) == FAILURE) { - return FAILURE; - } - - yy_scan_buffer(str, len TSRMLS_CC); - - return SUCCESS; -} -/* }}} */ - -/* {{{ zend_ini_escape_string() - */ -static void zend_ini_escape_string(zval *lval, char *str, int len, char quote_type TSRMLS_DC) -{ - register char *s, *t; - char *end; - - zend_ini_copy_value(lval, str, len); - - /* convert escape sequences */ - s = t = Z_STRVAL_P(lval); - end = s + Z_STRLEN_P(lval); - - while (s < end) { - if (*s == '\\') { - s++; - if (s >= end) { - *t++ = '\\'; - continue; - } - switch (*s) { - case '"': - if (*s != quote_type) { - *t++ = '\\'; - *t++ = *s; - break; - } - case '\\': - case '$': - *t++ = *s; - Z_STRLEN_P(lval)--; - break; - default: - *t++ = '\\'; - *t++ = *s; - break; - } - } else { - *t++ = *s; - } - if (*s == '\n' || (*s == '\r' && (*(s+1) != '\n'))) { - SCNG(lineno)++; - } - s++; - } - *t = 0; -} -/* }}} */ - -int ini_lex(zval *ini_lval TSRMLS_DC) -{ -restart: - SCNG(yy_text) = YYCURSOR; - -/* yymore_restart: */ - /* detect EOF */ - if (YYCURSOR >= YYLIMIT) { - if (YYSTATE == STATE(ST_VALUE) || YYSTATE == STATE(ST_RAW)) { - BEGIN(INITIAL); - return END_OF_LINE; - } - return 0; - } - - /* Eat any UTF-8 BOM we find in the first 3 bytes */ - if (YYCURSOR == SCNG(yy_start) && YYCURSOR + 3 < YYLIMIT) { - if (memcmp(YYCURSOR, "\xef\xbb\xbf", 3) == 0) { - YYCURSOR += 3; - goto restart; - } - } - -#line 337 "Zend/zend_ini_scanner.c" -{ - YYCTYPE yych; - unsigned int yyaccept = 0; - if (YYGETCONDITION() < 4) { - if (YYGETCONDITION() < 2) { - if (YYGETCONDITION() < 1) { - goto yyc_INITIAL; - } else { - goto yyc_ST_OFFSET; - } - } else { - if (YYGETCONDITION() < 3) { - goto yyc_ST_SECTION_VALUE; - } else { - goto yyc_ST_VALUE; - } - } - } else { - if (YYGETCONDITION() < 6) { - if (YYGETCONDITION() < 5) { - goto yyc_ST_SECTION_RAW; - } else { - goto yyc_ST_DOUBLE_QUOTES; - } - } else { - if (YYGETCONDITION() < 7) { - goto yyc_ST_VARNAME; - } else { - goto yyc_ST_RAW; - } - } - } -/* *********************************** */ -yyc_INITIAL: - { - static const unsigned char yybm[] = { - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 160, 0, 144, 144, 0, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 240, 128, 128, 144, 128, 144, 128, 144, - 128, 128, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 128, 144, 128, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 128, 144, 144, 128, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 128, 128, 128, 128, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, - }; - - YYDEBUG(0, *YYCURSOR); - YYFILL(5); - yych = *YYCURSOR; - YYDEBUG(-1, yych); - switch (yych) { - case '\t': goto yy4; - case '\n': goto yy6; - case '\r': goto yy8; - case ' ': goto yy9; - case '!': - case '"': - case '$': - case '&': - case '(': - case ')': - case '^': - case '{': - case '|': - case '}': - case '~': goto yy10; - case '#': goto yy12; - case '%': - case '\'': - case '*': - case '+': - case ',': - case '-': - case '.': - case '/': - case ':': - case '<': - case '>': - case '?': - case '@': - case ']': goto yy13; - case ';': goto yy14; - case '=': goto yy16; - case 'F': - case 'f': goto yy18; - case 'N': - case 'n': goto yy19; - case 'O': - case 'o': goto yy20; - case 'T': - case 't': goto yy21; - case 'Y': - case 'y': goto yy22; - case '[': goto yy23; - default: goto yy2; - } -yy2: - YYDEBUG(2, *YYCURSOR); - ++YYCURSOR; - yych = *YYCURSOR; - goto yy26; -yy3: - YYDEBUG(3, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 429 "Zend/zend_ini_scanner.l" - { /* Get option name */ - /* Eat leading whitespace */ - EAT_LEADING_WHITESPACE(); - - /* Eat trailing whitespace */ - EAT_TRAILING_WHITESPACE(); - - RETURN_TOKEN(TC_LABEL, yytext, yyleng); -} -#line 476 "Zend/zend_ini_scanner.c" -yy4: - YYDEBUG(4, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - goto yy68; -yy5: - YYDEBUG(5, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 575 "Zend/zend_ini_scanner.l" - { - /* eat whitespace */ - goto restart; -} -#line 490 "Zend/zend_ini_scanner.c" -yy6: - YYDEBUG(6, *YYCURSOR); - ++YYCURSOR; -yy7: - YYDEBUG(7, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 580 "Zend/zend_ini_scanner.l" - { - SCNG(lineno)++; - return END_OF_LINE; -} -#line 502 "Zend/zend_ini_scanner.c" -yy8: - YYDEBUG(8, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == '\n') goto yy71; - goto yy7; -yy9: - YYDEBUG(9, *YYCURSOR); - yyaccept = 1; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= ' ') { - if (yych <= '\n') { - if (yych <= 0x08) goto yy26; - if (yych <= '\t') goto yy67; - goto yy71; - } else { - if (yych == '\r') goto yy72; - if (yych <= 0x1F) goto yy26; - goto yy69; - } - } else { - if (yych <= ':') { - if (yych == '#') goto yy58; - goto yy26; - } else { - if (yych <= ';') goto yy53; - if (yych == '=') goto yy51; - goto yy26; - } - } -yy10: - YYDEBUG(10, *YYCURSOR); - ++YYCURSOR; - YYDEBUG(11, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 503 "Zend/zend_ini_scanner.l" - { /* Disallow these chars outside option values */ - return yytext[0]; -} -#line 541 "Zend/zend_ini_scanner.c" -yy12: - YYDEBUG(12, *YYCURSOR); - yyaccept = 1; - yych = *(YYMARKER = ++YYCURSOR); - goto yy59; -yy13: - YYDEBUG(13, *YYCURSOR); - yych = *++YYCURSOR; - goto yy26; -yy14: - YYDEBUG(14, *YYCURSOR); - yyaccept = 2; - yych = *(YYMARKER = ++YYCURSOR); - goto yy54; - YYDEBUG(15, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 603 "Zend/zend_ini_scanner.l" - { - return 0; -} -#line 562 "Zend/zend_ini_scanner.c" -yy16: - YYDEBUG(16, *YYCURSOR); - ++YYCURSOR; - yych = *YYCURSOR; - goto yy52; -yy17: - YYDEBUG(17, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 439 "Zend/zend_ini_scanner.l" - { /* Start option value */ - if (SCNG(scanner_mode) == ZEND_INI_SCANNER_RAW) { - yy_push_state(ST_RAW TSRMLS_CC); - } else { - yy_push_state(ST_VALUE TSRMLS_CC); - } - return '='; -} -#line 580 "Zend/zend_ini_scanner.c" -yy18: - YYDEBUG(18, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'A') goto yy48; - if (yych == 'a') goto yy48; - goto yy26; -yy19: - YYDEBUG(19, *YYCURSOR); - yych = *++YYCURSOR; - if (yych <= 'U') { - if (yych == 'O') goto yy44; - if (yych <= 'T') goto yy26; - goto yy45; - } else { - if (yych <= 'o') { - if (yych <= 'n') goto yy26; - goto yy44; - } else { - if (yych == 'u') goto yy45; - goto yy26; - } - } -yy20: - YYDEBUG(20, *YYCURSOR); - yych = *++YYCURSOR; - if (yych <= 'N') { - if (yych == 'F') goto yy38; - if (yych <= 'M') goto yy26; - goto yy31; - } else { - if (yych <= 'f') { - if (yych <= 'e') goto yy26; - goto yy38; - } else { - if (yych == 'n') goto yy31; - goto yy26; - } - } -yy21: - YYDEBUG(21, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'R') goto yy36; - if (yych == 'r') goto yy36; - goto yy26; -yy22: - YYDEBUG(22, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'E') goto yy27; - if (yych == 'e') goto yy27; - goto yy26; -yy23: - YYDEBUG(23, *YYCURSOR); - ++YYCURSOR; - YYDEBUG(24, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 358 "Zend/zend_ini_scanner.l" - { /* Section start */ - /* Enter section data lookup state */ - if (SCNG(scanner_mode) == ZEND_INI_SCANNER_RAW) { - yy_push_state(ST_SECTION_RAW TSRMLS_CC); - } else { - yy_push_state(ST_SECTION_VALUE TSRMLS_CC); - } - return TC_SECTION; -} -#line 646 "Zend/zend_ini_scanner.c" -yy25: - YYDEBUG(25, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; -yy26: - YYDEBUG(26, *YYCURSOR); - if (yybm[0+yych] & 16) { - goto yy25; - } - if (yych == '[') goto yy28; - goto yy3; -yy27: - YYDEBUG(27, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'S') goto yy31; - if (yych == 's') goto yy31; - goto yy26; -yy28: - YYDEBUG(28, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(29, *YYCURSOR); - if (yybm[0+yych] & 32) { - goto yy28; - } - YYDEBUG(30, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 383 "Zend/zend_ini_scanner.l" - { /* Start of option with offset */ - /* Eat leading whitespace */ - EAT_LEADING_WHITESPACE(); - - /* Eat trailing whitespace and [ */ - EAT_TRAILING_WHITESPACE_EX('['); - - /* Enter offset lookup state */ - yy_push_state(ST_OFFSET TSRMLS_CC); - - RETURN_TOKEN(TC_OFFSET, yytext, yyleng); -} -#line 689 "Zend/zend_ini_scanner.c" -yy31: - YYDEBUG(31, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(32, *YYCURSOR); - if (yybm[0+yych] & 64) { - goto yy31; - } - if (yych <= '\'') { - if (yych <= ' ') { - if (yych <= '\n') { - if (yych <= 0x08) goto yy25; - if (yych <= '\t') goto yy34; - } else { - if (yych != '\r') goto yy25; - } - } else { - if (yych <= '$') { - if (yych == '#') goto yy25; - } else { - if (yych != '&') goto yy25; - } - } - } else { - if (yych <= 'Z') { - if (yych <= ';') { - if (yych <= ')') goto yy33; - if (yych <= ':') goto yy25; - } else { - if (yych != '=') goto yy25; - } - } else { - if (yych <= '^') { - if (yych <= '[') goto yy28; - if (yych <= ']') goto yy25; - } else { - if (yych <= 'z') goto yy25; - if (yych >= 0x7F) goto yy25; - } - } - } -yy33: - YYDEBUG(33, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 421 "Zend/zend_ini_scanner.l" - { /* TRUE value (when used outside option value/offset this causes parse error!) */ - RETURN_TOKEN(BOOL_TRUE, "1", 1); -} -#line 739 "Zend/zend_ini_scanner.c" -yy34: - YYDEBUG(34, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(35, *YYCURSOR); - if (yych == '\t') goto yy34; - if (yych == ' ') goto yy34; - goto yy33; -yy36: - YYDEBUG(36, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'U') goto yy37; - if (yych != 'u') goto yy26; -yy37: - YYDEBUG(37, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'E') goto yy31; - if (yych == 'e') goto yy31; - goto yy26; -yy38: - YYDEBUG(38, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'F') goto yy39; - if (yych != 'f') goto yy26; -yy39: - YYDEBUG(39, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(40, *YYCURSOR); - if (yych <= '&') { - if (yych <= 0x1F) { - if (yych <= '\n') { - if (yych <= 0x08) goto yy25; - if (yych <= '\t') goto yy42; - } else { - if (yych != '\r') goto yy25; - } - } else { - if (yych <= '#') { - if (yych <= ' ') goto yy39; - if (yych >= '#') goto yy25; - } else { - if (yych == '%') goto yy25; - } - } - } else { - if (yych <= '=') { - if (yych <= ':') { - if (yych <= '\'') goto yy25; - if (yych >= '*') goto yy25; - } else { - if (yych == '<') goto yy25; - } - } else { - if (yych <= ']') { - if (yych == '[') goto yy28; - goto yy25; - } else { - if (yych <= '^') goto yy41; - if (yych <= 'z') goto yy25; - if (yych >= 0x7F) goto yy25; - } - } - } -yy41: - YYDEBUG(41, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 425 "Zend/zend_ini_scanner.l" - { /* FALSE value (when used outside option value/offset this causes parse error!)*/ - RETURN_TOKEN(BOOL_FALSE, "", 0); -} -#line 813 "Zend/zend_ini_scanner.c" -yy42: - YYDEBUG(42, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(43, *YYCURSOR); - if (yych == '\t') goto yy42; - if (yych == ' ') goto yy42; - goto yy41; -yy44: - YYDEBUG(44, *YYCURSOR); - yych = *++YYCURSOR; - if (yych <= '\'') { - if (yych <= 0x1F) { - if (yych <= '\n') { - if (yych <= 0x08) goto yy26; - if (yych <= '\t') goto yy42; - goto yy41; - } else { - if (yych == '\r') goto yy41; - goto yy26; - } - } else { - if (yych <= '#') { - if (yych <= ' ') goto yy39; - if (yych <= '"') goto yy41; - goto yy26; - } else { - if (yych == '%') goto yy26; - if (yych <= '&') goto yy41; - goto yy26; - } - } - } else { - if (yych <= 'N') { - if (yych <= ';') { - if (yych <= ')') goto yy41; - if (yych <= ':') goto yy26; - goto yy41; - } else { - if (yych == '=') goto yy41; - if (yych <= 'M') goto yy26; - goto yy47; - } - } else { - if (yych <= 'm') { - if (yych == '^') goto yy41; - goto yy26; - } else { - if (yych <= 'n') goto yy47; - if (yych <= 'z') goto yy26; - if (yych <= '~') goto yy41; - goto yy26; - } - } - } -yy45: - YYDEBUG(45, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'L') goto yy46; - if (yych != 'l') goto yy26; -yy46: - YYDEBUG(46, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'L') goto yy39; - if (yych == 'l') goto yy39; - goto yy26; -yy47: - YYDEBUG(47, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'E') goto yy39; - if (yych == 'e') goto yy39; - goto yy26; -yy48: - YYDEBUG(48, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'L') goto yy49; - if (yych != 'l') goto yy26; -yy49: - YYDEBUG(49, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'S') goto yy50; - if (yych != 's') goto yy26; -yy50: - YYDEBUG(50, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'E') goto yy39; - if (yych == 'e') goto yy39; - goto yy26; -yy51: - YYDEBUG(51, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; -yy52: - YYDEBUG(52, *YYCURSOR); - if (yych == '\t') goto yy51; - if (yych == ' ') goto yy51; - goto yy17; -yy53: - YYDEBUG(53, *YYCURSOR); - ++YYCURSOR; - YYFILL(2); - yych = *YYCURSOR; -yy54: - YYDEBUG(54, *YYCURSOR); - if (yybm[0+yych] & 128) { - goto yy53; - } - if (yych >= '\r') goto yy57; -yy55: - YYDEBUG(55, *YYCURSOR); - ++YYCURSOR; -yy56: - YYDEBUG(56, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 585 "Zend/zend_ini_scanner.l" - { /* Comment */ - BEGIN(INITIAL); - SCNG(lineno)++; - return END_OF_LINE; -} -#line 936 "Zend/zend_ini_scanner.c" -yy57: - YYDEBUG(57, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == '\n') goto yy55; - goto yy56; -yy58: - YYDEBUG(58, *YYCURSOR); - yyaccept = 1; - YYMARKER = ++YYCURSOR; - YYFILL(2); - yych = *YYCURSOR; -yy59: - YYDEBUG(59, *YYCURSOR); - if (yych <= '\'') { - if (yych <= ' ') { - if (yych <= '\n') { - if (yych <= 0x08) goto yy58; - if (yych >= '\n') goto yy64; - } else { - if (yych == '\r') goto yy66; - goto yy58; - } - } else { - if (yych <= '$') { - if (yych == '#') goto yy58; - } else { - if (yych != '&') goto yy58; - } - } - } else { - if (yych <= 'Z') { - if (yych <= ';') { - if (yych <= ')') goto yy60; - if (yych <= ':') goto yy58; - } else { - if (yych != '=') goto yy58; - } - } else { - if (yych <= '^') { - if (yych <= '[') goto yy62; - if (yych <= ']') goto yy58; - } else { - if (yych <= 'z') goto yy58; - if (yych >= 0x7F) goto yy58; - } - } - } -yy60: - YYDEBUG(60, *YYCURSOR); - ++YYCURSOR; - YYFILL(2); - yych = *YYCURSOR; - YYDEBUG(61, *YYCURSOR); - if (yych == '\n') goto yy64; - if (yych == '\r') goto yy66; - goto yy60; -yy62: - YYDEBUG(62, *YYCURSOR); - yyaccept = 3; - YYMARKER = ++YYCURSOR; - YYFILL(2); - yych = *YYCURSOR; - YYDEBUG(63, *YYCURSOR); - if (yych <= '\f') { - if (yych <= 0x08) goto yy60; - if (yych <= '\t') goto yy62; - if (yych >= '\v') goto yy60; - } else { - if (yych <= '\r') goto yy66; - if (yych == ' ') goto yy62; - goto yy60; - } -yy64: - YYDEBUG(64, *YYCURSOR); - ++YYCURSOR; -yy65: - YYDEBUG(65, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 591 "Zend/zend_ini_scanner.l" - { /* #Comment */ - zend_error(E_DEPRECATED, "Comments starting with '#' are deprecated in %s on line %d", zend_ini_scanner_get_filename(TSRMLS_C), SCNG(lineno)); - BEGIN(INITIAL); - SCNG(lineno)++; - return END_OF_LINE; -} -#line 1022 "Zend/zend_ini_scanner.c" -yy66: - YYDEBUG(66, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == '\n') goto yy64; - goto yy65; -yy67: - YYDEBUG(67, *YYCURSOR); - yyaccept = 0; - YYMARKER = ++YYCURSOR; - YYFILL(2); - yych = *YYCURSOR; -yy68: - YYDEBUG(68, *YYCURSOR); - if (yych <= ' ') { - if (yych <= '\n') { - if (yych <= 0x08) goto yy5; - if (yych <= '\t') goto yy67; - goto yy71; - } else { - if (yych == '\r') goto yy72; - if (yych <= 0x1F) goto yy5; - goto yy67; - } - } else { - if (yych <= ':') { - if (yych == '#') goto yy60; - goto yy5; - } else { - if (yych <= ';') goto yy53; - if (yych == '=') goto yy51; - goto yy5; - } - } -yy69: - YYDEBUG(69, *YYCURSOR); - yyaccept = 1; - YYMARKER = ++YYCURSOR; - YYFILL(2); - yych = *YYCURSOR; - YYDEBUG(70, *YYCURSOR); - if (yych <= '&') { - if (yych <= 0x1F) { - if (yych <= '\n') { - if (yych <= 0x08) goto yy25; - if (yych <= '\t') goto yy67; - } else { - if (yych == '\r') goto yy72; - goto yy25; - } - } else { - if (yych <= '#') { - if (yych <= ' ') goto yy69; - if (yych <= '"') goto yy3; - goto yy58; - } else { - if (yych == '%') goto yy25; - goto yy3; - } - } - } else { - if (yych <= '=') { - if (yych <= ':') { - if (yych <= '\'') goto yy25; - if (yych <= ')') goto yy3; - goto yy25; - } else { - if (yych <= ';') goto yy53; - if (yych <= '<') goto yy25; - goto yy51; - } - } else { - if (yych <= ']') { - if (yych == '[') goto yy28; - goto yy25; - } else { - if (yych <= '^') goto yy3; - if (yych <= 'z') goto yy25; - if (yych <= '~') goto yy3; - goto yy25; - } - } - } -yy71: - YYDEBUG(71, *YYCURSOR); - yych = *++YYCURSOR; - goto yy7; -yy72: - YYDEBUG(72, *YYCURSOR); - ++YYCURSOR; - if ((yych = *YYCURSOR) == '\n') goto yy71; - goto yy7; - } -/* *********************************** */ -yyc_ST_DOUBLE_QUOTES: - { - static const unsigned char yybm[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 128, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 128, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }; - YYDEBUG(73, *YYCURSOR); - YYFILL(2); - yych = *YYCURSOR; - if (yych == '"') goto yy77; - if (yych == '$') goto yy79; - YYDEBUG(75, *YYCURSOR); - ++YYCURSOR; -yy76: - YYDEBUG(76, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 535 "Zend/zend_ini_scanner.l" - { /* Escape double quoted string contents */ - if (YYCURSOR > YYLIMIT) { - return 0; - } - - while (YYCURSOR < YYLIMIT) { - switch (*YYCURSOR++) { - case '"': - if (YYCURSOR < YYLIMIT && YYCURSOR[-2] == '\\' && *YYCURSOR != '\r' && *YYCURSOR != '\n') { - continue; - } - break; - case '$': - if (*YYCURSOR == '{') { - break; - } - continue; - case '\\': - if (YYCURSOR < YYLIMIT && *YYCURSOR != '"') { - YYCURSOR++; - } - /* fall through */ - default: - continue; - } - - YYCURSOR--; - break; - } - - yyleng = YYCURSOR - SCNG(yy_text); - - zend_ini_escape_string(ini_lval, yytext, yyleng, '"' TSRMLS_CC); - return TC_QUOTED_STRING; -} -#line 1198 "Zend/zend_ini_scanner.c" -yy77: - YYDEBUG(77, *YYCURSOR); - ++YYCURSOR; - yych = *YYCURSOR; - goto yy83; -yy78: - YYDEBUG(78, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 530 "Zend/zend_ini_scanner.l" - { /* Double quoted '"' string ends */ - yy_pop_state(TSRMLS_C); - return '"'; -} -#line 1212 "Zend/zend_ini_scanner.c" -yy79: - YYDEBUG(79, *YYCURSOR); - yych = *++YYCURSOR; - if (yych != '{') goto yy76; - YYDEBUG(80, *YYCURSOR); - ++YYCURSOR; - YYDEBUG(81, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 401 "Zend/zend_ini_scanner.l" - { /* Variable start */ - yy_push_state(ST_VARNAME TSRMLS_CC); - return TC_DOLLAR_CURLY; -} -#line 1226 "Zend/zend_ini_scanner.c" -yy82: - YYDEBUG(82, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; -yy83: - YYDEBUG(83, *YYCURSOR); - if (yybm[0+yych] & 128) { - goto yy82; - } - goto yy78; - } -/* *********************************** */ -yyc_ST_OFFSET: - { - static const unsigned char yybm[] = { - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 194, 64, 66, 66, 64, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 194, 66, 64, 66, 68, 66, 66, 0, - 66, 66, 66, 66, 66, 66, 66, 66, - 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 66, 64, 66, 66, 66, 66, - 66, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 66, 72, 64, 66, 82, - 66, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, - }; - YYDEBUG(84, *YYCURSOR); - YYFILL(2); - yych = *YYCURSOR; - if (yych <= '-') { - if (yych <= ' ') { - if (yych <= '\n') { - if (yych <= 0x08) goto yy86; - if (yych <= '\t') goto yy88; - goto yy89; - } else { - if (yych == '\r') goto yy89; - if (yych >= ' ') goto yy88; - } - } else { - if (yych <= '$') { - if (yych == '"') goto yy91; - if (yych >= '$') goto yy93; - } else { - if (yych == '\'') goto yy94; - if (yych >= '-') goto yy95; - } - } - } else { - if (yych <= 'Z') { - if (yych <= '9') { - if (yych <= '.') goto yy96; - if (yych >= '0') goto yy97; - } else { - if (yych == ';') goto yy89; - if (yych >= 'A') goto yy99; - } - } else { - if (yych <= '^') { - if (yych <= '[') goto yy86; - if (yych <= '\\') goto yy101; - if (yych <= ']') goto yy102; - } else { - if (yych == '`') goto yy86; - if (yych <= 'z') goto yy99; - } - } - } -yy86: - YYDEBUG(86, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - goto yy105; -yy87: - YYDEBUG(87, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 521 "Zend/zend_ini_scanner.l" - { /* Get rest as section/offset value */ - RETURN_TOKEN(TC_STRING, yytext, yyleng); -} -#line 1330 "Zend/zend_ini_scanner.c" -yy88: - YYDEBUG(88, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yybm[0+yych] & 128) { - goto yy131; - } - if (yych == '"') goto yy133; - if (yych == ']') goto yy134; - goto yy105; -yy89: - YYDEBUG(89, *YYCURSOR); - ++YYCURSOR; -yy90: - YYDEBUG(90, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 603 "Zend/zend_ini_scanner.l" - { - return 0; -} -#line 1351 "Zend/zend_ini_scanner.c" -yy91: - YYDEBUG(91, *YYCURSOR); - ++YYCURSOR; -yy92: - YYDEBUG(92, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 525 "Zend/zend_ini_scanner.l" - { /* Double quoted '"' string start */ - yy_push_state(ST_DOUBLE_QUOTES TSRMLS_CC); - return '"'; -} -#line 1363 "Zend/zend_ini_scanner.c" -yy93: - YYDEBUG(93, *YYCURSOR); - yych = *++YYCURSOR; - if (yych <= '\\') { - if (yych <= 0x00) goto yy90; - if (yych <= '[') goto yy104; - goto yy109; - } else { - if (yych == '{') goto yy129; - goto yy104; - } -yy94: - YYDEBUG(94, *YYCURSOR); - yyaccept = 1; - yych = *(YYMARKER = ++YYCURSOR); - if (yybm[0+yych] & 64) { - goto yy125; - } - goto yy90; -yy95: - YYDEBUG(95, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '/') goto yy105; - if (yych <= '9') goto yy123; - goto yy105; -yy96: - YYDEBUG(96, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '/') goto yy105; - if (yych <= '9') goto yy121; - goto yy105; -yy97: - YYDEBUG(97, *YYCURSOR); - yyaccept = 2; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '\'') { - if (yych <= '\r') { - if (yych == '\n') goto yy98; - if (yych <= '\f') goto yy105; - } else { - if (yych == '"') goto yy98; - if (yych <= '&') goto yy105; - } - } else { - if (yych <= '9') { - if (yych == '.') goto yy117; - if (yych <= '/') goto yy105; - goto yy119; - } else { - if (yych <= ';') { - if (yych <= ':') goto yy105; - } else { - if (yych != ']') goto yy105; - } - } - } -yy98: - YYDEBUG(98, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 499 "Zend/zend_ini_scanner.l" - { /* Get number option value as string */ - RETURN_TOKEN(TC_NUMBER, yytext, yyleng); -} -#line 1429 "Zend/zend_ini_scanner.c" -yy99: - YYDEBUG(99, *YYCURSOR); - yyaccept = 3; - yych = *(YYMARKER = ++YYCURSOR); - if (yybm[0+yych] & 16) { - goto yy115; - } - if (yych <= '"') { - if (yych <= '\f') { - if (yych != '\n') goto yy105; - } else { - if (yych <= '\r') goto yy100; - if (yych <= '!') goto yy105; - } - } else { - if (yych <= ':') { - if (yych != '\'') goto yy105; - } else { - if (yych <= ';') goto yy100; - if (yych != ']') goto yy105; - } - } -yy100: - YYDEBUG(100, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 495 "Zend/zend_ini_scanner.l" - { /* Get constant option value */ - RETURN_TOKEN(TC_CONSTANT, yytext, yyleng); -} -#line 1459 "Zend/zend_ini_scanner.c" -yy101: - YYDEBUG(101, *YYCURSOR); - yych = *++YYCURSOR; - goto yy104; -yy102: - YYDEBUG(102, *YYCURSOR); - ++YYCURSOR; -yy103: - YYDEBUG(103, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 396 "Zend/zend_ini_scanner.l" - { /* End of section or an option offset */ - BEGIN(INITIAL); - return ']'; -} -#line 1475 "Zend/zend_ini_scanner.c" -yy104: - YYDEBUG(104, *YYCURSOR); - yyaccept = 0; - YYMARKER = ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; -yy105: - YYDEBUG(105, *YYCURSOR); - if (yybm[0+yych] & 2) { - goto yy104; - } - if (yych == '$') goto yy107; - if (yych != '\\') goto yy87; -yy106: - YYDEBUG(106, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - goto yy104; -yy107: - YYDEBUG(107, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - if (yych <= '\\') { - if (yych <= 0x00) goto yy108; - if (yych <= '[') goto yy104; - goto yy109; - } else { - if (yych != '{') goto yy104; - } -yy108: - YYDEBUG(108, *YYCURSOR); - YYCURSOR = YYMARKER; - if (yyaccept <= 1) { - if (yyaccept <= 0) { - goto yy87; - } else { - goto yy90; - } - } else { - if (yyaccept <= 2) { - goto yy98; - } else { - goto yy100; - } - } -yy109: - YYDEBUG(109, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - if (yybm[0+yych] & 4) { - goto yy110; - } - if (yych == '\\') goto yy112; - goto yy104; -yy110: - YYDEBUG(110, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(111, *YYCURSOR); - if (yybm[0+yych] & 4) { - goto yy110; - } - if (yych == '\\') goto yy114; - goto yy104; -yy112: - YYDEBUG(112, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(113, *YYCURSOR); - if (yybm[0+yych] & 4) { - goto yy110; - } - if (yych == '\\') goto yy112; - goto yy104; -yy114: - YYDEBUG(114, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - if (yybm[0+yych] & 4) { - goto yy110; - } - if (yych == '\\') goto yy112; - goto yy104; -yy115: - YYDEBUG(115, *YYCURSOR); - yyaccept = 3; - YYMARKER = ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(116, *YYCURSOR); - if (yybm[0+yych] & 16) { - goto yy115; - } - if (yych <= '$') { - if (yych <= '\r') { - if (yych == '\n') goto yy100; - if (yych <= '\f') goto yy104; - goto yy100; - } else { - if (yych == '"') goto yy100; - if (yych <= '#') goto yy104; - goto yy107; - } - } else { - if (yych <= ';') { - if (yych == '\'') goto yy100; - if (yych <= ':') goto yy104; - goto yy100; - } else { - if (yych <= '[') goto yy104; - if (yych <= '\\') goto yy106; - if (yych <= ']') goto yy100; - goto yy104; - } - } -yy117: - YYDEBUG(117, *YYCURSOR); - yyaccept = 2; - YYMARKER = ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(118, *YYCURSOR); - if (yybm[0+yych] & 32) { - goto yy117; - } - if (yych <= '$') { - if (yych <= '\r') { - if (yych == '\n') goto yy98; - if (yych <= '\f') goto yy104; - goto yy98; - } else { - if (yych == '"') goto yy98; - if (yych <= '#') goto yy104; - goto yy107; - } - } else { - if (yych <= ';') { - if (yych == '\'') goto yy98; - if (yych <= ':') goto yy104; - goto yy98; - } else { - if (yych <= '[') goto yy104; - if (yych <= '\\') goto yy106; - if (yych <= ']') goto yy98; - goto yy104; - } - } -yy119: - YYDEBUG(119, *YYCURSOR); - yyaccept = 2; - YYMARKER = ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(120, *YYCURSOR); - if (yych <= '\'') { - if (yych <= '!') { - if (yych <= '\n') { - if (yych <= '\t') goto yy104; - goto yy98; - } else { - if (yych == '\r') goto yy98; - goto yy104; - } - } else { - if (yych <= '#') { - if (yych <= '"') goto yy98; - goto yy104; - } else { - if (yych <= '$') goto yy107; - if (yych <= '&') goto yy104; - goto yy98; - } - } - } else { - if (yych <= ':') { - if (yych <= '.') { - if (yych <= '-') goto yy104; - goto yy117; - } else { - if (yych <= '/') goto yy104; - if (yych <= '9') goto yy119; - goto yy104; - } - } else { - if (yych <= '[') { - if (yych <= ';') goto yy98; - goto yy104; - } else { - if (yych <= '\\') goto yy106; - if (yych <= ']') goto yy98; - goto yy104; - } - } - } -yy121: - YYDEBUG(121, *YYCURSOR); - yyaccept = 2; - YYMARKER = ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(122, *YYCURSOR); - if (yych <= '&') { - if (yych <= '\r') { - if (yych == '\n') goto yy98; - if (yych <= '\f') goto yy104; - goto yy98; - } else { - if (yych <= '"') { - if (yych <= '!') goto yy104; - goto yy98; - } else { - if (yych == '$') goto yy107; - goto yy104; - } - } - } else { - if (yych <= ':') { - if (yych <= '\'') goto yy98; - if (yych <= '/') goto yy104; - if (yych <= '9') goto yy121; - goto yy104; - } else { - if (yych <= '[') { - if (yych <= ';') goto yy98; - goto yy104; - } else { - if (yych <= '\\') goto yy106; - if (yych <= ']') goto yy98; - goto yy104; - } - } - } -yy123: - YYDEBUG(123, *YYCURSOR); - yyaccept = 2; - YYMARKER = ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(124, *YYCURSOR); - if (yych <= '&') { - if (yych <= '\r') { - if (yych == '\n') goto yy98; - if (yych <= '\f') goto yy104; - goto yy98; - } else { - if (yych <= '"') { - if (yych <= '!') goto yy104; - goto yy98; - } else { - if (yych == '$') goto yy107; - goto yy104; - } - } - } else { - if (yych <= ':') { - if (yych <= '\'') goto yy98; - if (yych <= '/') goto yy104; - if (yych <= '9') goto yy123; - goto yy104; - } else { - if (yych <= '[') { - if (yych <= ';') goto yy98; - goto yy104; - } else { - if (yych <= '\\') goto yy106; - if (yych <= ']') goto yy98; - goto yy104; - } - } - } -yy125: - YYDEBUG(125, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(126, *YYCURSOR); - if (yybm[0+yych] & 64) { - goto yy125; - } - YYDEBUG(127, *YYCURSOR); - ++YYCURSOR; - YYDEBUG(128, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 368 "Zend/zend_ini_scanner.l" - { /* Raw string */ - /* Eat leading and trailing single quotes */ - if (yytext[0] == '\'' && yytext[yyleng - 1] == '\'') { - SCNG(yy_text)++; - yyleng = yyleng - 2; - } - RETURN_TOKEN(TC_RAW, yytext, yyleng); -} -#line 1774 "Zend/zend_ini_scanner.c" -yy129: - YYDEBUG(129, *YYCURSOR); - ++YYCURSOR; - YYDEBUG(130, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 401 "Zend/zend_ini_scanner.l" - { /* Variable start */ - yy_push_state(ST_VARNAME TSRMLS_CC); - return TC_DOLLAR_CURLY; -} -#line 1785 "Zend/zend_ini_scanner.c" -yy131: - YYDEBUG(131, *YYCURSOR); - yyaccept = 0; - YYMARKER = ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(132, *YYCURSOR); - if (yybm[0+yych] & 128) { - goto yy131; - } - if (yych <= '$') { - if (yych <= '\r') { - if (yych == '\n') goto yy87; - if (yych <= '\f') goto yy104; - goto yy87; - } else { - if (yych == '"') goto yy133; - if (yych <= '#') goto yy104; - goto yy107; - } - } else { - if (yych <= ';') { - if (yych == '\'') goto yy87; - if (yych <= ':') goto yy104; - goto yy87; - } else { - if (yych <= '[') goto yy104; - if (yych <= '\\') goto yy106; - if (yych <= ']') goto yy134; - goto yy104; - } - } -yy133: - YYDEBUG(133, *YYCURSOR); - yych = *++YYCURSOR; - goto yy92; -yy134: - YYDEBUG(134, *YYCURSOR); - ++YYCURSOR; - yych = *YYCURSOR; - goto yy103; - } -/* *********************************** */ -yyc_ST_RAW: - { - static const unsigned char yybm[] = { - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 192, 0, 64, 64, 0, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 192, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - }; - YYDEBUG(135, *YYCURSOR); - YYFILL(3); - yych = *YYCURSOR; - if (yych <= '\f') { - if (yych <= 0x08) { - if (yych >= 0x01) goto yy139; - } else { - if (yych <= '\t') goto yy141; - if (yych <= '\n') goto yy142; - goto yy139; - } - } else { - if (yych <= ' ') { - if (yych <= '\r') goto yy144; - if (yych <= 0x1F) goto yy139; - goto yy141; - } else { - if (yych == ';') goto yy145; - goto yy139; - } - } - YYDEBUG(137, *YYCURSOR); - ++YYCURSOR; - YYDEBUG(138, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 598 "Zend/zend_ini_scanner.l" - { /* End of option value (if EOF is reached before EOL */ - BEGIN(INITIAL); - return END_OF_LINE; -} -#line 1895 "Zend/zend_ini_scanner.c" -yy139: - YYDEBUG(139, *YYCURSOR); - ++YYCURSOR; -yy140: - YYDEBUG(140, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 448 "Zend/zend_ini_scanner.l" - { /* Raw value, only used when SCNG(scanner_mode) == ZEND_INI_SCANNER_RAW. */ - char *sc = NULL; - while (YYCURSOR < YYLIMIT) { - switch (*YYCURSOR) { - case '\n': - case '\r': - goto end_raw_value_chars; - break; - case ';': - if (sc == NULL) { - sc = YYCURSOR; - } - /* no break */ - default: - YYCURSOR++; - break; - } - } -end_raw_value_chars: - yyleng = YYCURSOR - SCNG(yy_text); - - /* Eat trailing semicolons */ - while (yytext[yyleng - 1] == ';') { - yyleng--; - } - - /* Eat leading and trailing double quotes */ - if (yytext[0] == '"' && yytext[yyleng - 1] == '"') { - SCNG(yy_text)++; - yyleng = yyleng - 2; - } else if (sc) { - YYCURSOR = sc; - yyleng = YYCURSOR - SCNG(yy_text); - } - RETURN_TOKEN(TC_RAW, yytext, yyleng); -} -#line 1939 "Zend/zend_ini_scanner.c" -yy141: - YYDEBUG(141, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '\r') { - if (yych <= 0x08) goto yy140; - if (yych <= '\n') goto yy153; - if (yych <= '\f') goto yy140; - goto yy153; - } else { - if (yych <= ' ') { - if (yych <= 0x1F) goto yy140; - goto yy153; - } else { - if (yych == ';') goto yy153; - goto yy140; - } - } -yy142: - YYDEBUG(142, *YYCURSOR); - ++YYCURSOR; -yy143: - YYDEBUG(143, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 489 "Zend/zend_ini_scanner.l" - { /* End of option value */ - BEGIN(INITIAL); - SCNG(lineno)++; - return END_OF_LINE; -} -#line 1970 "Zend/zend_ini_scanner.c" -yy144: - YYDEBUG(144, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == '\n') goto yy151; - goto yy143; -yy145: - YYDEBUG(145, *YYCURSOR); - yyaccept = 1; - yych = *(YYMARKER = ++YYCURSOR); - goto yy147; -yy146: - YYDEBUG(146, *YYCURSOR); - ++YYCURSOR; - YYFILL(2); - yych = *YYCURSOR; -yy147: - YYDEBUG(147, *YYCURSOR); - if (yybm[0+yych] & 64) { - goto yy146; - } - if (yych >= '\r') goto yy150; -yy148: - YYDEBUG(148, *YYCURSOR); - ++YYCURSOR; -yy149: - YYDEBUG(149, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 585 "Zend/zend_ini_scanner.l" - { /* Comment */ - BEGIN(INITIAL); - SCNG(lineno)++; - return END_OF_LINE; -} -#line 2004 "Zend/zend_ini_scanner.c" -yy150: - YYDEBUG(150, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == '\n') goto yy148; - goto yy149; -yy151: - YYDEBUG(151, *YYCURSOR); - yych = *++YYCURSOR; - goto yy143; -yy152: - YYDEBUG(152, *YYCURSOR); - yyaccept = 2; - YYMARKER = ++YYCURSOR; - YYFILL(2); - yych = *YYCURSOR; -yy153: - YYDEBUG(153, *YYCURSOR); - if (yybm[0+yych] & 128) { - goto yy152; - } - if (yych <= '\f') { - if (yych == '\n') goto yy151; - } else { - if (yych <= '\r') goto yy155; - if (yych == ';') goto yy146; - } - YYDEBUG(154, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 575 "Zend/zend_ini_scanner.l" - { - /* eat whitespace */ - goto restart; -} -#line 2038 "Zend/zend_ini_scanner.c" -yy155: - YYDEBUG(155, *YYCURSOR); - ++YYCURSOR; - if ((yych = *YYCURSOR) == '\n') goto yy151; - goto yy143; - } -/* *********************************** */ -yyc_ST_SECTION_RAW: - { - static const unsigned char yybm[] = { - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 192, 0, 128, 128, 0, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 192, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 0, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - }; - YYDEBUG(156, *YYCURSOR); - YYFILL(3); - yych = *YYCURSOR; - if (yych <= '\f') { - if (yych == '\n') goto yy160; - } else { - if (yych <= '\r') goto yy160; - if (yych == ']') goto yy162; - } - YYDEBUG(158, *YYCURSOR); - ++YYCURSOR; - yych = *YYCURSOR; - goto yy169; -yy159: - YYDEBUG(159, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 485 "Zend/zend_ini_scanner.l" - { /* Raw value, only used when SCNG(scanner_mode) == ZEND_INI_SCANNER_RAW. */ - RETURN_TOKEN(TC_RAW, yytext, yyleng); -} -#line 2102 "Zend/zend_ini_scanner.c" -yy160: - YYDEBUG(160, *YYCURSOR); - ++YYCURSOR; - YYDEBUG(161, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 603 "Zend/zend_ini_scanner.l" - { - return 0; -} -#line 2112 "Zend/zend_ini_scanner.c" -yy162: - YYDEBUG(162, *YYCURSOR); - ++YYCURSOR; - yych = *YYCURSOR; - goto yy165; -yy163: - YYDEBUG(163, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 377 "Zend/zend_ini_scanner.l" - { /* End of section */ - BEGIN(INITIAL); - SCNG(lineno)++; - return ']'; -} -#line 2127 "Zend/zend_ini_scanner.c" -yy164: - YYDEBUG(164, *YYCURSOR); - ++YYCURSOR; - YYFILL(2); - yych = *YYCURSOR; -yy165: - YYDEBUG(165, *YYCURSOR); - if (yybm[0+yych] & 64) { - goto yy164; - } - if (yych == '\n') goto yy166; - if (yych == '\r') goto yy167; - goto yy163; -yy166: - YYDEBUG(166, *YYCURSOR); - yych = *++YYCURSOR; - goto yy163; -yy167: - YYDEBUG(167, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == '\n') goto yy166; - goto yy163; -yy168: - YYDEBUG(168, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; -yy169: - YYDEBUG(169, *YYCURSOR); - if (yybm[0+yych] & 128) { - goto yy168; - } - goto yy159; - } -/* *********************************** */ -yyc_ST_SECTION_VALUE: - { - static const unsigned char yybm[] = { - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 134, 128, 132, 132, 128, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 134, 132, 128, 132, 136, 132, 132, 0, - 132, 132, 132, 132, 132, 132, 132, 132, - 228, 228, 228, 228, 228, 228, 228, 228, - 228, 228, 132, 128, 132, 132, 132, 132, - 132, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 132, 144, 128, 132, 164, - 132, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - }; - YYDEBUG(170, *YYCURSOR); - YYFILL(3); - yych = *YYCURSOR; - if (yych <= '-') { - if (yych <= ' ') { - if (yych <= '\n') { - if (yych <= 0x08) goto yy172; - if (yych <= '\t') goto yy174; - goto yy175; - } else { - if (yych == '\r') goto yy175; - if (yych >= ' ') goto yy174; - } - } else { - if (yych <= '$') { - if (yych == '"') goto yy177; - if (yych >= '$') goto yy179; - } else { - if (yych == '\'') goto yy180; - if (yych >= '-') goto yy181; - } - } - } else { - if (yych <= 'Z') { - if (yych <= '9') { - if (yych <= '.') goto yy182; - if (yych >= '0') goto yy183; - } else { - if (yych == ';') goto yy175; - if (yych >= 'A') goto yy185; - } - } else { - if (yych <= '^') { - if (yych <= '[') goto yy172; - if (yych <= '\\') goto yy187; - if (yych <= ']') goto yy188; - } else { - if (yych == '`') goto yy172; - if (yych <= 'z') goto yy185; - } - } - } -yy172: - YYDEBUG(172, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - goto yy195; -yy173: - YYDEBUG(173, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 521 "Zend/zend_ini_scanner.l" - { /* Get rest as section/offset value */ - RETURN_TOKEN(TC_STRING, yytext, yyleng); -} -#line 2253 "Zend/zend_ini_scanner.c" -yy174: - YYDEBUG(174, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= 0x1F) { - if (yych == '\t') goto yy221; - goto yy195; - } else { - if (yych <= ' ') goto yy221; - if (yych == '"') goto yy223; - goto yy195; - } -yy175: - YYDEBUG(175, *YYCURSOR); - ++YYCURSOR; -yy176: - YYDEBUG(176, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 603 "Zend/zend_ini_scanner.l" - { - return 0; -} -#line 2276 "Zend/zend_ini_scanner.c" -yy177: - YYDEBUG(177, *YYCURSOR); - ++YYCURSOR; -yy178: - YYDEBUG(178, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 525 "Zend/zend_ini_scanner.l" - { /* Double quoted '"' string start */ - yy_push_state(ST_DOUBLE_QUOTES TSRMLS_CC); - return '"'; -} -#line 2288 "Zend/zend_ini_scanner.c" -yy179: - YYDEBUG(179, *YYCURSOR); - yych = *++YYCURSOR; - if (yych <= '\\') { - if (yych <= 0x00) goto yy176; - if (yych <= '[') goto yy194; - goto yy199; - } else { - if (yych == '{') goto yy219; - goto yy194; - } -yy180: - YYDEBUG(180, *YYCURSOR); - yyaccept = 1; - yych = *(YYMARKER = ++YYCURSOR); - if (yybm[0+yych] & 128) { - goto yy215; - } - goto yy176; -yy181: - YYDEBUG(181, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '/') goto yy195; - if (yych <= '9') goto yy213; - goto yy195; -yy182: - YYDEBUG(182, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '/') goto yy195; - if (yych <= '9') goto yy211; - goto yy195; -yy183: - YYDEBUG(183, *YYCURSOR); - yyaccept = 2; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '\'') { - if (yych <= '\r') { - if (yych == '\n') goto yy184; - if (yych <= '\f') goto yy195; - } else { - if (yych == '"') goto yy184; - if (yych <= '&') goto yy195; - } - } else { - if (yych <= '9') { - if (yych == '.') goto yy207; - if (yych <= '/') goto yy195; - goto yy209; - } else { - if (yych <= ';') { - if (yych <= ':') goto yy195; - } else { - if (yych != ']') goto yy195; - } - } - } -yy184: - YYDEBUG(184, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 499 "Zend/zend_ini_scanner.l" - { /* Get number option value as string */ - RETURN_TOKEN(TC_NUMBER, yytext, yyleng); -} -#line 2354 "Zend/zend_ini_scanner.c" -yy185: - YYDEBUG(185, *YYCURSOR); - yyaccept = 3; - yych = *(YYMARKER = ++YYCURSOR); - if (yybm[0+yych] & 32) { - goto yy205; - } - if (yych <= '"') { - if (yych <= '\f') { - if (yych != '\n') goto yy195; - } else { - if (yych <= '\r') goto yy186; - if (yych <= '!') goto yy195; - } - } else { - if (yych <= ':') { - if (yych != '\'') goto yy195; - } else { - if (yych <= ';') goto yy186; - if (yych != ']') goto yy195; - } - } -yy186: - YYDEBUG(186, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 495 "Zend/zend_ini_scanner.l" - { /* Get constant option value */ - RETURN_TOKEN(TC_CONSTANT, yytext, yyleng); -} -#line 2384 "Zend/zend_ini_scanner.c" -yy187: - YYDEBUG(187, *YYCURSOR); - yych = *++YYCURSOR; - goto yy194; -yy188: - YYDEBUG(188, *YYCURSOR); - ++YYCURSOR; - yych = *YYCURSOR; - goto yy191; -yy189: - YYDEBUG(189, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 377 "Zend/zend_ini_scanner.l" - { /* End of section */ - BEGIN(INITIAL); - SCNG(lineno)++; - return ']'; -} -#line 2403 "Zend/zend_ini_scanner.c" -yy190: - YYDEBUG(190, *YYCURSOR); - ++YYCURSOR; - YYFILL(2); - yych = *YYCURSOR; -yy191: - YYDEBUG(191, *YYCURSOR); - if (yybm[0+yych] & 2) { - goto yy190; - } - if (yych == '\n') goto yy192; - if (yych == '\r') goto yy193; - goto yy189; -yy192: - YYDEBUG(192, *YYCURSOR); - yych = *++YYCURSOR; - goto yy189; -yy193: - YYDEBUG(193, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == '\n') goto yy192; - goto yy189; -yy194: - YYDEBUG(194, *YYCURSOR); - yyaccept = 0; - YYMARKER = ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; -yy195: - YYDEBUG(195, *YYCURSOR); - if (yybm[0+yych] & 4) { - goto yy194; - } - if (yych == '$') goto yy197; - if (yych != '\\') goto yy173; -yy196: - YYDEBUG(196, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - goto yy194; -yy197: - YYDEBUG(197, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - if (yych <= '\\') { - if (yych <= 0x00) goto yy198; - if (yych <= '[') goto yy194; - goto yy199; - } else { - if (yych != '{') goto yy194; - } -yy198: - YYDEBUG(198, *YYCURSOR); - YYCURSOR = YYMARKER; - if (yyaccept <= 1) { - if (yyaccept <= 0) { - goto yy173; - } else { - goto yy176; - } - } else { - if (yyaccept <= 2) { - goto yy184; - } else { - goto yy186; - } - } -yy199: - YYDEBUG(199, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - if (yybm[0+yych] & 8) { - goto yy200; - } - if (yych == '\\') goto yy202; - goto yy194; -yy200: - YYDEBUG(200, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(201, *YYCURSOR); - if (yybm[0+yych] & 8) { - goto yy200; - } - if (yych == '\\') goto yy204; - goto yy194; -yy202: - YYDEBUG(202, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(203, *YYCURSOR); - if (yybm[0+yych] & 8) { - goto yy200; - } - if (yych == '\\') goto yy202; - goto yy194; -yy204: - YYDEBUG(204, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - if (yybm[0+yych] & 8) { - goto yy200; - } - if (yych == '\\') goto yy202; - goto yy194; -yy205: - YYDEBUG(205, *YYCURSOR); - yyaccept = 3; - YYMARKER = ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(206, *YYCURSOR); - if (yybm[0+yych] & 32) { - goto yy205; - } - if (yych <= '$') { - if (yych <= '\r') { - if (yych == '\n') goto yy186; - if (yych <= '\f') goto yy194; - goto yy186; - } else { - if (yych == '"') goto yy186; - if (yych <= '#') goto yy194; - goto yy197; - } - } else { - if (yych <= ';') { - if (yych == '\'') goto yy186; - if (yych <= ':') goto yy194; - goto yy186; - } else { - if (yych <= '[') goto yy194; - if (yych <= '\\') goto yy196; - if (yych <= ']') goto yy186; - goto yy194; - } - } -yy207: - YYDEBUG(207, *YYCURSOR); - yyaccept = 2; - YYMARKER = ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(208, *YYCURSOR); - if (yybm[0+yych] & 64) { - goto yy207; - } - if (yych <= '$') { - if (yych <= '\r') { - if (yych == '\n') goto yy184; - if (yych <= '\f') goto yy194; - goto yy184; - } else { - if (yych == '"') goto yy184; - if (yych <= '#') goto yy194; - goto yy197; - } - } else { - if (yych <= ';') { - if (yych == '\'') goto yy184; - if (yych <= ':') goto yy194; - goto yy184; - } else { - if (yych <= '[') goto yy194; - if (yych <= '\\') goto yy196; - if (yych <= ']') goto yy184; - goto yy194; - } - } -yy209: - YYDEBUG(209, *YYCURSOR); - yyaccept = 2; - YYMARKER = ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(210, *YYCURSOR); - if (yych <= '\'') { - if (yych <= '!') { - if (yych <= '\n') { - if (yych <= '\t') goto yy194; - goto yy184; - } else { - if (yych == '\r') goto yy184; - goto yy194; - } - } else { - if (yych <= '#') { - if (yych <= '"') goto yy184; - goto yy194; - } else { - if (yych <= '$') goto yy197; - if (yych <= '&') goto yy194; - goto yy184; - } - } - } else { - if (yych <= ':') { - if (yych <= '.') { - if (yych <= '-') goto yy194; - goto yy207; - } else { - if (yych <= '/') goto yy194; - if (yych <= '9') goto yy209; - goto yy194; - } - } else { - if (yych <= '[') { - if (yych <= ';') goto yy184; - goto yy194; - } else { - if (yych <= '\\') goto yy196; - if (yych <= ']') goto yy184; - goto yy194; - } - } - } -yy211: - YYDEBUG(211, *YYCURSOR); - yyaccept = 2; - YYMARKER = ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(212, *YYCURSOR); - if (yych <= '&') { - if (yych <= '\r') { - if (yych == '\n') goto yy184; - if (yych <= '\f') goto yy194; - goto yy184; - } else { - if (yych <= '"') { - if (yych <= '!') goto yy194; - goto yy184; - } else { - if (yych == '$') goto yy197; - goto yy194; - } - } - } else { - if (yych <= ':') { - if (yych <= '\'') goto yy184; - if (yych <= '/') goto yy194; - if (yych <= '9') goto yy211; - goto yy194; - } else { - if (yych <= '[') { - if (yych <= ';') goto yy184; - goto yy194; - } else { - if (yych <= '\\') goto yy196; - if (yych <= ']') goto yy184; - goto yy194; - } - } - } -yy213: - YYDEBUG(213, *YYCURSOR); - yyaccept = 2; - YYMARKER = ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(214, *YYCURSOR); - if (yych <= '&') { - if (yych <= '\r') { - if (yych == '\n') goto yy184; - if (yych <= '\f') goto yy194; - goto yy184; - } else { - if (yych <= '"') { - if (yych <= '!') goto yy194; - goto yy184; - } else { - if (yych == '$') goto yy197; - goto yy194; - } - } - } else { - if (yych <= ':') { - if (yych <= '\'') goto yy184; - if (yych <= '/') goto yy194; - if (yych <= '9') goto yy213; - goto yy194; - } else { - if (yych <= '[') { - if (yych <= ';') goto yy184; - goto yy194; - } else { - if (yych <= '\\') goto yy196; - if (yych <= ']') goto yy184; - goto yy194; - } - } - } -yy215: - YYDEBUG(215, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(216, *YYCURSOR); - if (yybm[0+yych] & 128) { - goto yy215; - } - YYDEBUG(217, *YYCURSOR); - ++YYCURSOR; - YYDEBUG(218, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 368 "Zend/zend_ini_scanner.l" - { /* Raw string */ - /* Eat leading and trailing single quotes */ - if (yytext[0] == '\'' && yytext[yyleng - 1] == '\'') { - SCNG(yy_text)++; - yyleng = yyleng - 2; - } - RETURN_TOKEN(TC_RAW, yytext, yyleng); -} -#line 2724 "Zend/zend_ini_scanner.c" -yy219: - YYDEBUG(219, *YYCURSOR); - ++YYCURSOR; - YYDEBUG(220, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 401 "Zend/zend_ini_scanner.l" - { /* Variable start */ - yy_push_state(ST_VARNAME TSRMLS_CC); - return TC_DOLLAR_CURLY; -} -#line 2735 "Zend/zend_ini_scanner.c" -yy221: - YYDEBUG(221, *YYCURSOR); - yyaccept = 0; - YYMARKER = ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(222, *YYCURSOR); - if (yych <= '"') { - if (yych <= '\f') { - if (yych <= 0x08) goto yy194; - if (yych <= '\t') goto yy221; - if (yych <= '\n') goto yy173; - goto yy194; - } else { - if (yych <= 0x1F) { - if (yych <= '\r') goto yy173; - goto yy194; - } else { - if (yych <= ' ') goto yy221; - if (yych <= '!') goto yy194; - } - } - } else { - if (yych <= ':') { - if (yych <= '$') { - if (yych <= '#') goto yy194; - goto yy197; - } else { - if (yych == '\'') goto yy173; - goto yy194; - } - } else { - if (yych <= '[') { - if (yych <= ';') goto yy173; - goto yy194; - } else { - if (yych <= '\\') goto yy196; - if (yych <= ']') goto yy173; - goto yy194; - } - } - } -yy223: - YYDEBUG(223, *YYCURSOR); - ++YYCURSOR; - yych = *YYCURSOR; - goto yy178; - } -/* *********************************** */ -yyc_ST_VALUE: - { - static const unsigned char yybm[] = { - 160, 162, 162, 162, 162, 162, 162, 162, - 162, 176, 128, 162, 162, 128, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - 176, 160, 160, 162, 168, 162, 160, 32, - 160, 160, 162, 162, 162, 162, 162, 162, - 230, 230, 230, 230, 230, 230, 230, 230, - 230, 230, 162, 160, 162, 160, 162, 162, - 162, 166, 166, 166, 166, 166, 166, 166, - 166, 166, 166, 166, 166, 166, 166, 166, - 166, 166, 166, 166, 166, 166, 166, 166, - 166, 166, 166, 162, 162, 162, 160, 166, - 162, 166, 166, 166, 166, 166, 166, 166, - 166, 166, 166, 166, 166, 166, 166, 166, - 166, 166, 166, 166, 166, 166, 166, 166, - 166, 166, 166, 162, 160, 162, 160, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, - }; - YYDEBUG(224, *YYCURSOR); - YYFILL(6); - yych = *YYCURSOR; - YYDEBUG(-1, yych); - switch (yych) { - case 0x00: goto yy226; - case '\t': - case ' ': goto yy230; - case '\n': goto yy232; - case '\r': goto yy234; - case '!': - case '&': - case '(': - case ')': - case '^': - case '|': - case '~': goto yy235; - case '"': goto yy237; - case '$': goto yy239; - case '\'': goto yy240; - case '-': goto yy241; - case '.': goto yy242; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': goto yy243; - case ';': goto yy245; - case '=': goto yy246; - case 'A': - case 'B': - case 'C': - case 'D': - case 'E': - case 'G': - case 'H': - case 'I': - case 'J': - case 'K': - case 'L': - case 'M': - case 'P': - case 'Q': - case 'R': - case 'S': - case 'U': - case 'V': - case 'W': - case 'X': - case 'Z': - case '_': - case 'a': - case 'b': - case 'c': - case 'd': - case 'e': - case 'g': - case 'h': - case 'i': - case 'j': - case 'k': - case 'l': - case 'm': - case 'p': - case 'q': - case 'r': - case 's': - case 'u': - case 'v': - case 'w': - case 'x': - case 'z': goto yy248; - case 'F': - case 'f': goto yy250; - case 'N': - case 'n': goto yy251; - case 'O': - case 'o': goto yy252; - case 'T': - case 't': goto yy253; - case 'Y': - case 'y': goto yy254; - default: goto yy228; - } -yy226: - YYDEBUG(226, *YYCURSOR); - ++YYCURSOR; -yy227: - YYDEBUG(227, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 598 "Zend/zend_ini_scanner.l" - { /* End of option value (if EOF is reached before EOL */ - BEGIN(INITIAL); - return END_OF_LINE; -} -#line 2921 "Zend/zend_ini_scanner.c" -yy228: - YYDEBUG(228, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - goto yy256; -yy229: - YYDEBUG(229, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 517 "Zend/zend_ini_scanner.l" - { /* Get everything else as option/offset value */ - RETURN_TOKEN(TC_STRING, yytext, yyleng); -} -#line 2934 "Zend/zend_ini_scanner.c" -yy230: - YYDEBUG(230, *YYCURSOR); - yyaccept = 1; - yych = *(YYMARKER = ++YYCURSOR); - goto yy306; -yy231: - YYDEBUG(231, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 571 "Zend/zend_ini_scanner.l" - { - RETURN_TOKEN(TC_WHITESPACE, yytext, yyleng); -} -#line 2947 "Zend/zend_ini_scanner.c" -yy232: - YYDEBUG(232, *YYCURSOR); - ++YYCURSOR; -yy233: - YYDEBUG(233, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 489 "Zend/zend_ini_scanner.l" - { /* End of option value */ - BEGIN(INITIAL); - SCNG(lineno)++; - return END_OF_LINE; -} -#line 2960 "Zend/zend_ini_scanner.c" -yy234: - YYDEBUG(234, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == '\n') goto yy304; - goto yy233; -yy235: - YYDEBUG(235, *YYCURSOR); - ++YYCURSOR; - yych = *YYCURSOR; - goto yy303; -yy236: - YYDEBUG(236, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 507 "Zend/zend_ini_scanner.l" - { /* Boolean operators */ - return yytext[0]; -} -#line 2978 "Zend/zend_ini_scanner.c" -yy237: - YYDEBUG(237, *YYCURSOR); - ++YYCURSOR; -yy238: - YYDEBUG(238, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 525 "Zend/zend_ini_scanner.l" - { /* Double quoted '"' string start */ - yy_push_state(ST_DOUBLE_QUOTES TSRMLS_CC); - return '"'; -} -#line 2990 "Zend/zend_ini_scanner.c" -yy239: - YYDEBUG(239, *YYCURSOR); - yych = *++YYCURSOR; - if (yych <= '\\') { - if (yych <= 0x00) goto yy227; - if (yych <= '[') goto yy255; - goto yy262; - } else { - if (yych == '{') goto yy300; - goto yy255; - } -yy240: - YYDEBUG(240, *YYCURSOR); - yyaccept = 2; - yych = *(YYMARKER = ++YYCURSOR); - if (yybm[0+yych] & 128) { - goto yy296; - } - goto yy227; -yy241: - YYDEBUG(241, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '/') goto yy256; - if (yych <= '9') goto yy294; - goto yy256; -yy242: - YYDEBUG(242, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '/') goto yy256; - if (yych <= '9') goto yy292; - goto yy256; -yy243: - YYDEBUG(243, *YYCURSOR); - yyaccept = 3; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '/') { - if (yych <= 0x1F) { - if (yych <= '\n') { - if (yych <= 0x00) goto yy244; - if (yych <= 0x08) goto yy256; - } else { - if (yych != '\r') goto yy256; - } - } else { - if (yych <= ')') { - if (yych <= '"') goto yy244; - if (yych <= '%') goto yy256; - } else { - if (yych == '.') goto yy288; - goto yy256; - } - } - } else { - if (yych <= ']') { - if (yych <= ';') { - if (yych <= '9') goto yy290; - if (yych <= ':') goto yy256; - } else { - if (yych != '=') goto yy256; - } - } else { - if (yych <= '|') { - if (yych <= '^') goto yy244; - if (yych <= '{') goto yy256; - } else { - if (yych != '~') goto yy256; - } - } - } -yy244: - YYDEBUG(244, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 499 "Zend/zend_ini_scanner.l" - { /* Get number option value as string */ - RETURN_TOKEN(TC_NUMBER, yytext, yyleng); -} -#line 3069 "Zend/zend_ini_scanner.c" -yy245: - YYDEBUG(245, *YYCURSOR); - yyaccept = 2; - yych = *(YYMARKER = ++YYCURSOR); - goto yy284; -yy246: - YYDEBUG(246, *YYCURSOR); - ++YYCURSOR; - YYDEBUG(247, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 511 "Zend/zend_ini_scanner.l" - { /* Make = used in option value to trigger error */ - yyless(0); - BEGIN(INITIAL); - return END_OF_LINE; -} -#line 3086 "Zend/zend_ini_scanner.c" -yy248: - YYDEBUG(248, *YYCURSOR); - yyaccept = 4; - yych = *(YYMARKER = ++YYCURSOR); - if (yybm[0+yych] & 4) { - goto yy257; - } - if (yych <= ':') { - if (yych <= '\r') { - if (yych <= 0x08) { - if (yych >= 0x01) goto yy256; - } else { - if (yych <= '\n') goto yy249; - if (yych <= '\f') goto yy256; - } - } else { - if (yych <= '"') { - if (yych <= 0x1F) goto yy256; - } else { - if (yych <= '%') goto yy256; - if (yych >= '*') goto yy256; - } - } - } else { - if (yych <= '^') { - if (yych <= '<') { - if (yych >= '<') goto yy256; - } else { - if (yych <= '=') goto yy249; - if (yych <= ']') goto yy256; - } - } else { - if (yych <= '|') { - if (yych <= '{') goto yy256; - } else { - if (yych != '~') goto yy256; - } - } - } -yy249: - YYDEBUG(249, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 495 "Zend/zend_ini_scanner.l" - { /* Get constant option value */ - RETURN_TOKEN(TC_CONSTANT, yytext, yyleng); -} -#line 3133 "Zend/zend_ini_scanner.c" -yy250: - YYDEBUG(250, *YYCURSOR); - yyaccept = 4; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '<') { - if (yych <= '"') { - if (yych <= '\n') { - if (yych <= 0x00) goto yy249; - if (yych <= 0x08) goto yy256; - goto yy249; - } else { - if (yych == '\r') goto yy249; - if (yych <= 0x1F) goto yy256; - goto yy249; - } - } else { - if (yych <= '/') { - if (yych <= '%') goto yy256; - if (yych <= ')') goto yy249; - goto yy256; - } else { - if (yych <= '9') goto yy257; - if (yych == ';') goto yy249; - goto yy256; - } - } - } else { - if (yych <= '_') { - if (yych <= 'A') { - if (yych <= '=') goto yy249; - if (yych <= '@') goto yy256; - goto yy280; - } else { - if (yych <= 'Z') goto yy257; - if (yych <= ']') goto yy256; - if (yych <= '^') goto yy249; - goto yy257; - } - } else { - if (yych <= '{') { - if (yych <= '`') goto yy256; - if (yych <= 'a') goto yy280; - if (yych <= 'z') goto yy257; - goto yy256; - } else { - if (yych == '}') goto yy256; - if (yych <= '~') goto yy249; - goto yy256; - } - } - } -yy251: - YYDEBUG(251, *YYCURSOR); - yyaccept = 4; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= 'N') { - if (yych <= '%') { - if (yych <= '\f') { - if (yych <= 0x00) goto yy249; - if (yych <= 0x08) goto yy256; - if (yych <= '\n') goto yy249; - goto yy256; - } else { - if (yych <= '\r') goto yy249; - if (yych <= 0x1F) goto yy256; - if (yych <= '"') goto yy249; - goto yy256; - } - } else { - if (yych <= ':') { - if (yych <= ')') goto yy249; - if (yych <= '/') goto yy256; - if (yych <= '9') goto yy257; - goto yy256; - } else { - if (yych <= '<') { - if (yych <= ';') goto yy249; - goto yy256; - } else { - if (yych <= '=') goto yy249; - if (yych <= '@') goto yy256; - goto yy257; - } - } - } - } else { - if (yych <= 'n') { - if (yych <= 'Z') { - if (yych <= 'O') goto yy276; - if (yych == 'U') goto yy277; - goto yy257; - } else { - if (yych <= '^') { - if (yych <= ']') goto yy256; - goto yy249; - } else { - if (yych == '`') goto yy256; - goto yy257; - } - } - } else { - if (yych <= 'z') { - if (yych <= 'o') goto yy276; - if (yych == 'u') goto yy277; - goto yy257; - } else { - if (yych <= '|') { - if (yych <= '{') goto yy256; - goto yy249; - } else { - if (yych == '~') goto yy249; - goto yy256; - } - } - } - } -yy252: - YYDEBUG(252, *YYCURSOR); - yyaccept = 4; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= 'E') { - if (yych <= '%') { - if (yych <= '\f') { - if (yych <= 0x00) goto yy249; - if (yych <= 0x08) goto yy256; - if (yych <= '\n') goto yy249; - goto yy256; - } else { - if (yych <= '\r') goto yy249; - if (yych <= 0x1F) goto yy256; - if (yych <= '"') goto yy249; - goto yy256; - } - } else { - if (yych <= ':') { - if (yych <= ')') goto yy249; - if (yych <= '/') goto yy256; - if (yych <= '9') goto yy257; - goto yy256; - } else { - if (yych <= '<') { - if (yych <= ';') goto yy249; - goto yy256; - } else { - if (yych <= '=') goto yy249; - if (yych <= '@') goto yy256; - goto yy257; - } - } - } - } else { - if (yych <= 'e') { - if (yych <= 'Z') { - if (yych <= 'F') goto yy271; - if (yych == 'N') goto yy265; - goto yy257; - } else { - if (yych <= '^') { - if (yych <= ']') goto yy256; - goto yy249; - } else { - if (yych == '`') goto yy256; - goto yy257; - } - } - } else { - if (yych <= 'z') { - if (yych <= 'f') goto yy271; - if (yych == 'n') goto yy265; - goto yy257; - } else { - if (yych <= '|') { - if (yych <= '{') goto yy256; - goto yy249; - } else { - if (yych == '~') goto yy249; - goto yy256; - } - } - } - } -yy253: - YYDEBUG(253, *YYCURSOR); - yyaccept = 4; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '=') { - if (yych <= '"') { - if (yych <= '\n') { - if (yych <= 0x00) goto yy249; - if (yych <= 0x08) goto yy256; - goto yy249; - } else { - if (yych == '\r') goto yy249; - if (yych <= 0x1F) goto yy256; - goto yy249; - } - } else { - if (yych <= '9') { - if (yych <= '%') goto yy256; - if (yych <= ')') goto yy249; - if (yych <= '/') goto yy256; - goto yy257; - } else { - if (yych == ';') goto yy249; - if (yych <= '<') goto yy256; - goto yy249; - } - } - } else { - if (yych <= '`') { - if (yych <= 'Z') { - if (yych <= '@') goto yy256; - if (yych == 'R') goto yy269; - goto yy257; - } else { - if (yych <= ']') goto yy256; - if (yych <= '^') goto yy249; - if (yych <= '_') goto yy257; - goto yy256; - } - } else { - if (yych <= '{') { - if (yych == 'r') goto yy269; - if (yych <= 'z') goto yy257; - goto yy256; - } else { - if (yych == '}') goto yy256; - if (yych <= '~') goto yy249; - goto yy256; - } - } - } -yy254: - YYDEBUG(254, *YYCURSOR); - yyaccept = 4; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '=') { - if (yych <= '"') { - if (yych <= '\n') { - if (yych <= 0x00) goto yy249; - if (yych <= 0x08) goto yy256; - goto yy249; - } else { - if (yych == '\r') goto yy249; - if (yych <= 0x1F) goto yy256; - goto yy249; - } - } else { - if (yych <= '9') { - if (yych <= '%') goto yy256; - if (yych <= ')') goto yy249; - if (yych <= '/') goto yy256; - goto yy257; - } else { - if (yych == ';') goto yy249; - if (yych <= '<') goto yy256; - goto yy249; - } - } - } else { - if (yych <= '`') { - if (yych <= 'Z') { - if (yych <= '@') goto yy256; - if (yych == 'E') goto yy259; - goto yy257; - } else { - if (yych <= ']') goto yy256; - if (yych <= '^') goto yy249; - if (yych <= '_') goto yy257; - goto yy256; - } - } else { - if (yych <= '{') { - if (yych == 'e') goto yy259; - if (yych <= 'z') goto yy257; - goto yy256; - } else { - if (yych == '}') goto yy256; - if (yych <= '~') goto yy249; - goto yy256; - } - } - } -yy255: - YYDEBUG(255, *YYCURSOR); - yyaccept = 0; - YYMARKER = ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; -yy256: - YYDEBUG(256, *YYCURSOR); - if (yybm[0+yych] & 2) { - goto yy255; - } - if (yych == '$') goto yy260; - goto yy229; -yy257: - YYDEBUG(257, *YYCURSOR); - yyaccept = 4; - YYMARKER = ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(258, *YYCURSOR); - if (yybm[0+yych] & 4) { - goto yy257; - } - if (yych <= ')') { - if (yych <= '\r') { - if (yych <= 0x08) { - if (yych <= 0x00) goto yy249; - goto yy255; - } else { - if (yych <= '\n') goto yy249; - if (yych <= '\f') goto yy255; - goto yy249; - } - } else { - if (yych <= '#') { - if (yych <= 0x1F) goto yy255; - if (yych <= '"') goto yy249; - goto yy255; - } else { - if (yych <= '$') goto yy260; - if (yych <= '%') goto yy255; - goto yy249; - } - } - } else { - if (yych <= ']') { - if (yych <= ';') { - if (yych <= ':') goto yy255; - goto yy249; - } else { - if (yych == '=') goto yy249; - goto yy255; - } - } else { - if (yych <= '|') { - if (yych <= '^') goto yy249; - if (yych <= '{') goto yy255; - goto yy249; - } else { - if (yych == '~') goto yy249; - goto yy255; - } - } - } -yy259: - YYDEBUG(259, *YYCURSOR); - yyaccept = 4; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '=') { - if (yych <= '"') { - if (yych <= '\n') { - if (yych <= 0x00) goto yy249; - if (yych <= 0x08) goto yy256; - goto yy249; - } else { - if (yych == '\r') goto yy249; - if (yych <= 0x1F) goto yy256; - goto yy249; - } - } else { - if (yych <= '9') { - if (yych <= '%') goto yy256; - if (yych <= ')') goto yy249; - if (yych <= '/') goto yy256; - goto yy257; - } else { - if (yych == ';') goto yy249; - if (yych <= '<') goto yy256; - goto yy249; - } - } - } else { - if (yych <= '`') { - if (yych <= 'Z') { - if (yych <= '@') goto yy256; - if (yych == 'S') goto yy265; - goto yy257; - } else { - if (yych <= ']') goto yy256; - if (yych <= '^') goto yy249; - if (yych <= '_') goto yy257; - goto yy256; - } - } else { - if (yych <= '{') { - if (yych == 's') goto yy265; - if (yych <= 'z') goto yy257; - goto yy256; - } else { - if (yych == '}') goto yy256; - if (yych <= '~') goto yy249; - goto yy256; - } - } - } -yy260: - YYDEBUG(260, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - if (yych <= '\\') { - if (yych <= 0x00) goto yy261; - if (yych <= '[') goto yy255; - goto yy262; - } else { - if (yych != '{') goto yy255; - } -yy261: - YYDEBUG(261, *YYCURSOR); - YYCURSOR = YYMARKER; - if (yyaccept <= 3) { - if (yyaccept <= 1) { - if (yyaccept <= 0) { - goto yy229; - } else { - goto yy231; - } - } else { - if (yyaccept <= 2) { - goto yy227; - } else { - goto yy244; - } - } - } else { - if (yyaccept <= 5) { - if (yyaccept <= 4) { - goto yy249; - } else { - goto yy266; - } - } else { - goto yy273; - } - } -yy262: - YYDEBUG(262, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - if (yybm[0+yych] & 8) { - goto yy263; - } - goto yy255; -yy263: - YYDEBUG(263, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(264, *YYCURSOR); - if (yybm[0+yych] & 8) { - goto yy263; - } - if (yych <= 0x00) goto yy229; - if (yych == '\\') goto yy262; - goto yy255; -yy265: - YYDEBUG(265, *YYCURSOR); - yyaccept = 5; - yych = *(YYMARKER = ++YYCURSOR); - if (yybm[0+yych] & 16) { - goto yy267; - } - if (yych <= ';') { - if (yych <= ' ') { - if (yych <= '\n') { - if (yych <= 0x00) goto yy266; - if (yych <= '\t') goto yy256; - } else { - if (yych != '\r') goto yy256; - } - } else { - if (yych <= ')') { - if (yych <= '"') goto yy266; - if (yych <= '%') goto yy256; - } else { - if (yych <= '/') goto yy256; - if (yych <= '9') goto yy257; - if (yych <= ':') goto yy256; - } - } - } else { - if (yych <= '_') { - if (yych <= '@') { - if (yych != '=') goto yy256; - } else { - if (yych <= 'Z') goto yy257; - if (yych <= ']') goto yy256; - if (yych >= '_') goto yy257; - } - } else { - if (yych <= '{') { - if (yych <= '`') goto yy256; - if (yych <= 'z') goto yy257; - goto yy256; - } else { - if (yych == '}') goto yy256; - if (yych >= 0x7F) goto yy256; - } - } - } -yy266: - YYDEBUG(266, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 421 "Zend/zend_ini_scanner.l" - { /* TRUE value (when used outside option value/offset this causes parse error!) */ - RETURN_TOKEN(BOOL_TRUE, "1", 1); -} -#line 3645 "Zend/zend_ini_scanner.c" -yy267: - YYDEBUG(267, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(268, *YYCURSOR); - if (yybm[0+yych] & 16) { - goto yy267; - } - goto yy266; -yy269: - YYDEBUG(269, *YYCURSOR); - yyaccept = 4; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '=') { - if (yych <= '"') { - if (yych <= '\n') { - if (yych <= 0x00) goto yy249; - if (yych <= 0x08) goto yy256; - goto yy249; - } else { - if (yych == '\r') goto yy249; - if (yych <= 0x1F) goto yy256; - goto yy249; - } - } else { - if (yych <= '9') { - if (yych <= '%') goto yy256; - if (yych <= ')') goto yy249; - if (yych <= '/') goto yy256; - goto yy257; - } else { - if (yych == ';') goto yy249; - if (yych <= '<') goto yy256; - goto yy249; - } - } - } else { - if (yych <= '`') { - if (yych <= 'Z') { - if (yych <= '@') goto yy256; - if (yych != 'U') goto yy257; - } else { - if (yych <= ']') goto yy256; - if (yych <= '^') goto yy249; - if (yych <= '_') goto yy257; - goto yy256; - } - } else { - if (yych <= '{') { - if (yych == 'u') goto yy270; - if (yych <= 'z') goto yy257; - goto yy256; - } else { - if (yych == '}') goto yy256; - if (yych <= '~') goto yy249; - goto yy256; - } - } - } -yy270: - YYDEBUG(270, *YYCURSOR); - yyaccept = 4; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '=') { - if (yych <= '"') { - if (yych <= '\n') { - if (yych <= 0x00) goto yy249; - if (yych <= 0x08) goto yy256; - goto yy249; - } else { - if (yych == '\r') goto yy249; - if (yych <= 0x1F) goto yy256; - goto yy249; - } - } else { - if (yych <= '9') { - if (yych <= '%') goto yy256; - if (yych <= ')') goto yy249; - if (yych <= '/') goto yy256; - goto yy257; - } else { - if (yych == ';') goto yy249; - if (yych <= '<') goto yy256; - goto yy249; - } - } - } else { - if (yych <= '`') { - if (yych <= 'Z') { - if (yych <= '@') goto yy256; - if (yych == 'E') goto yy265; - goto yy257; - } else { - if (yych <= ']') goto yy256; - if (yych <= '^') goto yy249; - if (yych <= '_') goto yy257; - goto yy256; - } - } else { - if (yych <= '{') { - if (yych == 'e') goto yy265; - if (yych <= 'z') goto yy257; - goto yy256; - } else { - if (yych == '}') goto yy256; - if (yych <= '~') goto yy249; - goto yy256; - } - } - } -yy271: - YYDEBUG(271, *YYCURSOR); - yyaccept = 4; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '=') { - if (yych <= '"') { - if (yych <= '\n') { - if (yych <= 0x00) goto yy249; - if (yych <= 0x08) goto yy256; - goto yy249; - } else { - if (yych == '\r') goto yy249; - if (yych <= 0x1F) goto yy256; - goto yy249; - } - } else { - if (yych <= '9') { - if (yych <= '%') goto yy256; - if (yych <= ')') goto yy249; - if (yych <= '/') goto yy256; - goto yy257; - } else { - if (yych == ';') goto yy249; - if (yych <= '<') goto yy256; - goto yy249; - } - } - } else { - if (yych <= '`') { - if (yych <= 'Z') { - if (yych <= '@') goto yy256; - if (yych != 'F') goto yy257; - } else { - if (yych <= ']') goto yy256; - if (yych <= '^') goto yy249; - if (yych <= '_') goto yy257; - goto yy256; - } - } else { - if (yych <= '{') { - if (yych == 'f') goto yy272; - if (yych <= 'z') goto yy257; - goto yy256; - } else { - if (yych == '}') goto yy256; - if (yych <= '~') goto yy249; - goto yy256; - } - } - } -yy272: - YYDEBUG(272, *YYCURSOR); - yyaccept = 6; - yych = *(YYMARKER = ++YYCURSOR); - if (yybm[0+yych] & 4) { - goto yy257; - } - if (yych <= ')') { - if (yych <= '\f') { - if (yych <= 0x08) { - if (yych >= 0x01) goto yy256; - } else { - if (yych <= '\t') goto yy274; - if (yych >= '\v') goto yy256; - } - } else { - if (yych <= ' ') { - if (yych <= '\r') goto yy273; - if (yych <= 0x1F) goto yy256; - goto yy274; - } else { - if (yych <= '"') goto yy273; - if (yych <= '%') goto yy256; - } - } - } else { - if (yych <= ']') { - if (yych <= ';') { - if (yych <= ':') goto yy256; - } else { - if (yych != '=') goto yy256; - } - } else { - if (yych <= '|') { - if (yych <= '^') goto yy273; - if (yych <= '{') goto yy256; - } else { - if (yych != '~') goto yy256; - } - } - } -yy273: - YYDEBUG(273, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 425 "Zend/zend_ini_scanner.l" - { /* FALSE value (when used outside option value/offset this causes parse error!)*/ - RETURN_TOKEN(BOOL_FALSE, "", 0); -} -#line 3855 "Zend/zend_ini_scanner.c" -yy274: - YYDEBUG(274, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(275, *YYCURSOR); - if (yych == '\t') goto yy274; - if (yych == ' ') goto yy274; - goto yy273; -yy276: - YYDEBUG(276, *YYCURSOR); - yyaccept = 6; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '<') { - if (yych <= ' ') { - if (yych <= '\n') { - if (yych <= 0x00) goto yy273; - if (yych <= 0x08) goto yy256; - if (yych <= '\t') goto yy274; - goto yy273; - } else { - if (yych == '\r') goto yy273; - if (yych <= 0x1F) goto yy256; - goto yy274; - } - } else { - if (yych <= '/') { - if (yych <= '"') goto yy273; - if (yych <= '%') goto yy256; - if (yych <= ')') goto yy273; - goto yy256; - } else { - if (yych <= '9') goto yy257; - if (yych == ';') goto yy273; - goto yy256; - } - } - } else { - if (yych <= '_') { - if (yych <= 'N') { - if (yych <= '=') goto yy273; - if (yych <= '@') goto yy256; - if (yych <= 'M') goto yy257; - goto yy279; - } else { - if (yych <= 'Z') goto yy257; - if (yych <= ']') goto yy256; - if (yych <= '^') goto yy273; - goto yy257; - } - } else { - if (yych <= 'z') { - if (yych <= '`') goto yy256; - if (yych == 'n') goto yy279; - goto yy257; - } else { - if (yych <= '|') { - if (yych <= '{') goto yy256; - goto yy273; - } else { - if (yych == '~') goto yy273; - goto yy256; - } - } - } - } -yy277: - YYDEBUG(277, *YYCURSOR); - yyaccept = 4; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '=') { - if (yych <= '"') { - if (yych <= '\n') { - if (yych <= 0x00) goto yy249; - if (yych <= 0x08) goto yy256; - goto yy249; - } else { - if (yych == '\r') goto yy249; - if (yych <= 0x1F) goto yy256; - goto yy249; - } - } else { - if (yych <= '9') { - if (yych <= '%') goto yy256; - if (yych <= ')') goto yy249; - if (yych <= '/') goto yy256; - goto yy257; - } else { - if (yych == ';') goto yy249; - if (yych <= '<') goto yy256; - goto yy249; - } - } - } else { - if (yych <= '`') { - if (yych <= 'Z') { - if (yych <= '@') goto yy256; - if (yych != 'L') goto yy257; - } else { - if (yych <= ']') goto yy256; - if (yych <= '^') goto yy249; - if (yych <= '_') goto yy257; - goto yy256; - } - } else { - if (yych <= '{') { - if (yych == 'l') goto yy278; - if (yych <= 'z') goto yy257; - goto yy256; - } else { - if (yych == '}') goto yy256; - if (yych <= '~') goto yy249; - goto yy256; - } - } - } -yy278: - YYDEBUG(278, *YYCURSOR); - yyaccept = 4; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '=') { - if (yych <= '"') { - if (yych <= '\n') { - if (yych <= 0x00) goto yy249; - if (yych <= 0x08) goto yy256; - goto yy249; - } else { - if (yych == '\r') goto yy249; - if (yych <= 0x1F) goto yy256; - goto yy249; - } - } else { - if (yych <= '9') { - if (yych <= '%') goto yy256; - if (yych <= ')') goto yy249; - if (yych <= '/') goto yy256; - goto yy257; - } else { - if (yych == ';') goto yy249; - if (yych <= '<') goto yy256; - goto yy249; - } - } - } else { - if (yych <= '`') { - if (yych <= 'Z') { - if (yych <= '@') goto yy256; - if (yych == 'L') goto yy272; - goto yy257; - } else { - if (yych <= ']') goto yy256; - if (yych <= '^') goto yy249; - if (yych <= '_') goto yy257; - goto yy256; - } - } else { - if (yych <= '{') { - if (yych == 'l') goto yy272; - if (yych <= 'z') goto yy257; - goto yy256; - } else { - if (yych == '}') goto yy256; - if (yych <= '~') goto yy249; - goto yy256; - } - } - } -yy279: - YYDEBUG(279, *YYCURSOR); - yyaccept = 4; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '=') { - if (yych <= '"') { - if (yych <= '\n') { - if (yych <= 0x00) goto yy249; - if (yych <= 0x08) goto yy256; - goto yy249; - } else { - if (yych == '\r') goto yy249; - if (yych <= 0x1F) goto yy256; - goto yy249; - } - } else { - if (yych <= '9') { - if (yych <= '%') goto yy256; - if (yych <= ')') goto yy249; - if (yych <= '/') goto yy256; - goto yy257; - } else { - if (yych == ';') goto yy249; - if (yych <= '<') goto yy256; - goto yy249; - } - } - } else { - if (yych <= '`') { - if (yych <= 'Z') { - if (yych <= '@') goto yy256; - if (yych == 'E') goto yy272; - goto yy257; - } else { - if (yych <= ']') goto yy256; - if (yych <= '^') goto yy249; - if (yych <= '_') goto yy257; - goto yy256; - } - } else { - if (yych <= '{') { - if (yych == 'e') goto yy272; - if (yych <= 'z') goto yy257; - goto yy256; - } else { - if (yych == '}') goto yy256; - if (yych <= '~') goto yy249; - goto yy256; - } - } - } -yy280: - YYDEBUG(280, *YYCURSOR); - yyaccept = 4; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '=') { - if (yych <= '"') { - if (yych <= '\n') { - if (yych <= 0x00) goto yy249; - if (yych <= 0x08) goto yy256; - goto yy249; - } else { - if (yych == '\r') goto yy249; - if (yych <= 0x1F) goto yy256; - goto yy249; - } - } else { - if (yych <= '9') { - if (yych <= '%') goto yy256; - if (yych <= ')') goto yy249; - if (yych <= '/') goto yy256; - goto yy257; - } else { - if (yych == ';') goto yy249; - if (yych <= '<') goto yy256; - goto yy249; - } - } - } else { - if (yych <= '`') { - if (yych <= 'Z') { - if (yych <= '@') goto yy256; - if (yych != 'L') goto yy257; - } else { - if (yych <= ']') goto yy256; - if (yych <= '^') goto yy249; - if (yych <= '_') goto yy257; - goto yy256; - } - } else { - if (yych <= '{') { - if (yych == 'l') goto yy281; - if (yych <= 'z') goto yy257; - goto yy256; - } else { - if (yych == '}') goto yy256; - if (yych <= '~') goto yy249; - goto yy256; - } - } - } -yy281: - YYDEBUG(281, *YYCURSOR); - yyaccept = 4; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '=') { - if (yych <= '"') { - if (yych <= '\n') { - if (yych <= 0x00) goto yy249; - if (yych <= 0x08) goto yy256; - goto yy249; - } else { - if (yych == '\r') goto yy249; - if (yych <= 0x1F) goto yy256; - goto yy249; - } - } else { - if (yych <= '9') { - if (yych <= '%') goto yy256; - if (yych <= ')') goto yy249; - if (yych <= '/') goto yy256; - goto yy257; - } else { - if (yych == ';') goto yy249; - if (yych <= '<') goto yy256; - goto yy249; - } - } - } else { - if (yych <= '`') { - if (yych <= 'Z') { - if (yych <= '@') goto yy256; - if (yych != 'S') goto yy257; - } else { - if (yych <= ']') goto yy256; - if (yych <= '^') goto yy249; - if (yych <= '_') goto yy257; - goto yy256; - } - } else { - if (yych <= '{') { - if (yych == 's') goto yy282; - if (yych <= 'z') goto yy257; - goto yy256; - } else { - if (yych == '}') goto yy256; - if (yych <= '~') goto yy249; - goto yy256; - } - } - } -yy282: - YYDEBUG(282, *YYCURSOR); - yyaccept = 4; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '=') { - if (yych <= '"') { - if (yych <= '\n') { - if (yych <= 0x00) goto yy249; - if (yych <= 0x08) goto yy256; - goto yy249; - } else { - if (yych == '\r') goto yy249; - if (yych <= 0x1F) goto yy256; - goto yy249; - } - } else { - if (yych <= '9') { - if (yych <= '%') goto yy256; - if (yych <= ')') goto yy249; - if (yych <= '/') goto yy256; - goto yy257; - } else { - if (yych == ';') goto yy249; - if (yych <= '<') goto yy256; - goto yy249; - } - } - } else { - if (yych <= '`') { - if (yych <= 'Z') { - if (yych <= '@') goto yy256; - if (yych == 'E') goto yy272; - goto yy257; - } else { - if (yych <= ']') goto yy256; - if (yych <= '^') goto yy249; - if (yych <= '_') goto yy257; - goto yy256; - } - } else { - if (yych <= '{') { - if (yych == 'e') goto yy272; - if (yych <= 'z') goto yy257; - goto yy256; - } else { - if (yych == '}') goto yy256; - if (yych <= '~') goto yy249; - goto yy256; - } - } - } -yy283: - YYDEBUG(283, *YYCURSOR); - ++YYCURSOR; - YYFILL(2); - yych = *YYCURSOR; -yy284: - YYDEBUG(284, *YYCURSOR); - if (yybm[0+yych] & 32) { - goto yy283; - } - if (yych >= '\r') goto yy287; -yy285: - YYDEBUG(285, *YYCURSOR); - ++YYCURSOR; -yy286: - YYDEBUG(286, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 585 "Zend/zend_ini_scanner.l" - { /* Comment */ - BEGIN(INITIAL); - SCNG(lineno)++; - return END_OF_LINE; -} -#line 4248 "Zend/zend_ini_scanner.c" -yy287: - YYDEBUG(287, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == '\n') goto yy285; - goto yy286; -yy288: - YYDEBUG(288, *YYCURSOR); - yyaccept = 3; - YYMARKER = ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(289, *YYCURSOR); - if (yybm[0+yych] & 64) { - goto yy288; - } - if (yych <= ')') { - if (yych <= '\r') { - if (yych <= 0x08) { - if (yych <= 0x00) goto yy244; - goto yy255; - } else { - if (yych <= '\n') goto yy244; - if (yych <= '\f') goto yy255; - goto yy244; - } - } else { - if (yych <= '#') { - if (yych <= 0x1F) goto yy255; - if (yych <= '"') goto yy244; - goto yy255; - } else { - if (yych <= '$') goto yy260; - if (yych <= '%') goto yy255; - goto yy244; - } - } - } else { - if (yych <= ']') { - if (yych <= ';') { - if (yych <= ':') goto yy255; - goto yy244; - } else { - if (yych == '=') goto yy244; - goto yy255; - } - } else { - if (yych <= '|') { - if (yych <= '^') goto yy244; - if (yych <= '{') goto yy255; - goto yy244; - } else { - if (yych == '~') goto yy244; - goto yy255; - } - } - } -yy290: - YYDEBUG(290, *YYCURSOR); - yyaccept = 3; - YYMARKER = ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(291, *YYCURSOR); - if (yych <= '.') { - if (yych <= 0x1F) { - if (yych <= '\n') { - if (yych <= 0x00) goto yy244; - if (yych <= 0x08) goto yy255; - goto yy244; - } else { - if (yych == '\r') goto yy244; - goto yy255; - } - } else { - if (yych <= '$') { - if (yych <= '"') goto yy244; - if (yych <= '#') goto yy255; - goto yy260; - } else { - if (yych <= '%') goto yy255; - if (yych <= ')') goto yy244; - if (yych <= '-') goto yy255; - goto yy288; - } - } - } else { - if (yych <= '=') { - if (yych <= ':') { - if (yych <= '/') goto yy255; - if (yych <= '9') goto yy290; - goto yy255; - } else { - if (yych == '<') goto yy255; - goto yy244; - } - } else { - if (yych <= '{') { - if (yych == '^') goto yy244; - goto yy255; - } else { - if (yych == '}') goto yy255; - if (yych <= '~') goto yy244; - goto yy255; - } - } - } -yy292: - YYDEBUG(292, *YYCURSOR); - yyaccept = 3; - YYMARKER = ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(293, *YYCURSOR); - if (yych <= '/') { - if (yych <= 0x1F) { - if (yych <= '\n') { - if (yych <= 0x00) goto yy244; - if (yych <= 0x08) goto yy255; - goto yy244; - } else { - if (yych == '\r') goto yy244; - goto yy255; - } - } else { - if (yych <= '$') { - if (yych <= '"') goto yy244; - if (yych <= '#') goto yy255; - goto yy260; - } else { - if (yych <= '%') goto yy255; - if (yych <= ')') goto yy244; - goto yy255; - } - } - } else { - if (yych <= ']') { - if (yych <= ';') { - if (yych <= '9') goto yy292; - if (yych <= ':') goto yy255; - goto yy244; - } else { - if (yych == '=') goto yy244; - goto yy255; - } - } else { - if (yych <= '|') { - if (yych <= '^') goto yy244; - if (yych <= '{') goto yy255; - goto yy244; - } else { - if (yych == '~') goto yy244; - goto yy255; - } - } - } -yy294: - YYDEBUG(294, *YYCURSOR); - yyaccept = 3; - YYMARKER = ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(295, *YYCURSOR); - if (yych <= '/') { - if (yych <= 0x1F) { - if (yych <= '\n') { - if (yych <= 0x00) goto yy244; - if (yych <= 0x08) goto yy255; - goto yy244; - } else { - if (yych == '\r') goto yy244; - goto yy255; - } - } else { - if (yych <= '$') { - if (yych <= '"') goto yy244; - if (yych <= '#') goto yy255; - goto yy260; - } else { - if (yych <= '%') goto yy255; - if (yych <= ')') goto yy244; - goto yy255; - } - } - } else { - if (yych <= ']') { - if (yych <= ';') { - if (yych <= '9') goto yy294; - if (yych <= ':') goto yy255; - goto yy244; - } else { - if (yych == '=') goto yy244; - goto yy255; - } - } else { - if (yych <= '|') { - if (yych <= '^') goto yy244; - if (yych <= '{') goto yy255; - goto yy244; - } else { - if (yych == '~') goto yy244; - goto yy255; - } - } - } -yy296: - YYDEBUG(296, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(297, *YYCURSOR); - if (yybm[0+yych] & 128) { - goto yy296; - } - YYDEBUG(298, *YYCURSOR); - ++YYCURSOR; - YYDEBUG(299, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 368 "Zend/zend_ini_scanner.l" - { /* Raw string */ - /* Eat leading and trailing single quotes */ - if (yytext[0] == '\'' && yytext[yyleng - 1] == '\'') { - SCNG(yy_text)++; - yyleng = yyleng - 2; - } - RETURN_TOKEN(TC_RAW, yytext, yyleng); -} -#line 4475 "Zend/zend_ini_scanner.c" -yy300: - YYDEBUG(300, *YYCURSOR); - ++YYCURSOR; - YYDEBUG(301, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 401 "Zend/zend_ini_scanner.l" - { /* Variable start */ - yy_push_state(ST_VARNAME TSRMLS_CC); - return TC_DOLLAR_CURLY; -} -#line 4486 "Zend/zend_ini_scanner.c" -yy302: - YYDEBUG(302, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; -yy303: - YYDEBUG(303, *YYCURSOR); - if (yych == '\t') goto yy302; - if (yych == ' ') goto yy302; - goto yy236; -yy304: - YYDEBUG(304, *YYCURSOR); - yych = *++YYCURSOR; - goto yy233; -yy305: - YYDEBUG(305, *YYCURSOR); - yyaccept = 1; - YYMARKER = ++YYCURSOR; - YYFILL(2); - yych = *YYCURSOR; -yy306: - YYDEBUG(306, *YYCURSOR); - if (yych <= 0x1F) { - if (yych <= '\n') { - if (yych <= 0x08) goto yy231; - if (yych <= '\t') goto yy305; - goto yy304; - } else { - if (yych == '\r') goto yy308; - goto yy231; - } - } else { - if (yych <= '"') { - if (yych <= ' ') goto yy305; - if (yych <= '!') goto yy231; - } else { - if (yych == ';') goto yy283; - goto yy231; - } - } - YYDEBUG(307, *YYCURSOR); - yych = *++YYCURSOR; - goto yy238; -yy308: - YYDEBUG(308, *YYCURSOR); - ++YYCURSOR; - if ((yych = *YYCURSOR) == '\n') goto yy304; - goto yy233; - } -/* *********************************** */ -yyc_ST_VARNAME: - { - static const unsigned char yybm[] = { - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 0, 0, 128, 128, 0, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 0, 0, 128, 0, 128, 0, 128, - 0, 0, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 0, 128, 0, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 0, 128, 128, 0, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 0, 0, 0, 0, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - }; - YYDEBUG(309, *YYCURSOR); - YYFILL(2); - yych = *YYCURSOR; - if (yych <= ')') { - if (yych <= '"') { - if (yych <= '\f') { - if (yych <= 0x08) goto yy311; - if (yych <= '\n') goto yy313; - } else { - if (yych <= '\r') goto yy313; - if (yych >= '!') goto yy313; - } - } else { - if (yych <= '%') { - if (yych == '$') goto yy313; - } else { - if (yych != '\'') goto yy313; - } - } - } else { - if (yych <= '[') { - if (yych <= '<') { - if (yych == ';') goto yy313; - } else { - if (yych <= '=') goto yy313; - if (yych >= '[') goto yy313; - } - } else { - if (yych <= 'z') { - if (yych == '^') goto yy313; - } else { - if (yych == '}') goto yy315; - if (yych <= '~') goto yy313; - } - } - } -yy311: - YYDEBUG(311, *YYCURSOR); - ++YYCURSOR; - yych = *YYCURSOR; - goto yy318; -yy312: - YYDEBUG(312, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 406 "Zend/zend_ini_scanner.l" - { /* Variable name */ - /* Eat leading whitespace */ - EAT_LEADING_WHITESPACE(); - - /* Eat trailing whitespace */ - EAT_TRAILING_WHITESPACE(); - - RETURN_TOKEN(TC_VARNAME, yytext, yyleng); -} -#line 4627 "Zend/zend_ini_scanner.c" -yy313: - YYDEBUG(313, *YYCURSOR); - ++YYCURSOR; - YYDEBUG(314, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 603 "Zend/zend_ini_scanner.l" - { - return 0; -} -#line 4637 "Zend/zend_ini_scanner.c" -yy315: - YYDEBUG(315, *YYCURSOR); - ++YYCURSOR; - YYDEBUG(316, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 416 "Zend/zend_ini_scanner.l" - { /* Variable end */ - yy_pop_state(TSRMLS_C); - return '}'; -} -#line 4648 "Zend/zend_ini_scanner.c" -yy317: - YYDEBUG(317, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; -yy318: - YYDEBUG(318, *YYCURSOR); - if (yybm[0+yych] & 128) { - goto yy317; - } - goto yy312; - } -} -#line 607 "Zend/zend_ini_scanner.l" - -} +/* Generated by re2c 0.13.5 */ +#line 1 "Zend/zend_ini_scanner.l" +/* + +----------------------------------------------------------------------+ + | Zend Engine | + +----------------------------------------------------------------------+ + | Copyright (c) 1998-2013 Zend Technologies Ltd. (http://www.zend.com) | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.00 of the Zend license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.zend.com/license/2_00.txt. | + | If you did not receive a copy of the Zend license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@zend.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Zeev Suraski | + | Jani Taskinen | + | Marcus Boerger | + | Nuno Lopes | + | Scott MacVicar | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#include +#include "zend.h" +#include "zend_globals.h" +#include +#include "zend_ini_scanner.h" + +#if 0 +# define YYDEBUG(s, c) printf("state: %d char: %c\n", s, c) +#else +# define YYDEBUG(s, c) +#endif + +#include "zend_ini_scanner_defs.h" + +#define YYCTYPE unsigned char +/* allow the scanner to read one null byte after the end of the string (from ZEND_MMAP_AHEAD) + * so that if will be able to terminate to match the current token (e.g. non-enclosed string) */ +#define YYFILL(n) { if (YYCURSOR > YYLIMIT) return 0; } +#define YYCURSOR SCNG(yy_cursor) +#define YYLIMIT SCNG(yy_limit) +#define YYMARKER SCNG(yy_marker) + +#define YYGETCONDITION() SCNG(yy_state) +#define YYSETCONDITION(s) SCNG(yy_state) = s + +#define STATE(name) yyc##name + +/* emulate flex constructs */ +#define BEGIN(state) YYSETCONDITION(STATE(state)) +#define YYSTATE YYGETCONDITION() +#define yytext ((char*)SCNG(yy_text)) +#define yyleng SCNG(yy_leng) +#define yyless(x) do { YYCURSOR = (unsigned char*)yytext + x; \ + yyleng = (unsigned int)x; } while(0) + +/* #define yymore() goto yymore_restart */ + +/* perform sanity check. If this message is triggered you should + increase the ZEND_MMAP_AHEAD value in the zend_streams.h file */ +#define YYMAXFILL 6 +#if ZEND_MMAP_AHEAD < (YYMAXFILL + 1) +# error ZEND_MMAP_AHEAD should be greater than YYMAXFILL +#endif + + +/* How it works (for the core ini directives): + * =========================================== + * + * 1. Scanner scans file for tokens and passes them to parser. + * 2. Parser parses the tokens and passes the name/value pairs to the callback + * function which stores them in the configuration hash table. + * 3. Later REGISTER_INI_ENTRIES() is called which triggers the actual + * registering of ini entries and uses zend_get_configuration_directive() + * to fetch the previously stored name/value pair from configuration hash table + * and registers the static ini entries which match the name to the value + * into EG(ini_directives) hash table. + * 4. PATH section entries are used per-request from down to top, each overriding + * previous if one exists. zend_alter_ini_entry() is called for each entry. + * Settings in PATH section are ZEND_INI_SYSTEM accessible and thus mimics the + * php_admin_* directives used within Apache httpd.conf when PHP is compiled as + * module for Apache. + * 5. User defined ini files (like .htaccess for apache) are parsed for each request and + * stored in separate hash defined by SAPI. + */ + +/* TODO: (ordered by importance :-) + * =============================================================================== + * + * - Separate constant lookup totally from plain strings (using CONSTANT pattern) + * - Add #if .. #else .. #endif and ==, !=, <, > , <=, >= operators + * - Add #include "some.ini" + * - Allow variables to refer to options also when using parse_ini_file() + * + */ + +/* Globals Macros */ +#define SCNG INI_SCNG +#ifdef ZTS +ZEND_API ts_rsrc_id ini_scanner_globals_id; +#else +ZEND_API zend_ini_scanner_globals ini_scanner_globals; +#endif + +/* Eat leading whitespace */ +#define EAT_LEADING_WHITESPACE() \ + while (yytext[0]) { \ + if (yytext[0] == ' ' || yytext[0] == '\t') { \ + SCNG(yy_text)++; \ + yyleng--; \ + } else { \ + break; \ + } \ + } + +/* Eat trailing whitespace + extra char */ +#define EAT_TRAILING_WHITESPACE_EX(ch) \ + while (yyleng > 0 && ( \ + (ch != 'X' && yytext[yyleng - 1] == ch) || \ + yytext[yyleng - 1] == '\n' || \ + yytext[yyleng - 1] == '\r' || \ + yytext[yyleng - 1] == '\t' || \ + yytext[yyleng - 1] == ' ') \ + ) { \ + yyleng--; \ + } + +/* Eat trailing whitespace */ +#define EAT_TRAILING_WHITESPACE() EAT_TRAILING_WHITESPACE_EX('X') + +#define zend_ini_copy_value(retval, str, len) { \ + Z_STRVAL_P(retval) = zend_strndup(str, len); \ + Z_STRLEN_P(retval) = len; \ + Z_TYPE_P(retval) = IS_STRING; \ +} + +#define RETURN_TOKEN(type, str, len) { \ + zend_ini_copy_value(ini_lval, str, len); \ + return type; \ +} + +static void _yy_push_state(int new_state TSRMLS_DC) +{ + zend_stack_push(&SCNG(state_stack), (void *) &YYGETCONDITION(), sizeof(int)); + YYSETCONDITION(new_state); +} + +#define yy_push_state(state_and_tsrm) _yy_push_state(yyc##state_and_tsrm) + +static void yy_pop_state(TSRMLS_D) +{ + int *stack_state; + zend_stack_top(&SCNG(state_stack), (void **) &stack_state); + YYSETCONDITION(*stack_state); + zend_stack_del_top(&SCNG(state_stack)); +} + +static void yy_scan_buffer(char *str, unsigned int len TSRMLS_DC) +{ + YYCURSOR = (YYCTYPE*)str; + SCNG(yy_start) = YYCURSOR; + YYLIMIT = YYCURSOR + len; +} + +#define ini_filename SCNG(filename) + +/* {{{ init_ini_scanner() +*/ +static int init_ini_scanner(int scanner_mode, zend_file_handle *fh TSRMLS_DC) +{ + /* Sanity check */ + if (scanner_mode != ZEND_INI_SCANNER_NORMAL && scanner_mode != ZEND_INI_SCANNER_RAW) { + zend_error(E_WARNING, "Invalid scanner mode"); + return FAILURE; + } + + SCNG(lineno) = 1; + SCNG(scanner_mode) = scanner_mode; + SCNG(yy_in) = fh; + + if (fh != NULL) { + ini_filename = zend_strndup(fh->filename, strlen(fh->filename)); + } else { + ini_filename = NULL; + } + + zend_stack_init(&SCNG(state_stack)); + BEGIN(INITIAL); + + return SUCCESS; +} +/* }}} */ + +/* {{{ shutdown_ini_scanner() +*/ +void shutdown_ini_scanner(TSRMLS_D) +{ + zend_stack_destroy(&SCNG(state_stack)); + if (ini_filename) { + free(ini_filename); + } +} +/* }}} */ + +/* {{{ zend_ini_scanner_get_lineno() +*/ +int zend_ini_scanner_get_lineno(TSRMLS_D) +{ + return SCNG(lineno); +} +/* }}} */ + +/* {{{ zend_ini_scanner_get_filename() +*/ +char *zend_ini_scanner_get_filename(TSRMLS_D) +{ + return ini_filename ? ini_filename : "Unknown"; +} +/* }}} */ + +/* {{{ zend_ini_open_file_for_scanning() +*/ +int zend_ini_open_file_for_scanning(zend_file_handle *fh, int scanner_mode TSRMLS_DC) +{ + char *buf; + size_t size; + + if (zend_stream_fixup(fh, &buf, &size TSRMLS_CC) == FAILURE) { + return FAILURE; + } + + if (init_ini_scanner(scanner_mode, fh TSRMLS_CC) == FAILURE) { + zend_file_handle_dtor(fh TSRMLS_CC); + return FAILURE; + } + + yy_scan_buffer(buf, size TSRMLS_CC); + + return SUCCESS; +} +/* }}} */ + +/* {{{ zend_ini_prepare_string_for_scanning() +*/ +int zend_ini_prepare_string_for_scanning(char *str, int scanner_mode TSRMLS_DC) +{ + int len = strlen(str); + + if (init_ini_scanner(scanner_mode, NULL TSRMLS_CC) == FAILURE) { + return FAILURE; + } + + yy_scan_buffer(str, len TSRMLS_CC); + + return SUCCESS; +} +/* }}} */ + +/* {{{ zend_ini_escape_string() + */ +static void zend_ini_escape_string(zval *lval, char *str, int len, char quote_type TSRMLS_DC) +{ + register char *s, *t; + char *end; + + zend_ini_copy_value(lval, str, len); + + /* convert escape sequences */ + s = t = Z_STRVAL_P(lval); + end = s + Z_STRLEN_P(lval); + + while (s < end) { + if (*s == '\\') { + s++; + if (s >= end) { + *t++ = '\\'; + continue; + } + switch (*s) { + case '"': + if (*s != quote_type) { + *t++ = '\\'; + *t++ = *s; + break; + } + case '\\': + case '$': + *t++ = *s; + Z_STRLEN_P(lval)--; + break; + default: + *t++ = '\\'; + *t++ = *s; + break; + } + } else { + *t++ = *s; + } + if (*s == '\n' || (*s == '\r' && (*(s+1) != '\n'))) { + SCNG(lineno)++; + } + s++; + } + *t = 0; +} +/* }}} */ + +int ini_lex(zval *ini_lval TSRMLS_DC) +{ +restart: + SCNG(yy_text) = YYCURSOR; + +/* yymore_restart: */ + /* detect EOF */ + if (YYCURSOR >= YYLIMIT) { + if (YYSTATE == STATE(ST_VALUE) || YYSTATE == STATE(ST_RAW)) { + BEGIN(INITIAL); + return END_OF_LINE; + } + return 0; + } + + /* Eat any UTF-8 BOM we find in the first 3 bytes */ + if (YYCURSOR == SCNG(yy_start) && YYCURSOR + 3 < YYLIMIT) { + if (memcmp(YYCURSOR, "\xef\xbb\xbf", 3) == 0) { + YYCURSOR += 3; + goto restart; + } + } + +#line 337 "Zend/zend_ini_scanner.c" +{ + YYCTYPE yych; + unsigned int yyaccept = 0; + if (YYGETCONDITION() < 4) { + if (YYGETCONDITION() < 2) { + if (YYGETCONDITION() < 1) { + goto yyc_INITIAL; + } else { + goto yyc_ST_OFFSET; + } + } else { + if (YYGETCONDITION() < 3) { + goto yyc_ST_SECTION_VALUE; + } else { + goto yyc_ST_VALUE; + } + } + } else { + if (YYGETCONDITION() < 6) { + if (YYGETCONDITION() < 5) { + goto yyc_ST_SECTION_RAW; + } else { + goto yyc_ST_DOUBLE_QUOTES; + } + } else { + if (YYGETCONDITION() < 7) { + goto yyc_ST_VARNAME; + } else { + goto yyc_ST_RAW; + } + } + } +/* *********************************** */ +yyc_INITIAL: + { + static const unsigned char yybm[] = { + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 160, 0, 144, 144, 0, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 240, 128, 128, 144, 128, 144, 128, 144, + 128, 128, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 128, 144, 128, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 128, 144, 144, 128, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 128, 128, 128, 128, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + }; + + YYDEBUG(0, *YYCURSOR); + YYFILL(5); + yych = *YYCURSOR; + YYDEBUG(-1, yych); + switch (yych) { + case '\t': goto yy4; + case '\n': goto yy6; + case '\r': goto yy8; + case ' ': goto yy9; + case '!': + case '"': + case '$': + case '&': + case '(': + case ')': + case '^': + case '{': + case '|': + case '}': + case '~': goto yy10; + case '#': goto yy12; + case '%': + case '\'': + case '*': + case '+': + case ',': + case '-': + case '.': + case '/': + case ':': + case '<': + case '>': + case '?': + case '@': + case ']': goto yy13; + case ';': goto yy14; + case '=': goto yy16; + case 'F': + case 'f': goto yy18; + case 'N': + case 'n': goto yy19; + case 'O': + case 'o': goto yy20; + case 'T': + case 't': goto yy21; + case 'Y': + case 'y': goto yy22; + case '[': goto yy23; + default: goto yy2; + } +yy2: + YYDEBUG(2, *YYCURSOR); + ++YYCURSOR; + yych = *YYCURSOR; + goto yy26; +yy3: + YYDEBUG(3, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 429 "Zend/zend_ini_scanner.l" + { /* Get option name */ + /* Eat leading whitespace */ + EAT_LEADING_WHITESPACE(); + + /* Eat trailing whitespace */ + EAT_TRAILING_WHITESPACE(); + + RETURN_TOKEN(TC_LABEL, yytext, yyleng); +} +#line 476 "Zend/zend_ini_scanner.c" +yy4: + YYDEBUG(4, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + goto yy68; +yy5: + YYDEBUG(5, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 575 "Zend/zend_ini_scanner.l" + { + /* eat whitespace */ + goto restart; +} +#line 490 "Zend/zend_ini_scanner.c" +yy6: + YYDEBUG(6, *YYCURSOR); + ++YYCURSOR; +yy7: + YYDEBUG(7, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 580 "Zend/zend_ini_scanner.l" + { + SCNG(lineno)++; + return END_OF_LINE; +} +#line 502 "Zend/zend_ini_scanner.c" +yy8: + YYDEBUG(8, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == '\n') goto yy71; + goto yy7; +yy9: + YYDEBUG(9, *YYCURSOR); + yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= ' ') { + if (yych <= '\n') { + if (yych <= 0x08) goto yy26; + if (yych <= '\t') goto yy67; + goto yy71; + } else { + if (yych == '\r') goto yy72; + if (yych <= 0x1F) goto yy26; + goto yy69; + } + } else { + if (yych <= ':') { + if (yych == '#') goto yy58; + goto yy26; + } else { + if (yych <= ';') goto yy53; + if (yych == '=') goto yy51; + goto yy26; + } + } +yy10: + YYDEBUG(10, *YYCURSOR); + ++YYCURSOR; + YYDEBUG(11, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 503 "Zend/zend_ini_scanner.l" + { /* Disallow these chars outside option values */ + return yytext[0]; +} +#line 541 "Zend/zend_ini_scanner.c" +yy12: + YYDEBUG(12, *YYCURSOR); + yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + goto yy59; +yy13: + YYDEBUG(13, *YYCURSOR); + yych = *++YYCURSOR; + goto yy26; +yy14: + YYDEBUG(14, *YYCURSOR); + yyaccept = 2; + yych = *(YYMARKER = ++YYCURSOR); + goto yy54; + YYDEBUG(15, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 603 "Zend/zend_ini_scanner.l" + { + return 0; +} +#line 562 "Zend/zend_ini_scanner.c" +yy16: + YYDEBUG(16, *YYCURSOR); + ++YYCURSOR; + yych = *YYCURSOR; + goto yy52; +yy17: + YYDEBUG(17, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 439 "Zend/zend_ini_scanner.l" + { /* Start option value */ + if (SCNG(scanner_mode) == ZEND_INI_SCANNER_RAW) { + yy_push_state(ST_RAW TSRMLS_CC); + } else { + yy_push_state(ST_VALUE TSRMLS_CC); + } + return '='; +} +#line 580 "Zend/zend_ini_scanner.c" +yy18: + YYDEBUG(18, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'A') goto yy48; + if (yych == 'a') goto yy48; + goto yy26; +yy19: + YYDEBUG(19, *YYCURSOR); + yych = *++YYCURSOR; + if (yych <= 'U') { + if (yych == 'O') goto yy44; + if (yych <= 'T') goto yy26; + goto yy45; + } else { + if (yych <= 'o') { + if (yych <= 'n') goto yy26; + goto yy44; + } else { + if (yych == 'u') goto yy45; + goto yy26; + } + } +yy20: + YYDEBUG(20, *YYCURSOR); + yych = *++YYCURSOR; + if (yych <= 'N') { + if (yych == 'F') goto yy38; + if (yych <= 'M') goto yy26; + goto yy31; + } else { + if (yych <= 'f') { + if (yych <= 'e') goto yy26; + goto yy38; + } else { + if (yych == 'n') goto yy31; + goto yy26; + } + } +yy21: + YYDEBUG(21, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'R') goto yy36; + if (yych == 'r') goto yy36; + goto yy26; +yy22: + YYDEBUG(22, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'E') goto yy27; + if (yych == 'e') goto yy27; + goto yy26; +yy23: + YYDEBUG(23, *YYCURSOR); + ++YYCURSOR; + YYDEBUG(24, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 358 "Zend/zend_ini_scanner.l" + { /* Section start */ + /* Enter section data lookup state */ + if (SCNG(scanner_mode) == ZEND_INI_SCANNER_RAW) { + yy_push_state(ST_SECTION_RAW TSRMLS_CC); + } else { + yy_push_state(ST_SECTION_VALUE TSRMLS_CC); + } + return TC_SECTION; +} +#line 646 "Zend/zend_ini_scanner.c" +yy25: + YYDEBUG(25, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; +yy26: + YYDEBUG(26, *YYCURSOR); + if (yybm[0+yych] & 16) { + goto yy25; + } + if (yych == '[') goto yy28; + goto yy3; +yy27: + YYDEBUG(27, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'S') goto yy31; + if (yych == 's') goto yy31; + goto yy26; +yy28: + YYDEBUG(28, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(29, *YYCURSOR); + if (yybm[0+yych] & 32) { + goto yy28; + } + YYDEBUG(30, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 383 "Zend/zend_ini_scanner.l" + { /* Start of option with offset */ + /* Eat leading whitespace */ + EAT_LEADING_WHITESPACE(); + + /* Eat trailing whitespace and [ */ + EAT_TRAILING_WHITESPACE_EX('['); + + /* Enter offset lookup state */ + yy_push_state(ST_OFFSET TSRMLS_CC); + + RETURN_TOKEN(TC_OFFSET, yytext, yyleng); +} +#line 689 "Zend/zend_ini_scanner.c" +yy31: + YYDEBUG(31, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(32, *YYCURSOR); + if (yybm[0+yych] & 64) { + goto yy31; + } + if (yych <= '\'') { + if (yych <= ' ') { + if (yych <= '\n') { + if (yych <= 0x08) goto yy25; + if (yych <= '\t') goto yy34; + } else { + if (yych != '\r') goto yy25; + } + } else { + if (yych <= '$') { + if (yych == '#') goto yy25; + } else { + if (yych != '&') goto yy25; + } + } + } else { + if (yych <= 'Z') { + if (yych <= ';') { + if (yych <= ')') goto yy33; + if (yych <= ':') goto yy25; + } else { + if (yych != '=') goto yy25; + } + } else { + if (yych <= '^') { + if (yych <= '[') goto yy28; + if (yych <= ']') goto yy25; + } else { + if (yych <= 'z') goto yy25; + if (yych >= 0x7F) goto yy25; + } + } + } +yy33: + YYDEBUG(33, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 421 "Zend/zend_ini_scanner.l" + { /* TRUE value (when used outside option value/offset this causes parse error!) */ + RETURN_TOKEN(BOOL_TRUE, "1", 1); +} +#line 739 "Zend/zend_ini_scanner.c" +yy34: + YYDEBUG(34, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(35, *YYCURSOR); + if (yych == '\t') goto yy34; + if (yych == ' ') goto yy34; + goto yy33; +yy36: + YYDEBUG(36, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'U') goto yy37; + if (yych != 'u') goto yy26; +yy37: + YYDEBUG(37, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'E') goto yy31; + if (yych == 'e') goto yy31; + goto yy26; +yy38: + YYDEBUG(38, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'F') goto yy39; + if (yych != 'f') goto yy26; +yy39: + YYDEBUG(39, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(40, *YYCURSOR); + if (yych <= '&') { + if (yych <= 0x1F) { + if (yych <= '\n') { + if (yych <= 0x08) goto yy25; + if (yych <= '\t') goto yy42; + } else { + if (yych != '\r') goto yy25; + } + } else { + if (yych <= '#') { + if (yych <= ' ') goto yy39; + if (yych >= '#') goto yy25; + } else { + if (yych == '%') goto yy25; + } + } + } else { + if (yych <= '=') { + if (yych <= ':') { + if (yych <= '\'') goto yy25; + if (yych >= '*') goto yy25; + } else { + if (yych == '<') goto yy25; + } + } else { + if (yych <= ']') { + if (yych == '[') goto yy28; + goto yy25; + } else { + if (yych <= '^') goto yy41; + if (yych <= 'z') goto yy25; + if (yych >= 0x7F) goto yy25; + } + } + } +yy41: + YYDEBUG(41, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 425 "Zend/zend_ini_scanner.l" + { /* FALSE value (when used outside option value/offset this causes parse error!)*/ + RETURN_TOKEN(BOOL_FALSE, "", 0); +} +#line 813 "Zend/zend_ini_scanner.c" +yy42: + YYDEBUG(42, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(43, *YYCURSOR); + if (yych == '\t') goto yy42; + if (yych == ' ') goto yy42; + goto yy41; +yy44: + YYDEBUG(44, *YYCURSOR); + yych = *++YYCURSOR; + if (yych <= '\'') { + if (yych <= 0x1F) { + if (yych <= '\n') { + if (yych <= 0x08) goto yy26; + if (yych <= '\t') goto yy42; + goto yy41; + } else { + if (yych == '\r') goto yy41; + goto yy26; + } + } else { + if (yych <= '#') { + if (yych <= ' ') goto yy39; + if (yych <= '"') goto yy41; + goto yy26; + } else { + if (yych == '%') goto yy26; + if (yych <= '&') goto yy41; + goto yy26; + } + } + } else { + if (yych <= 'N') { + if (yych <= ';') { + if (yych <= ')') goto yy41; + if (yych <= ':') goto yy26; + goto yy41; + } else { + if (yych == '=') goto yy41; + if (yych <= 'M') goto yy26; + goto yy47; + } + } else { + if (yych <= 'm') { + if (yych == '^') goto yy41; + goto yy26; + } else { + if (yych <= 'n') goto yy47; + if (yych <= 'z') goto yy26; + if (yych <= '~') goto yy41; + goto yy26; + } + } + } +yy45: + YYDEBUG(45, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'L') goto yy46; + if (yych != 'l') goto yy26; +yy46: + YYDEBUG(46, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'L') goto yy39; + if (yych == 'l') goto yy39; + goto yy26; +yy47: + YYDEBUG(47, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'E') goto yy39; + if (yych == 'e') goto yy39; + goto yy26; +yy48: + YYDEBUG(48, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'L') goto yy49; + if (yych != 'l') goto yy26; +yy49: + YYDEBUG(49, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'S') goto yy50; + if (yych != 's') goto yy26; +yy50: + YYDEBUG(50, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'E') goto yy39; + if (yych == 'e') goto yy39; + goto yy26; +yy51: + YYDEBUG(51, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; +yy52: + YYDEBUG(52, *YYCURSOR); + if (yych == '\t') goto yy51; + if (yych == ' ') goto yy51; + goto yy17; +yy53: + YYDEBUG(53, *YYCURSOR); + ++YYCURSOR; + YYFILL(2); + yych = *YYCURSOR; +yy54: + YYDEBUG(54, *YYCURSOR); + if (yybm[0+yych] & 128) { + goto yy53; + } + if (yych >= '\r') goto yy57; +yy55: + YYDEBUG(55, *YYCURSOR); + ++YYCURSOR; +yy56: + YYDEBUG(56, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 585 "Zend/zend_ini_scanner.l" + { /* Comment */ + BEGIN(INITIAL); + SCNG(lineno)++; + return END_OF_LINE; +} +#line 936 "Zend/zend_ini_scanner.c" +yy57: + YYDEBUG(57, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == '\n') goto yy55; + goto yy56; +yy58: + YYDEBUG(58, *YYCURSOR); + yyaccept = 1; + YYMARKER = ++YYCURSOR; + YYFILL(2); + yych = *YYCURSOR; +yy59: + YYDEBUG(59, *YYCURSOR); + if (yych <= '\'') { + if (yych <= ' ') { + if (yych <= '\n') { + if (yych <= 0x08) goto yy58; + if (yych >= '\n') goto yy64; + } else { + if (yych == '\r') goto yy66; + goto yy58; + } + } else { + if (yych <= '$') { + if (yych == '#') goto yy58; + } else { + if (yych != '&') goto yy58; + } + } + } else { + if (yych <= 'Z') { + if (yych <= ';') { + if (yych <= ')') goto yy60; + if (yych <= ':') goto yy58; + } else { + if (yych != '=') goto yy58; + } + } else { + if (yych <= '^') { + if (yych <= '[') goto yy62; + if (yych <= ']') goto yy58; + } else { + if (yych <= 'z') goto yy58; + if (yych >= 0x7F) goto yy58; + } + } + } +yy60: + YYDEBUG(60, *YYCURSOR); + ++YYCURSOR; + YYFILL(2); + yych = *YYCURSOR; + YYDEBUG(61, *YYCURSOR); + if (yych == '\n') goto yy64; + if (yych == '\r') goto yy66; + goto yy60; +yy62: + YYDEBUG(62, *YYCURSOR); + yyaccept = 3; + YYMARKER = ++YYCURSOR; + YYFILL(2); + yych = *YYCURSOR; + YYDEBUG(63, *YYCURSOR); + if (yych <= '\f') { + if (yych <= 0x08) goto yy60; + if (yych <= '\t') goto yy62; + if (yych >= '\v') goto yy60; + } else { + if (yych <= '\r') goto yy66; + if (yych == ' ') goto yy62; + goto yy60; + } +yy64: + YYDEBUG(64, *YYCURSOR); + ++YYCURSOR; +yy65: + YYDEBUG(65, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 591 "Zend/zend_ini_scanner.l" + { /* #Comment */ + zend_error(E_DEPRECATED, "Comments starting with '#' are deprecated in %s on line %d", zend_ini_scanner_get_filename(TSRMLS_C), SCNG(lineno)); + BEGIN(INITIAL); + SCNG(lineno)++; + return END_OF_LINE; +} +#line 1022 "Zend/zend_ini_scanner.c" +yy66: + YYDEBUG(66, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == '\n') goto yy64; + goto yy65; +yy67: + YYDEBUG(67, *YYCURSOR); + yyaccept = 0; + YYMARKER = ++YYCURSOR; + YYFILL(2); + yych = *YYCURSOR; +yy68: + YYDEBUG(68, *YYCURSOR); + if (yych <= ' ') { + if (yych <= '\n') { + if (yych <= 0x08) goto yy5; + if (yych <= '\t') goto yy67; + goto yy71; + } else { + if (yych == '\r') goto yy72; + if (yych <= 0x1F) goto yy5; + goto yy67; + } + } else { + if (yych <= ':') { + if (yych == '#') goto yy60; + goto yy5; + } else { + if (yych <= ';') goto yy53; + if (yych == '=') goto yy51; + goto yy5; + } + } +yy69: + YYDEBUG(69, *YYCURSOR); + yyaccept = 1; + YYMARKER = ++YYCURSOR; + YYFILL(2); + yych = *YYCURSOR; + YYDEBUG(70, *YYCURSOR); + if (yych <= '&') { + if (yych <= 0x1F) { + if (yych <= '\n') { + if (yych <= 0x08) goto yy25; + if (yych <= '\t') goto yy67; + } else { + if (yych == '\r') goto yy72; + goto yy25; + } + } else { + if (yych <= '#') { + if (yych <= ' ') goto yy69; + if (yych <= '"') goto yy3; + goto yy58; + } else { + if (yych == '%') goto yy25; + goto yy3; + } + } + } else { + if (yych <= '=') { + if (yych <= ':') { + if (yych <= '\'') goto yy25; + if (yych <= ')') goto yy3; + goto yy25; + } else { + if (yych <= ';') goto yy53; + if (yych <= '<') goto yy25; + goto yy51; + } + } else { + if (yych <= ']') { + if (yych == '[') goto yy28; + goto yy25; + } else { + if (yych <= '^') goto yy3; + if (yych <= 'z') goto yy25; + if (yych <= '~') goto yy3; + goto yy25; + } + } + } +yy71: + YYDEBUG(71, *YYCURSOR); + yych = *++YYCURSOR; + goto yy7; +yy72: + YYDEBUG(72, *YYCURSOR); + ++YYCURSOR; + if ((yych = *YYCURSOR) == '\n') goto yy71; + goto yy7; + } +/* *********************************** */ +yyc_ST_DOUBLE_QUOTES: + { + static const unsigned char yybm[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 128, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 128, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + }; + YYDEBUG(73, *YYCURSOR); + YYFILL(2); + yych = *YYCURSOR; + if (yych == '"') goto yy77; + if (yych == '$') goto yy79; + YYDEBUG(75, *YYCURSOR); + ++YYCURSOR; +yy76: + YYDEBUG(76, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 535 "Zend/zend_ini_scanner.l" + { /* Escape double quoted string contents */ + if (YYCURSOR > YYLIMIT) { + return 0; + } + + while (YYCURSOR < YYLIMIT) { + switch (*YYCURSOR++) { + case '"': + if (YYCURSOR < YYLIMIT && YYCURSOR[-2] == '\\' && *YYCURSOR != '\r' && *YYCURSOR != '\n') { + continue; + } + break; + case '$': + if (*YYCURSOR == '{') { + break; + } + continue; + case '\\': + if (YYCURSOR < YYLIMIT && *YYCURSOR != '"') { + YYCURSOR++; + } + /* fall through */ + default: + continue; + } + + YYCURSOR--; + break; + } + + yyleng = YYCURSOR - SCNG(yy_text); + + zend_ini_escape_string(ini_lval, yytext, yyleng, '"' TSRMLS_CC); + return TC_QUOTED_STRING; +} +#line 1198 "Zend/zend_ini_scanner.c" +yy77: + YYDEBUG(77, *YYCURSOR); + ++YYCURSOR; + yych = *YYCURSOR; + goto yy83; +yy78: + YYDEBUG(78, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 530 "Zend/zend_ini_scanner.l" + { /* Double quoted '"' string ends */ + yy_pop_state(TSRMLS_C); + return '"'; +} +#line 1212 "Zend/zend_ini_scanner.c" +yy79: + YYDEBUG(79, *YYCURSOR); + yych = *++YYCURSOR; + if (yych != '{') goto yy76; + YYDEBUG(80, *YYCURSOR); + ++YYCURSOR; + YYDEBUG(81, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 401 "Zend/zend_ini_scanner.l" + { /* Variable start */ + yy_push_state(ST_VARNAME TSRMLS_CC); + return TC_DOLLAR_CURLY; +} +#line 1226 "Zend/zend_ini_scanner.c" +yy82: + YYDEBUG(82, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; +yy83: + YYDEBUG(83, *YYCURSOR); + if (yybm[0+yych] & 128) { + goto yy82; + } + goto yy78; + } +/* *********************************** */ +yyc_ST_OFFSET: + { + static const unsigned char yybm[] = { + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 194, 64, 66, 66, 64, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 194, 66, 64, 66, 68, 66, 66, 0, + 66, 66, 66, 66, 66, 66, 66, 66, + 114, 114, 114, 114, 114, 114, 114, 114, + 114, 114, 66, 64, 66, 66, 66, 66, + 66, 82, 82, 82, 82, 82, 82, 82, + 82, 82, 82, 82, 82, 82, 82, 82, + 82, 82, 82, 82, 82, 82, 82, 82, + 82, 82, 82, 66, 72, 64, 66, 82, + 66, 82, 82, 82, 82, 82, 82, 82, + 82, 82, 82, 82, 82, 82, 82, 82, + 82, 82, 82, 82, 82, 82, 82, 82, + 82, 82, 82, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, + }; + YYDEBUG(84, *YYCURSOR); + YYFILL(2); + yych = *YYCURSOR; + if (yych <= '-') { + if (yych <= ' ') { + if (yych <= '\n') { + if (yych <= 0x08) goto yy86; + if (yych <= '\t') goto yy88; + goto yy89; + } else { + if (yych == '\r') goto yy89; + if (yych >= ' ') goto yy88; + } + } else { + if (yych <= '$') { + if (yych == '"') goto yy91; + if (yych >= '$') goto yy93; + } else { + if (yych == '\'') goto yy94; + if (yych >= '-') goto yy95; + } + } + } else { + if (yych <= 'Z') { + if (yych <= '9') { + if (yych <= '.') goto yy96; + if (yych >= '0') goto yy97; + } else { + if (yych == ';') goto yy89; + if (yych >= 'A') goto yy99; + } + } else { + if (yych <= '^') { + if (yych <= '[') goto yy86; + if (yych <= '\\') goto yy101; + if (yych <= ']') goto yy102; + } else { + if (yych == '`') goto yy86; + if (yych <= 'z') goto yy99; + } + } + } +yy86: + YYDEBUG(86, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + goto yy105; +yy87: + YYDEBUG(87, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 521 "Zend/zend_ini_scanner.l" + { /* Get rest as section/offset value */ + RETURN_TOKEN(TC_STRING, yytext, yyleng); +} +#line 1330 "Zend/zend_ini_scanner.c" +yy88: + YYDEBUG(88, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yybm[0+yych] & 128) { + goto yy131; + } + if (yych == '"') goto yy133; + if (yych == ']') goto yy134; + goto yy105; +yy89: + YYDEBUG(89, *YYCURSOR); + ++YYCURSOR; +yy90: + YYDEBUG(90, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 603 "Zend/zend_ini_scanner.l" + { + return 0; +} +#line 1351 "Zend/zend_ini_scanner.c" +yy91: + YYDEBUG(91, *YYCURSOR); + ++YYCURSOR; +yy92: + YYDEBUG(92, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 525 "Zend/zend_ini_scanner.l" + { /* Double quoted '"' string start */ + yy_push_state(ST_DOUBLE_QUOTES TSRMLS_CC); + return '"'; +} +#line 1363 "Zend/zend_ini_scanner.c" +yy93: + YYDEBUG(93, *YYCURSOR); + yych = *++YYCURSOR; + if (yych <= '\\') { + if (yych <= 0x00) goto yy90; + if (yych <= '[') goto yy104; + goto yy109; + } else { + if (yych == '{') goto yy129; + goto yy104; + } +yy94: + YYDEBUG(94, *YYCURSOR); + yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + if (yybm[0+yych] & 64) { + goto yy125; + } + goto yy90; +yy95: + YYDEBUG(95, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '/') goto yy105; + if (yych <= '9') goto yy123; + goto yy105; +yy96: + YYDEBUG(96, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '/') goto yy105; + if (yych <= '9') goto yy121; + goto yy105; +yy97: + YYDEBUG(97, *YYCURSOR); + yyaccept = 2; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '\'') { + if (yych <= '\r') { + if (yych == '\n') goto yy98; + if (yych <= '\f') goto yy105; + } else { + if (yych == '"') goto yy98; + if (yych <= '&') goto yy105; + } + } else { + if (yych <= '9') { + if (yych == '.') goto yy117; + if (yych <= '/') goto yy105; + goto yy119; + } else { + if (yych <= ';') { + if (yych <= ':') goto yy105; + } else { + if (yych != ']') goto yy105; + } + } + } +yy98: + YYDEBUG(98, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 499 "Zend/zend_ini_scanner.l" + { /* Get number option value as string */ + RETURN_TOKEN(TC_NUMBER, yytext, yyleng); +} +#line 1429 "Zend/zend_ini_scanner.c" +yy99: + YYDEBUG(99, *YYCURSOR); + yyaccept = 3; + yych = *(YYMARKER = ++YYCURSOR); + if (yybm[0+yych] & 16) { + goto yy115; + } + if (yych <= '"') { + if (yych <= '\f') { + if (yych != '\n') goto yy105; + } else { + if (yych <= '\r') goto yy100; + if (yych <= '!') goto yy105; + } + } else { + if (yych <= ':') { + if (yych != '\'') goto yy105; + } else { + if (yych <= ';') goto yy100; + if (yych != ']') goto yy105; + } + } +yy100: + YYDEBUG(100, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 495 "Zend/zend_ini_scanner.l" + { /* Get constant option value */ + RETURN_TOKEN(TC_CONSTANT, yytext, yyleng); +} +#line 1459 "Zend/zend_ini_scanner.c" +yy101: + YYDEBUG(101, *YYCURSOR); + yych = *++YYCURSOR; + goto yy104; +yy102: + YYDEBUG(102, *YYCURSOR); + ++YYCURSOR; +yy103: + YYDEBUG(103, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 396 "Zend/zend_ini_scanner.l" + { /* End of section or an option offset */ + BEGIN(INITIAL); + return ']'; +} +#line 1475 "Zend/zend_ini_scanner.c" +yy104: + YYDEBUG(104, *YYCURSOR); + yyaccept = 0; + YYMARKER = ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; +yy105: + YYDEBUG(105, *YYCURSOR); + if (yybm[0+yych] & 2) { + goto yy104; + } + if (yych == '$') goto yy107; + if (yych != '\\') goto yy87; +yy106: + YYDEBUG(106, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + goto yy104; +yy107: + YYDEBUG(107, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + if (yych <= '\\') { + if (yych <= 0x00) goto yy108; + if (yych <= '[') goto yy104; + goto yy109; + } else { + if (yych != '{') goto yy104; + } +yy108: + YYDEBUG(108, *YYCURSOR); + YYCURSOR = YYMARKER; + if (yyaccept <= 1) { + if (yyaccept <= 0) { + goto yy87; + } else { + goto yy90; + } + } else { + if (yyaccept <= 2) { + goto yy98; + } else { + goto yy100; + } + } +yy109: + YYDEBUG(109, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + if (yybm[0+yych] & 4) { + goto yy110; + } + if (yych == '\\') goto yy112; + goto yy104; +yy110: + YYDEBUG(110, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(111, *YYCURSOR); + if (yybm[0+yych] & 4) { + goto yy110; + } + if (yych == '\\') goto yy114; + goto yy104; +yy112: + YYDEBUG(112, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(113, *YYCURSOR); + if (yybm[0+yych] & 4) { + goto yy110; + } + if (yych == '\\') goto yy112; + goto yy104; +yy114: + YYDEBUG(114, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + if (yybm[0+yych] & 4) { + goto yy110; + } + if (yych == '\\') goto yy112; + goto yy104; +yy115: + YYDEBUG(115, *YYCURSOR); + yyaccept = 3; + YYMARKER = ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(116, *YYCURSOR); + if (yybm[0+yych] & 16) { + goto yy115; + } + if (yych <= '$') { + if (yych <= '\r') { + if (yych == '\n') goto yy100; + if (yych <= '\f') goto yy104; + goto yy100; + } else { + if (yych == '"') goto yy100; + if (yych <= '#') goto yy104; + goto yy107; + } + } else { + if (yych <= ';') { + if (yych == '\'') goto yy100; + if (yych <= ':') goto yy104; + goto yy100; + } else { + if (yych <= '[') goto yy104; + if (yych <= '\\') goto yy106; + if (yych <= ']') goto yy100; + goto yy104; + } + } +yy117: + YYDEBUG(117, *YYCURSOR); + yyaccept = 2; + YYMARKER = ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(118, *YYCURSOR); + if (yybm[0+yych] & 32) { + goto yy117; + } + if (yych <= '$') { + if (yych <= '\r') { + if (yych == '\n') goto yy98; + if (yych <= '\f') goto yy104; + goto yy98; + } else { + if (yych == '"') goto yy98; + if (yych <= '#') goto yy104; + goto yy107; + } + } else { + if (yych <= ';') { + if (yych == '\'') goto yy98; + if (yych <= ':') goto yy104; + goto yy98; + } else { + if (yych <= '[') goto yy104; + if (yych <= '\\') goto yy106; + if (yych <= ']') goto yy98; + goto yy104; + } + } +yy119: + YYDEBUG(119, *YYCURSOR); + yyaccept = 2; + YYMARKER = ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(120, *YYCURSOR); + if (yych <= '\'') { + if (yych <= '!') { + if (yych <= '\n') { + if (yych <= '\t') goto yy104; + goto yy98; + } else { + if (yych == '\r') goto yy98; + goto yy104; + } + } else { + if (yych <= '#') { + if (yych <= '"') goto yy98; + goto yy104; + } else { + if (yych <= '$') goto yy107; + if (yych <= '&') goto yy104; + goto yy98; + } + } + } else { + if (yych <= ':') { + if (yych <= '.') { + if (yych <= '-') goto yy104; + goto yy117; + } else { + if (yych <= '/') goto yy104; + if (yych <= '9') goto yy119; + goto yy104; + } + } else { + if (yych <= '[') { + if (yych <= ';') goto yy98; + goto yy104; + } else { + if (yych <= '\\') goto yy106; + if (yych <= ']') goto yy98; + goto yy104; + } + } + } +yy121: + YYDEBUG(121, *YYCURSOR); + yyaccept = 2; + YYMARKER = ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(122, *YYCURSOR); + if (yych <= '&') { + if (yych <= '\r') { + if (yych == '\n') goto yy98; + if (yych <= '\f') goto yy104; + goto yy98; + } else { + if (yych <= '"') { + if (yych <= '!') goto yy104; + goto yy98; + } else { + if (yych == '$') goto yy107; + goto yy104; + } + } + } else { + if (yych <= ':') { + if (yych <= '\'') goto yy98; + if (yych <= '/') goto yy104; + if (yych <= '9') goto yy121; + goto yy104; + } else { + if (yych <= '[') { + if (yych <= ';') goto yy98; + goto yy104; + } else { + if (yych <= '\\') goto yy106; + if (yych <= ']') goto yy98; + goto yy104; + } + } + } +yy123: + YYDEBUG(123, *YYCURSOR); + yyaccept = 2; + YYMARKER = ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(124, *YYCURSOR); + if (yych <= '&') { + if (yych <= '\r') { + if (yych == '\n') goto yy98; + if (yych <= '\f') goto yy104; + goto yy98; + } else { + if (yych <= '"') { + if (yych <= '!') goto yy104; + goto yy98; + } else { + if (yych == '$') goto yy107; + goto yy104; + } + } + } else { + if (yych <= ':') { + if (yych <= '\'') goto yy98; + if (yych <= '/') goto yy104; + if (yych <= '9') goto yy123; + goto yy104; + } else { + if (yych <= '[') { + if (yych <= ';') goto yy98; + goto yy104; + } else { + if (yych <= '\\') goto yy106; + if (yych <= ']') goto yy98; + goto yy104; + } + } + } +yy125: + YYDEBUG(125, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(126, *YYCURSOR); + if (yybm[0+yych] & 64) { + goto yy125; + } + YYDEBUG(127, *YYCURSOR); + ++YYCURSOR; + YYDEBUG(128, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 368 "Zend/zend_ini_scanner.l" + { /* Raw string */ + /* Eat leading and trailing single quotes */ + if (yytext[0] == '\'' && yytext[yyleng - 1] == '\'') { + SCNG(yy_text)++; + yyleng = yyleng - 2; + } + RETURN_TOKEN(TC_RAW, yytext, yyleng); +} +#line 1774 "Zend/zend_ini_scanner.c" +yy129: + YYDEBUG(129, *YYCURSOR); + ++YYCURSOR; + YYDEBUG(130, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 401 "Zend/zend_ini_scanner.l" + { /* Variable start */ + yy_push_state(ST_VARNAME TSRMLS_CC); + return TC_DOLLAR_CURLY; +} +#line 1785 "Zend/zend_ini_scanner.c" +yy131: + YYDEBUG(131, *YYCURSOR); + yyaccept = 0; + YYMARKER = ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(132, *YYCURSOR); + if (yybm[0+yych] & 128) { + goto yy131; + } + if (yych <= '$') { + if (yych <= '\r') { + if (yych == '\n') goto yy87; + if (yych <= '\f') goto yy104; + goto yy87; + } else { + if (yych == '"') goto yy133; + if (yych <= '#') goto yy104; + goto yy107; + } + } else { + if (yych <= ';') { + if (yych == '\'') goto yy87; + if (yych <= ':') goto yy104; + goto yy87; + } else { + if (yych <= '[') goto yy104; + if (yych <= '\\') goto yy106; + if (yych <= ']') goto yy134; + goto yy104; + } + } +yy133: + YYDEBUG(133, *YYCURSOR); + yych = *++YYCURSOR; + goto yy92; +yy134: + YYDEBUG(134, *YYCURSOR); + ++YYCURSOR; + yych = *YYCURSOR; + goto yy103; + } +/* *********************************** */ +yyc_ST_RAW: + { + static const unsigned char yybm[] = { + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 192, 0, 64, 64, 0, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 192, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + }; + YYDEBUG(135, *YYCURSOR); + YYFILL(3); + yych = *YYCURSOR; + if (yych <= '\f') { + if (yych <= 0x08) { + if (yych >= 0x01) goto yy139; + } else { + if (yych <= '\t') goto yy141; + if (yych <= '\n') goto yy142; + goto yy139; + } + } else { + if (yych <= ' ') { + if (yych <= '\r') goto yy144; + if (yych <= 0x1F) goto yy139; + goto yy141; + } else { + if (yych == ';') goto yy145; + goto yy139; + } + } + YYDEBUG(137, *YYCURSOR); + ++YYCURSOR; + YYDEBUG(138, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 598 "Zend/zend_ini_scanner.l" + { /* End of option value (if EOF is reached before EOL */ + BEGIN(INITIAL); + return END_OF_LINE; +} +#line 1895 "Zend/zend_ini_scanner.c" +yy139: + YYDEBUG(139, *YYCURSOR); + ++YYCURSOR; +yy140: + YYDEBUG(140, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 448 "Zend/zend_ini_scanner.l" + { /* Raw value, only used when SCNG(scanner_mode) == ZEND_INI_SCANNER_RAW. */ + char *sc = NULL; + while (YYCURSOR < YYLIMIT) { + switch (*YYCURSOR) { + case '\n': + case '\r': + goto end_raw_value_chars; + break; + case ';': + if (sc == NULL) { + sc = YYCURSOR; + } + /* no break */ + default: + YYCURSOR++; + break; + } + } +end_raw_value_chars: + yyleng = YYCURSOR - SCNG(yy_text); + + /* Eat trailing semicolons */ + while (yytext[yyleng - 1] == ';') { + yyleng--; + } + + /* Eat leading and trailing double quotes */ + if (yytext[0] == '"' && yytext[yyleng - 1] == '"') { + SCNG(yy_text)++; + yyleng = yyleng - 2; + } else if (sc) { + YYCURSOR = sc; + yyleng = YYCURSOR - SCNG(yy_text); + } + RETURN_TOKEN(TC_RAW, yytext, yyleng); +} +#line 1939 "Zend/zend_ini_scanner.c" +yy141: + YYDEBUG(141, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '\r') { + if (yych <= 0x08) goto yy140; + if (yych <= '\n') goto yy153; + if (yych <= '\f') goto yy140; + goto yy153; + } else { + if (yych <= ' ') { + if (yych <= 0x1F) goto yy140; + goto yy153; + } else { + if (yych == ';') goto yy153; + goto yy140; + } + } +yy142: + YYDEBUG(142, *YYCURSOR); + ++YYCURSOR; +yy143: + YYDEBUG(143, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 489 "Zend/zend_ini_scanner.l" + { /* End of option value */ + BEGIN(INITIAL); + SCNG(lineno)++; + return END_OF_LINE; +} +#line 1970 "Zend/zend_ini_scanner.c" +yy144: + YYDEBUG(144, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == '\n') goto yy151; + goto yy143; +yy145: + YYDEBUG(145, *YYCURSOR); + yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + goto yy147; +yy146: + YYDEBUG(146, *YYCURSOR); + ++YYCURSOR; + YYFILL(2); + yych = *YYCURSOR; +yy147: + YYDEBUG(147, *YYCURSOR); + if (yybm[0+yych] & 64) { + goto yy146; + } + if (yych >= '\r') goto yy150; +yy148: + YYDEBUG(148, *YYCURSOR); + ++YYCURSOR; +yy149: + YYDEBUG(149, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 585 "Zend/zend_ini_scanner.l" + { /* Comment */ + BEGIN(INITIAL); + SCNG(lineno)++; + return END_OF_LINE; +} +#line 2004 "Zend/zend_ini_scanner.c" +yy150: + YYDEBUG(150, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == '\n') goto yy148; + goto yy149; +yy151: + YYDEBUG(151, *YYCURSOR); + yych = *++YYCURSOR; + goto yy143; +yy152: + YYDEBUG(152, *YYCURSOR); + yyaccept = 2; + YYMARKER = ++YYCURSOR; + YYFILL(2); + yych = *YYCURSOR; +yy153: + YYDEBUG(153, *YYCURSOR); + if (yybm[0+yych] & 128) { + goto yy152; + } + if (yych <= '\f') { + if (yych == '\n') goto yy151; + } else { + if (yych <= '\r') goto yy155; + if (yych == ';') goto yy146; + } + YYDEBUG(154, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 575 "Zend/zend_ini_scanner.l" + { + /* eat whitespace */ + goto restart; +} +#line 2038 "Zend/zend_ini_scanner.c" +yy155: + YYDEBUG(155, *YYCURSOR); + ++YYCURSOR; + if ((yych = *YYCURSOR) == '\n') goto yy151; + goto yy143; + } +/* *********************************** */ +yyc_ST_SECTION_RAW: + { + static const unsigned char yybm[] = { + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 192, 0, 128, 128, 0, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 192, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 0, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + }; + YYDEBUG(156, *YYCURSOR); + YYFILL(3); + yych = *YYCURSOR; + if (yych <= '\f') { + if (yych == '\n') goto yy160; + } else { + if (yych <= '\r') goto yy160; + if (yych == ']') goto yy162; + } + YYDEBUG(158, *YYCURSOR); + ++YYCURSOR; + yych = *YYCURSOR; + goto yy169; +yy159: + YYDEBUG(159, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 485 "Zend/zend_ini_scanner.l" + { /* Raw value, only used when SCNG(scanner_mode) == ZEND_INI_SCANNER_RAW. */ + RETURN_TOKEN(TC_RAW, yytext, yyleng); +} +#line 2102 "Zend/zend_ini_scanner.c" +yy160: + YYDEBUG(160, *YYCURSOR); + ++YYCURSOR; + YYDEBUG(161, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 603 "Zend/zend_ini_scanner.l" + { + return 0; +} +#line 2112 "Zend/zend_ini_scanner.c" +yy162: + YYDEBUG(162, *YYCURSOR); + ++YYCURSOR; + yych = *YYCURSOR; + goto yy165; +yy163: + YYDEBUG(163, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 377 "Zend/zend_ini_scanner.l" + { /* End of section */ + BEGIN(INITIAL); + SCNG(lineno)++; + return ']'; +} +#line 2127 "Zend/zend_ini_scanner.c" +yy164: + YYDEBUG(164, *YYCURSOR); + ++YYCURSOR; + YYFILL(2); + yych = *YYCURSOR; +yy165: + YYDEBUG(165, *YYCURSOR); + if (yybm[0+yych] & 64) { + goto yy164; + } + if (yych == '\n') goto yy166; + if (yych == '\r') goto yy167; + goto yy163; +yy166: + YYDEBUG(166, *YYCURSOR); + yych = *++YYCURSOR; + goto yy163; +yy167: + YYDEBUG(167, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == '\n') goto yy166; + goto yy163; +yy168: + YYDEBUG(168, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; +yy169: + YYDEBUG(169, *YYCURSOR); + if (yybm[0+yych] & 128) { + goto yy168; + } + goto yy159; + } +/* *********************************** */ +yyc_ST_SECTION_VALUE: + { + static const unsigned char yybm[] = { + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 134, 128, 132, 132, 128, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 134, 132, 128, 132, 136, 132, 132, 0, + 132, 132, 132, 132, 132, 132, 132, 132, + 228, 228, 228, 228, 228, 228, 228, 228, + 228, 228, 132, 128, 132, 132, 132, 132, + 132, 164, 164, 164, 164, 164, 164, 164, + 164, 164, 164, 164, 164, 164, 164, 164, + 164, 164, 164, 164, 164, 164, 164, 164, + 164, 164, 164, 132, 144, 128, 132, 164, + 132, 164, 164, 164, 164, 164, 164, 164, + 164, 164, 164, 164, 164, 164, 164, 164, + 164, 164, 164, 164, 164, 164, 164, 164, + 164, 164, 164, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + }; + YYDEBUG(170, *YYCURSOR); + YYFILL(3); + yych = *YYCURSOR; + if (yych <= '-') { + if (yych <= ' ') { + if (yych <= '\n') { + if (yych <= 0x08) goto yy172; + if (yych <= '\t') goto yy174; + goto yy175; + } else { + if (yych == '\r') goto yy175; + if (yych >= ' ') goto yy174; + } + } else { + if (yych <= '$') { + if (yych == '"') goto yy177; + if (yych >= '$') goto yy179; + } else { + if (yych == '\'') goto yy180; + if (yych >= '-') goto yy181; + } + } + } else { + if (yych <= 'Z') { + if (yych <= '9') { + if (yych <= '.') goto yy182; + if (yych >= '0') goto yy183; + } else { + if (yych == ';') goto yy175; + if (yych >= 'A') goto yy185; + } + } else { + if (yych <= '^') { + if (yych <= '[') goto yy172; + if (yych <= '\\') goto yy187; + if (yych <= ']') goto yy188; + } else { + if (yych == '`') goto yy172; + if (yych <= 'z') goto yy185; + } + } + } +yy172: + YYDEBUG(172, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + goto yy195; +yy173: + YYDEBUG(173, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 521 "Zend/zend_ini_scanner.l" + { /* Get rest as section/offset value */ + RETURN_TOKEN(TC_STRING, yytext, yyleng); +} +#line 2253 "Zend/zend_ini_scanner.c" +yy174: + YYDEBUG(174, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= 0x1F) { + if (yych == '\t') goto yy221; + goto yy195; + } else { + if (yych <= ' ') goto yy221; + if (yych == '"') goto yy223; + goto yy195; + } +yy175: + YYDEBUG(175, *YYCURSOR); + ++YYCURSOR; +yy176: + YYDEBUG(176, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 603 "Zend/zend_ini_scanner.l" + { + return 0; +} +#line 2276 "Zend/zend_ini_scanner.c" +yy177: + YYDEBUG(177, *YYCURSOR); + ++YYCURSOR; +yy178: + YYDEBUG(178, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 525 "Zend/zend_ini_scanner.l" + { /* Double quoted '"' string start */ + yy_push_state(ST_DOUBLE_QUOTES TSRMLS_CC); + return '"'; +} +#line 2288 "Zend/zend_ini_scanner.c" +yy179: + YYDEBUG(179, *YYCURSOR); + yych = *++YYCURSOR; + if (yych <= '\\') { + if (yych <= 0x00) goto yy176; + if (yych <= '[') goto yy194; + goto yy199; + } else { + if (yych == '{') goto yy219; + goto yy194; + } +yy180: + YYDEBUG(180, *YYCURSOR); + yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + if (yybm[0+yych] & 128) { + goto yy215; + } + goto yy176; +yy181: + YYDEBUG(181, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '/') goto yy195; + if (yych <= '9') goto yy213; + goto yy195; +yy182: + YYDEBUG(182, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '/') goto yy195; + if (yych <= '9') goto yy211; + goto yy195; +yy183: + YYDEBUG(183, *YYCURSOR); + yyaccept = 2; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '\'') { + if (yych <= '\r') { + if (yych == '\n') goto yy184; + if (yych <= '\f') goto yy195; + } else { + if (yych == '"') goto yy184; + if (yych <= '&') goto yy195; + } + } else { + if (yych <= '9') { + if (yych == '.') goto yy207; + if (yych <= '/') goto yy195; + goto yy209; + } else { + if (yych <= ';') { + if (yych <= ':') goto yy195; + } else { + if (yych != ']') goto yy195; + } + } + } +yy184: + YYDEBUG(184, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 499 "Zend/zend_ini_scanner.l" + { /* Get number option value as string */ + RETURN_TOKEN(TC_NUMBER, yytext, yyleng); +} +#line 2354 "Zend/zend_ini_scanner.c" +yy185: + YYDEBUG(185, *YYCURSOR); + yyaccept = 3; + yych = *(YYMARKER = ++YYCURSOR); + if (yybm[0+yych] & 32) { + goto yy205; + } + if (yych <= '"') { + if (yych <= '\f') { + if (yych != '\n') goto yy195; + } else { + if (yych <= '\r') goto yy186; + if (yych <= '!') goto yy195; + } + } else { + if (yych <= ':') { + if (yych != '\'') goto yy195; + } else { + if (yych <= ';') goto yy186; + if (yych != ']') goto yy195; + } + } +yy186: + YYDEBUG(186, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 495 "Zend/zend_ini_scanner.l" + { /* Get constant option value */ + RETURN_TOKEN(TC_CONSTANT, yytext, yyleng); +} +#line 2384 "Zend/zend_ini_scanner.c" +yy187: + YYDEBUG(187, *YYCURSOR); + yych = *++YYCURSOR; + goto yy194; +yy188: + YYDEBUG(188, *YYCURSOR); + ++YYCURSOR; + yych = *YYCURSOR; + goto yy191; +yy189: + YYDEBUG(189, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 377 "Zend/zend_ini_scanner.l" + { /* End of section */ + BEGIN(INITIAL); + SCNG(lineno)++; + return ']'; +} +#line 2403 "Zend/zend_ini_scanner.c" +yy190: + YYDEBUG(190, *YYCURSOR); + ++YYCURSOR; + YYFILL(2); + yych = *YYCURSOR; +yy191: + YYDEBUG(191, *YYCURSOR); + if (yybm[0+yych] & 2) { + goto yy190; + } + if (yych == '\n') goto yy192; + if (yych == '\r') goto yy193; + goto yy189; +yy192: + YYDEBUG(192, *YYCURSOR); + yych = *++YYCURSOR; + goto yy189; +yy193: + YYDEBUG(193, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == '\n') goto yy192; + goto yy189; +yy194: + YYDEBUG(194, *YYCURSOR); + yyaccept = 0; + YYMARKER = ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; +yy195: + YYDEBUG(195, *YYCURSOR); + if (yybm[0+yych] & 4) { + goto yy194; + } + if (yych == '$') goto yy197; + if (yych != '\\') goto yy173; +yy196: + YYDEBUG(196, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + goto yy194; +yy197: + YYDEBUG(197, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + if (yych <= '\\') { + if (yych <= 0x00) goto yy198; + if (yych <= '[') goto yy194; + goto yy199; + } else { + if (yych != '{') goto yy194; + } +yy198: + YYDEBUG(198, *YYCURSOR); + YYCURSOR = YYMARKER; + if (yyaccept <= 1) { + if (yyaccept <= 0) { + goto yy173; + } else { + goto yy176; + } + } else { + if (yyaccept <= 2) { + goto yy184; + } else { + goto yy186; + } + } +yy199: + YYDEBUG(199, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + if (yybm[0+yych] & 8) { + goto yy200; + } + if (yych == '\\') goto yy202; + goto yy194; +yy200: + YYDEBUG(200, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(201, *YYCURSOR); + if (yybm[0+yych] & 8) { + goto yy200; + } + if (yych == '\\') goto yy204; + goto yy194; +yy202: + YYDEBUG(202, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(203, *YYCURSOR); + if (yybm[0+yych] & 8) { + goto yy200; + } + if (yych == '\\') goto yy202; + goto yy194; +yy204: + YYDEBUG(204, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + if (yybm[0+yych] & 8) { + goto yy200; + } + if (yych == '\\') goto yy202; + goto yy194; +yy205: + YYDEBUG(205, *YYCURSOR); + yyaccept = 3; + YYMARKER = ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(206, *YYCURSOR); + if (yybm[0+yych] & 32) { + goto yy205; + } + if (yych <= '$') { + if (yych <= '\r') { + if (yych == '\n') goto yy186; + if (yych <= '\f') goto yy194; + goto yy186; + } else { + if (yych == '"') goto yy186; + if (yych <= '#') goto yy194; + goto yy197; + } + } else { + if (yych <= ';') { + if (yych == '\'') goto yy186; + if (yych <= ':') goto yy194; + goto yy186; + } else { + if (yych <= '[') goto yy194; + if (yych <= '\\') goto yy196; + if (yych <= ']') goto yy186; + goto yy194; + } + } +yy207: + YYDEBUG(207, *YYCURSOR); + yyaccept = 2; + YYMARKER = ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(208, *YYCURSOR); + if (yybm[0+yych] & 64) { + goto yy207; + } + if (yych <= '$') { + if (yych <= '\r') { + if (yych == '\n') goto yy184; + if (yych <= '\f') goto yy194; + goto yy184; + } else { + if (yych == '"') goto yy184; + if (yych <= '#') goto yy194; + goto yy197; + } + } else { + if (yych <= ';') { + if (yych == '\'') goto yy184; + if (yych <= ':') goto yy194; + goto yy184; + } else { + if (yych <= '[') goto yy194; + if (yych <= '\\') goto yy196; + if (yych <= ']') goto yy184; + goto yy194; + } + } +yy209: + YYDEBUG(209, *YYCURSOR); + yyaccept = 2; + YYMARKER = ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(210, *YYCURSOR); + if (yych <= '\'') { + if (yych <= '!') { + if (yych <= '\n') { + if (yych <= '\t') goto yy194; + goto yy184; + } else { + if (yych == '\r') goto yy184; + goto yy194; + } + } else { + if (yych <= '#') { + if (yych <= '"') goto yy184; + goto yy194; + } else { + if (yych <= '$') goto yy197; + if (yych <= '&') goto yy194; + goto yy184; + } + } + } else { + if (yych <= ':') { + if (yych <= '.') { + if (yych <= '-') goto yy194; + goto yy207; + } else { + if (yych <= '/') goto yy194; + if (yych <= '9') goto yy209; + goto yy194; + } + } else { + if (yych <= '[') { + if (yych <= ';') goto yy184; + goto yy194; + } else { + if (yych <= '\\') goto yy196; + if (yych <= ']') goto yy184; + goto yy194; + } + } + } +yy211: + YYDEBUG(211, *YYCURSOR); + yyaccept = 2; + YYMARKER = ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(212, *YYCURSOR); + if (yych <= '&') { + if (yych <= '\r') { + if (yych == '\n') goto yy184; + if (yych <= '\f') goto yy194; + goto yy184; + } else { + if (yych <= '"') { + if (yych <= '!') goto yy194; + goto yy184; + } else { + if (yych == '$') goto yy197; + goto yy194; + } + } + } else { + if (yych <= ':') { + if (yych <= '\'') goto yy184; + if (yych <= '/') goto yy194; + if (yych <= '9') goto yy211; + goto yy194; + } else { + if (yych <= '[') { + if (yych <= ';') goto yy184; + goto yy194; + } else { + if (yych <= '\\') goto yy196; + if (yych <= ']') goto yy184; + goto yy194; + } + } + } +yy213: + YYDEBUG(213, *YYCURSOR); + yyaccept = 2; + YYMARKER = ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(214, *YYCURSOR); + if (yych <= '&') { + if (yych <= '\r') { + if (yych == '\n') goto yy184; + if (yych <= '\f') goto yy194; + goto yy184; + } else { + if (yych <= '"') { + if (yych <= '!') goto yy194; + goto yy184; + } else { + if (yych == '$') goto yy197; + goto yy194; + } + } + } else { + if (yych <= ':') { + if (yych <= '\'') goto yy184; + if (yych <= '/') goto yy194; + if (yych <= '9') goto yy213; + goto yy194; + } else { + if (yych <= '[') { + if (yych <= ';') goto yy184; + goto yy194; + } else { + if (yych <= '\\') goto yy196; + if (yych <= ']') goto yy184; + goto yy194; + } + } + } +yy215: + YYDEBUG(215, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(216, *YYCURSOR); + if (yybm[0+yych] & 128) { + goto yy215; + } + YYDEBUG(217, *YYCURSOR); + ++YYCURSOR; + YYDEBUG(218, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 368 "Zend/zend_ini_scanner.l" + { /* Raw string */ + /* Eat leading and trailing single quotes */ + if (yytext[0] == '\'' && yytext[yyleng - 1] == '\'') { + SCNG(yy_text)++; + yyleng = yyleng - 2; + } + RETURN_TOKEN(TC_RAW, yytext, yyleng); +} +#line 2724 "Zend/zend_ini_scanner.c" +yy219: + YYDEBUG(219, *YYCURSOR); + ++YYCURSOR; + YYDEBUG(220, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 401 "Zend/zend_ini_scanner.l" + { /* Variable start */ + yy_push_state(ST_VARNAME TSRMLS_CC); + return TC_DOLLAR_CURLY; +} +#line 2735 "Zend/zend_ini_scanner.c" +yy221: + YYDEBUG(221, *YYCURSOR); + yyaccept = 0; + YYMARKER = ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(222, *YYCURSOR); + if (yych <= '"') { + if (yych <= '\f') { + if (yych <= 0x08) goto yy194; + if (yych <= '\t') goto yy221; + if (yych <= '\n') goto yy173; + goto yy194; + } else { + if (yych <= 0x1F) { + if (yych <= '\r') goto yy173; + goto yy194; + } else { + if (yych <= ' ') goto yy221; + if (yych <= '!') goto yy194; + } + } + } else { + if (yych <= ':') { + if (yych <= '$') { + if (yych <= '#') goto yy194; + goto yy197; + } else { + if (yych == '\'') goto yy173; + goto yy194; + } + } else { + if (yych <= '[') { + if (yych <= ';') goto yy173; + goto yy194; + } else { + if (yych <= '\\') goto yy196; + if (yych <= ']') goto yy173; + goto yy194; + } + } + } +yy223: + YYDEBUG(223, *YYCURSOR); + ++YYCURSOR; + yych = *YYCURSOR; + goto yy178; + } +/* *********************************** */ +yyc_ST_VALUE: + { + static const unsigned char yybm[] = { + 160, 162, 162, 162, 162, 162, 162, 162, + 162, 176, 128, 162, 162, 128, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + 176, 160, 160, 162, 168, 162, 160, 32, + 160, 160, 162, 162, 162, 162, 162, 162, + 230, 230, 230, 230, 230, 230, 230, 230, + 230, 230, 162, 160, 162, 160, 162, 162, + 162, 166, 166, 166, 166, 166, 166, 166, + 166, 166, 166, 166, 166, 166, 166, 166, + 166, 166, 166, 166, 166, 166, 166, 166, + 166, 166, 166, 162, 162, 162, 160, 166, + 162, 166, 166, 166, 166, 166, 166, 166, + 166, 166, 166, 166, 166, 166, 166, 166, + 166, 166, 166, 166, 166, 166, 166, 166, + 166, 166, 166, 162, 160, 162, 160, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, + }; + YYDEBUG(224, *YYCURSOR); + YYFILL(6); + yych = *YYCURSOR; + YYDEBUG(-1, yych); + switch (yych) { + case 0x00: goto yy226; + case '\t': + case ' ': goto yy230; + case '\n': goto yy232; + case '\r': goto yy234; + case '!': + case '&': + case '(': + case ')': + case '^': + case '|': + case '~': goto yy235; + case '"': goto yy237; + case '$': goto yy239; + case '\'': goto yy240; + case '-': goto yy241; + case '.': goto yy242; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy243; + case ';': goto yy245; + case '=': goto yy246; + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Z': + case '_': + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'p': + case 'q': + case 'r': + case 's': + case 'u': + case 'v': + case 'w': + case 'x': + case 'z': goto yy248; + case 'F': + case 'f': goto yy250; + case 'N': + case 'n': goto yy251; + case 'O': + case 'o': goto yy252; + case 'T': + case 't': goto yy253; + case 'Y': + case 'y': goto yy254; + default: goto yy228; + } +yy226: + YYDEBUG(226, *YYCURSOR); + ++YYCURSOR; +yy227: + YYDEBUG(227, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 598 "Zend/zend_ini_scanner.l" + { /* End of option value (if EOF is reached before EOL */ + BEGIN(INITIAL); + return END_OF_LINE; +} +#line 2921 "Zend/zend_ini_scanner.c" +yy228: + YYDEBUG(228, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + goto yy256; +yy229: + YYDEBUG(229, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 517 "Zend/zend_ini_scanner.l" + { /* Get everything else as option/offset value */ + RETURN_TOKEN(TC_STRING, yytext, yyleng); +} +#line 2934 "Zend/zend_ini_scanner.c" +yy230: + YYDEBUG(230, *YYCURSOR); + yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + goto yy306; +yy231: + YYDEBUG(231, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 571 "Zend/zend_ini_scanner.l" + { + RETURN_TOKEN(TC_WHITESPACE, yytext, yyleng); +} +#line 2947 "Zend/zend_ini_scanner.c" +yy232: + YYDEBUG(232, *YYCURSOR); + ++YYCURSOR; +yy233: + YYDEBUG(233, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 489 "Zend/zend_ini_scanner.l" + { /* End of option value */ + BEGIN(INITIAL); + SCNG(lineno)++; + return END_OF_LINE; +} +#line 2960 "Zend/zend_ini_scanner.c" +yy234: + YYDEBUG(234, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == '\n') goto yy304; + goto yy233; +yy235: + YYDEBUG(235, *YYCURSOR); + ++YYCURSOR; + yych = *YYCURSOR; + goto yy303; +yy236: + YYDEBUG(236, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 507 "Zend/zend_ini_scanner.l" + { /* Boolean operators */ + return yytext[0]; +} +#line 2978 "Zend/zend_ini_scanner.c" +yy237: + YYDEBUG(237, *YYCURSOR); + ++YYCURSOR; +yy238: + YYDEBUG(238, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 525 "Zend/zend_ini_scanner.l" + { /* Double quoted '"' string start */ + yy_push_state(ST_DOUBLE_QUOTES TSRMLS_CC); + return '"'; +} +#line 2990 "Zend/zend_ini_scanner.c" +yy239: + YYDEBUG(239, *YYCURSOR); + yych = *++YYCURSOR; + if (yych <= '\\') { + if (yych <= 0x00) goto yy227; + if (yych <= '[') goto yy255; + goto yy262; + } else { + if (yych == '{') goto yy300; + goto yy255; + } +yy240: + YYDEBUG(240, *YYCURSOR); + yyaccept = 2; + yych = *(YYMARKER = ++YYCURSOR); + if (yybm[0+yych] & 128) { + goto yy296; + } + goto yy227; +yy241: + YYDEBUG(241, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '/') goto yy256; + if (yych <= '9') goto yy294; + goto yy256; +yy242: + YYDEBUG(242, *YYCURSOR); + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '/') goto yy256; + if (yych <= '9') goto yy292; + goto yy256; +yy243: + YYDEBUG(243, *YYCURSOR); + yyaccept = 3; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '/') { + if (yych <= 0x1F) { + if (yych <= '\n') { + if (yych <= 0x00) goto yy244; + if (yych <= 0x08) goto yy256; + } else { + if (yych != '\r') goto yy256; + } + } else { + if (yych <= ')') { + if (yych <= '"') goto yy244; + if (yych <= '%') goto yy256; + } else { + if (yych == '.') goto yy288; + goto yy256; + } + } + } else { + if (yych <= ']') { + if (yych <= ';') { + if (yych <= '9') goto yy290; + if (yych <= ':') goto yy256; + } else { + if (yych != '=') goto yy256; + } + } else { + if (yych <= '|') { + if (yych <= '^') goto yy244; + if (yych <= '{') goto yy256; + } else { + if (yych != '~') goto yy256; + } + } + } +yy244: + YYDEBUG(244, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 499 "Zend/zend_ini_scanner.l" + { /* Get number option value as string */ + RETURN_TOKEN(TC_NUMBER, yytext, yyleng); +} +#line 3069 "Zend/zend_ini_scanner.c" +yy245: + YYDEBUG(245, *YYCURSOR); + yyaccept = 2; + yych = *(YYMARKER = ++YYCURSOR); + goto yy284; +yy246: + YYDEBUG(246, *YYCURSOR); + ++YYCURSOR; + YYDEBUG(247, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 511 "Zend/zend_ini_scanner.l" + { /* Make = used in option value to trigger error */ + yyless(0); + BEGIN(INITIAL); + return END_OF_LINE; +} +#line 3086 "Zend/zend_ini_scanner.c" +yy248: + YYDEBUG(248, *YYCURSOR); + yyaccept = 4; + yych = *(YYMARKER = ++YYCURSOR); + if (yybm[0+yych] & 4) { + goto yy257; + } + if (yych <= ':') { + if (yych <= '\r') { + if (yych <= 0x08) { + if (yych >= 0x01) goto yy256; + } else { + if (yych <= '\n') goto yy249; + if (yych <= '\f') goto yy256; + } + } else { + if (yych <= '"') { + if (yych <= 0x1F) goto yy256; + } else { + if (yych <= '%') goto yy256; + if (yych >= '*') goto yy256; + } + } + } else { + if (yych <= '^') { + if (yych <= '<') { + if (yych >= '<') goto yy256; + } else { + if (yych <= '=') goto yy249; + if (yych <= ']') goto yy256; + } + } else { + if (yych <= '|') { + if (yych <= '{') goto yy256; + } else { + if (yych != '~') goto yy256; + } + } + } +yy249: + YYDEBUG(249, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 495 "Zend/zend_ini_scanner.l" + { /* Get constant option value */ + RETURN_TOKEN(TC_CONSTANT, yytext, yyleng); +} +#line 3133 "Zend/zend_ini_scanner.c" +yy250: + YYDEBUG(250, *YYCURSOR); + yyaccept = 4; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '<') { + if (yych <= '"') { + if (yych <= '\n') { + if (yych <= 0x00) goto yy249; + if (yych <= 0x08) goto yy256; + goto yy249; + } else { + if (yych == '\r') goto yy249; + if (yych <= 0x1F) goto yy256; + goto yy249; + } + } else { + if (yych <= '/') { + if (yych <= '%') goto yy256; + if (yych <= ')') goto yy249; + goto yy256; + } else { + if (yych <= '9') goto yy257; + if (yych == ';') goto yy249; + goto yy256; + } + } + } else { + if (yych <= '_') { + if (yych <= 'A') { + if (yych <= '=') goto yy249; + if (yych <= '@') goto yy256; + goto yy280; + } else { + if (yych <= 'Z') goto yy257; + if (yych <= ']') goto yy256; + if (yych <= '^') goto yy249; + goto yy257; + } + } else { + if (yych <= '{') { + if (yych <= '`') goto yy256; + if (yych <= 'a') goto yy280; + if (yych <= 'z') goto yy257; + goto yy256; + } else { + if (yych == '}') goto yy256; + if (yych <= '~') goto yy249; + goto yy256; + } + } + } +yy251: + YYDEBUG(251, *YYCURSOR); + yyaccept = 4; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= 'N') { + if (yych <= '%') { + if (yych <= '\f') { + if (yych <= 0x00) goto yy249; + if (yych <= 0x08) goto yy256; + if (yych <= '\n') goto yy249; + goto yy256; + } else { + if (yych <= '\r') goto yy249; + if (yych <= 0x1F) goto yy256; + if (yych <= '"') goto yy249; + goto yy256; + } + } else { + if (yych <= ':') { + if (yych <= ')') goto yy249; + if (yych <= '/') goto yy256; + if (yych <= '9') goto yy257; + goto yy256; + } else { + if (yych <= '<') { + if (yych <= ';') goto yy249; + goto yy256; + } else { + if (yych <= '=') goto yy249; + if (yych <= '@') goto yy256; + goto yy257; + } + } + } + } else { + if (yych <= 'n') { + if (yych <= 'Z') { + if (yych <= 'O') goto yy276; + if (yych == 'U') goto yy277; + goto yy257; + } else { + if (yych <= '^') { + if (yych <= ']') goto yy256; + goto yy249; + } else { + if (yych == '`') goto yy256; + goto yy257; + } + } + } else { + if (yych <= 'z') { + if (yych <= 'o') goto yy276; + if (yych == 'u') goto yy277; + goto yy257; + } else { + if (yych <= '|') { + if (yych <= '{') goto yy256; + goto yy249; + } else { + if (yych == '~') goto yy249; + goto yy256; + } + } + } + } +yy252: + YYDEBUG(252, *YYCURSOR); + yyaccept = 4; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= 'E') { + if (yych <= '%') { + if (yych <= '\f') { + if (yych <= 0x00) goto yy249; + if (yych <= 0x08) goto yy256; + if (yych <= '\n') goto yy249; + goto yy256; + } else { + if (yych <= '\r') goto yy249; + if (yych <= 0x1F) goto yy256; + if (yych <= '"') goto yy249; + goto yy256; + } + } else { + if (yych <= ':') { + if (yych <= ')') goto yy249; + if (yych <= '/') goto yy256; + if (yych <= '9') goto yy257; + goto yy256; + } else { + if (yych <= '<') { + if (yych <= ';') goto yy249; + goto yy256; + } else { + if (yych <= '=') goto yy249; + if (yych <= '@') goto yy256; + goto yy257; + } + } + } + } else { + if (yych <= 'e') { + if (yych <= 'Z') { + if (yych <= 'F') goto yy271; + if (yych == 'N') goto yy265; + goto yy257; + } else { + if (yych <= '^') { + if (yych <= ']') goto yy256; + goto yy249; + } else { + if (yych == '`') goto yy256; + goto yy257; + } + } + } else { + if (yych <= 'z') { + if (yych <= 'f') goto yy271; + if (yych == 'n') goto yy265; + goto yy257; + } else { + if (yych <= '|') { + if (yych <= '{') goto yy256; + goto yy249; + } else { + if (yych == '~') goto yy249; + goto yy256; + } + } + } + } +yy253: + YYDEBUG(253, *YYCURSOR); + yyaccept = 4; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '=') { + if (yych <= '"') { + if (yych <= '\n') { + if (yych <= 0x00) goto yy249; + if (yych <= 0x08) goto yy256; + goto yy249; + } else { + if (yych == '\r') goto yy249; + if (yych <= 0x1F) goto yy256; + goto yy249; + } + } else { + if (yych <= '9') { + if (yych <= '%') goto yy256; + if (yych <= ')') goto yy249; + if (yych <= '/') goto yy256; + goto yy257; + } else { + if (yych == ';') goto yy249; + if (yych <= '<') goto yy256; + goto yy249; + } + } + } else { + if (yych <= '`') { + if (yych <= 'Z') { + if (yych <= '@') goto yy256; + if (yych == 'R') goto yy269; + goto yy257; + } else { + if (yych <= ']') goto yy256; + if (yych <= '^') goto yy249; + if (yych <= '_') goto yy257; + goto yy256; + } + } else { + if (yych <= '{') { + if (yych == 'r') goto yy269; + if (yych <= 'z') goto yy257; + goto yy256; + } else { + if (yych == '}') goto yy256; + if (yych <= '~') goto yy249; + goto yy256; + } + } + } +yy254: + YYDEBUG(254, *YYCURSOR); + yyaccept = 4; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '=') { + if (yych <= '"') { + if (yych <= '\n') { + if (yych <= 0x00) goto yy249; + if (yych <= 0x08) goto yy256; + goto yy249; + } else { + if (yych == '\r') goto yy249; + if (yych <= 0x1F) goto yy256; + goto yy249; + } + } else { + if (yych <= '9') { + if (yych <= '%') goto yy256; + if (yych <= ')') goto yy249; + if (yych <= '/') goto yy256; + goto yy257; + } else { + if (yych == ';') goto yy249; + if (yych <= '<') goto yy256; + goto yy249; + } + } + } else { + if (yych <= '`') { + if (yych <= 'Z') { + if (yych <= '@') goto yy256; + if (yych == 'E') goto yy259; + goto yy257; + } else { + if (yych <= ']') goto yy256; + if (yych <= '^') goto yy249; + if (yych <= '_') goto yy257; + goto yy256; + } + } else { + if (yych <= '{') { + if (yych == 'e') goto yy259; + if (yych <= 'z') goto yy257; + goto yy256; + } else { + if (yych == '}') goto yy256; + if (yych <= '~') goto yy249; + goto yy256; + } + } + } +yy255: + YYDEBUG(255, *YYCURSOR); + yyaccept = 0; + YYMARKER = ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; +yy256: + YYDEBUG(256, *YYCURSOR); + if (yybm[0+yych] & 2) { + goto yy255; + } + if (yych == '$') goto yy260; + goto yy229; +yy257: + YYDEBUG(257, *YYCURSOR); + yyaccept = 4; + YYMARKER = ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(258, *YYCURSOR); + if (yybm[0+yych] & 4) { + goto yy257; + } + if (yych <= ')') { + if (yych <= '\r') { + if (yych <= 0x08) { + if (yych <= 0x00) goto yy249; + goto yy255; + } else { + if (yych <= '\n') goto yy249; + if (yych <= '\f') goto yy255; + goto yy249; + } + } else { + if (yych <= '#') { + if (yych <= 0x1F) goto yy255; + if (yych <= '"') goto yy249; + goto yy255; + } else { + if (yych <= '$') goto yy260; + if (yych <= '%') goto yy255; + goto yy249; + } + } + } else { + if (yych <= ']') { + if (yych <= ';') { + if (yych <= ':') goto yy255; + goto yy249; + } else { + if (yych == '=') goto yy249; + goto yy255; + } + } else { + if (yych <= '|') { + if (yych <= '^') goto yy249; + if (yych <= '{') goto yy255; + goto yy249; + } else { + if (yych == '~') goto yy249; + goto yy255; + } + } + } +yy259: + YYDEBUG(259, *YYCURSOR); + yyaccept = 4; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '=') { + if (yych <= '"') { + if (yych <= '\n') { + if (yych <= 0x00) goto yy249; + if (yych <= 0x08) goto yy256; + goto yy249; + } else { + if (yych == '\r') goto yy249; + if (yych <= 0x1F) goto yy256; + goto yy249; + } + } else { + if (yych <= '9') { + if (yych <= '%') goto yy256; + if (yych <= ')') goto yy249; + if (yych <= '/') goto yy256; + goto yy257; + } else { + if (yych == ';') goto yy249; + if (yych <= '<') goto yy256; + goto yy249; + } + } + } else { + if (yych <= '`') { + if (yych <= 'Z') { + if (yych <= '@') goto yy256; + if (yych == 'S') goto yy265; + goto yy257; + } else { + if (yych <= ']') goto yy256; + if (yych <= '^') goto yy249; + if (yych <= '_') goto yy257; + goto yy256; + } + } else { + if (yych <= '{') { + if (yych == 's') goto yy265; + if (yych <= 'z') goto yy257; + goto yy256; + } else { + if (yych == '}') goto yy256; + if (yych <= '~') goto yy249; + goto yy256; + } + } + } +yy260: + YYDEBUG(260, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + if (yych <= '\\') { + if (yych <= 0x00) goto yy261; + if (yych <= '[') goto yy255; + goto yy262; + } else { + if (yych != '{') goto yy255; + } +yy261: + YYDEBUG(261, *YYCURSOR); + YYCURSOR = YYMARKER; + if (yyaccept <= 3) { + if (yyaccept <= 1) { + if (yyaccept <= 0) { + goto yy229; + } else { + goto yy231; + } + } else { + if (yyaccept <= 2) { + goto yy227; + } else { + goto yy244; + } + } + } else { + if (yyaccept <= 5) { + if (yyaccept <= 4) { + goto yy249; + } else { + goto yy266; + } + } else { + goto yy273; + } + } +yy262: + YYDEBUG(262, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + if (yybm[0+yych] & 8) { + goto yy263; + } + goto yy255; +yy263: + YYDEBUG(263, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(264, *YYCURSOR); + if (yybm[0+yych] & 8) { + goto yy263; + } + if (yych <= 0x00) goto yy229; + if (yych == '\\') goto yy262; + goto yy255; +yy265: + YYDEBUG(265, *YYCURSOR); + yyaccept = 5; + yych = *(YYMARKER = ++YYCURSOR); + if (yybm[0+yych] & 16) { + goto yy267; + } + if (yych <= ';') { + if (yych <= ' ') { + if (yych <= '\n') { + if (yych <= 0x00) goto yy266; + if (yych <= '\t') goto yy256; + } else { + if (yych != '\r') goto yy256; + } + } else { + if (yych <= ')') { + if (yych <= '"') goto yy266; + if (yych <= '%') goto yy256; + } else { + if (yych <= '/') goto yy256; + if (yych <= '9') goto yy257; + if (yych <= ':') goto yy256; + } + } + } else { + if (yych <= '_') { + if (yych <= '@') { + if (yych != '=') goto yy256; + } else { + if (yych <= 'Z') goto yy257; + if (yych <= ']') goto yy256; + if (yych >= '_') goto yy257; + } + } else { + if (yych <= '{') { + if (yych <= '`') goto yy256; + if (yych <= 'z') goto yy257; + goto yy256; + } else { + if (yych == '}') goto yy256; + if (yych >= 0x7F) goto yy256; + } + } + } +yy266: + YYDEBUG(266, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 421 "Zend/zend_ini_scanner.l" + { /* TRUE value (when used outside option value/offset this causes parse error!) */ + RETURN_TOKEN(BOOL_TRUE, "1", 1); +} +#line 3645 "Zend/zend_ini_scanner.c" +yy267: + YYDEBUG(267, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(268, *YYCURSOR); + if (yybm[0+yych] & 16) { + goto yy267; + } + goto yy266; +yy269: + YYDEBUG(269, *YYCURSOR); + yyaccept = 4; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '=') { + if (yych <= '"') { + if (yych <= '\n') { + if (yych <= 0x00) goto yy249; + if (yych <= 0x08) goto yy256; + goto yy249; + } else { + if (yych == '\r') goto yy249; + if (yych <= 0x1F) goto yy256; + goto yy249; + } + } else { + if (yych <= '9') { + if (yych <= '%') goto yy256; + if (yych <= ')') goto yy249; + if (yych <= '/') goto yy256; + goto yy257; + } else { + if (yych == ';') goto yy249; + if (yych <= '<') goto yy256; + goto yy249; + } + } + } else { + if (yych <= '`') { + if (yych <= 'Z') { + if (yych <= '@') goto yy256; + if (yych != 'U') goto yy257; + } else { + if (yych <= ']') goto yy256; + if (yych <= '^') goto yy249; + if (yych <= '_') goto yy257; + goto yy256; + } + } else { + if (yych <= '{') { + if (yych == 'u') goto yy270; + if (yych <= 'z') goto yy257; + goto yy256; + } else { + if (yych == '}') goto yy256; + if (yych <= '~') goto yy249; + goto yy256; + } + } + } +yy270: + YYDEBUG(270, *YYCURSOR); + yyaccept = 4; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '=') { + if (yych <= '"') { + if (yych <= '\n') { + if (yych <= 0x00) goto yy249; + if (yych <= 0x08) goto yy256; + goto yy249; + } else { + if (yych == '\r') goto yy249; + if (yych <= 0x1F) goto yy256; + goto yy249; + } + } else { + if (yych <= '9') { + if (yych <= '%') goto yy256; + if (yych <= ')') goto yy249; + if (yych <= '/') goto yy256; + goto yy257; + } else { + if (yych == ';') goto yy249; + if (yych <= '<') goto yy256; + goto yy249; + } + } + } else { + if (yych <= '`') { + if (yych <= 'Z') { + if (yych <= '@') goto yy256; + if (yych == 'E') goto yy265; + goto yy257; + } else { + if (yych <= ']') goto yy256; + if (yych <= '^') goto yy249; + if (yych <= '_') goto yy257; + goto yy256; + } + } else { + if (yych <= '{') { + if (yych == 'e') goto yy265; + if (yych <= 'z') goto yy257; + goto yy256; + } else { + if (yych == '}') goto yy256; + if (yych <= '~') goto yy249; + goto yy256; + } + } + } +yy271: + YYDEBUG(271, *YYCURSOR); + yyaccept = 4; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '=') { + if (yych <= '"') { + if (yych <= '\n') { + if (yych <= 0x00) goto yy249; + if (yych <= 0x08) goto yy256; + goto yy249; + } else { + if (yych == '\r') goto yy249; + if (yych <= 0x1F) goto yy256; + goto yy249; + } + } else { + if (yych <= '9') { + if (yych <= '%') goto yy256; + if (yych <= ')') goto yy249; + if (yych <= '/') goto yy256; + goto yy257; + } else { + if (yych == ';') goto yy249; + if (yych <= '<') goto yy256; + goto yy249; + } + } + } else { + if (yych <= '`') { + if (yych <= 'Z') { + if (yych <= '@') goto yy256; + if (yych != 'F') goto yy257; + } else { + if (yych <= ']') goto yy256; + if (yych <= '^') goto yy249; + if (yych <= '_') goto yy257; + goto yy256; + } + } else { + if (yych <= '{') { + if (yych == 'f') goto yy272; + if (yych <= 'z') goto yy257; + goto yy256; + } else { + if (yych == '}') goto yy256; + if (yych <= '~') goto yy249; + goto yy256; + } + } + } +yy272: + YYDEBUG(272, *YYCURSOR); + yyaccept = 6; + yych = *(YYMARKER = ++YYCURSOR); + if (yybm[0+yych] & 4) { + goto yy257; + } + if (yych <= ')') { + if (yych <= '\f') { + if (yych <= 0x08) { + if (yych >= 0x01) goto yy256; + } else { + if (yych <= '\t') goto yy274; + if (yych >= '\v') goto yy256; + } + } else { + if (yych <= ' ') { + if (yych <= '\r') goto yy273; + if (yych <= 0x1F) goto yy256; + goto yy274; + } else { + if (yych <= '"') goto yy273; + if (yych <= '%') goto yy256; + } + } + } else { + if (yych <= ']') { + if (yych <= ';') { + if (yych <= ':') goto yy256; + } else { + if (yych != '=') goto yy256; + } + } else { + if (yych <= '|') { + if (yych <= '^') goto yy273; + if (yych <= '{') goto yy256; + } else { + if (yych != '~') goto yy256; + } + } + } +yy273: + YYDEBUG(273, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 425 "Zend/zend_ini_scanner.l" + { /* FALSE value (when used outside option value/offset this causes parse error!)*/ + RETURN_TOKEN(BOOL_FALSE, "", 0); +} +#line 3855 "Zend/zend_ini_scanner.c" +yy274: + YYDEBUG(274, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(275, *YYCURSOR); + if (yych == '\t') goto yy274; + if (yych == ' ') goto yy274; + goto yy273; +yy276: + YYDEBUG(276, *YYCURSOR); + yyaccept = 6; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '<') { + if (yych <= ' ') { + if (yych <= '\n') { + if (yych <= 0x00) goto yy273; + if (yych <= 0x08) goto yy256; + if (yych <= '\t') goto yy274; + goto yy273; + } else { + if (yych == '\r') goto yy273; + if (yych <= 0x1F) goto yy256; + goto yy274; + } + } else { + if (yych <= '/') { + if (yych <= '"') goto yy273; + if (yych <= '%') goto yy256; + if (yych <= ')') goto yy273; + goto yy256; + } else { + if (yych <= '9') goto yy257; + if (yych == ';') goto yy273; + goto yy256; + } + } + } else { + if (yych <= '_') { + if (yych <= 'N') { + if (yych <= '=') goto yy273; + if (yych <= '@') goto yy256; + if (yych <= 'M') goto yy257; + goto yy279; + } else { + if (yych <= 'Z') goto yy257; + if (yych <= ']') goto yy256; + if (yych <= '^') goto yy273; + goto yy257; + } + } else { + if (yych <= 'z') { + if (yych <= '`') goto yy256; + if (yych == 'n') goto yy279; + goto yy257; + } else { + if (yych <= '|') { + if (yych <= '{') goto yy256; + goto yy273; + } else { + if (yych == '~') goto yy273; + goto yy256; + } + } + } + } +yy277: + YYDEBUG(277, *YYCURSOR); + yyaccept = 4; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '=') { + if (yych <= '"') { + if (yych <= '\n') { + if (yych <= 0x00) goto yy249; + if (yych <= 0x08) goto yy256; + goto yy249; + } else { + if (yych == '\r') goto yy249; + if (yych <= 0x1F) goto yy256; + goto yy249; + } + } else { + if (yych <= '9') { + if (yych <= '%') goto yy256; + if (yych <= ')') goto yy249; + if (yych <= '/') goto yy256; + goto yy257; + } else { + if (yych == ';') goto yy249; + if (yych <= '<') goto yy256; + goto yy249; + } + } + } else { + if (yych <= '`') { + if (yych <= 'Z') { + if (yych <= '@') goto yy256; + if (yych != 'L') goto yy257; + } else { + if (yych <= ']') goto yy256; + if (yych <= '^') goto yy249; + if (yych <= '_') goto yy257; + goto yy256; + } + } else { + if (yych <= '{') { + if (yych == 'l') goto yy278; + if (yych <= 'z') goto yy257; + goto yy256; + } else { + if (yych == '}') goto yy256; + if (yych <= '~') goto yy249; + goto yy256; + } + } + } +yy278: + YYDEBUG(278, *YYCURSOR); + yyaccept = 4; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '=') { + if (yych <= '"') { + if (yych <= '\n') { + if (yych <= 0x00) goto yy249; + if (yych <= 0x08) goto yy256; + goto yy249; + } else { + if (yych == '\r') goto yy249; + if (yych <= 0x1F) goto yy256; + goto yy249; + } + } else { + if (yych <= '9') { + if (yych <= '%') goto yy256; + if (yych <= ')') goto yy249; + if (yych <= '/') goto yy256; + goto yy257; + } else { + if (yych == ';') goto yy249; + if (yych <= '<') goto yy256; + goto yy249; + } + } + } else { + if (yych <= '`') { + if (yych <= 'Z') { + if (yych <= '@') goto yy256; + if (yych == 'L') goto yy272; + goto yy257; + } else { + if (yych <= ']') goto yy256; + if (yych <= '^') goto yy249; + if (yych <= '_') goto yy257; + goto yy256; + } + } else { + if (yych <= '{') { + if (yych == 'l') goto yy272; + if (yych <= 'z') goto yy257; + goto yy256; + } else { + if (yych == '}') goto yy256; + if (yych <= '~') goto yy249; + goto yy256; + } + } + } +yy279: + YYDEBUG(279, *YYCURSOR); + yyaccept = 4; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '=') { + if (yych <= '"') { + if (yych <= '\n') { + if (yych <= 0x00) goto yy249; + if (yych <= 0x08) goto yy256; + goto yy249; + } else { + if (yych == '\r') goto yy249; + if (yych <= 0x1F) goto yy256; + goto yy249; + } + } else { + if (yych <= '9') { + if (yych <= '%') goto yy256; + if (yych <= ')') goto yy249; + if (yych <= '/') goto yy256; + goto yy257; + } else { + if (yych == ';') goto yy249; + if (yych <= '<') goto yy256; + goto yy249; + } + } + } else { + if (yych <= '`') { + if (yych <= 'Z') { + if (yych <= '@') goto yy256; + if (yych == 'E') goto yy272; + goto yy257; + } else { + if (yych <= ']') goto yy256; + if (yych <= '^') goto yy249; + if (yych <= '_') goto yy257; + goto yy256; + } + } else { + if (yych <= '{') { + if (yych == 'e') goto yy272; + if (yych <= 'z') goto yy257; + goto yy256; + } else { + if (yych == '}') goto yy256; + if (yych <= '~') goto yy249; + goto yy256; + } + } + } +yy280: + YYDEBUG(280, *YYCURSOR); + yyaccept = 4; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '=') { + if (yych <= '"') { + if (yych <= '\n') { + if (yych <= 0x00) goto yy249; + if (yych <= 0x08) goto yy256; + goto yy249; + } else { + if (yych == '\r') goto yy249; + if (yych <= 0x1F) goto yy256; + goto yy249; + } + } else { + if (yych <= '9') { + if (yych <= '%') goto yy256; + if (yych <= ')') goto yy249; + if (yych <= '/') goto yy256; + goto yy257; + } else { + if (yych == ';') goto yy249; + if (yych <= '<') goto yy256; + goto yy249; + } + } + } else { + if (yych <= '`') { + if (yych <= 'Z') { + if (yych <= '@') goto yy256; + if (yych != 'L') goto yy257; + } else { + if (yych <= ']') goto yy256; + if (yych <= '^') goto yy249; + if (yych <= '_') goto yy257; + goto yy256; + } + } else { + if (yych <= '{') { + if (yych == 'l') goto yy281; + if (yych <= 'z') goto yy257; + goto yy256; + } else { + if (yych == '}') goto yy256; + if (yych <= '~') goto yy249; + goto yy256; + } + } + } +yy281: + YYDEBUG(281, *YYCURSOR); + yyaccept = 4; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '=') { + if (yych <= '"') { + if (yych <= '\n') { + if (yych <= 0x00) goto yy249; + if (yych <= 0x08) goto yy256; + goto yy249; + } else { + if (yych == '\r') goto yy249; + if (yych <= 0x1F) goto yy256; + goto yy249; + } + } else { + if (yych <= '9') { + if (yych <= '%') goto yy256; + if (yych <= ')') goto yy249; + if (yych <= '/') goto yy256; + goto yy257; + } else { + if (yych == ';') goto yy249; + if (yych <= '<') goto yy256; + goto yy249; + } + } + } else { + if (yych <= '`') { + if (yych <= 'Z') { + if (yych <= '@') goto yy256; + if (yych != 'S') goto yy257; + } else { + if (yych <= ']') goto yy256; + if (yych <= '^') goto yy249; + if (yych <= '_') goto yy257; + goto yy256; + } + } else { + if (yych <= '{') { + if (yych == 's') goto yy282; + if (yych <= 'z') goto yy257; + goto yy256; + } else { + if (yych == '}') goto yy256; + if (yych <= '~') goto yy249; + goto yy256; + } + } + } +yy282: + YYDEBUG(282, *YYCURSOR); + yyaccept = 4; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '=') { + if (yych <= '"') { + if (yych <= '\n') { + if (yych <= 0x00) goto yy249; + if (yych <= 0x08) goto yy256; + goto yy249; + } else { + if (yych == '\r') goto yy249; + if (yych <= 0x1F) goto yy256; + goto yy249; + } + } else { + if (yych <= '9') { + if (yych <= '%') goto yy256; + if (yych <= ')') goto yy249; + if (yych <= '/') goto yy256; + goto yy257; + } else { + if (yych == ';') goto yy249; + if (yych <= '<') goto yy256; + goto yy249; + } + } + } else { + if (yych <= '`') { + if (yych <= 'Z') { + if (yych <= '@') goto yy256; + if (yych == 'E') goto yy272; + goto yy257; + } else { + if (yych <= ']') goto yy256; + if (yych <= '^') goto yy249; + if (yych <= '_') goto yy257; + goto yy256; + } + } else { + if (yych <= '{') { + if (yych == 'e') goto yy272; + if (yych <= 'z') goto yy257; + goto yy256; + } else { + if (yych == '}') goto yy256; + if (yych <= '~') goto yy249; + goto yy256; + } + } + } +yy283: + YYDEBUG(283, *YYCURSOR); + ++YYCURSOR; + YYFILL(2); + yych = *YYCURSOR; +yy284: + YYDEBUG(284, *YYCURSOR); + if (yybm[0+yych] & 32) { + goto yy283; + } + if (yych >= '\r') goto yy287; +yy285: + YYDEBUG(285, *YYCURSOR); + ++YYCURSOR; +yy286: + YYDEBUG(286, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 585 "Zend/zend_ini_scanner.l" + { /* Comment */ + BEGIN(INITIAL); + SCNG(lineno)++; + return END_OF_LINE; +} +#line 4248 "Zend/zend_ini_scanner.c" +yy287: + YYDEBUG(287, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == '\n') goto yy285; + goto yy286; +yy288: + YYDEBUG(288, *YYCURSOR); + yyaccept = 3; + YYMARKER = ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(289, *YYCURSOR); + if (yybm[0+yych] & 64) { + goto yy288; + } + if (yych <= ')') { + if (yych <= '\r') { + if (yych <= 0x08) { + if (yych <= 0x00) goto yy244; + goto yy255; + } else { + if (yych <= '\n') goto yy244; + if (yych <= '\f') goto yy255; + goto yy244; + } + } else { + if (yych <= '#') { + if (yych <= 0x1F) goto yy255; + if (yych <= '"') goto yy244; + goto yy255; + } else { + if (yych <= '$') goto yy260; + if (yych <= '%') goto yy255; + goto yy244; + } + } + } else { + if (yych <= ']') { + if (yych <= ';') { + if (yych <= ':') goto yy255; + goto yy244; + } else { + if (yych == '=') goto yy244; + goto yy255; + } + } else { + if (yych <= '|') { + if (yych <= '^') goto yy244; + if (yych <= '{') goto yy255; + goto yy244; + } else { + if (yych == '~') goto yy244; + goto yy255; + } + } + } +yy290: + YYDEBUG(290, *YYCURSOR); + yyaccept = 3; + YYMARKER = ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(291, *YYCURSOR); + if (yych <= '.') { + if (yych <= 0x1F) { + if (yych <= '\n') { + if (yych <= 0x00) goto yy244; + if (yych <= 0x08) goto yy255; + goto yy244; + } else { + if (yych == '\r') goto yy244; + goto yy255; + } + } else { + if (yych <= '$') { + if (yych <= '"') goto yy244; + if (yych <= '#') goto yy255; + goto yy260; + } else { + if (yych <= '%') goto yy255; + if (yych <= ')') goto yy244; + if (yych <= '-') goto yy255; + goto yy288; + } + } + } else { + if (yych <= '=') { + if (yych <= ':') { + if (yych <= '/') goto yy255; + if (yych <= '9') goto yy290; + goto yy255; + } else { + if (yych == '<') goto yy255; + goto yy244; + } + } else { + if (yych <= '{') { + if (yych == '^') goto yy244; + goto yy255; + } else { + if (yych == '}') goto yy255; + if (yych <= '~') goto yy244; + goto yy255; + } + } + } +yy292: + YYDEBUG(292, *YYCURSOR); + yyaccept = 3; + YYMARKER = ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(293, *YYCURSOR); + if (yych <= '/') { + if (yych <= 0x1F) { + if (yych <= '\n') { + if (yych <= 0x00) goto yy244; + if (yych <= 0x08) goto yy255; + goto yy244; + } else { + if (yych == '\r') goto yy244; + goto yy255; + } + } else { + if (yych <= '$') { + if (yych <= '"') goto yy244; + if (yych <= '#') goto yy255; + goto yy260; + } else { + if (yych <= '%') goto yy255; + if (yych <= ')') goto yy244; + goto yy255; + } + } + } else { + if (yych <= ']') { + if (yych <= ';') { + if (yych <= '9') goto yy292; + if (yych <= ':') goto yy255; + goto yy244; + } else { + if (yych == '=') goto yy244; + goto yy255; + } + } else { + if (yych <= '|') { + if (yych <= '^') goto yy244; + if (yych <= '{') goto yy255; + goto yy244; + } else { + if (yych == '~') goto yy244; + goto yy255; + } + } + } +yy294: + YYDEBUG(294, *YYCURSOR); + yyaccept = 3; + YYMARKER = ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(295, *YYCURSOR); + if (yych <= '/') { + if (yych <= 0x1F) { + if (yych <= '\n') { + if (yych <= 0x00) goto yy244; + if (yych <= 0x08) goto yy255; + goto yy244; + } else { + if (yych == '\r') goto yy244; + goto yy255; + } + } else { + if (yych <= '$') { + if (yych <= '"') goto yy244; + if (yych <= '#') goto yy255; + goto yy260; + } else { + if (yych <= '%') goto yy255; + if (yych <= ')') goto yy244; + goto yy255; + } + } + } else { + if (yych <= ']') { + if (yych <= ';') { + if (yych <= '9') goto yy294; + if (yych <= ':') goto yy255; + goto yy244; + } else { + if (yych == '=') goto yy244; + goto yy255; + } + } else { + if (yych <= '|') { + if (yych <= '^') goto yy244; + if (yych <= '{') goto yy255; + goto yy244; + } else { + if (yych == '~') goto yy244; + goto yy255; + } + } + } +yy296: + YYDEBUG(296, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(297, *YYCURSOR); + if (yybm[0+yych] & 128) { + goto yy296; + } + YYDEBUG(298, *YYCURSOR); + ++YYCURSOR; + YYDEBUG(299, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 368 "Zend/zend_ini_scanner.l" + { /* Raw string */ + /* Eat leading and trailing single quotes */ + if (yytext[0] == '\'' && yytext[yyleng - 1] == '\'') { + SCNG(yy_text)++; + yyleng = yyleng - 2; + } + RETURN_TOKEN(TC_RAW, yytext, yyleng); +} +#line 4475 "Zend/zend_ini_scanner.c" +yy300: + YYDEBUG(300, *YYCURSOR); + ++YYCURSOR; + YYDEBUG(301, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 401 "Zend/zend_ini_scanner.l" + { /* Variable start */ + yy_push_state(ST_VARNAME TSRMLS_CC); + return TC_DOLLAR_CURLY; +} +#line 4486 "Zend/zend_ini_scanner.c" +yy302: + YYDEBUG(302, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; +yy303: + YYDEBUG(303, *YYCURSOR); + if (yych == '\t') goto yy302; + if (yych == ' ') goto yy302; + goto yy236; +yy304: + YYDEBUG(304, *YYCURSOR); + yych = *++YYCURSOR; + goto yy233; +yy305: + YYDEBUG(305, *YYCURSOR); + yyaccept = 1; + YYMARKER = ++YYCURSOR; + YYFILL(2); + yych = *YYCURSOR; +yy306: + YYDEBUG(306, *YYCURSOR); + if (yych <= 0x1F) { + if (yych <= '\n') { + if (yych <= 0x08) goto yy231; + if (yych <= '\t') goto yy305; + goto yy304; + } else { + if (yych == '\r') goto yy308; + goto yy231; + } + } else { + if (yych <= '"') { + if (yych <= ' ') goto yy305; + if (yych <= '!') goto yy231; + } else { + if (yych == ';') goto yy283; + goto yy231; + } + } + YYDEBUG(307, *YYCURSOR); + yych = *++YYCURSOR; + goto yy238; +yy308: + YYDEBUG(308, *YYCURSOR); + ++YYCURSOR; + if ((yych = *YYCURSOR) == '\n') goto yy304; + goto yy233; + } +/* *********************************** */ +yyc_ST_VARNAME: + { + static const unsigned char yybm[] = { + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 0, 0, 128, 128, 0, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 0, 0, 128, 0, 128, 0, 128, + 0, 0, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 0, 128, 0, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 0, 128, 128, 0, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 0, 0, 0, 0, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + }; + YYDEBUG(309, *YYCURSOR); + YYFILL(2); + yych = *YYCURSOR; + if (yych <= ')') { + if (yych <= '"') { + if (yych <= '\f') { + if (yych <= 0x08) goto yy311; + if (yych <= '\n') goto yy313; + } else { + if (yych <= '\r') goto yy313; + if (yych >= '!') goto yy313; + } + } else { + if (yych <= '%') { + if (yych == '$') goto yy313; + } else { + if (yych != '\'') goto yy313; + } + } + } else { + if (yych <= '[') { + if (yych <= '<') { + if (yych == ';') goto yy313; + } else { + if (yych <= '=') goto yy313; + if (yych >= '[') goto yy313; + } + } else { + if (yych <= 'z') { + if (yych == '^') goto yy313; + } else { + if (yych == '}') goto yy315; + if (yych <= '~') goto yy313; + } + } + } +yy311: + YYDEBUG(311, *YYCURSOR); + ++YYCURSOR; + yych = *YYCURSOR; + goto yy318; +yy312: + YYDEBUG(312, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 406 "Zend/zend_ini_scanner.l" + { /* Variable name */ + /* Eat leading whitespace */ + EAT_LEADING_WHITESPACE(); + + /* Eat trailing whitespace */ + EAT_TRAILING_WHITESPACE(); + + RETURN_TOKEN(TC_VARNAME, yytext, yyleng); +} +#line 4627 "Zend/zend_ini_scanner.c" +yy313: + YYDEBUG(313, *YYCURSOR); + ++YYCURSOR; + YYDEBUG(314, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 603 "Zend/zend_ini_scanner.l" + { + return 0; +} +#line 4637 "Zend/zend_ini_scanner.c" +yy315: + YYDEBUG(315, *YYCURSOR); + ++YYCURSOR; + YYDEBUG(316, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 416 "Zend/zend_ini_scanner.l" + { /* Variable end */ + yy_pop_state(TSRMLS_C); + return '}'; +} +#line 4648 "Zend/zend_ini_scanner.c" +yy317: + YYDEBUG(317, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; +yy318: + YYDEBUG(318, *YYCURSOR); + if (yybm[0+yych] & 128) { + goto yy317; + } + goto yy312; + } +} +#line 607 "Zend/zend_ini_scanner.l" + +} diff --git a/Zend/zend_interfaces.c b/Zend/zend_interfaces.c index 16751549b46c2..b2c7eb7dd6aa7 100644 --- a/Zend/zend_interfaces.c +++ b/Zend/zend_interfaces.c @@ -162,7 +162,7 @@ ZEND_API int zend_user_it_valid(zend_object_iterator *_iter TSRMLS_DC) zend_call_method_with_0_params(&object, iter->ce, &iter->ce->iterator_funcs.zf_valid, "valid", &more); if (more) { - result = i_zend_is_true(more); + result = i_zend_is_true(more TSRMLS_CC); zval_ptr_dtor(&more); return result ? SUCCESS : FAILURE; } diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 403146e16486e..d8874df7f384e 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -212,6 +212,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); %token T_NS_C "__NAMESPACE__ (T_NS_C)" %token T_DIR "__DIR__ (T_DIR)" %token T_NS_SEPARATOR "\\ (T_NS_SEPARATOR)" +%token T_ELLIPSIS "... (T_ELLIPSIS)" %% /* Rules */ @@ -240,6 +241,8 @@ top_statement: | T_NAMESPACE '{' { zend_do_begin_namespace(NULL, 1 TSRMLS_CC); } top_statement_list '}' { zend_do_end_namespace(TSRMLS_C); } | T_USE use_declarations ';' { zend_verify_namespace(TSRMLS_C); } + | T_USE T_FUNCTION use_function_declarations ';' { zend_verify_namespace(TSRMLS_C); } + | T_USE T_CONST use_const_declarations ';' { zend_verify_namespace(TSRMLS_C); } | constant_declaration ';' { zend_verify_namespace(TSRMLS_C); } ; @@ -255,6 +258,30 @@ use_declaration: | T_NS_SEPARATOR namespace_name T_AS T_STRING { zend_do_use(&$2, &$4, 1 TSRMLS_CC); } ; +use_function_declarations: + use_function_declarations ',' use_function_declaration + | use_function_declaration +; + +use_function_declaration: + namespace_name { zend_do_use_function(&$1, NULL, 0 TSRMLS_CC); } + | namespace_name T_AS T_STRING { zend_do_use_function(&$1, &$3, 0 TSRMLS_CC); } + | T_NS_SEPARATOR namespace_name { zend_do_use_function(&$2, NULL, 1 TSRMLS_CC); } + | T_NS_SEPARATOR namespace_name T_AS T_STRING { zend_do_use_function(&$2, &$4, 1 TSRMLS_CC); } +; + +use_const_declarations: + use_const_declarations ',' use_const_declaration + | use_const_declaration +; + +use_const_declaration: + namespace_name { zend_do_use_const(&$1, NULL, 0 TSRMLS_CC); } + | namespace_name T_AS T_STRING { zend_do_use_const(&$1, &$3, 0 TSRMLS_CC); } + | T_NS_SEPARATOR namespace_name { zend_do_use_const(&$2, NULL, 1 TSRMLS_CC); } + | T_NS_SEPARATOR namespace_name T_AS T_STRING { zend_do_use_const(&$2, &$4, 1 TSRMLS_CC); } +; + constant_declaration: constant_declaration ',' T_STRING '=' static_scalar { zend_do_declare_constant(&$3, &$5 TSRMLS_CC); } | T_CONST T_STRING '=' static_scalar { zend_do_declare_constant(&$2, &$4 TSRMLS_CC); } @@ -270,7 +297,7 @@ inner_statement: statement | function_declaration_statement | class_declaration_statement - | T_HALT_COMPILER '(' ')' ';' { zend_error(E_COMPILE_ERROR, "__HALT_COMPILER() can only be used from the outermost scope"); } + | T_HALT_COMPILER '(' ')' ';' { zend_error_noreturn(E_COMPILE_ERROR, "__HALT_COMPILER() can only be used from the outermost scope"); } ; @@ -371,10 +398,14 @@ class_declaration_statement: ; is_reference: - /* empty */ { $$.op_type = ZEND_RETURN_VAL; } - | '&' { $$.op_type = ZEND_RETURN_REF; } + /* empty */ { $$.op_type = 0; } + | '&' { $$.op_type = 1; } ; +is_variadic: + /* empty */ { $$.op_type = 0; } + | T_ELLIPSIS { $$.op_type = 1; } +; unticked_function_declaration_statement: function is_reference T_STRING { zend_do_begin_function_declaration(&$1, &$3, 0, $2.op_type, NULL TSRMLS_CC); } @@ -523,14 +554,15 @@ parameter_list: non_empty_parameter_list: - optional_class_type T_VARIABLE { $$.op_type = IS_UNUSED; $$.u.op.num=1; zend_do_receive_arg(ZEND_RECV, &$2, &$$, NULL, &$1, 0 TSRMLS_CC); } - | optional_class_type '&' T_VARIABLE { $$.op_type = IS_UNUSED; $$.u.op.num=1; zend_do_receive_arg(ZEND_RECV, &$3, &$$, NULL, &$1, 1 TSRMLS_CC); } - | optional_class_type '&' T_VARIABLE '=' static_scalar { $$.op_type = IS_UNUSED; $$.u.op.num=1; zend_do_receive_arg(ZEND_RECV_INIT, &$3, &$$, &$5, &$1, 1 TSRMLS_CC); } - | optional_class_type T_VARIABLE '=' static_scalar { $$.op_type = IS_UNUSED; $$.u.op.num=1; zend_do_receive_arg(ZEND_RECV_INIT, &$2, &$$, &$4, &$1, 0 TSRMLS_CC); } - | non_empty_parameter_list ',' optional_class_type T_VARIABLE { $$=$1; $$.u.op.num++; zend_do_receive_arg(ZEND_RECV, &$4, &$$, NULL, &$3, 0 TSRMLS_CC); } - | non_empty_parameter_list ',' optional_class_type '&' T_VARIABLE { $$=$1; $$.u.op.num++; zend_do_receive_arg(ZEND_RECV, &$5, &$$, NULL, &$3, 1 TSRMLS_CC); } - | non_empty_parameter_list ',' optional_class_type '&' T_VARIABLE '=' static_scalar { $$=$1; $$.u.op.num++; zend_do_receive_arg(ZEND_RECV_INIT, &$5, &$$, &$7, &$3, 1 TSRMLS_CC); } - | non_empty_parameter_list ',' optional_class_type T_VARIABLE '=' static_scalar { $$=$1; $$.u.op.num++; zend_do_receive_arg(ZEND_RECV_INIT, &$4, &$$, &$6, &$3, 0 TSRMLS_CC); } + parameter + | non_empty_parameter_list ',' parameter +; + +parameter: + optional_class_type is_reference is_variadic T_VARIABLE + { zend_do_receive_param(ZEND_RECV, &$4, NULL, &$1, $2.op_type, $3.op_type TSRMLS_CC); } + | optional_class_type is_reference is_variadic T_VARIABLE '=' static_scalar + { zend_do_receive_param(ZEND_RECV_INIT, &$4, &$6, &$1, $2.op_type, $3.op_type TSRMLS_CC); } ; @@ -553,9 +585,11 @@ non_empty_function_call_parameter_list: expr_without_variable { Z_LVAL($$.u.constant) = 1; zend_do_pass_param(&$1, ZEND_SEND_VAL, Z_LVAL($$.u.constant) TSRMLS_CC); } | variable { Z_LVAL($$.u.constant) = 1; zend_do_pass_param(&$1, ZEND_SEND_VAR, Z_LVAL($$.u.constant) TSRMLS_CC); } | '&' w_variable { Z_LVAL($$.u.constant) = 1; zend_do_pass_param(&$2, ZEND_SEND_REF, Z_LVAL($$.u.constant) TSRMLS_CC); } + | T_ELLIPSIS expr { Z_LVAL($$.u.constant) = 0; zend_do_unpack_params(&$2, Z_LVAL($$.u.constant) TSRMLS_CC); } | non_empty_function_call_parameter_list ',' expr_without_variable { Z_LVAL($$.u.constant)=Z_LVAL($1.u.constant)+1; zend_do_pass_param(&$3, ZEND_SEND_VAL, Z_LVAL($$.u.constant) TSRMLS_CC); } | non_empty_function_call_parameter_list ',' variable { Z_LVAL($$.u.constant)=Z_LVAL($1.u.constant)+1; zend_do_pass_param(&$3, ZEND_SEND_VAR, Z_LVAL($$.u.constant) TSRMLS_CC); } | non_empty_function_call_parameter_list ',' '&' w_variable { Z_LVAL($$.u.constant)=Z_LVAL($1.u.constant)+1; zend_do_pass_param(&$4, ZEND_SEND_REF, Z_LVAL($$.u.constant) TSRMLS_CC); } + | non_empty_function_call_parameter_list ',' T_ELLIPSIS expr { Z_LVAL($$.u.constant)=Z_LVAL($1.u.constant); zend_do_unpack_params(&$4, Z_LVAL($$.u.constant) TSRMLS_CC); } ; global_var_list: @@ -941,25 +975,62 @@ common_scalar: | T_START_HEREDOC T_END_HEREDOC { ZVAL_EMPTY_STRING(&$$.u.constant); INIT_PZVAL(&$$.u.constant); $$.op_type = IS_CONST; } ; +static_class_constant: + class_name T_PAAMAYIM_NEKUDOTAYIM T_STRING { zend_do_fetch_constant(&$$, &$1, &$3, ZEND_CT, 0 TSRMLS_CC); } +; static_scalar: /* compile-time evaluated scalars */ - common_scalar { $$ = $1; } - | static_class_name_scalar { $$ = $1; } - | namespace_name { zend_do_fetch_constant(&$$, NULL, &$1, ZEND_CT, 1 TSRMLS_CC); } - | T_NAMESPACE T_NS_SEPARATOR namespace_name { $$.op_type = IS_CONST; ZVAL_EMPTY_STRING(&$$.u.constant); zend_do_build_namespace_name(&$$, &$$, &$3 TSRMLS_CC); $3 = $$; zend_do_fetch_constant(&$$, NULL, &$3, ZEND_CT, 0 TSRMLS_CC); } - | T_NS_SEPARATOR namespace_name { char *tmp = estrndup(Z_STRVAL($2.u.constant), Z_STRLEN($2.u.constant)+1); memcpy(&(tmp[1]), Z_STRVAL($2.u.constant), Z_STRLEN($2.u.constant)+1); tmp[0] = '\\'; efree(Z_STRVAL($2.u.constant)); Z_STRVAL($2.u.constant) = tmp; ++Z_STRLEN($2.u.constant); zend_do_fetch_constant(&$$, NULL, &$2, ZEND_CT, 0 TSRMLS_CC); } - | '+' static_scalar { ZVAL_LONG(&$1.u.constant, 0); add_function(&$2.u.constant, &$1.u.constant, &$2.u.constant TSRMLS_CC); $$ = $2; } - | '-' static_scalar { ZVAL_LONG(&$1.u.constant, 0); sub_function(&$2.u.constant, &$1.u.constant, &$2.u.constant TSRMLS_CC); $$ = $2; } + static_scalar_value { zend_do_constant_expression(&$$, $1.u.ast TSRMLS_CC); } | T_ARRAY '(' static_array_pair_list ')' { $$ = $3; Z_TYPE($$.u.constant) = IS_CONSTANT_ARRAY; } | '[' static_array_pair_list ']' { $$ = $2; Z_TYPE($$.u.constant) = IS_CONSTANT_ARRAY; } - | static_class_constant { $$ = $1; } - | T_CLASS_C { $$ = $1; } ; -static_class_constant: - class_name T_PAAMAYIM_NEKUDOTAYIM T_STRING { zend_do_fetch_constant(&$$, &$1, &$3, ZEND_CT, 0 TSRMLS_CC); } +static_scalar_value: + common_scalar { $$.u.ast = zend_ast_create_constant(&$1.u.constant); } + | static_class_name_scalar { $$.u.ast = zend_ast_create_constant(&$1.u.constant); } + | namespace_name { zend_do_fetch_constant(&$$, NULL, &$1, ZEND_CT, 1 TSRMLS_CC); $$.u.ast = zend_ast_create_constant(&$$.u.constant); } + | T_NAMESPACE T_NS_SEPARATOR namespace_name { $$.op_type = IS_CONST; ZVAL_EMPTY_STRING(&$$.u.constant); zend_do_build_namespace_name(&$$, &$$, &$3 TSRMLS_CC); $3 = $$; zend_do_fetch_constant(&$$, NULL, &$3, ZEND_CT, 0 TSRMLS_CC); $$.u.ast = zend_ast_create_constant(&$$.u.constant); } + | T_NS_SEPARATOR namespace_name { char *tmp = estrndup(Z_STRVAL($2.u.constant), Z_STRLEN($2.u.constant)+1); memcpy(&(tmp[1]), Z_STRVAL($2.u.constant), Z_STRLEN($2.u.constant)+1); tmp[0] = '\\'; efree(Z_STRVAL($2.u.constant)); Z_STRVAL($2.u.constant) = tmp; ++Z_STRLEN($2.u.constant); zend_do_fetch_constant(&$$, NULL, &$2, ZEND_CT, 0 TSRMLS_CC); $$.u.ast = zend_ast_create_constant(&$$.u.constant); } + | static_class_constant { $$.u.ast = zend_ast_create_constant(&$1.u.constant); } + | T_CLASS_C { $$.u.ast = zend_ast_create_constant(&$1.u.constant); } + | static_operation { $$ = $1; } +; + +static_operation: + static_scalar_value '+' static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_ADD, $1.u.ast, $3.u.ast); } + | static_scalar_value '-' static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_SUB, $1.u.ast, $3.u.ast); } + | static_scalar_value '*' static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_MUL, $1.u.ast, $3.u.ast); } + | static_scalar_value '/' static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_DIV, $1.u.ast, $3.u.ast); } + | static_scalar_value '%' static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_MOD, $1.u.ast, $3.u.ast); } + | '!' static_scalar_value { $$.u.ast = zend_ast_create_unary(ZEND_BOOL_NOT, $2.u.ast); } + | '~' static_scalar_value { $$.u.ast = zend_ast_create_unary(ZEND_BW_NOT, $2.u.ast); } + | static_scalar_value '|' static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_BW_OR, $1.u.ast, $3.u.ast); } + | static_scalar_value '&' static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_BW_AND, $1.u.ast, $3.u.ast); } + | static_scalar_value '^' static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_BW_XOR, $1.u.ast, $3.u.ast); } + | static_scalar_value T_SL static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_SL, $1.u.ast, $3.u.ast); } + | static_scalar_value T_SR static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_SR, $1.u.ast, $3.u.ast); } + | static_scalar_value '.' static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_CONCAT, $1.u.ast, $3.u.ast); } + | static_scalar_value T_LOGICAL_XOR static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_BOOL_XOR, $1.u.ast, $3.u.ast); } + | static_scalar_value T_LOGICAL_AND static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_BOOL_AND, $1.u.ast, $3.u.ast); } + | static_scalar_value T_LOGICAL_OR static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_BOOL_OR, $1.u.ast, $3.u.ast); } + | static_scalar_value T_BOOLEAN_AND static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_BOOL_AND, $1.u.ast, $3.u.ast); } + | static_scalar_value T_BOOLEAN_OR static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_BOOL_OR, $1.u.ast, $3.u.ast); } + | static_scalar_value T_IS_IDENTICAL static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_IS_IDENTICAL, $1.u.ast, $3.u.ast); } + | static_scalar_value T_IS_NOT_IDENTICAL static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_IS_NOT_IDENTICAL, $1.u.ast, $3.u.ast); } + | static_scalar_value T_IS_EQUAL static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_IS_EQUAL, $1.u.ast, $3.u.ast); } + | static_scalar_value T_IS_NOT_EQUAL static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_IS_NOT_EQUAL, $1.u.ast, $3.u.ast); } + | static_scalar_value '<' static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_IS_SMALLER, $1.u.ast, $3.u.ast); } + | static_scalar_value '>' static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_IS_SMALLER, $3.u.ast, $1.u.ast); } + | static_scalar_value T_IS_SMALLER_OR_EQUAL static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_IS_SMALLER_OR_EQUAL, $1.u.ast, $3.u.ast); } + | static_scalar_value T_IS_GREATER_OR_EQUAL static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_IS_SMALLER_OR_EQUAL, $3.u.ast, $1.u.ast); } + | static_scalar_value '?' ':' static_scalar_value { $$.u.ast = zend_ast_create_ternary(ZEND_SELECT, $1.u.ast, NULL, $4.u.ast); } + | static_scalar_value '?' static_scalar_value ':' static_scalar_value { $$.u.ast = zend_ast_create_ternary(ZEND_SELECT, $1.u.ast, $3.u.ast, $5.u.ast); } + | '+' static_scalar_value { $$.u.ast = zend_ast_create_unary(ZEND_UNARY_PLUS, $2.u.ast); } + | '-' static_scalar_value { $$.u.ast = zend_ast_create_unary(ZEND_UNARY_MINUS, $2.u.ast); } + | '(' static_scalar_value ')' { $$ = $2; } ; + scalar: T_STRING_VARNAME { $$ = $1; } | class_name_scalar { $$ = $1; } @@ -1196,7 +1267,7 @@ isset_variables: isset_variable: variable { zend_do_isset_or_isempty(ZEND_ISSET, &$$, &$1 TSRMLS_CC); } - | expr_without_variable { zend_error(E_COMPILE_ERROR, "Cannot use isset() on the result of an expression (you can use \"null !== expression\" instead)"); } + | expr_without_variable { zend_error_noreturn(E_COMPILE_ERROR, "Cannot use isset() on the result of an expression (you can use \"null !== expression\" instead)"); } ; class_constant: diff --git a/Zend/zend_language_scanner.c b/Zend/zend_language_scanner.c index d5768d3345569..76e3e5645129a 100644 --- a/Zend/zend_language_scanner.c +++ b/Zend/zend_language_scanner.c @@ -49,7 +49,7 @@ #include "zend_API.h" #include "zend_strtod.h" #include "zend_exceptions.h" -#include "tsrm_virtual_cwd.h" +#include "zend_virtual_cwd.h" #include "tsrm_config_common.h" #define YYCTYPE unsigned char @@ -1096,7 +1096,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) yy3: YYDEBUG(3, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1738 "Zend/zend_language_scanner.l" +#line 1741 "Zend/zend_language_scanner.l" { if (YYCURSOR > YYLIMIT) { return 0; @@ -1174,7 +1174,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) yy6: YYDEBUG(6, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1728 "Zend/zend_language_scanner.l" +#line 1731 "Zend/zend_language_scanner.l" { if (CG(short_tags)) { ZVAL_STRINGL(zendlval, yytext, yyleng, 0); /* no copying - intentional */ @@ -1191,7 +1191,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) if ((yych = *YYCURSOR) == '=') goto yy43; YYDEBUG(8, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1709 "Zend/zend_language_scanner.l" +#line 1712 "Zend/zend_language_scanner.l" { if (CG(asp_tags)) { ZVAL_STRINGL(zendlval, yytext, yyleng, 0); /* no copying - intentional */ @@ -1387,7 +1387,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) ++YYCURSOR; YYDEBUG(38, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1675 "Zend/zend_language_scanner.l" +#line 1678 "Zend/zend_language_scanner.l" { YYCTYPE *bracket = (YYCTYPE*)zend_memrchr(yytext, '<', yyleng - (sizeof("script language=php>") - 1)); @@ -1429,7 +1429,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) ++YYCURSOR; YYDEBUG(44, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1691 "Zend/zend_language_scanner.l" +#line 1694 "Zend/zend_language_scanner.l" { if (CG(asp_tags)) { ZVAL_STRINGL(zendlval, yytext, yyleng, 0); /* no copying - intentional */ @@ -1445,7 +1445,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) ++YYCURSOR; YYDEBUG(46, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1702 "Zend/zend_language_scanner.l" +#line 1705 "Zend/zend_language_scanner.l" { ZVAL_STRINGL(zendlval, yytext, yyleng, 0); /* no copying - intentional */ BEGIN(ST_IN_SCRIPTING); @@ -1478,7 +1478,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) yy51: YYDEBUG(51, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1720 "Zend/zend_language_scanner.l" +#line 1723 "Zend/zend_language_scanner.l" { ZVAL_STRINGL(zendlval, yytext, yyleng, 0); /* no copying - intentional */ HANDLE_NEWLINE(yytext[yyleng-1]); @@ -1556,7 +1556,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) yy56: YYDEBUG(56, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2183 "Zend/zend_language_scanner.l" +#line 2186 "Zend/zend_language_scanner.l" { if (YYCURSOR > YYLIMIT) { return 0; @@ -1608,7 +1608,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) ++YYCURSOR; YYDEBUG(59, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2127 "Zend/zend_language_scanner.l" +#line 2130 "Zend/zend_language_scanner.l" { BEGIN(ST_IN_SCRIPTING); return '`'; @@ -1623,7 +1623,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) ++YYCURSOR; YYDEBUG(62, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2114 "Zend/zend_language_scanner.l" +#line 2117 "Zend/zend_language_scanner.l" { Z_LVAL_P(zendlval) = (long) '{'; yy_push_state(ST_IN_SCRIPTING TSRMLS_CC); @@ -1646,7 +1646,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) yy65: YYDEBUG(65, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1820 "Zend/zend_language_scanner.l" +#line 1823 "Zend/zend_language_scanner.l" { zend_copy_value(zendlval, (yytext+1), (yyleng-1)); zendlval->type = IS_STRING; @@ -1658,7 +1658,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) ++YYCURSOR; YYDEBUG(67, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1454 "Zend/zend_language_scanner.l" +#line 1457 "Zend/zend_language_scanner.l" { yy_push_state(ST_LOOKING_FOR_VARNAME TSRMLS_CC); return T_DOLLAR_OPEN_CURLY_BRACES; @@ -1677,7 +1677,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) ++YYCURSOR; YYDEBUG(71, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1812 "Zend/zend_language_scanner.l" +#line 1815 "Zend/zend_language_scanner.l" { yyless(yyleng - 1); yy_push_state(ST_VAR_OFFSET TSRMLS_CC); @@ -1703,7 +1703,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) ++YYCURSOR; YYDEBUG(74, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1802 "Zend/zend_language_scanner.l" +#line 1805 "Zend/zend_language_scanner.l" { yyless(yyleng - 3); yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC); @@ -1779,7 +1779,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) yy78: YYDEBUG(78, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2133 "Zend/zend_language_scanner.l" +#line 2136 "Zend/zend_language_scanner.l" { if (GET_DOUBLE_QUOTES_SCANNED_LENGTH()) { YYCURSOR += GET_DOUBLE_QUOTES_SCANNED_LENGTH() - 1; @@ -1839,7 +1839,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) ++YYCURSOR; YYDEBUG(81, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2122 "Zend/zend_language_scanner.l" +#line 2125 "Zend/zend_language_scanner.l" { BEGIN(ST_IN_SCRIPTING); return '"'; @@ -1854,7 +1854,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) ++YYCURSOR; YYDEBUG(84, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2114 "Zend/zend_language_scanner.l" +#line 2117 "Zend/zend_language_scanner.l" { Z_LVAL_P(zendlval) = (long) '{'; yy_push_state(ST_IN_SCRIPTING TSRMLS_CC); @@ -1877,7 +1877,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) yy87: YYDEBUG(87, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1820 "Zend/zend_language_scanner.l" +#line 1823 "Zend/zend_language_scanner.l" { zend_copy_value(zendlval, (yytext+1), (yyleng-1)); zendlval->type = IS_STRING; @@ -1889,7 +1889,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) ++YYCURSOR; YYDEBUG(89, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1454 "Zend/zend_language_scanner.l" +#line 1457 "Zend/zend_language_scanner.l" { yy_push_state(ST_LOOKING_FOR_VARNAME TSRMLS_CC); return T_DOLLAR_OPEN_CURLY_BRACES; @@ -1908,7 +1908,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) ++YYCURSOR; YYDEBUG(93, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1812 "Zend/zend_language_scanner.l" +#line 1815 "Zend/zend_language_scanner.l" { yyless(yyleng - 1); yy_push_state(ST_VAR_OFFSET TSRMLS_CC); @@ -1934,7 +1934,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) ++YYCURSOR; YYDEBUG(96, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1802 "Zend/zend_language_scanner.l" +#line 1805 "Zend/zend_language_scanner.l" { yyless(yyleng - 3); yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC); @@ -1953,7 +1953,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) ++YYCURSOR; YYDEBUG(100, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2100 "Zend/zend_language_scanner.l" +#line 2103 "Zend/zend_language_scanner.l" { zend_heredoc_label *heredoc_label = zend_ptr_stack_pop(&SCNG(heredoc_label_stack)); @@ -2028,7 +2028,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) yy104: YYDEBUG(104, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2225 "Zend/zend_language_scanner.l" +#line 2228 "Zend/zend_language_scanner.l" { int newline = 0; @@ -2116,7 +2116,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) ++YYCURSOR; YYDEBUG(108, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2114 "Zend/zend_language_scanner.l" +#line 2117 "Zend/zend_language_scanner.l" { Z_LVAL_P(zendlval) = (long) '{'; yy_push_state(ST_IN_SCRIPTING TSRMLS_CC); @@ -2139,7 +2139,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) yy111: YYDEBUG(111, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1820 "Zend/zend_language_scanner.l" +#line 1823 "Zend/zend_language_scanner.l" { zend_copy_value(zendlval, (yytext+1), (yyleng-1)); zendlval->type = IS_STRING; @@ -2151,7 +2151,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) ++YYCURSOR; YYDEBUG(113, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1454 "Zend/zend_language_scanner.l" +#line 1457 "Zend/zend_language_scanner.l" { yy_push_state(ST_LOOKING_FOR_VARNAME TSRMLS_CC); return T_DOLLAR_OPEN_CURLY_BRACES; @@ -2170,7 +2170,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) ++YYCURSOR; YYDEBUG(117, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1812 "Zend/zend_language_scanner.l" +#line 1815 "Zend/zend_language_scanner.l" { yyless(yyleng - 1); yy_push_state(ST_VAR_OFFSET TSRMLS_CC); @@ -2196,7 +2196,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) ++YYCURSOR; YYDEBUG(120, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1802 "Zend/zend_language_scanner.l" +#line 1805 "Zend/zend_language_scanner.l" { yyless(yyleng - 3); yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC); @@ -2281,14 +2281,14 @@ int lex_scan(zval *zendlval TSRMLS_DC) case '\n': case '\r': case ' ': goto yy140; - case '!': goto yy153; + case '!': goto yy154; case '"': goto yy180; case '#': goto yy176; case '$': goto yy165; case '%': goto yy159; case '&': goto yy160; case '\'': goto yy178; - case '(': goto yy147; + case '(': goto yy148; case ')': case ',': case ';': @@ -2296,11 +2296,11 @@ int lex_scan(zval *zendlval TSRMLS_DC) case '[': case ']': case '~': goto yy166; - case '*': goto yy156; - case '+': goto yy152; + case '*': goto yy157; + case '+': goto yy153; case '-': goto yy138; - case '.': goto yy158; - case '/': goto yy157; + case '.': goto yy145; + case '/': goto yy158; case '0': goto yy172; case '1': case '2': @@ -2312,9 +2312,9 @@ int lex_scan(zval *zendlval TSRMLS_DC) case '8': case '9': goto yy174; case ':': goto yy142; - case '<': goto yy154; - case '=': goto yy150; - case '>': goto yy155; + case '<': goto yy155; + case '=': goto yy151; + case '>': goto yy156; case '?': goto yy167; case 'A': case 'a': goto yy133; @@ -2333,9 +2333,9 @@ int lex_scan(zval *zendlval TSRMLS_DC) case 'I': case 'i': goto yy131; case 'L': - case 'l': goto yy151; + case 'l': goto yy152; case 'N': - case 'n': goto yy145; + case 'n': goto yy146; case 'O': case 'o': goto yy163; case 'P': @@ -2347,9 +2347,9 @@ int lex_scan(zval *zendlval TSRMLS_DC) case 'T': case 't': goto yy130; case 'U': - case 'u': goto yy148; + case 'u': goto yy149; case 'V': - case 'v': goto yy146; + case 'v': goto yy147; case 'W': case 'w': goto yy132; case 'X': @@ -2358,7 +2358,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) case 'y': goto yy129; case '\\': goto yy143; case '^': goto yy162; - case '_': goto yy149; + case '_': goto yy150; case '`': goto yy182; case '{': goto yy168; case '|': goto yy161; @@ -2371,23 +2371,23 @@ int lex_scan(zval *zendlval TSRMLS_DC) YYDEBUG(-1, yych); switch ((yych = *YYCURSOR)) { case 'C': - case 'c': goto yy735; + case 'c': goto yy738; case 'L': - case 'l': goto yy736; + case 'l': goto yy739; case 'M': - case 'm': goto yy737; + case 'm': goto yy740; case 'N': - case 'n': goto yy738; + case 'n': goto yy741; case 'V': - case 'v': goto yy739; + case 'v': goto yy742; case 'X': - case 'x': goto yy740; + case 'x': goto yy743; default: goto yy187; } yy124: YYDEBUG(124, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1843 "Zend/zend_language_scanner.l" +#line 1846 "Zend/zend_language_scanner.l" { zend_copy_value(zendlval, yytext, yyleng); zendlval->type = IS_STRING; @@ -2399,20 +2399,20 @@ int lex_scan(zval *zendlval TSRMLS_DC) yych = *++YYCURSOR; if (yych <= 'O') { if (yych <= 'H') { - if (yych == 'E') goto yy717; + if (yych == 'E') goto yy720; goto yy187; } else { - if (yych <= 'I') goto yy718; + if (yych <= 'I') goto yy721; if (yych <= 'N') goto yy187; - goto yy719; + goto yy722; } } else { if (yych <= 'h') { - if (yych == 'e') goto yy717; + if (yych == 'e') goto yy720; goto yy187; } else { - if (yych <= 'i') goto yy718; - if (yych == 'o') goto yy719; + if (yych <= 'i') goto yy721; + if (yych == 'o') goto yy722; goto yy187; } } @@ -2421,20 +2421,20 @@ int lex_scan(zval *zendlval TSRMLS_DC) yych = *++YYCURSOR; if (yych <= 'U') { if (yych <= 'N') { - if (yych == 'I') goto yy693; + if (yych == 'I') goto yy696; goto yy187; } else { - if (yych <= 'O') goto yy694; + if (yych <= 'O') goto yy697; if (yych <= 'T') goto yy187; - goto yy695; + goto yy698; } } else { if (yych <= 'n') { - if (yych == 'i') goto yy693; + if (yych == 'i') goto yy696; goto yy187; } else { - if (yych <= 'o') goto yy694; - if (yych == 'u') goto yy695; + if (yych <= 'o') goto yy697; + if (yych == 'u') goto yy698; goto yy187; } } @@ -2443,48 +2443,48 @@ int lex_scan(zval *zendlval TSRMLS_DC) yych = *++YYCURSOR; if (yych <= 'O') { if (yych <= 'K') { - if (yych == 'A') goto yy658; + if (yych == 'A') goto yy661; goto yy187; } else { - if (yych <= 'L') goto yy659; + if (yych <= 'L') goto yy662; if (yych <= 'N') goto yy187; - goto yy660; + goto yy663; } } else { if (yych <= 'k') { - if (yych == 'a') goto yy658; + if (yych == 'a') goto yy661; goto yy187; } else { - if (yych <= 'l') goto yy659; - if (yych == 'o') goto yy660; + if (yych <= 'l') goto yy662; + if (yych == 'o') goto yy663; goto yy187; } } yy128: YYDEBUG(128, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy640; - if (yych == 'e') goto yy640; + if (yych == 'E') goto yy643; + if (yych == 'e') goto yy643; goto yy187; yy129: YYDEBUG(129, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'I') goto yy635; - if (yych == 'i') goto yy635; + if (yych == 'I') goto yy638; + if (yych == 'i') goto yy638; goto yy187; yy130: YYDEBUG(130, *YYCURSOR); yych = *++YYCURSOR; if (yych <= 'R') { - if (yych == 'H') goto yy623; + if (yych == 'H') goto yy626; if (yych <= 'Q') goto yy187; - goto yy624; + goto yy627; } else { if (yych <= 'h') { if (yych <= 'g') goto yy187; - goto yy623; + goto yy626; } else { - if (yych == 'r') goto yy624; + if (yych == 'r') goto yy627; goto yy187; } } @@ -2493,53 +2493,53 @@ int lex_scan(zval *zendlval TSRMLS_DC) yych = *++YYCURSOR; if (yych <= 'S') { if (yych <= 'L') { - if (yych == 'F') goto yy570; + if (yych == 'F') goto yy573; goto yy187; } else { - if (yych <= 'M') goto yy572; - if (yych <= 'N') goto yy573; + if (yych <= 'M') goto yy575; + if (yych <= 'N') goto yy576; if (yych <= 'R') goto yy187; - goto yy574; + goto yy577; } } else { if (yych <= 'm') { - if (yych == 'f') goto yy570; + if (yych == 'f') goto yy573; if (yych <= 'l') goto yy187; - goto yy572; + goto yy575; } else { - if (yych <= 'n') goto yy573; - if (yych == 's') goto yy574; + if (yych <= 'n') goto yy576; + if (yych == 's') goto yy577; goto yy187; } } yy132: YYDEBUG(132, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'H') goto yy565; - if (yych == 'h') goto yy565; + if (yych == 'H') goto yy568; + if (yych == 'h') goto yy568; goto yy187; yy133: YYDEBUG(133, *YYCURSOR); yych = *++YYCURSOR; if (yych <= 'S') { if (yych <= 'M') { - if (yych == 'B') goto yy547; + if (yych == 'B') goto yy550; goto yy187; } else { - if (yych <= 'N') goto yy548; + if (yych <= 'N') goto yy551; if (yych <= 'Q') goto yy187; - if (yych <= 'R') goto yy549; - goto yy550; + if (yych <= 'R') goto yy552; + goto yy553; } } else { if (yych <= 'n') { - if (yych == 'b') goto yy547; + if (yych == 'b') goto yy550; if (yych <= 'm') goto yy187; - goto yy548; + goto yy551; } else { if (yych <= 'q') goto yy187; - if (yych <= 'r') goto yy549; - if (yych <= 's') goto yy550; + if (yych <= 'r') goto yy552; + if (yych <= 's') goto yy553; goto yy187; } } @@ -2547,15 +2547,15 @@ int lex_scan(zval *zendlval TSRMLS_DC) YYDEBUG(134, *YYCURSOR); yych = *++YYCURSOR; if (yych <= 'W') { - if (yych == 'T') goto yy535; + if (yych == 'T') goto yy538; if (yych <= 'V') goto yy187; - goto yy536; + goto yy539; } else { if (yych <= 't') { if (yych <= 's') goto yy187; - goto yy535; + goto yy538; } else { - if (yych == 'w') goto yy536; + if (yych == 'w') goto yy539; goto yy187; } } @@ -2566,18 +2566,18 @@ int lex_scan(zval *zendlval TSRMLS_DC) if (yych <= ';') { if (yych <= '"') { if (yych <= '!') goto yy187; - goto yy527; + goto yy530; } else { - if (yych == '\'') goto yy528; + if (yych == '\'') goto yy531; goto yy187; } } else { if (yych <= 'R') { - if (yych <= '<') goto yy526; + if (yych <= '<') goto yy529; if (yych <= 'Q') goto yy187; - goto yy529; + goto yy532; } else { - if (yych == 'r') goto yy529; + if (yych == 'r') goto yy532; goto yy187; } } @@ -2585,15 +2585,15 @@ int lex_scan(zval *zendlval TSRMLS_DC) YYDEBUG(136, *YYCURSOR); yych = *++YYCURSOR; if (yych <= 'O') { - if (yych == 'L') goto yy516; + if (yych == 'L') goto yy519; if (yych <= 'N') goto yy187; - goto yy517; + goto yy520; } else { if (yych <= 'l') { if (yych <= 'k') goto yy187; - goto yy516; + goto yy519; } else { - if (yych == 'o') goto yy517; + if (yych == 'o') goto yy520; goto yy187; } } @@ -2601,15 +2601,15 @@ int lex_scan(zval *zendlval TSRMLS_DC) YYDEBUG(137, *YYCURSOR); yych = *++YYCURSOR; if (yych <= 'U') { - if (yych == 'R') goto yy492; + if (yych == 'R') goto yy495; if (yych <= 'T') goto yy187; - goto yy493; + goto yy496; } else { if (yych <= 'r') { if (yych <= 'q') goto yy187; - goto yy492; + goto yy495; } else { - if (yych == 'u') goto yy493; + if (yych == 'u') goto yy496; goto yy187; } } @@ -2617,15 +2617,15 @@ int lex_scan(zval *zendlval TSRMLS_DC) YYDEBUG(138, *YYCURSOR); ++YYCURSOR; if ((yych = *YYCURSOR) <= '<') { - if (yych == '-') goto yy488; + if (yych == '-') goto yy491; } else { - if (yych <= '=') goto yy486; - if (yych <= '>') goto yy490; + if (yych <= '=') goto yy489; + if (yych <= '>') goto yy493; } yy139: YYDEBUG(139, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1443 "Zend/zend_language_scanner.l" +#line 1446 "Zend/zend_language_scanner.l" { return yytext[0]; } @@ -2634,11 +2634,11 @@ int lex_scan(zval *zendlval TSRMLS_DC) YYDEBUG(140, *YYCURSOR); ++YYCURSOR; yych = *YYCURSOR; - goto yy485; + goto yy488; yy141: YYDEBUG(141, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1176 "Zend/zend_language_scanner.l" +#line 1175 "Zend/zend_language_scanner.l" { ZVAL_STRINGL(zendlval, yytext, yyleng, 0); /* no copying - intentional */ HANDLE_NEWLINES(yytext, yyleng); @@ -2648,181 +2648,186 @@ int lex_scan(zval *zendlval TSRMLS_DC) yy142: YYDEBUG(142, *YYCURSOR); yych = *++YYCURSOR; - if (yych == ':') goto yy482; + if (yych == ':') goto yy485; goto yy139; yy143: YYDEBUG(143, *YYCURSOR); ++YYCURSOR; YYDEBUG(144, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1203 "Zend/zend_language_scanner.l" +#line 1202 "Zend/zend_language_scanner.l" { return T_NS_SEPARATOR; } #line 2663 "Zend/zend_language_scanner.c" yy145: YYDEBUG(145, *YYCURSOR); + yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '/') { + if (yych == '.') goto yy482; + goto yy139; + } else { + if (yych <= '9') goto yy478; + if (yych == '=') goto yy480; + goto yy139; + } +yy146: + YYDEBUG(146, *YYCURSOR); yych = *++YYCURSOR; if (yych <= 'E') { - if (yych == 'A') goto yy470; + if (yych == 'A') goto yy466; if (yych <= 'D') goto yy187; - goto yy471; + goto yy467; } else { if (yych <= 'a') { if (yych <= '`') goto yy187; - goto yy470; + goto yy466; } else { - if (yych == 'e') goto yy471; + if (yych == 'e') goto yy467; goto yy187; } } -yy146: - YYDEBUG(146, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'A') goto yy467; - if (yych == 'a') goto yy467; - goto yy187; yy147: YYDEBUG(147, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'A') goto yy463; + if (yych == 'a') goto yy463; + goto yy187; +yy148: + YYDEBUG(148, *YYCURSOR); yyaccept = 1; yych = *(YYMARKER = ++YYCURSOR); if (yych <= 'S') { if (yych <= 'D') { if (yych <= ' ') { - if (yych == '\t') goto yy392; + if (yych == '\t') goto yy388; if (yych <= 0x1F) goto yy139; - goto yy392; + goto yy388; } else { if (yych <= '@') goto yy139; if (yych == 'C') goto yy139; - goto yy392; + goto yy388; } } else { if (yych <= 'I') { - if (yych == 'F') goto yy392; + if (yych == 'F') goto yy388; if (yych <= 'H') goto yy139; - goto yy392; + goto yy388; } else { - if (yych == 'O') goto yy392; + if (yych == 'O') goto yy388; if (yych <= 'Q') goto yy139; - goto yy392; + goto yy388; } } } else { if (yych <= 'f') { if (yych <= 'b') { - if (yych == 'U') goto yy392; + if (yych == 'U') goto yy388; if (yych <= '`') goto yy139; - goto yy392; + goto yy388; } else { - if (yych == 'd') goto yy392; + if (yych == 'd') goto yy388; if (yych <= 'e') goto yy139; - goto yy392; + goto yy388; } } else { if (yych <= 'o') { - if (yych == 'i') goto yy392; + if (yych == 'i') goto yy388; if (yych <= 'n') goto yy139; - goto yy392; + goto yy388; } else { if (yych <= 's') { if (yych <= 'q') goto yy139; - goto yy392; + goto yy388; } else { - if (yych == 'u') goto yy392; + if (yych == 'u') goto yy388; goto yy139; } } } } -yy148: - YYDEBUG(148, *YYCURSOR); +yy149: + YYDEBUG(149, *YYCURSOR); yych = *++YYCURSOR; if (yych <= 'S') { - if (yych == 'N') goto yy383; + if (yych == 'N') goto yy379; if (yych <= 'R') goto yy187; - goto yy384; + goto yy380; } else { if (yych <= 'n') { if (yych <= 'm') goto yy187; - goto yy383; + goto yy379; } else { - if (yych == 's') goto yy384; + if (yych == 's') goto yy380; goto yy187; } } -yy149: - YYDEBUG(149, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == '_') goto yy301; - goto yy187; yy150: YYDEBUG(150, *YYCURSOR); yych = *++YYCURSOR; - if (yych <= '<') goto yy139; - if (yych <= '=') goto yy295; - if (yych <= '>') goto yy297; - goto yy139; + if (yych == '_') goto yy297; + goto yy187; yy151: YYDEBUG(151, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'I') goto yy291; - if (yych == 'i') goto yy291; - goto yy187; + if (yych <= '<') goto yy139; + if (yych <= '=') goto yy291; + if (yych <= '>') goto yy293; + goto yy139; yy152: YYDEBUG(152, *YYCURSOR); yych = *++YYCURSOR; - if (yych == '+') goto yy289; - if (yych == '=') goto yy287; - goto yy139; + if (yych == 'I') goto yy287; + if (yych == 'i') goto yy287; + goto yy187; yy153: YYDEBUG(153, *YYCURSOR); yych = *++YYCURSOR; - if (yych == '=') goto yy284; + if (yych == '+') goto yy285; + if (yych == '=') goto yy283; goto yy139; yy154: YYDEBUG(154, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == '=') goto yy280; + goto yy139; +yy155: + YYDEBUG(155, *YYCURSOR); yyaccept = 1; yych = *(YYMARKER = ++YYCURSOR); if (yych <= ';') { - if (yych == '/') goto yy256; + if (yych == '/') goto yy252; goto yy139; } else { - if (yych <= '<') goto yy254; - if (yych <= '=') goto yy257; - if (yych <= '>') goto yy259; + if (yych <= '<') goto yy250; + if (yych <= '=') goto yy253; + if (yych <= '>') goto yy255; goto yy139; } -yy155: - YYDEBUG(155, *YYCURSOR); - yych = *++YYCURSOR; - if (yych <= '<') goto yy139; - if (yych <= '=') goto yy250; - if (yych <= '>') goto yy248; - goto yy139; yy156: YYDEBUG(156, *YYCURSOR); yych = *++YYCURSOR; - if (yych == '=') goto yy246; + if (yych <= '<') goto yy139; + if (yych <= '=') goto yy246; + if (yych <= '>') goto yy244; goto yy139; yy157: YYDEBUG(157, *YYCURSOR); yych = *++YYCURSOR; + if (yych == '=') goto yy242; + goto yy139; +yy158: + YYDEBUG(158, *YYCURSOR); + yych = *++YYCURSOR; if (yych <= '.') { - if (yych == '*') goto yy238; + if (yych == '*') goto yy234; goto yy139; } else { - if (yych <= '/') goto yy240; - if (yych == '=') goto yy241; + if (yych <= '/') goto yy236; + if (yych == '=') goto yy237; goto yy139; } -yy158: - YYDEBUG(158, *YYCURSOR); - yych = *++YYCURSOR; - if (yych <= '/') goto yy139; - if (yych <= '9') goto yy234; - if (yych == '=') goto yy236; - goto yy139; yy159: YYDEBUG(159, *YYCURSOR); yych = *++YYCURSOR; @@ -2887,18 +2892,18 @@ int lex_scan(zval *zendlval TSRMLS_DC) ++YYCURSOR; YYDEBUG(169, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1448 "Zend/zend_language_scanner.l" +#line 1451 "Zend/zend_language_scanner.l" { yy_push_state(ST_IN_SCRIPTING TSRMLS_CC); return '{'; } -#line 2896 "Zend/zend_language_scanner.c" +#line 2901 "Zend/zend_language_scanner.c" yy170: YYDEBUG(170, *YYCURSOR); ++YYCURSOR; YYDEBUG(171, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1460 "Zend/zend_language_scanner.l" +#line 1463 "Zend/zend_language_scanner.l" { RESET_DOC_COMMENT(); if (!zend_stack_is_empty(&SCNG(state_stack))) { @@ -2906,7 +2911,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) } return '}'; } -#line 2910 "Zend/zend_language_scanner.c" +#line 2915 "Zend/zend_language_scanner.c" yy172: YYDEBUG(172, *YYCURSOR); yyaccept = 2; @@ -2934,7 +2939,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) yy173: YYDEBUG(173, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1510 "Zend/zend_language_scanner.l" +#line 1513 "Zend/zend_language_scanner.l" { if (yyleng < MAX_LENGTH_OF_LONG - 1) { /* Won't overflow */ Z_LVAL_P(zendlval) = strtol(yytext, NULL, 0); @@ -2955,7 +2960,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) zendlval->type = IS_LONG; return T_LNUMBER; } -#line 2959 "Zend/zend_language_scanner.c" +#line 2964 "Zend/zend_language_scanner.c" yy174: YYDEBUG(174, *YYCURSOR); yyaccept = 2; @@ -2983,7 +2988,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) yy177: YYDEBUG(177, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1850 "Zend/zend_language_scanner.l" +#line 1853 "Zend/zend_language_scanner.l" { while (YYCURSOR < YYLIMIT) { switch (*YYCURSOR++) { @@ -3017,14 +3022,14 @@ int lex_scan(zval *zendlval TSRMLS_DC) return T_COMMENT; } -#line 3021 "Zend/zend_language_scanner.c" +#line 3026 "Zend/zend_language_scanner.c" yy178: YYDEBUG(178, *YYCURSOR); ++YYCURSOR; yy179: YYDEBUG(179, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1937 "Zend/zend_language_scanner.l" +#line 1940 "Zend/zend_language_scanner.l" { register char *s, *t; char *end; @@ -3090,14 +3095,14 @@ int lex_scan(zval *zendlval TSRMLS_DC) } return T_CONSTANT_ENCAPSED_STRING; } -#line 3094 "Zend/zend_language_scanner.c" +#line 3099 "Zend/zend_language_scanner.c" yy180: YYDEBUG(180, *YYCURSOR); ++YYCURSOR; yy181: YYDEBUG(181, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2004 "Zend/zend_language_scanner.l" +#line 2007 "Zend/zend_language_scanner.l" { int bprefix = (yytext[0] != '"') ? 1 : 0; @@ -3138,24 +3143,24 @@ int lex_scan(zval *zendlval TSRMLS_DC) BEGIN(ST_DOUBLE_QUOTES); return '"'; } -#line 3142 "Zend/zend_language_scanner.c" +#line 3147 "Zend/zend_language_scanner.c" yy182: YYDEBUG(182, *YYCURSOR); ++YYCURSOR; YYDEBUG(183, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2094 "Zend/zend_language_scanner.l" +#line 2097 "Zend/zend_language_scanner.l" { BEGIN(ST_BACKQUOTE); return '`'; } -#line 3153 "Zend/zend_language_scanner.c" +#line 3158 "Zend/zend_language_scanner.c" yy184: YYDEBUG(184, *YYCURSOR); ++YYCURSOR; YYDEBUG(185, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2357 "Zend/zend_language_scanner.l" +#line 2360 "Zend/zend_language_scanner.l" { if (YYCURSOR > YYLIMIT) { return 0; @@ -3164,7 +3169,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) zend_error(E_COMPILE_WARNING,"Unexpected character in input: '%c' (ASCII=%d) state=%d", yytext[0], yytext[0], YYSTATE); goto restart; } -#line 3168 "Zend/zend_language_scanner.c" +#line 3173 "Zend/zend_language_scanner.c" yy186: YYDEBUG(186, *YYCURSOR); ++YYCURSOR; @@ -3191,12 +3196,12 @@ int lex_scan(zval *zendlval TSRMLS_DC) yy190: YYDEBUG(190, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1569 "Zend/zend_language_scanner.l" +#line 1572 "Zend/zend_language_scanner.l" { ZVAL_DOUBLE(zendlval, zend_strtod(yytext, NULL)); return T_DNUMBER; } -#line 3200 "Zend/zend_language_scanner.c" +#line 3205 "Zend/zend_language_scanner.c" yy191: YYDEBUG(191, *YYCURSOR); yyaccept = 2; @@ -3243,10 +3248,10 @@ int lex_scan(zval *zendlval TSRMLS_DC) if (yyaccept <= 3) { goto yy190; } else { - goto yy239; + goto yy235; } } else { - goto yy255; + goto yy251; } } yy195: @@ -3288,7 +3293,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) } YYDEBUG(202, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1486 "Zend/zend_language_scanner.l" +#line 1489 "Zend/zend_language_scanner.l" { char *bin = yytext + 2; /* Skip "0b" */ int len = yyleng - 2; @@ -3312,7 +3317,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) return T_DNUMBER; } } -#line 3316 "Zend/zend_language_scanner.c" +#line 3321 "Zend/zend_language_scanner.c" yy203: YYDEBUG(203, *YYCURSOR); ++YYCURSOR; @@ -3324,7 +3329,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) } YYDEBUG(205, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1531 "Zend/zend_language_scanner.l" +#line 1534 "Zend/zend_language_scanner.l" { char *hex = yytext + 2; /* Skip "0x" */ int len = yyleng - 2; @@ -3348,7 +3353,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) return T_DNUMBER; } } -#line 3352 "Zend/zend_language_scanner.c" +#line 3357 "Zend/zend_language_scanner.c" yy206: YYDEBUG(206, *YYCURSOR); ++YYCURSOR; @@ -3357,13 +3362,13 @@ int lex_scan(zval *zendlval TSRMLS_DC) yy207: YYDEBUG(207, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1918 "Zend/zend_language_scanner.l" +#line 1921 "Zend/zend_language_scanner.l" { ZVAL_STRINGL(zendlval, yytext, yyleng, 0); /* no copying - intentional */ BEGIN(INITIAL); return T_CLOSE_TAG; /* implicit ';' at php-end tag */ } -#line 3367 "Zend/zend_language_scanner.c" +#line 3372 "Zend/zend_language_scanner.c" yy208: YYDEBUG(208, *YYCURSOR); yych = *++YYCURSOR; @@ -3397,13 +3402,13 @@ int lex_scan(zval *zendlval TSRMLS_DC) yy212: YYDEBUG(212, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1820 "Zend/zend_language_scanner.l" +#line 1823 "Zend/zend_language_scanner.l" { zend_copy_value(zendlval, (yytext+1), (yyleng-1)); zendlval->type = IS_STRING; return T_VARIABLE; } -#line 3407 "Zend/zend_language_scanner.c" +#line 3412 "Zend/zend_language_scanner.c" yy213: YYDEBUG(213, *YYCURSOR); yych = *++YYCURSOR; @@ -3417,11 +3422,11 @@ int lex_scan(zval *zendlval TSRMLS_DC) } YYDEBUG(215, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1431 "Zend/zend_language_scanner.l" +#line 1434 "Zend/zend_language_scanner.l" { return T_LOGICAL_XOR; } -#line 3425 "Zend/zend_language_scanner.c" +#line 3430 "Zend/zend_language_scanner.c" yy216: YYDEBUG(216, *YYCURSOR); ++YYCURSOR; @@ -3430,61 +3435,61 @@ int lex_scan(zval *zendlval TSRMLS_DC) } YYDEBUG(217, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1423 "Zend/zend_language_scanner.l" +#line 1426 "Zend/zend_language_scanner.l" { return T_LOGICAL_OR; } -#line 3438 "Zend/zend_language_scanner.c" +#line 3443 "Zend/zend_language_scanner.c" yy218: YYDEBUG(218, *YYCURSOR); ++YYCURSOR; YYDEBUG(219, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1411 "Zend/zend_language_scanner.l" +#line 1414 "Zend/zend_language_scanner.l" { return T_XOR_EQUAL; } -#line 3448 "Zend/zend_language_scanner.c" +#line 3453 "Zend/zend_language_scanner.c" yy220: YYDEBUG(220, *YYCURSOR); ++YYCURSOR; YYDEBUG(221, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1415 "Zend/zend_language_scanner.l" +#line 1418 "Zend/zend_language_scanner.l" { return T_BOOLEAN_OR; } -#line 3458 "Zend/zend_language_scanner.c" +#line 3463 "Zend/zend_language_scanner.c" yy222: YYDEBUG(222, *YYCURSOR); ++YYCURSOR; YYDEBUG(223, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1407 "Zend/zend_language_scanner.l" +#line 1410 "Zend/zend_language_scanner.l" { return T_OR_EQUAL; } -#line 3468 "Zend/zend_language_scanner.c" +#line 3473 "Zend/zend_language_scanner.c" yy224: YYDEBUG(224, *YYCURSOR); ++YYCURSOR; YYDEBUG(225, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1419 "Zend/zend_language_scanner.l" +#line 1422 "Zend/zend_language_scanner.l" { return T_BOOLEAN_AND; } -#line 3478 "Zend/zend_language_scanner.c" +#line 3483 "Zend/zend_language_scanner.c" yy226: YYDEBUG(226, *YYCURSOR); ++YYCURSOR; YYDEBUG(227, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1403 "Zend/zend_language_scanner.l" +#line 1406 "Zend/zend_language_scanner.l" { return T_AND_EQUAL; } -#line 3488 "Zend/zend_language_scanner.c" +#line 3493 "Zend/zend_language_scanner.c" yy228: YYDEBUG(228, *YYCURSOR); ++YYCURSOR; @@ -3493,7 +3498,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) yy229: YYDEBUG(229, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1925 "Zend/zend_language_scanner.l" +#line 1928 "Zend/zend_language_scanner.l" { if (CG(asp_tags)) { BEGIN(INITIAL); @@ -3504,17 +3509,17 @@ int lex_scan(zval *zendlval TSRMLS_DC) return yytext[0]; } } -#line 3508 "Zend/zend_language_scanner.c" +#line 3513 "Zend/zend_language_scanner.c" yy230: YYDEBUG(230, *YYCURSOR); ++YYCURSOR; YYDEBUG(231, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1391 "Zend/zend_language_scanner.l" +#line 1394 "Zend/zend_language_scanner.l" { return T_MOD_EQUAL; } -#line 3518 "Zend/zend_language_scanner.c" +#line 3523 "Zend/zend_language_scanner.c" yy232: YYDEBUG(232, *YYCURSOR); yych = *++YYCURSOR; @@ -3526,39 +3531,13 @@ int lex_scan(zval *zendlval TSRMLS_DC) goto yy229; yy234: YYDEBUG(234, *YYCURSOR); - yyaccept = 3; - YYMARKER = ++YYCURSOR; - YYFILL(3); - yych = *YYCURSOR; - YYDEBUG(235, *YYCURSOR); - if (yych <= 'D') { - if (yych <= '/') goto yy190; - if (yych <= '9') goto yy234; - goto yy190; - } else { - if (yych <= 'E') goto yy193; - if (yych == 'e') goto yy193; - goto yy190; - } -yy236: - YYDEBUG(236, *YYCURSOR); - ++YYCURSOR; - YYDEBUG(237, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 1387 "Zend/zend_language_scanner.l" - { - return T_CONCAT_EQUAL; -} -#line 3553 "Zend/zend_language_scanner.c" -yy238: - YYDEBUG(238, *YYCURSOR); yyaccept = 4; yych = *(YYMARKER = ++YYCURSOR); - if (yych == '*') goto yy243; -yy239: - YYDEBUG(239, *YYCURSOR); + if (yych == '*') goto yy239; +yy235: + YYDEBUG(235, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1884 "Zend/zend_language_scanner.l" +#line 1887 "Zend/zend_language_scanner.l" { int doc_com; @@ -3592,281 +3571,281 @@ int lex_scan(zval *zendlval TSRMLS_DC) return T_COMMENT; } -#line 3596 "Zend/zend_language_scanner.c" -yy240: - YYDEBUG(240, *YYCURSOR); +#line 3575 "Zend/zend_language_scanner.c" +yy236: + YYDEBUG(236, *YYCURSOR); yych = *++YYCURSOR; goto yy177; -yy241: - YYDEBUG(241, *YYCURSOR); +yy237: + YYDEBUG(237, *YYCURSOR); ++YYCURSOR; - YYDEBUG(242, *YYCURSOR); + YYDEBUG(238, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1383 "Zend/zend_language_scanner.l" +#line 1386 "Zend/zend_language_scanner.l" { return T_DIV_EQUAL; } -#line 3610 "Zend/zend_language_scanner.c" -yy243: - YYDEBUG(243, *YYCURSOR); +#line 3589 "Zend/zend_language_scanner.c" +yy239: + YYDEBUG(239, *YYCURSOR); yych = *++YYCURSOR; if (yybm[0+yych] & 64) { - goto yy244; + goto yy240; } goto yy194; -yy244: - YYDEBUG(244, *YYCURSOR); +yy240: + YYDEBUG(240, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(245, *YYCURSOR); + YYDEBUG(241, *YYCURSOR); if (yybm[0+yych] & 64) { - goto yy244; + goto yy240; } - goto yy239; -yy246: - YYDEBUG(246, *YYCURSOR); + goto yy235; +yy242: + YYDEBUG(242, *YYCURSOR); ++YYCURSOR; - YYDEBUG(247, *YYCURSOR); + YYDEBUG(243, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1379 "Zend/zend_language_scanner.l" +#line 1382 "Zend/zend_language_scanner.l" { return T_MUL_EQUAL; } -#line 3637 "Zend/zend_language_scanner.c" -yy248: - YYDEBUG(248, *YYCURSOR); +#line 3616 "Zend/zend_language_scanner.c" +yy244: + YYDEBUG(244, *YYCURSOR); ++YYCURSOR; - if ((yych = *YYCURSOR) == '=') goto yy252; - YYDEBUG(249, *YYCURSOR); + if ((yych = *YYCURSOR) == '=') goto yy248; + YYDEBUG(245, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1439 "Zend/zend_language_scanner.l" +#line 1442 "Zend/zend_language_scanner.l" { return T_SR; } -#line 3648 "Zend/zend_language_scanner.c" -yy250: - YYDEBUG(250, *YYCURSOR); +#line 3627 "Zend/zend_language_scanner.c" +yy246: + YYDEBUG(246, *YYCURSOR); ++YYCURSOR; - YYDEBUG(251, *YYCURSOR); + YYDEBUG(247, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1367 "Zend/zend_language_scanner.l" +#line 1370 "Zend/zend_language_scanner.l" { return T_IS_GREATER_OR_EQUAL; } -#line 3658 "Zend/zend_language_scanner.c" -yy252: - YYDEBUG(252, *YYCURSOR); +#line 3637 "Zend/zend_language_scanner.c" +yy248: + YYDEBUG(248, *YYCURSOR); ++YYCURSOR; - YYDEBUG(253, *YYCURSOR); + YYDEBUG(249, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1399 "Zend/zend_language_scanner.l" +#line 1402 "Zend/zend_language_scanner.l" { return T_SR_EQUAL; } -#line 3668 "Zend/zend_language_scanner.c" -yy254: - YYDEBUG(254, *YYCURSOR); +#line 3647 "Zend/zend_language_scanner.c" +yy250: + YYDEBUG(250, *YYCURSOR); yyaccept = 5; yych = *(YYMARKER = ++YYCURSOR); - if (yych <= ';') goto yy255; - if (yych <= '<') goto yy270; - if (yych <= '=') goto yy268; -yy255: - YYDEBUG(255, *YYCURSOR); + if (yych <= ';') goto yy251; + if (yych <= '<') goto yy266; + if (yych <= '=') goto yy264; +yy251: + YYDEBUG(251, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1435 "Zend/zend_language_scanner.l" +#line 1438 "Zend/zend_language_scanner.l" { return T_SL; } -#line 3683 "Zend/zend_language_scanner.c" -yy256: - YYDEBUG(256, *YYCURSOR); +#line 3662 "Zend/zend_language_scanner.c" +yy252: + YYDEBUG(252, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'S') goto yy261; - if (yych == 's') goto yy261; + if (yych == 'S') goto yy257; + if (yych == 's') goto yy257; goto yy194; -yy257: - YYDEBUG(257, *YYCURSOR); +yy253: + YYDEBUG(253, *YYCURSOR); ++YYCURSOR; - YYDEBUG(258, *YYCURSOR); + YYDEBUG(254, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1363 "Zend/zend_language_scanner.l" +#line 1366 "Zend/zend_language_scanner.l" { return T_IS_SMALLER_OR_EQUAL; } -#line 3699 "Zend/zend_language_scanner.c" -yy259: - YYDEBUG(259, *YYCURSOR); +#line 3678 "Zend/zend_language_scanner.c" +yy255: + YYDEBUG(255, *YYCURSOR); ++YYCURSOR; -yy260: - YYDEBUG(260, *YYCURSOR); +yy256: + YYDEBUG(256, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1359 "Zend/zend_language_scanner.l" +#line 1362 "Zend/zend_language_scanner.l" { return T_IS_NOT_EQUAL; } -#line 3710 "Zend/zend_language_scanner.c" -yy261: - YYDEBUG(261, *YYCURSOR); +#line 3689 "Zend/zend_language_scanner.c" +yy257: + YYDEBUG(257, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'C') goto yy262; + if (yych == 'C') goto yy258; if (yych != 'c') goto yy194; -yy262: - YYDEBUG(262, *YYCURSOR); +yy258: + YYDEBUG(258, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'R') goto yy263; + if (yych == 'R') goto yy259; if (yych != 'r') goto yy194; -yy263: - YYDEBUG(263, *YYCURSOR); +yy259: + YYDEBUG(259, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'I') goto yy264; + if (yych == 'I') goto yy260; if (yych != 'i') goto yy194; -yy264: - YYDEBUG(264, *YYCURSOR); +yy260: + YYDEBUG(260, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'P') goto yy265; + if (yych == 'P') goto yy261; if (yych != 'p') goto yy194; -yy265: - YYDEBUG(265, *YYCURSOR); +yy261: + YYDEBUG(261, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy266; + if (yych == 'T') goto yy262; if (yych != 't') goto yy194; -yy266: - YYDEBUG(266, *YYCURSOR); +yy262: + YYDEBUG(262, *YYCURSOR); ++YYCURSOR; YYFILL(3); yych = *YYCURSOR; - YYDEBUG(267, *YYCURSOR); + YYDEBUG(263, *YYCURSOR); if (yych <= '\r') { if (yych <= 0x08) goto yy194; - if (yych <= '\n') goto yy266; + if (yych <= '\n') goto yy262; if (yych <= '\f') goto yy194; - goto yy266; + goto yy262; } else { if (yych <= ' ') { if (yych <= 0x1F) goto yy194; - goto yy266; + goto yy262; } else { if (yych == '>') goto yy206; goto yy194; } } -yy268: - YYDEBUG(268, *YYCURSOR); +yy264: + YYDEBUG(264, *YYCURSOR); ++YYCURSOR; - YYDEBUG(269, *YYCURSOR); + YYDEBUG(265, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1395 "Zend/zend_language_scanner.l" +#line 1398 "Zend/zend_language_scanner.l" { return T_SL_EQUAL; } -#line 3765 "Zend/zend_language_scanner.c" -yy270: - YYDEBUG(270, *YYCURSOR); +#line 3744 "Zend/zend_language_scanner.c" +yy266: + YYDEBUG(266, *YYCURSOR); ++YYCURSOR; YYFILL(2); yych = *YYCURSOR; - YYDEBUG(271, *YYCURSOR); + YYDEBUG(267, *YYCURSOR); if (yybm[0+yych] & 128) { - goto yy270; + goto yy266; } if (yych <= 'Z') { if (yych <= '&') { - if (yych == '"') goto yy275; + if (yych == '"') goto yy271; goto yy194; } else { - if (yych <= '\'') goto yy274; + if (yych <= '\'') goto yy270; if (yych <= '@') goto yy194; } } else { if (yych <= '`') { if (yych != '_') goto yy194; } else { - if (yych <= 'z') goto yy272; + if (yych <= 'z') goto yy268; if (yych <= '~') goto yy194; } } -yy272: - YYDEBUG(272, *YYCURSOR); +yy268: + YYDEBUG(268, *YYCURSOR); ++YYCURSOR; YYFILL(2); yych = *YYCURSOR; - YYDEBUG(273, *YYCURSOR); + YYDEBUG(269, *YYCURSOR); if (yych <= '@') { if (yych <= '\f') { - if (yych == '\n') goto yy279; + if (yych == '\n') goto yy275; goto yy194; } else { - if (yych <= '\r') goto yy281; + if (yych <= '\r') goto yy277; if (yych <= '/') goto yy194; - if (yych <= '9') goto yy272; + if (yych <= '9') goto yy268; goto yy194; } } else { if (yych <= '_') { - if (yych <= 'Z') goto yy272; + if (yych <= 'Z') goto yy268; if (yych <= '^') goto yy194; - goto yy272; + goto yy268; } else { if (yych <= '`') goto yy194; - if (yych <= 'z') goto yy272; + if (yych <= 'z') goto yy268; if (yych <= '~') goto yy194; - goto yy272; + goto yy268; } } -yy274: - YYDEBUG(274, *YYCURSOR); +yy270: + YYDEBUG(270, *YYCURSOR); yych = *++YYCURSOR; if (yych == '\'') goto yy194; - if (yych <= '/') goto yy283; + if (yych <= '/') goto yy279; if (yych <= '9') goto yy194; - goto yy283; -yy275: - YYDEBUG(275, *YYCURSOR); + goto yy279; +yy271: + YYDEBUG(271, *YYCURSOR); yych = *++YYCURSOR; if (yych == '"') goto yy194; - if (yych <= '/') goto yy277; + if (yych <= '/') goto yy273; if (yych <= '9') goto yy194; - goto yy277; -yy276: - YYDEBUG(276, *YYCURSOR); + goto yy273; +yy272: + YYDEBUG(272, *YYCURSOR); ++YYCURSOR; YYFILL(3); yych = *YYCURSOR; -yy277: - YYDEBUG(277, *YYCURSOR); +yy273: + YYDEBUG(273, *YYCURSOR); if (yych <= 'Z') { if (yych <= '/') { if (yych != '"') goto yy194; } else { - if (yych <= '9') goto yy276; + if (yych <= '9') goto yy272; if (yych <= '@') goto yy194; - goto yy276; + goto yy272; } } else { if (yych <= '`') { - if (yych == '_') goto yy276; + if (yych == '_') goto yy272; goto yy194; } else { - if (yych <= 'z') goto yy276; + if (yych <= 'z') goto yy272; if (yych <= '~') goto yy194; - goto yy276; + goto yy272; } } -yy278: - YYDEBUG(278, *YYCURSOR); +yy274: + YYDEBUG(274, *YYCURSOR); yych = *++YYCURSOR; - if (yych == '\n') goto yy279; - if (yych == '\r') goto yy281; + if (yych == '\n') goto yy275; + if (yych == '\r') goto yy277; goto yy194; -yy279: - YYDEBUG(279, *YYCURSOR); +yy275: + YYDEBUG(275, *YYCURSOR); ++YYCURSOR; -yy280: - YYDEBUG(280, *YYCURSOR); +yy276: + YYDEBUG(276, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2046 "Zend/zend_language_scanner.l" +#line 2049 "Zend/zend_language_scanner.l" { char *s; int bprefix = (yytext[0] != '<') ? 1 : 0; @@ -3913,255 +3892,255 @@ int lex_scan(zval *zendlval TSRMLS_DC) return T_START_HEREDOC; } -#line 3917 "Zend/zend_language_scanner.c" -yy281: - YYDEBUG(281, *YYCURSOR); +#line 3896 "Zend/zend_language_scanner.c" +yy277: + YYDEBUG(277, *YYCURSOR); yych = *++YYCURSOR; - if (yych == '\n') goto yy279; - goto yy280; -yy282: - YYDEBUG(282, *YYCURSOR); + if (yych == '\n') goto yy275; + goto yy276; +yy278: + YYDEBUG(278, *YYCURSOR); ++YYCURSOR; YYFILL(3); yych = *YYCURSOR; -yy283: - YYDEBUG(283, *YYCURSOR); +yy279: + YYDEBUG(279, *YYCURSOR); if (yych <= 'Z') { if (yych <= '/') { - if (yych == '\'') goto yy278; + if (yych == '\'') goto yy274; goto yy194; } else { - if (yych <= '9') goto yy282; + if (yych <= '9') goto yy278; if (yych <= '@') goto yy194; - goto yy282; + goto yy278; } } else { if (yych <= '`') { - if (yych == '_') goto yy282; + if (yych == '_') goto yy278; goto yy194; } else { - if (yych <= 'z') goto yy282; + if (yych <= 'z') goto yy278; if (yych <= '~') goto yy194; - goto yy282; + goto yy278; } } -yy284: - YYDEBUG(284, *YYCURSOR); +yy280: + YYDEBUG(280, *YYCURSOR); yych = *++YYCURSOR; - if (yych != '=') goto yy260; - YYDEBUG(285, *YYCURSOR); + if (yych != '=') goto yy256; + YYDEBUG(281, *YYCURSOR); ++YYCURSOR; - YYDEBUG(286, *YYCURSOR); + YYDEBUG(282, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1351 "Zend/zend_language_scanner.l" +#line 1354 "Zend/zend_language_scanner.l" { return T_IS_NOT_IDENTICAL; } -#line 3961 "Zend/zend_language_scanner.c" -yy287: - YYDEBUG(287, *YYCURSOR); +#line 3940 "Zend/zend_language_scanner.c" +yy283: + YYDEBUG(283, *YYCURSOR); ++YYCURSOR; - YYDEBUG(288, *YYCURSOR); + YYDEBUG(284, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1371 "Zend/zend_language_scanner.l" +#line 1374 "Zend/zend_language_scanner.l" { return T_PLUS_EQUAL; } -#line 3971 "Zend/zend_language_scanner.c" -yy289: - YYDEBUG(289, *YYCURSOR); +#line 3950 "Zend/zend_language_scanner.c" +yy285: + YYDEBUG(285, *YYCURSOR); ++YYCURSOR; - YYDEBUG(290, *YYCURSOR); + YYDEBUG(286, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1339 "Zend/zend_language_scanner.l" +#line 1342 "Zend/zend_language_scanner.l" { return T_INC; } -#line 3981 "Zend/zend_language_scanner.c" -yy291: - YYDEBUG(291, *YYCURSOR); +#line 3960 "Zend/zend_language_scanner.c" +yy287: + YYDEBUG(287, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'S') goto yy292; + if (yych == 'S') goto yy288; if (yych != 's') goto yy187; -yy292: - YYDEBUG(292, *YYCURSOR); +yy288: + YYDEBUG(288, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy293; + if (yych == 'T') goto yy289; if (yych != 't') goto yy187; -yy293: - YYDEBUG(293, *YYCURSOR); +yy289: + YYDEBUG(289, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(294, *YYCURSOR); + YYDEBUG(290, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1327 "Zend/zend_language_scanner.l" +#line 1330 "Zend/zend_language_scanner.l" { return T_LIST; } -#line 4004 "Zend/zend_language_scanner.c" -yy295: - YYDEBUG(295, *YYCURSOR); +#line 3983 "Zend/zend_language_scanner.c" +yy291: + YYDEBUG(291, *YYCURSOR); ++YYCURSOR; - if ((yych = *YYCURSOR) == '=') goto yy299; - YYDEBUG(296, *YYCURSOR); + if ((yych = *YYCURSOR) == '=') goto yy295; + YYDEBUG(292, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1355 "Zend/zend_language_scanner.l" +#line 1358 "Zend/zend_language_scanner.l" { return T_IS_EQUAL; } -#line 4015 "Zend/zend_language_scanner.c" -yy297: - YYDEBUG(297, *YYCURSOR); +#line 3994 "Zend/zend_language_scanner.c" +yy293: + YYDEBUG(293, *YYCURSOR); ++YYCURSOR; - YYDEBUG(298, *YYCURSOR); + YYDEBUG(294, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1323 "Zend/zend_language_scanner.l" +#line 1326 "Zend/zend_language_scanner.l" { return T_DOUBLE_ARROW; } -#line 4025 "Zend/zend_language_scanner.c" -yy299: - YYDEBUG(299, *YYCURSOR); +#line 4004 "Zend/zend_language_scanner.c" +yy295: + YYDEBUG(295, *YYCURSOR); ++YYCURSOR; - YYDEBUG(300, *YYCURSOR); + YYDEBUG(296, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1347 "Zend/zend_language_scanner.l" +#line 1350 "Zend/zend_language_scanner.l" { return T_IS_IDENTICAL; } -#line 4035 "Zend/zend_language_scanner.c" -yy301: - YYDEBUG(301, *YYCURSOR); +#line 4014 "Zend/zend_language_scanner.c" +yy297: + YYDEBUG(297, *YYCURSOR); yych = *++YYCURSOR; YYDEBUG(-1, yych); switch (yych) { case 'C': - case 'c': goto yy303; + case 'c': goto yy299; case 'D': - case 'd': goto yy308; + case 'd': goto yy304; case 'F': - case 'f': goto yy305; + case 'f': goto yy301; case 'H': - case 'h': goto yy302; + case 'h': goto yy298; case 'L': - case 'l': goto yy307; + case 'l': goto yy303; case 'M': - case 'm': goto yy306; + case 'm': goto yy302; case 'N': - case 'n': goto yy309; + case 'n': goto yy305; case 'T': - case 't': goto yy304; + case 't': goto yy300; default: goto yy187; } -yy302: - YYDEBUG(302, *YYCURSOR); +yy298: + YYDEBUG(298, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy370; - if (yych == 'a') goto yy370; + if (yych == 'A') goto yy366; + if (yych == 'a') goto yy366; goto yy187; -yy303: - YYDEBUG(303, *YYCURSOR); +yy299: + YYDEBUG(299, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'L') goto yy363; - if (yych == 'l') goto yy363; + if (yych == 'L') goto yy359; + if (yych == 'l') goto yy359; goto yy187; -yy304: - YYDEBUG(304, *YYCURSOR); +yy300: + YYDEBUG(300, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'R') goto yy356; - if (yych == 'r') goto yy356; + if (yych == 'R') goto yy352; + if (yych == 'r') goto yy352; goto yy187; -yy305: - YYDEBUG(305, *YYCURSOR); +yy301: + YYDEBUG(301, *YYCURSOR); yych = *++YYCURSOR; if (yych <= 'U') { - if (yych == 'I') goto yy340; + if (yych == 'I') goto yy336; if (yych <= 'T') goto yy187; - goto yy341; + goto yy337; } else { if (yych <= 'i') { if (yych <= 'h') goto yy187; - goto yy340; + goto yy336; } else { - if (yych == 'u') goto yy341; + if (yych == 'u') goto yy337; goto yy187; } } +yy302: + YYDEBUG(302, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'E') goto yy328; + if (yych == 'e') goto yy328; + goto yy187; +yy303: + YYDEBUG(303, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'I') goto yy322; + if (yych == 'i') goto yy322; + goto yy187; +yy304: + YYDEBUG(304, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'I') goto yy317; + if (yych == 'i') goto yy317; + goto yy187; +yy305: + YYDEBUG(305, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'A') goto yy306; + if (yych != 'a') goto yy187; yy306: YYDEBUG(306, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy332; - if (yych == 'e') goto yy332; - goto yy187; + if (yych == 'M') goto yy307; + if (yych != 'm') goto yy187; yy307: YYDEBUG(307, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'I') goto yy326; - if (yych == 'i') goto yy326; - goto yy187; + if (yych == 'E') goto yy308; + if (yych != 'e') goto yy187; yy308: YYDEBUG(308, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'I') goto yy321; - if (yych == 'i') goto yy321; - goto yy187; + if (yych == 'S') goto yy309; + if (yych != 's') goto yy187; yy309: YYDEBUG(309, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy310; - if (yych != 'a') goto yy187; + if (yych == 'P') goto yy310; + if (yych != 'p') goto yy187; yy310: YYDEBUG(310, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'M') goto yy311; - if (yych != 'm') goto yy187; + if (yych == 'A') goto yy311; + if (yych != 'a') goto yy187; yy311: YYDEBUG(311, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy312; - if (yych != 'e') goto yy187; + if (yych == 'C') goto yy312; + if (yych != 'c') goto yy187; yy312: YYDEBUG(312, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'S') goto yy313; - if (yych != 's') goto yy187; + if (yych == 'E') goto yy313; + if (yych != 'e') goto yy187; yy313: YYDEBUG(313, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'P') goto yy314; - if (yych != 'p') goto yy187; -yy314: - YYDEBUG(314, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'A') goto yy315; - if (yych != 'a') goto yy187; -yy315: - YYDEBUG(315, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'C') goto yy316; - if (yych != 'c') goto yy187; -yy316: - YYDEBUG(316, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'E') goto yy317; - if (yych != 'e') goto yy187; -yy317: - YYDEBUG(317, *YYCURSOR); - yych = *++YYCURSOR; if (yych != '_') goto yy187; - YYDEBUG(318, *YYCURSOR); + YYDEBUG(314, *YYCURSOR); yych = *++YYCURSOR; if (yych != '_') goto yy187; - YYDEBUG(319, *YYCURSOR); + YYDEBUG(315, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(320, *YYCURSOR); + YYDEBUG(316, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1665 "Zend/zend_language_scanner.l" +#line 1668 "Zend/zend_language_scanner.l" { if (CG(current_namespace)) { *zendlval = *CG(current_namespace); @@ -4171,27 +4150,27 @@ int lex_scan(zval *zendlval TSRMLS_DC) } return T_NS_C; } -#line 4175 "Zend/zend_language_scanner.c" -yy321: - YYDEBUG(321, *YYCURSOR); +#line 4154 "Zend/zend_language_scanner.c" +yy317: + YYDEBUG(317, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'R') goto yy322; + if (yych == 'R') goto yy318; if (yych != 'r') goto yy187; -yy322: - YYDEBUG(322, *YYCURSOR); +yy318: + YYDEBUG(318, *YYCURSOR); yych = *++YYCURSOR; if (yych != '_') goto yy187; - YYDEBUG(323, *YYCURSOR); + YYDEBUG(319, *YYCURSOR); yych = *++YYCURSOR; if (yych != '_') goto yy187; - YYDEBUG(324, *YYCURSOR); + YYDEBUG(320, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(325, *YYCURSOR); + YYDEBUG(321, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1640 "Zend/zend_language_scanner.l" +#line 1643 "Zend/zend_language_scanner.l" { char *filename = zend_get_compiled_filename(TSRMLS_C); const size_t filename_len = strlen(filename); @@ -4216,72 +4195,72 @@ int lex_scan(zval *zendlval TSRMLS_DC) ZVAL_STRING(zendlval, dirname, 0); return T_DIR; } -#line 4220 "Zend/zend_language_scanner.c" -yy326: - YYDEBUG(326, *YYCURSOR); +#line 4199 "Zend/zend_language_scanner.c" +yy322: + YYDEBUG(322, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'N') goto yy327; + if (yych == 'N') goto yy323; if (yych != 'n') goto yy187; -yy327: - YYDEBUG(327, *YYCURSOR); +yy323: + YYDEBUG(323, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy328; + if (yych == 'E') goto yy324; if (yych != 'e') goto yy187; -yy328: - YYDEBUG(328, *YYCURSOR); +yy324: + YYDEBUG(324, *YYCURSOR); yych = *++YYCURSOR; if (yych != '_') goto yy187; - YYDEBUG(329, *YYCURSOR); + YYDEBUG(325, *YYCURSOR); yych = *++YYCURSOR; if (yych != '_') goto yy187; - YYDEBUG(330, *YYCURSOR); + YYDEBUG(326, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(331, *YYCURSOR); + YYDEBUG(327, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1625 "Zend/zend_language_scanner.l" +#line 1628 "Zend/zend_language_scanner.l" { ZVAL_LONG(zendlval, CG(zend_lineno)); return T_LINE; } -#line 4250 "Zend/zend_language_scanner.c" -yy332: - YYDEBUG(332, *YYCURSOR); +#line 4229 "Zend/zend_language_scanner.c" +yy328: + YYDEBUG(328, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy333; + if (yych == 'T') goto yy329; if (yych != 't') goto yy187; -yy333: - YYDEBUG(333, *YYCURSOR); +yy329: + YYDEBUG(329, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'H') goto yy334; + if (yych == 'H') goto yy330; if (yych != 'h') goto yy187; -yy334: - YYDEBUG(334, *YYCURSOR); +yy330: + YYDEBUG(330, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'O') goto yy335; + if (yych == 'O') goto yy331; if (yych != 'o') goto yy187; -yy335: - YYDEBUG(335, *YYCURSOR); +yy331: + YYDEBUG(331, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'D') goto yy336; + if (yych == 'D') goto yy332; if (yych != 'd') goto yy187; -yy336: - YYDEBUG(336, *YYCURSOR); +yy332: + YYDEBUG(332, *YYCURSOR); yych = *++YYCURSOR; if (yych != '_') goto yy187; - YYDEBUG(337, *YYCURSOR); + YYDEBUG(333, *YYCURSOR); yych = *++YYCURSOR; if (yych != '_') goto yy187; - YYDEBUG(338, *YYCURSOR); + YYDEBUG(334, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(339, *YYCURSOR); + YYDEBUG(335, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1612 "Zend/zend_language_scanner.l" +#line 1615 "Zend/zend_language_scanner.l" { const char *class_name = CG(active_class_entry) ? CG(active_class_entry)->name : NULL; const char *func_name = CG(active_op_array)? CG(active_op_array)->function_name : NULL; @@ -4294,58 +4273,58 @@ int lex_scan(zval *zendlval TSRMLS_DC) zendlval->type = IS_STRING; return T_METHOD_C; } -#line 4298 "Zend/zend_language_scanner.c" -yy340: - YYDEBUG(340, *YYCURSOR); +#line 4277 "Zend/zend_language_scanner.c" +yy336: + YYDEBUG(336, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'L') goto yy351; - if (yych == 'l') goto yy351; + if (yych == 'L') goto yy347; + if (yych == 'l') goto yy347; goto yy187; -yy341: - YYDEBUG(341, *YYCURSOR); +yy337: + YYDEBUG(337, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'N') goto yy342; + if (yych == 'N') goto yy338; if (yych != 'n') goto yy187; -yy342: - YYDEBUG(342, *YYCURSOR); +yy338: + YYDEBUG(338, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'C') goto yy343; + if (yych == 'C') goto yy339; if (yych != 'c') goto yy187; -yy343: - YYDEBUG(343, *YYCURSOR); +yy339: + YYDEBUG(339, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy344; + if (yych == 'T') goto yy340; if (yych != 't') goto yy187; -yy344: - YYDEBUG(344, *YYCURSOR); +yy340: + YYDEBUG(340, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'I') goto yy345; + if (yych == 'I') goto yy341; if (yych != 'i') goto yy187; -yy345: - YYDEBUG(345, *YYCURSOR); +yy341: + YYDEBUG(341, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'O') goto yy346; + if (yych == 'O') goto yy342; if (yych != 'o') goto yy187; -yy346: - YYDEBUG(346, *YYCURSOR); +yy342: + YYDEBUG(342, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'N') goto yy347; + if (yych == 'N') goto yy343; if (yych != 'n') goto yy187; -yy347: - YYDEBUG(347, *YYCURSOR); +yy343: + YYDEBUG(343, *YYCURSOR); yych = *++YYCURSOR; if (yych != '_') goto yy187; - YYDEBUG(348, *YYCURSOR); + YYDEBUG(344, *YYCURSOR); yych = *++YYCURSOR; if (yych != '_') goto yy187; - YYDEBUG(349, *YYCURSOR); + YYDEBUG(345, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(350, *YYCURSOR); + YYDEBUG(346, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1602 "Zend/zend_language_scanner.l" +#line 1605 "Zend/zend_language_scanner.l" { zend_op_array *op_array = CG(active_op_array); if (op_array && op_array->function_name) { @@ -4355,27 +4334,27 @@ int lex_scan(zval *zendlval TSRMLS_DC) } return T_FUNC_C; } -#line 4359 "Zend/zend_language_scanner.c" -yy351: - YYDEBUG(351, *YYCURSOR); +#line 4338 "Zend/zend_language_scanner.c" +yy347: + YYDEBUG(347, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy352; + if (yych == 'E') goto yy348; if (yych != 'e') goto yy187; -yy352: - YYDEBUG(352, *YYCURSOR); +yy348: + YYDEBUG(348, *YYCURSOR); yych = *++YYCURSOR; if (yych != '_') goto yy187; - YYDEBUG(353, *YYCURSOR); + YYDEBUG(349, *YYCURSOR); yych = *++YYCURSOR; if (yych != '_') goto yy187; - YYDEBUG(354, *YYCURSOR); + YYDEBUG(350, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(355, *YYCURSOR); + YYDEBUG(351, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1630 "Zend/zend_language_scanner.l" +#line 1633 "Zend/zend_language_scanner.l" { char *filename = zend_get_compiled_filename(TSRMLS_C); @@ -4385,37 +4364,37 @@ int lex_scan(zval *zendlval TSRMLS_DC) ZVAL_STRING(zendlval, filename, 1); return T_FILE; } -#line 4389 "Zend/zend_language_scanner.c" -yy356: - YYDEBUG(356, *YYCURSOR); +#line 4368 "Zend/zend_language_scanner.c" +yy352: + YYDEBUG(352, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy357; + if (yych == 'A') goto yy353; if (yych != 'a') goto yy187; -yy357: - YYDEBUG(357, *YYCURSOR); +yy353: + YYDEBUG(353, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'I') goto yy358; + if (yych == 'I') goto yy354; if (yych != 'i') goto yy187; -yy358: - YYDEBUG(358, *YYCURSOR); +yy354: + YYDEBUG(354, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy359; + if (yych == 'T') goto yy355; if (yych != 't') goto yy187; -yy359: - YYDEBUG(359, *YYCURSOR); +yy355: + YYDEBUG(355, *YYCURSOR); yych = *++YYCURSOR; if (yych != '_') goto yy187; - YYDEBUG(360, *YYCURSOR); + YYDEBUG(356, *YYCURSOR); yych = *++YYCURSOR; if (yych != '_') goto yy187; - YYDEBUG(361, *YYCURSOR); + YYDEBUG(357, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(362, *YYCURSOR); + YYDEBUG(358, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1592 "Zend/zend_language_scanner.l" +#line 1595 "Zend/zend_language_scanner.l" { zend_class_entry *ce = CG(active_class_entry); if (ce && ce->name && ZEND_ACC_TRAIT == (ce->ce_flags & ZEND_ACC_TRAIT)) { @@ -4425,37 +4404,37 @@ int lex_scan(zval *zendlval TSRMLS_DC) } return T_TRAIT_C; } -#line 4429 "Zend/zend_language_scanner.c" -yy363: - YYDEBUG(363, *YYCURSOR); +#line 4408 "Zend/zend_language_scanner.c" +yy359: + YYDEBUG(359, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy364; + if (yych == 'A') goto yy360; if (yych != 'a') goto yy187; -yy364: - YYDEBUG(364, *YYCURSOR); +yy360: + YYDEBUG(360, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'S') goto yy365; + if (yych == 'S') goto yy361; if (yych != 's') goto yy187; -yy365: - YYDEBUG(365, *YYCURSOR); +yy361: + YYDEBUG(361, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'S') goto yy366; + if (yych == 'S') goto yy362; if (yych != 's') goto yy187; -yy366: - YYDEBUG(366, *YYCURSOR); +yy362: + YYDEBUG(362, *YYCURSOR); yych = *++YYCURSOR; if (yych != '_') goto yy187; - YYDEBUG(367, *YYCURSOR); + YYDEBUG(363, *YYCURSOR); yych = *++YYCURSOR; if (yych != '_') goto yy187; - YYDEBUG(368, *YYCURSOR); + YYDEBUG(364, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(369, *YYCURSOR); + YYDEBUG(365, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1574 "Zend/zend_language_scanner.l" +#line 1577 "Zend/zend_language_scanner.l" { zend_class_entry *ce = CG(active_class_entry); if (ce && ZEND_ACC_TRAIT == (ce->ce_flags & ZEND_ACC_TRAIT)) { @@ -4473,60 +4452,84 @@ int lex_scan(zval *zendlval TSRMLS_DC) } return T_CLASS_C; } -#line 4477 "Zend/zend_language_scanner.c" +#line 4456 "Zend/zend_language_scanner.c" +yy366: + YYDEBUG(366, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'L') goto yy367; + if (yych != 'l') goto yy187; +yy367: + YYDEBUG(367, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'T') goto yy368; + if (yych != 't') goto yy187; +yy368: + YYDEBUG(368, *YYCURSOR); + yych = *++YYCURSOR; + if (yych != '_') goto yy187; + YYDEBUG(369, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'C') goto yy370; + if (yych != 'c') goto yy187; yy370: YYDEBUG(370, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'L') goto yy371; - if (yych != 'l') goto yy187; + if (yych == 'O') goto yy371; + if (yych != 'o') goto yy187; yy371: YYDEBUG(371, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy372; - if (yych != 't') goto yy187; + if (yych == 'M') goto yy372; + if (yych != 'm') goto yy187; yy372: YYDEBUG(372, *YYCURSOR); yych = *++YYCURSOR; - if (yych != '_') goto yy187; + if (yych == 'P') goto yy373; + if (yych != 'p') goto yy187; +yy373: YYDEBUG(373, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'C') goto yy374; - if (yych != 'c') goto yy187; + if (yych == 'I') goto yy374; + if (yych != 'i') goto yy187; yy374: YYDEBUG(374, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'O') goto yy375; - if (yych != 'o') goto yy187; + if (yych == 'L') goto yy375; + if (yych != 'l') goto yy187; yy375: YYDEBUG(375, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'M') goto yy376; - if (yych != 'm') goto yy187; + if (yych == 'E') goto yy376; + if (yych != 'e') goto yy187; yy376: YYDEBUG(376, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'P') goto yy377; - if (yych != 'p') goto yy187; + if (yych == 'R') goto yy377; + if (yych != 'r') goto yy187; yy377: YYDEBUG(377, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'I') goto yy378; - if (yych != 'i') goto yy187; -yy378: + ++YYCURSOR; + if (yybm[0+(yych = *YYCURSOR)] & 4) { + goto yy186; + } YYDEBUG(378, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'L') goto yy379; - if (yych != 'l') goto yy187; + yyleng = YYCURSOR - SCNG(yy_text); +#line 1294 "Zend/zend_language_scanner.l" + { + return T_HALT_COMPILER; +} +#line 4522 "Zend/zend_language_scanner.c" yy379: YYDEBUG(379, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy380; - if (yych != 'e') goto yy187; + if (yych == 'S') goto yy383; + if (yych == 's') goto yy383; + goto yy187; yy380: YYDEBUG(380, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'R') goto yy381; - if (yych != 'r') goto yy187; + if (yych == 'E') goto yy381; + if (yych != 'e') goto yy187; yy381: YYDEBUG(381, *YYCURSOR); ++YYCURSOR; @@ -4535,22 +4538,21 @@ int lex_scan(zval *zendlval TSRMLS_DC) } YYDEBUG(382, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1291 "Zend/zend_language_scanner.l" +#line 1274 "Zend/zend_language_scanner.l" { - return T_HALT_COMPILER; + return T_USE; } -#line 4543 "Zend/zend_language_scanner.c" +#line 4546 "Zend/zend_language_scanner.c" yy383: YYDEBUG(383, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'S') goto yy387; - if (yych == 's') goto yy387; - goto yy187; + if (yych == 'E') goto yy384; + if (yych != 'e') goto yy187; yy384: YYDEBUG(384, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy385; - if (yych != 'e') goto yy187; + if (yych == 'T') goto yy385; + if (yych != 't') goto yy187; yy385: YYDEBUG(385, *YYCURSOR); ++YYCURSOR; @@ -4559,742 +4561,743 @@ int lex_scan(zval *zendlval TSRMLS_DC) } YYDEBUG(386, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1271 "Zend/zend_language_scanner.l" +#line 1322 "Zend/zend_language_scanner.l" { - return T_USE; + return T_UNSET; } -#line 4567 "Zend/zend_language_scanner.c" +#line 4569 "Zend/zend_language_scanner.c" yy387: YYDEBUG(387, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'E') goto yy388; - if (yych != 'e') goto yy187; -yy388: - YYDEBUG(388, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'T') goto yy389; - if (yych != 't') goto yy187; -yy389: - YYDEBUG(389, *YYCURSOR); - ++YYCURSOR; - if (yybm[0+(yych = *YYCURSOR)] & 4) { - goto yy186; - } - YYDEBUG(390, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 1319 "Zend/zend_language_scanner.l" - { - return T_UNSET; -} -#line 4590 "Zend/zend_language_scanner.c" -yy391: - YYDEBUG(391, *YYCURSOR); ++YYCURSOR; YYFILL(7); yych = *YYCURSOR; -yy392: - YYDEBUG(392, *YYCURSOR); +yy388: + YYDEBUG(388, *YYCURSOR); if (yych <= 'S') { if (yych <= 'D') { if (yych <= ' ') { - if (yych == '\t') goto yy391; + if (yych == '\t') goto yy387; if (yych <= 0x1F) goto yy194; - goto yy391; + goto yy387; } else { if (yych <= 'A') { if (yych <= '@') goto yy194; - goto yy396; + goto yy392; } else { - if (yych <= 'B') goto yy394; + if (yych <= 'B') goto yy390; if (yych <= 'C') goto yy194; - goto yy399; + goto yy395; } } } else { if (yych <= 'I') { - if (yych == 'F') goto yy400; + if (yych == 'F') goto yy396; if (yych <= 'H') goto yy194; - goto yy401; + goto yy397; } else { if (yych <= 'O') { if (yych <= 'N') goto yy194; - goto yy395; + goto yy391; } else { if (yych <= 'Q') goto yy194; - if (yych <= 'R') goto yy398; - goto yy397; + if (yych <= 'R') goto yy394; + goto yy393; } } } } else { if (yych <= 'f') { if (yych <= 'a') { - if (yych == 'U') goto yy393; + if (yych == 'U') goto yy389; if (yych <= '`') goto yy194; - goto yy396; + goto yy392; } else { if (yych <= 'c') { - if (yych <= 'b') goto yy394; + if (yych <= 'b') goto yy390; goto yy194; } else { - if (yych <= 'd') goto yy399; + if (yych <= 'd') goto yy395; if (yych <= 'e') goto yy194; - goto yy400; + goto yy396; } } } else { if (yych <= 'q') { if (yych <= 'i') { if (yych <= 'h') goto yy194; - goto yy401; + goto yy397; } else { - if (yych == 'o') goto yy395; + if (yych == 'o') goto yy391; goto yy194; } } else { if (yych <= 's') { - if (yych <= 'r') goto yy398; - goto yy397; + if (yych <= 'r') goto yy394; + goto yy393; } else { if (yych != 'u') goto yy194; } } } } -yy393: - YYDEBUG(393, *YYCURSOR); +yy389: + YYDEBUG(389, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'N') goto yy460; - if (yych == 'n') goto yy460; + if (yych == 'N') goto yy456; + if (yych == 'n') goto yy456; goto yy194; -yy394: - YYDEBUG(394, *YYCURSOR); +yy390: + YYDEBUG(390, *YYCURSOR); yych = *++YYCURSOR; if (yych <= 'O') { - if (yych == 'I') goto yy447; + if (yych == 'I') goto yy443; if (yych <= 'N') goto yy194; - goto yy448; + goto yy444; } else { if (yych <= 'i') { if (yych <= 'h') goto yy194; - goto yy447; + goto yy443; } else { - if (yych == 'o') goto yy448; + if (yych == 'o') goto yy444; goto yy194; } } +yy391: + YYDEBUG(391, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'B') goto yy435; + if (yych == 'b') goto yy435; + goto yy194; +yy392: + YYDEBUG(392, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'R') goto yy428; + if (yych == 'r') goto yy428; + goto yy194; +yy393: + YYDEBUG(393, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'T') goto yy420; + if (yych == 't') goto yy420; + goto yy194; +yy394: + YYDEBUG(394, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'E') goto yy418; + if (yych == 'e') goto yy418; + goto yy194; yy395: YYDEBUG(395, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'B') goto yy439; - if (yych == 'b') goto yy439; + if (yych == 'O') goto yy414; + if (yych == 'o') goto yy414; goto yy194; yy396: YYDEBUG(396, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'R') goto yy432; - if (yych == 'r') goto yy432; + if (yych == 'L') goto yy407; + if (yych == 'l') goto yy407; goto yy194; yy397: YYDEBUG(397, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy424; - if (yych == 't') goto yy424; - goto yy194; + if (yych == 'N') goto yy398; + if (yych != 'n') goto yy194; yy398: YYDEBUG(398, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy422; - if (yych == 'e') goto yy422; - goto yy194; + if (yych == 'T') goto yy399; + if (yych != 't') goto yy194; yy399: YYDEBUG(399, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'O') goto yy418; - if (yych == 'o') goto yy418; - goto yy194; + if (yych == 'E') goto yy400; + if (yych != 'e') goto yy402; yy400: YYDEBUG(400, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'L') goto yy411; - if (yych == 'l') goto yy411; + if (yych == 'G') goto yy405; + if (yych == 'g') goto yy405; goto yy194; yy401: YYDEBUG(401, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'N') goto yy402; - if (yych != 'n') goto yy194; -yy402: - YYDEBUG(402, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'T') goto yy403; - if (yych != 't') goto yy194; -yy403: - YYDEBUG(403, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'E') goto yy404; - if (yych != 'e') goto yy406; -yy404: - YYDEBUG(404, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'G') goto yy409; - if (yych == 'g') goto yy409; - goto yy194; -yy405: - YYDEBUG(405, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; -yy406: - YYDEBUG(406, *YYCURSOR); +yy402: + YYDEBUG(402, *YYCURSOR); if (yych <= 0x1F) { - if (yych == '\t') goto yy405; + if (yych == '\t') goto yy401; goto yy194; } else { - if (yych <= ' ') goto yy405; + if (yych <= ' ') goto yy401; if (yych != ')') goto yy194; } - YYDEBUG(407, *YYCURSOR); + YYDEBUG(403, *YYCURSOR); ++YYCURSOR; - YYDEBUG(408, *YYCURSOR); + YYDEBUG(404, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1219 "Zend/zend_language_scanner.l" +#line 1222 "Zend/zend_language_scanner.l" { return T_INT_CAST; } -#line 4766 "Zend/zend_language_scanner.c" -yy409: - YYDEBUG(409, *YYCURSOR); +#line 4745 "Zend/zend_language_scanner.c" +yy405: + YYDEBUG(405, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy410; + if (yych == 'E') goto yy406; if (yych != 'e') goto yy194; -yy410: - YYDEBUG(410, *YYCURSOR); +yy406: + YYDEBUG(406, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'R') goto yy405; - if (yych == 'r') goto yy405; + if (yych == 'R') goto yy401; + if (yych == 'r') goto yy401; goto yy194; -yy411: - YYDEBUG(411, *YYCURSOR); +yy407: + YYDEBUG(407, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'O') goto yy412; + if (yych == 'O') goto yy408; if (yych != 'o') goto yy194; -yy412: - YYDEBUG(412, *YYCURSOR); +yy408: + YYDEBUG(408, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy413; + if (yych == 'A') goto yy409; if (yych != 'a') goto yy194; -yy413: - YYDEBUG(413, *YYCURSOR); +yy409: + YYDEBUG(409, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy414; + if (yych == 'T') goto yy410; if (yych != 't') goto yy194; -yy414: - YYDEBUG(414, *YYCURSOR); +yy410: + YYDEBUG(410, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(415, *YYCURSOR); + YYDEBUG(411, *YYCURSOR); if (yych <= 0x1F) { - if (yych == '\t') goto yy414; + if (yych == '\t') goto yy410; goto yy194; } else { - if (yych <= ' ') goto yy414; + if (yych <= ' ') goto yy410; if (yych != ')') goto yy194; } - YYDEBUG(416, *YYCURSOR); + YYDEBUG(412, *YYCURSOR); ++YYCURSOR; - YYDEBUG(417, *YYCURSOR); + YYDEBUG(413, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1223 "Zend/zend_language_scanner.l" +#line 1226 "Zend/zend_language_scanner.l" { return T_DOUBLE_CAST; } -#line 4814 "Zend/zend_language_scanner.c" -yy418: - YYDEBUG(418, *YYCURSOR); +#line 4793 "Zend/zend_language_scanner.c" +yy414: + YYDEBUG(414, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'U') goto yy419; + if (yych == 'U') goto yy415; if (yych != 'u') goto yy194; -yy419: - YYDEBUG(419, *YYCURSOR); +yy415: + YYDEBUG(415, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'B') goto yy420; + if (yych == 'B') goto yy416; if (yych != 'b') goto yy194; -yy420: - YYDEBUG(420, *YYCURSOR); +yy416: + YYDEBUG(416, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'L') goto yy421; + if (yych == 'L') goto yy417; if (yych != 'l') goto yy194; -yy421: - YYDEBUG(421, *YYCURSOR); +yy417: + YYDEBUG(417, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy414; - if (yych == 'e') goto yy414; + if (yych == 'E') goto yy410; + if (yych == 'e') goto yy410; goto yy194; -yy422: - YYDEBUG(422, *YYCURSOR); +yy418: + YYDEBUG(418, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy423; + if (yych == 'A') goto yy419; if (yych != 'a') goto yy194; -yy423: - YYDEBUG(423, *YYCURSOR); +yy419: + YYDEBUG(419, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'L') goto yy414; - if (yych == 'l') goto yy414; + if (yych == 'L') goto yy410; + if (yych == 'l') goto yy410; goto yy194; -yy424: - YYDEBUG(424, *YYCURSOR); +yy420: + YYDEBUG(420, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'R') goto yy425; + if (yych == 'R') goto yy421; if (yych != 'r') goto yy194; -yy425: - YYDEBUG(425, *YYCURSOR); +yy421: + YYDEBUG(421, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'I') goto yy426; + if (yych == 'I') goto yy422; if (yych != 'i') goto yy194; -yy426: - YYDEBUG(426, *YYCURSOR); +yy422: + YYDEBUG(422, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'N') goto yy427; + if (yych == 'N') goto yy423; if (yych != 'n') goto yy194; -yy427: - YYDEBUG(427, *YYCURSOR); +yy423: + YYDEBUG(423, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'G') goto yy428; + if (yych == 'G') goto yy424; if (yych != 'g') goto yy194; -yy428: - YYDEBUG(428, *YYCURSOR); +yy424: + YYDEBUG(424, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(429, *YYCURSOR); + YYDEBUG(425, *YYCURSOR); if (yych <= 0x1F) { - if (yych == '\t') goto yy428; + if (yych == '\t') goto yy424; goto yy194; } else { - if (yych <= ' ') goto yy428; + if (yych <= ' ') goto yy424; if (yych != ')') goto yy194; } - YYDEBUG(430, *YYCURSOR); + YYDEBUG(426, *YYCURSOR); ++YYCURSOR; - YYDEBUG(431, *YYCURSOR); + YYDEBUG(427, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1227 "Zend/zend_language_scanner.l" +#line 1230 "Zend/zend_language_scanner.l" { return T_STRING_CAST; } -#line 4888 "Zend/zend_language_scanner.c" -yy432: - YYDEBUG(432, *YYCURSOR); +#line 4867 "Zend/zend_language_scanner.c" +yy428: + YYDEBUG(428, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'R') goto yy433; + if (yych == 'R') goto yy429; if (yych != 'r') goto yy194; -yy433: - YYDEBUG(433, *YYCURSOR); +yy429: + YYDEBUG(429, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy434; + if (yych == 'A') goto yy430; if (yych != 'a') goto yy194; -yy434: - YYDEBUG(434, *YYCURSOR); +yy430: + YYDEBUG(430, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'Y') goto yy435; + if (yych == 'Y') goto yy431; if (yych != 'y') goto yy194; -yy435: - YYDEBUG(435, *YYCURSOR); +yy431: + YYDEBUG(431, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(436, *YYCURSOR); + YYDEBUG(432, *YYCURSOR); if (yych <= 0x1F) { - if (yych == '\t') goto yy435; + if (yych == '\t') goto yy431; goto yy194; } else { - if (yych <= ' ') goto yy435; + if (yych <= ' ') goto yy431; if (yych != ')') goto yy194; } - YYDEBUG(437, *YYCURSOR); + YYDEBUG(433, *YYCURSOR); ++YYCURSOR; - YYDEBUG(438, *YYCURSOR); + YYDEBUG(434, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1231 "Zend/zend_language_scanner.l" +#line 1234 "Zend/zend_language_scanner.l" { return T_ARRAY_CAST; } -#line 4925 "Zend/zend_language_scanner.c" -yy439: - YYDEBUG(439, *YYCURSOR); +#line 4904 "Zend/zend_language_scanner.c" +yy435: + YYDEBUG(435, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'J') goto yy440; + if (yych == 'J') goto yy436; if (yych != 'j') goto yy194; -yy440: - YYDEBUG(440, *YYCURSOR); +yy436: + YYDEBUG(436, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy441; + if (yych == 'E') goto yy437; if (yych != 'e') goto yy194; -yy441: - YYDEBUG(441, *YYCURSOR); +yy437: + YYDEBUG(437, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'C') goto yy442; + if (yych == 'C') goto yy438; if (yych != 'c') goto yy194; -yy442: - YYDEBUG(442, *YYCURSOR); +yy438: + YYDEBUG(438, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy443; + if (yych == 'T') goto yy439; if (yych != 't') goto yy194; -yy443: - YYDEBUG(443, *YYCURSOR); +yy439: + YYDEBUG(439, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(444, *YYCURSOR); + YYDEBUG(440, *YYCURSOR); if (yych <= 0x1F) { - if (yych == '\t') goto yy443; + if (yych == '\t') goto yy439; goto yy194; } else { - if (yych <= ' ') goto yy443; + if (yych <= ' ') goto yy439; if (yych != ')') goto yy194; } - YYDEBUG(445, *YYCURSOR); + YYDEBUG(441, *YYCURSOR); ++YYCURSOR; - YYDEBUG(446, *YYCURSOR); + YYDEBUG(442, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1235 "Zend/zend_language_scanner.l" +#line 1238 "Zend/zend_language_scanner.l" { return T_OBJECT_CAST; } -#line 4967 "Zend/zend_language_scanner.c" -yy447: - YYDEBUG(447, *YYCURSOR); +#line 4946 "Zend/zend_language_scanner.c" +yy443: + YYDEBUG(443, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'N') goto yy457; - if (yych == 'n') goto yy457; + if (yych == 'N') goto yy453; + if (yych == 'n') goto yy453; goto yy194; -yy448: - YYDEBUG(448, *YYCURSOR); +yy444: + YYDEBUG(444, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'O') goto yy449; + if (yych == 'O') goto yy445; if (yych != 'o') goto yy194; -yy449: - YYDEBUG(449, *YYCURSOR); +yy445: + YYDEBUG(445, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'L') goto yy450; + if (yych == 'L') goto yy446; if (yych != 'l') goto yy194; -yy450: - YYDEBUG(450, *YYCURSOR); +yy446: + YYDEBUG(446, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy455; - if (yych == 'e') goto yy455; - goto yy452; -yy451: - YYDEBUG(451, *YYCURSOR); + if (yych == 'E') goto yy451; + if (yych == 'e') goto yy451; + goto yy448; +yy447: + YYDEBUG(447, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; -yy452: - YYDEBUG(452, *YYCURSOR); +yy448: + YYDEBUG(448, *YYCURSOR); if (yych <= 0x1F) { - if (yych == '\t') goto yy451; + if (yych == '\t') goto yy447; goto yy194; } else { - if (yych <= ' ') goto yy451; + if (yych <= ' ') goto yy447; if (yych != ')') goto yy194; } - YYDEBUG(453, *YYCURSOR); + YYDEBUG(449, *YYCURSOR); ++YYCURSOR; - YYDEBUG(454, *YYCURSOR); + YYDEBUG(450, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1239 "Zend/zend_language_scanner.l" +#line 1242 "Zend/zend_language_scanner.l" { return T_BOOL_CAST; } -#line 5012 "Zend/zend_language_scanner.c" -yy455: - YYDEBUG(455, *YYCURSOR); +#line 4991 "Zend/zend_language_scanner.c" +yy451: + YYDEBUG(451, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy456; + if (yych == 'A') goto yy452; if (yych != 'a') goto yy194; -yy456: - YYDEBUG(456, *YYCURSOR); +yy452: + YYDEBUG(452, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'N') goto yy451; - if (yych == 'n') goto yy451; + if (yych == 'N') goto yy447; + if (yych == 'n') goto yy447; goto yy194; -yy457: - YYDEBUG(457, *YYCURSOR); +yy453: + YYDEBUG(453, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy458; + if (yych == 'A') goto yy454; if (yych != 'a') goto yy194; -yy458: - YYDEBUG(458, *YYCURSOR); +yy454: + YYDEBUG(454, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'R') goto yy459; + if (yych == 'R') goto yy455; if (yych != 'r') goto yy194; -yy459: - YYDEBUG(459, *YYCURSOR); +yy455: + YYDEBUG(455, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'Y') goto yy428; - if (yych == 'y') goto yy428; + if (yych == 'Y') goto yy424; + if (yych == 'y') goto yy424; goto yy194; -yy460: - YYDEBUG(460, *YYCURSOR); +yy456: + YYDEBUG(456, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'S') goto yy461; + if (yych == 'S') goto yy457; if (yych != 's') goto yy194; -yy461: - YYDEBUG(461, *YYCURSOR); +yy457: + YYDEBUG(457, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy462; + if (yych == 'E') goto yy458; if (yych != 'e') goto yy194; -yy462: - YYDEBUG(462, *YYCURSOR); +yy458: + YYDEBUG(458, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy463; + if (yych == 'T') goto yy459; if (yych != 't') goto yy194; -yy463: - YYDEBUG(463, *YYCURSOR); +yy459: + YYDEBUG(459, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(464, *YYCURSOR); + YYDEBUG(460, *YYCURSOR); if (yych <= 0x1F) { - if (yych == '\t') goto yy463; + if (yych == '\t') goto yy459; goto yy194; } else { - if (yych <= ' ') goto yy463; + if (yych <= ' ') goto yy459; if (yych != ')') goto yy194; } - YYDEBUG(465, *YYCURSOR); + YYDEBUG(461, *YYCURSOR); ++YYCURSOR; - YYDEBUG(466, *YYCURSOR); + YYDEBUG(462, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1243 "Zend/zend_language_scanner.l" +#line 1246 "Zend/zend_language_scanner.l" { return T_UNSET_CAST; } -#line 5076 "Zend/zend_language_scanner.c" -yy467: - YYDEBUG(467, *YYCURSOR); +#line 5055 "Zend/zend_language_scanner.c" +yy463: + YYDEBUG(463, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'R') goto yy468; + if (yych == 'R') goto yy464; if (yych != 'r') goto yy187; -yy468: - YYDEBUG(468, *YYCURSOR); +yy464: + YYDEBUG(464, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(469, *YYCURSOR); + YYDEBUG(465, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1215 "Zend/zend_language_scanner.l" +#line 1218 "Zend/zend_language_scanner.l" { return T_VAR; } -#line 5094 "Zend/zend_language_scanner.c" -yy470: - YYDEBUG(470, *YYCURSOR); +#line 5073 "Zend/zend_language_scanner.c" +yy466: + YYDEBUG(466, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'M') goto yy474; - if (yych == 'm') goto yy474; + if (yych == 'M') goto yy470; + if (yych == 'm') goto yy470; goto yy187; -yy471: - YYDEBUG(471, *YYCURSOR); +yy467: + YYDEBUG(467, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'W') goto yy472; + if (yych == 'W') goto yy468; if (yych != 'w') goto yy187; -yy472: - YYDEBUG(472, *YYCURSOR); +yy468: + YYDEBUG(468, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(473, *YYCURSOR); + YYDEBUG(469, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1207 "Zend/zend_language_scanner.l" +#line 1210 "Zend/zend_language_scanner.l" { return T_NEW; } -#line 5118 "Zend/zend_language_scanner.c" -yy474: - YYDEBUG(474, *YYCURSOR); +#line 5097 "Zend/zend_language_scanner.c" +yy470: + YYDEBUG(470, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy475; + if (yych == 'E') goto yy471; if (yych != 'e') goto yy187; -yy475: - YYDEBUG(475, *YYCURSOR); +yy471: + YYDEBUG(471, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'S') goto yy476; + if (yych == 'S') goto yy472; if (yych != 's') goto yy187; -yy476: - YYDEBUG(476, *YYCURSOR); +yy472: + YYDEBUG(472, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'P') goto yy477; + if (yych == 'P') goto yy473; if (yych != 'p') goto yy187; -yy477: - YYDEBUG(477, *YYCURSOR); +yy473: + YYDEBUG(473, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy478; + if (yych == 'A') goto yy474; if (yych != 'a') goto yy187; -yy478: - YYDEBUG(478, *YYCURSOR); +yy474: + YYDEBUG(474, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'C') goto yy479; + if (yych == 'C') goto yy475; if (yych != 'c') goto yy187; -yy479: - YYDEBUG(479, *YYCURSOR); +yy475: + YYDEBUG(475, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy480; + if (yych == 'E') goto yy476; if (yych != 'e') goto yy187; -yy480: - YYDEBUG(480, *YYCURSOR); +yy476: + YYDEBUG(476, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(481, *YYCURSOR); + YYDEBUG(477, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1267 "Zend/zend_language_scanner.l" +#line 1270 "Zend/zend_language_scanner.l" { return T_NAMESPACE; } -#line 5161 "Zend/zend_language_scanner.c" +#line 5140 "Zend/zend_language_scanner.c" +yy478: + YYDEBUG(478, *YYCURSOR); + yyaccept = 3; + YYMARKER = ++YYCURSOR; + YYFILL(3); + yych = *YYCURSOR; + YYDEBUG(479, *YYCURSOR); + if (yych <= 'D') { + if (yych <= '/') goto yy190; + if (yych <= '9') goto yy478; + goto yy190; + } else { + if (yych <= 'E') goto yy193; + if (yych == 'e') goto yy193; + goto yy190; + } +yy480: + YYDEBUG(480, *YYCURSOR); + ++YYCURSOR; + YYDEBUG(481, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 1390 "Zend/zend_language_scanner.l" + { + return T_CONCAT_EQUAL; +} +#line 5166 "Zend/zend_language_scanner.c" yy482: YYDEBUG(482, *YYCURSOR); - ++YYCURSOR; + yych = *++YYCURSOR; + if (yych != '.') goto yy194; YYDEBUG(483, *YYCURSOR); + ++YYCURSOR; + YYDEBUG(484, *YYCURSOR); + yyleng = YYCURSOR - SCNG(yy_text); +#line 1206 "Zend/zend_language_scanner.l" + { + return T_ELLIPSIS; +} +#line 5179 "Zend/zend_language_scanner.c" +yy485: + YYDEBUG(485, *YYCURSOR); + ++YYCURSOR; + YYDEBUG(486, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1199 "Zend/zend_language_scanner.l" +#line 1198 "Zend/zend_language_scanner.l" { return T_PAAMAYIM_NEKUDOTAYIM; } -#line 5171 "Zend/zend_language_scanner.c" -yy484: - YYDEBUG(484, *YYCURSOR); +#line 5189 "Zend/zend_language_scanner.c" +yy487: + YYDEBUG(487, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; -yy485: - YYDEBUG(485, *YYCURSOR); +yy488: + YYDEBUG(488, *YYCURSOR); if (yych <= '\f') { if (yych <= 0x08) goto yy141; - if (yych <= '\n') goto yy484; + if (yych <= '\n') goto yy487; goto yy141; } else { - if (yych <= '\r') goto yy484; - if (yych == ' ') goto yy484; + if (yych <= '\r') goto yy487; + if (yych == ' ') goto yy487; goto yy141; } -yy486: - YYDEBUG(486, *YYCURSOR); +yy489: + YYDEBUG(489, *YYCURSOR); ++YYCURSOR; - YYDEBUG(487, *YYCURSOR); + YYDEBUG(490, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1375 "Zend/zend_language_scanner.l" +#line 1378 "Zend/zend_language_scanner.l" { return T_MINUS_EQUAL; } -#line 5197 "Zend/zend_language_scanner.c" -yy488: - YYDEBUG(488, *YYCURSOR); +#line 5215 "Zend/zend_language_scanner.c" +yy491: + YYDEBUG(491, *YYCURSOR); ++YYCURSOR; - YYDEBUG(489, *YYCURSOR); + YYDEBUG(492, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1343 "Zend/zend_language_scanner.l" +#line 1346 "Zend/zend_language_scanner.l" { return T_DEC; } -#line 5207 "Zend/zend_language_scanner.c" -yy490: - YYDEBUG(490, *YYCURSOR); +#line 5225 "Zend/zend_language_scanner.c" +yy493: + YYDEBUG(493, *YYCURSOR); ++YYCURSOR; - YYDEBUG(491, *YYCURSOR); + YYDEBUG(494, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1171 "Zend/zend_language_scanner.l" +#line 1170 "Zend/zend_language_scanner.l" { yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC); return T_OBJECT_OPERATOR; } -#line 5218 "Zend/zend_language_scanner.c" -yy492: - YYDEBUG(492, *YYCURSOR); +#line 5236 "Zend/zend_language_scanner.c" +yy495: + YYDEBUG(495, *YYCURSOR); yych = *++YYCURSOR; if (yych <= 'O') { - if (yych == 'I') goto yy499; + if (yych == 'I') goto yy502; if (yych <= 'N') goto yy187; - goto yy500; + goto yy503; } else { if (yych <= 'i') { if (yych <= 'h') goto yy187; - goto yy499; + goto yy502; } else { - if (yych == 'o') goto yy500; + if (yych == 'o') goto yy503; goto yy187; } } -yy493: - YYDEBUG(493, *YYCURSOR); +yy496: + YYDEBUG(496, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'B') goto yy494; + if (yych == 'B') goto yy497; if (yych != 'b') goto yy187; -yy494: - YYDEBUG(494, *YYCURSOR); +yy497: + YYDEBUG(497, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'L') goto yy495; + if (yych == 'L') goto yy498; if (yych != 'l') goto yy187; -yy495: - YYDEBUG(495, *YYCURSOR); +yy498: + YYDEBUG(498, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'I') goto yy496; + if (yych == 'I') goto yy499; if (yych != 'i') goto yy187; -yy496: - YYDEBUG(496, *YYCURSOR); +yy499: + YYDEBUG(499, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'C') goto yy497; + if (yych == 'C') goto yy500; if (yych != 'c') goto yy187; -yy497: - YYDEBUG(497, *YYCURSOR); +yy500: + YYDEBUG(500, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(498, *YYCURSOR); + YYDEBUG(501, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1315 "Zend/zend_language_scanner.l" +#line 1318 "Zend/zend_language_scanner.l" { return T_PUBLIC; } -#line 5267 "Zend/zend_language_scanner.c" -yy499: - YYDEBUG(499, *YYCURSOR); +#line 5285 "Zend/zend_language_scanner.c" +yy502: + YYDEBUG(502, *YYCURSOR); yych = *++YYCURSOR; if (yych <= 'V') { - if (yych == 'N') goto yy508; + if (yych == 'N') goto yy511; if (yych <= 'U') goto yy187; - goto yy509; + goto yy512; } else { if (yych <= 'n') { if (yych <= 'm') goto yy187; - goto yy508; + goto yy511; } else { - if (yych == 'v') goto yy509; + if (yych == 'v') goto yy512; goto yy187; } } -yy500: - YYDEBUG(500, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'T') goto yy501; - if (yych != 't') goto yy187; -yy501: - YYDEBUG(501, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'E') goto yy502; - if (yych != 'e') goto yy187; -yy502: - YYDEBUG(502, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'C') goto yy503; - if (yych != 'c') goto yy187; yy503: YYDEBUG(503, *YYCURSOR); yych = *++YYCURSOR; @@ -5308,1072 +5311,1069 @@ int lex_scan(zval *zendlval TSRMLS_DC) yy505: YYDEBUG(505, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'D') goto yy506; - if (yych != 'd') goto yy187; + if (yych == 'C') goto yy506; + if (yych != 'c') goto yy187; yy506: YYDEBUG(506, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'T') goto yy507; + if (yych != 't') goto yy187; +yy507: + YYDEBUG(507, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'E') goto yy508; + if (yych != 'e') goto yy187; +yy508: + YYDEBUG(508, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'D') goto yy509; + if (yych != 'd') goto yy187; +yy509: + YYDEBUG(509, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(507, *YYCURSOR); + YYDEBUG(510, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1311 "Zend/zend_language_scanner.l" +#line 1314 "Zend/zend_language_scanner.l" { return T_PROTECTED; } -#line 5326 "Zend/zend_language_scanner.c" -yy508: - YYDEBUG(508, *YYCURSOR); +#line 5344 "Zend/zend_language_scanner.c" +yy511: + YYDEBUG(511, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy514; - if (yych == 't') goto yy514; + if (yych == 'T') goto yy517; + if (yych == 't') goto yy517; goto yy187; -yy509: - YYDEBUG(509, *YYCURSOR); +yy512: + YYDEBUG(512, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy510; + if (yych == 'A') goto yy513; if (yych != 'a') goto yy187; -yy510: - YYDEBUG(510, *YYCURSOR); +yy513: + YYDEBUG(513, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy511; + if (yych == 'T') goto yy514; if (yych != 't') goto yy187; -yy511: - YYDEBUG(511, *YYCURSOR); +yy514: + YYDEBUG(514, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy512; + if (yych == 'E') goto yy515; if (yych != 'e') goto yy187; -yy512: - YYDEBUG(512, *YYCURSOR); +yy515: + YYDEBUG(515, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(513, *YYCURSOR); + YYDEBUG(516, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1307 "Zend/zend_language_scanner.l" +#line 1310 "Zend/zend_language_scanner.l" { return T_PRIVATE; } -#line 5360 "Zend/zend_language_scanner.c" -yy514: - YYDEBUG(514, *YYCURSOR); +#line 5378 "Zend/zend_language_scanner.c" +yy517: + YYDEBUG(517, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(515, *YYCURSOR); + YYDEBUG(518, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1147 "Zend/zend_language_scanner.l" +#line 1146 "Zend/zend_language_scanner.l" { return T_PRINT; } -#line 5373 "Zend/zend_language_scanner.c" -yy516: - YYDEBUG(516, *YYCURSOR); +#line 5391 "Zend/zend_language_scanner.c" +yy519: + YYDEBUG(519, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'O') goto yy521; - if (yych == 'o') goto yy521; + if (yych == 'O') goto yy524; + if (yych == 'o') goto yy524; goto yy187; -yy517: - YYDEBUG(517, *YYCURSOR); +yy520: + YYDEBUG(520, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy518; + if (yych == 'T') goto yy521; if (yych != 't') goto yy187; -yy518: - YYDEBUG(518, *YYCURSOR); +yy521: + YYDEBUG(521, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'O') goto yy519; + if (yych == 'O') goto yy522; if (yych != 'o') goto yy187; -yy519: - YYDEBUG(519, *YYCURSOR); +yy522: + YYDEBUG(522, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(520, *YYCURSOR); + YYDEBUG(523, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1139 "Zend/zend_language_scanner.l" +#line 1138 "Zend/zend_language_scanner.l" { return T_GOTO; } -#line 5402 "Zend/zend_language_scanner.c" -yy521: - YYDEBUG(521, *YYCURSOR); +#line 5420 "Zend/zend_language_scanner.c" +yy524: + YYDEBUG(524, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'B') goto yy522; + if (yych == 'B') goto yy525; if (yych != 'b') goto yy187; -yy522: - YYDEBUG(522, *YYCURSOR); +yy525: + YYDEBUG(525, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy523; + if (yych == 'A') goto yy526; if (yych != 'a') goto yy187; -yy523: - YYDEBUG(523, *YYCURSOR); +yy526: + YYDEBUG(526, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'L') goto yy524; + if (yych == 'L') goto yy527; if (yych != 'l') goto yy187; -yy524: - YYDEBUG(524, *YYCURSOR); +yy527: + YYDEBUG(527, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(525, *YYCURSOR); + YYDEBUG(528, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1279 "Zend/zend_language_scanner.l" +#line 1282 "Zend/zend_language_scanner.l" { return T_GLOBAL; } -#line 5430 "Zend/zend_language_scanner.c" -yy526: - YYDEBUG(526, *YYCURSOR); +#line 5448 "Zend/zend_language_scanner.c" +yy529: + YYDEBUG(529, *YYCURSOR); yych = *++YYCURSOR; - if (yych == '<') goto yy534; + if (yych == '<') goto yy537; goto yy194; -yy527: - YYDEBUG(527, *YYCURSOR); +yy530: + YYDEBUG(530, *YYCURSOR); yych = *++YYCURSOR; goto yy181; -yy528: - YYDEBUG(528, *YYCURSOR); +yy531: + YYDEBUG(531, *YYCURSOR); yych = *++YYCURSOR; goto yy179; -yy529: - YYDEBUG(529, *YYCURSOR); +yy532: + YYDEBUG(532, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy530; + if (yych == 'E') goto yy533; if (yych != 'e') goto yy187; -yy530: - YYDEBUG(530, *YYCURSOR); +yy533: + YYDEBUG(533, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy531; + if (yych == 'A') goto yy534; if (yych != 'a') goto yy187; -yy531: - YYDEBUG(531, *YYCURSOR); +yy534: + YYDEBUG(534, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'K') goto yy532; + if (yych == 'K') goto yy535; if (yych != 'k') goto yy187; -yy532: - YYDEBUG(532, *YYCURSOR); +yy535: + YYDEBUG(535, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(533, *YYCURSOR); + YYDEBUG(536, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1131 "Zend/zend_language_scanner.l" +#line 1130 "Zend/zend_language_scanner.l" { return T_BREAK; } -#line 5471 "Zend/zend_language_scanner.c" -yy534: - YYDEBUG(534, *YYCURSOR); +#line 5489 "Zend/zend_language_scanner.c" +yy537: + YYDEBUG(537, *YYCURSOR); yych = *++YYCURSOR; - if (yych == '<') goto yy270; + if (yych == '<') goto yy266; goto yy194; -yy535: - YYDEBUG(535, *YYCURSOR); +yy538: + YYDEBUG(538, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy542; - if (yych == 'a') goto yy542; + if (yych == 'A') goto yy545; + if (yych == 'a') goto yy545; goto yy187; -yy536: - YYDEBUG(536, *YYCURSOR); +yy539: + YYDEBUG(539, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'I') goto yy537; + if (yych == 'I') goto yy540; if (yych != 'i') goto yy187; -yy537: - YYDEBUG(537, *YYCURSOR); +yy540: + YYDEBUG(540, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy538; + if (yych == 'T') goto yy541; if (yych != 't') goto yy187; -yy538: - YYDEBUG(538, *YYCURSOR); +yy541: + YYDEBUG(541, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'C') goto yy539; + if (yych == 'C') goto yy542; if (yych != 'c') goto yy187; -yy539: - YYDEBUG(539, *YYCURSOR); +yy542: + YYDEBUG(542, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'H') goto yy540; + if (yych == 'H') goto yy543; if (yych != 'h') goto yy187; -yy540: - YYDEBUG(540, *YYCURSOR); +yy543: + YYDEBUG(543, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(541, *YYCURSOR); + YYDEBUG(544, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1115 "Zend/zend_language_scanner.l" +#line 1114 "Zend/zend_language_scanner.l" { return T_SWITCH; } -#line 5515 "Zend/zend_language_scanner.c" -yy542: - YYDEBUG(542, *YYCURSOR); +#line 5533 "Zend/zend_language_scanner.c" +yy545: + YYDEBUG(545, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy543; + if (yych == 'T') goto yy546; if (yych != 't') goto yy187; -yy543: - YYDEBUG(543, *YYCURSOR); +yy546: + YYDEBUG(546, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'I') goto yy544; + if (yych == 'I') goto yy547; if (yych != 'i') goto yy187; -yy544: - YYDEBUG(544, *YYCURSOR); +yy547: + YYDEBUG(547, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'C') goto yy545; + if (yych == 'C') goto yy548; if (yych != 'c') goto yy187; -yy545: - YYDEBUG(545, *YYCURSOR); +yy548: + YYDEBUG(548, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(546, *YYCURSOR); + YYDEBUG(549, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1295 "Zend/zend_language_scanner.l" +#line 1298 "Zend/zend_language_scanner.l" { return T_STATIC; } -#line 5543 "Zend/zend_language_scanner.c" -yy547: - YYDEBUG(547, *YYCURSOR); +#line 5561 "Zend/zend_language_scanner.c" +yy550: + YYDEBUG(550, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'S') goto yy558; - if (yych == 's') goto yy558; + if (yych == 'S') goto yy561; + if (yych == 's') goto yy561; goto yy187; -yy548: - YYDEBUG(548, *YYCURSOR); +yy551: + YYDEBUG(551, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'D') goto yy556; - if (yych == 'd') goto yy556; + if (yych == 'D') goto yy559; + if (yych == 'd') goto yy559; goto yy187; -yy549: - YYDEBUG(549, *YYCURSOR); +yy552: + YYDEBUG(552, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'R') goto yy552; - if (yych == 'r') goto yy552; + if (yych == 'R') goto yy555; + if (yych == 'r') goto yy555; goto yy187; -yy550: - YYDEBUG(550, *YYCURSOR); +yy553: + YYDEBUG(553, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(551, *YYCURSOR); + YYDEBUG(554, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1111 "Zend/zend_language_scanner.l" +#line 1110 "Zend/zend_language_scanner.l" { return T_AS; } -#line 5574 "Zend/zend_language_scanner.c" -yy552: - YYDEBUG(552, *YYCURSOR); +#line 5592 "Zend/zend_language_scanner.c" +yy555: + YYDEBUG(555, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy553; + if (yych == 'A') goto yy556; if (yych != 'a') goto yy187; -yy553: - YYDEBUG(553, *YYCURSOR); +yy556: + YYDEBUG(556, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'Y') goto yy554; + if (yych == 'Y') goto yy557; if (yych != 'y') goto yy187; -yy554: - YYDEBUG(554, *YYCURSOR); +yy557: + YYDEBUG(557, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(555, *YYCURSOR); + YYDEBUG(558, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1331 "Zend/zend_language_scanner.l" +#line 1334 "Zend/zend_language_scanner.l" { return T_ARRAY; } -#line 5597 "Zend/zend_language_scanner.c" -yy556: - YYDEBUG(556, *YYCURSOR); +#line 5615 "Zend/zend_language_scanner.c" +yy559: + YYDEBUG(559, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(557, *YYCURSOR); + YYDEBUG(560, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1427 "Zend/zend_language_scanner.l" +#line 1430 "Zend/zend_language_scanner.l" { return T_LOGICAL_AND; } -#line 5610 "Zend/zend_language_scanner.c" -yy558: - YYDEBUG(558, *YYCURSOR); +#line 5628 "Zend/zend_language_scanner.c" +yy561: + YYDEBUG(561, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy559; + if (yych == 'T') goto yy562; if (yych != 't') goto yy187; -yy559: - YYDEBUG(559, *YYCURSOR); +yy562: + YYDEBUG(562, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'R') goto yy560; + if (yych == 'R') goto yy563; if (yych != 'r') goto yy187; -yy560: - YYDEBUG(560, *YYCURSOR); +yy563: + YYDEBUG(563, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy561; + if (yych == 'A') goto yy564; if (yych != 'a') goto yy187; -yy561: - YYDEBUG(561, *YYCURSOR); +yy564: + YYDEBUG(564, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'C') goto yy562; + if (yych == 'C') goto yy565; if (yych != 'c') goto yy187; -yy562: - YYDEBUG(562, *YYCURSOR); +yy565: + YYDEBUG(565, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy563; + if (yych == 'T') goto yy566; if (yych != 't') goto yy187; -yy563: - YYDEBUG(563, *YYCURSOR); +yy566: + YYDEBUG(566, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(564, *YYCURSOR); + YYDEBUG(567, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1299 "Zend/zend_language_scanner.l" +#line 1302 "Zend/zend_language_scanner.l" { return T_ABSTRACT; } -#line 5648 "Zend/zend_language_scanner.c" -yy565: - YYDEBUG(565, *YYCURSOR); +#line 5666 "Zend/zend_language_scanner.c" +yy568: + YYDEBUG(568, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'I') goto yy566; + if (yych == 'I') goto yy569; if (yych != 'i') goto yy187; -yy566: - YYDEBUG(566, *YYCURSOR); +yy569: + YYDEBUG(569, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'L') goto yy567; + if (yych == 'L') goto yy570; if (yych != 'l') goto yy187; -yy567: - YYDEBUG(567, *YYCURSOR); +yy570: + YYDEBUG(570, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy568; + if (yych == 'E') goto yy571; if (yych != 'e') goto yy187; -yy568: - YYDEBUG(568, *YYCURSOR); +yy571: + YYDEBUG(571, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(569, *YYCURSOR); + YYDEBUG(572, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1071 "Zend/zend_language_scanner.l" +#line 1070 "Zend/zend_language_scanner.l" { return T_WHILE; } -#line 5676 "Zend/zend_language_scanner.c" -yy570: - YYDEBUG(570, *YYCURSOR); +#line 5694 "Zend/zend_language_scanner.c" +yy573: + YYDEBUG(573, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(571, *YYCURSOR); + YYDEBUG(574, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1055 "Zend/zend_language_scanner.l" +#line 1054 "Zend/zend_language_scanner.l" { return T_IF; } -#line 5689 "Zend/zend_language_scanner.c" -yy572: - YYDEBUG(572, *YYCURSOR); +#line 5707 "Zend/zend_language_scanner.c" +yy575: + YYDEBUG(575, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'P') goto yy614; - if (yych == 'p') goto yy614; + if (yych == 'P') goto yy617; + if (yych == 'p') goto yy617; goto yy187; -yy573: - YYDEBUG(573, *YYCURSOR); +yy576: + YYDEBUG(576, *YYCURSOR); yych = *++YYCURSOR; if (yych <= 'T') { if (yych <= 'C') { if (yych <= 'B') goto yy187; - goto yy581; + goto yy584; } else { if (yych <= 'R') goto yy187; - if (yych <= 'S') goto yy579; - goto yy580; + if (yych <= 'S') goto yy582; + goto yy583; } } else { if (yych <= 'r') { - if (yych == 'c') goto yy581; + if (yych == 'c') goto yy584; goto yy187; } else { - if (yych <= 's') goto yy579; - if (yych <= 't') goto yy580; + if (yych <= 's') goto yy582; + if (yych <= 't') goto yy583; goto yy187; } } -yy574: - YYDEBUG(574, *YYCURSOR); +yy577: + YYDEBUG(577, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'S') goto yy575; + if (yych == 'S') goto yy578; if (yych != 's') goto yy187; -yy575: - YYDEBUG(575, *YYCURSOR); +yy578: + YYDEBUG(578, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy576; + if (yych == 'E') goto yy579; if (yych != 'e') goto yy187; -yy576: - YYDEBUG(576, *YYCURSOR); +yy579: + YYDEBUG(579, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy577; + if (yych == 'T') goto yy580; if (yych != 't') goto yy187; -yy577: - YYDEBUG(577, *YYCURSOR); +yy580: + YYDEBUG(580, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(578, *YYCURSOR); + YYDEBUG(581, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1283 "Zend/zend_language_scanner.l" +#line 1286 "Zend/zend_language_scanner.l" { return T_ISSET; } -#line 5745 "Zend/zend_language_scanner.c" -yy579: - YYDEBUG(579, *YYCURSOR); +#line 5763 "Zend/zend_language_scanner.c" +yy582: + YYDEBUG(582, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy600; - if (yych == 't') goto yy600; + if (yych == 'T') goto yy603; + if (yych == 't') goto yy603; goto yy187; -yy580: - YYDEBUG(580, *YYCURSOR); +yy583: + YYDEBUG(583, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy593; - if (yych == 'e') goto yy593; + if (yych == 'E') goto yy596; + if (yych == 'e') goto yy596; goto yy187; -yy581: - YYDEBUG(581, *YYCURSOR); +yy584: + YYDEBUG(584, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'L') goto yy582; + if (yych == 'L') goto yy585; if (yych != 'l') goto yy187; -yy582: - YYDEBUG(582, *YYCURSOR); +yy585: + YYDEBUG(585, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'U') goto yy583; + if (yych == 'U') goto yy586; if (yych != 'u') goto yy187; -yy583: - YYDEBUG(583, *YYCURSOR); +yy586: + YYDEBUG(586, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'D') goto yy584; + if (yych == 'D') goto yy587; if (yych != 'd') goto yy187; -yy584: - YYDEBUG(584, *YYCURSOR); +yy587: + YYDEBUG(587, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy585; + if (yych == 'E') goto yy588; if (yych != 'e') goto yy187; -yy585: - YYDEBUG(585, *YYCURSOR); +yy588: + YYDEBUG(588, *YYCURSOR); ++YYCURSOR; if ((yych = *YYCURSOR) <= '^') { if (yych <= '9') { if (yych >= '0') goto yy186; } else { - if (yych <= '@') goto yy586; + if (yych <= '@') goto yy589; if (yych <= 'Z') goto yy186; } } else { if (yych <= '`') { - if (yych <= '_') goto yy587; + if (yych <= '_') goto yy590; } else { if (yych <= 'z') goto yy186; if (yych >= 0x7F) goto yy186; } } -yy586: - YYDEBUG(586, *YYCURSOR); +yy589: + YYDEBUG(589, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1251 "Zend/zend_language_scanner.l" +#line 1254 "Zend/zend_language_scanner.l" { return T_INCLUDE; } -#line 5803 "Zend/zend_language_scanner.c" -yy587: - YYDEBUG(587, *YYCURSOR); +#line 5821 "Zend/zend_language_scanner.c" +yy590: + YYDEBUG(590, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'O') goto yy588; + if (yych == 'O') goto yy591; if (yych != 'o') goto yy187; -yy588: - YYDEBUG(588, *YYCURSOR); +yy591: + YYDEBUG(591, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'N') goto yy589; + if (yych == 'N') goto yy592; if (yych != 'n') goto yy187; -yy589: - YYDEBUG(589, *YYCURSOR); +yy592: + YYDEBUG(592, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'C') goto yy590; + if (yych == 'C') goto yy593; if (yych != 'c') goto yy187; -yy590: - YYDEBUG(590, *YYCURSOR); +yy593: + YYDEBUG(593, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy591; + if (yych == 'E') goto yy594; if (yych != 'e') goto yy187; -yy591: - YYDEBUG(591, *YYCURSOR); +yy594: + YYDEBUG(594, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(592, *YYCURSOR); + YYDEBUG(595, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1255 "Zend/zend_language_scanner.l" +#line 1258 "Zend/zend_language_scanner.l" { return T_INCLUDE_ONCE; } -#line 5836 "Zend/zend_language_scanner.c" -yy593: - YYDEBUG(593, *YYCURSOR); +#line 5854 "Zend/zend_language_scanner.c" +yy596: + YYDEBUG(596, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'R') goto yy594; + if (yych == 'R') goto yy597; if (yych != 'r') goto yy187; -yy594: - YYDEBUG(594, *YYCURSOR); +yy597: + YYDEBUG(597, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'F') goto yy595; + if (yych == 'F') goto yy598; if (yych != 'f') goto yy187; -yy595: - YYDEBUG(595, *YYCURSOR); +yy598: + YYDEBUG(598, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy596; + if (yych == 'A') goto yy599; if (yych != 'a') goto yy187; -yy596: - YYDEBUG(596, *YYCURSOR); +yy599: + YYDEBUG(599, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'C') goto yy597; + if (yych == 'C') goto yy600; if (yych != 'c') goto yy187; -yy597: - YYDEBUG(597, *YYCURSOR); +yy600: + YYDEBUG(600, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy598; + if (yych == 'E') goto yy601; if (yych != 'e') goto yy187; -yy598: - YYDEBUG(598, *YYCURSOR); +yy601: + YYDEBUG(601, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(599, *YYCURSOR); + YYDEBUG(602, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1155 "Zend/zend_language_scanner.l" +#line 1154 "Zend/zend_language_scanner.l" { return T_INTERFACE; } -#line 5874 "Zend/zend_language_scanner.c" -yy600: - YYDEBUG(600, *YYCURSOR); +#line 5892 "Zend/zend_language_scanner.c" +yy603: + YYDEBUG(603, *YYCURSOR); yych = *++YYCURSOR; if (yych <= 'E') { - if (yych == 'A') goto yy601; + if (yych == 'A') goto yy604; if (yych <= 'D') goto yy187; - goto yy602; + goto yy605; } else { if (yych <= 'a') { if (yych <= '`') goto yy187; } else { - if (yych == 'e') goto yy602; + if (yych == 'e') goto yy605; goto yy187; } } -yy601: - YYDEBUG(601, *YYCURSOR); +yy604: + YYDEBUG(604, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'N') goto yy608; - if (yych == 'n') goto yy608; + if (yych == 'N') goto yy611; + if (yych == 'n') goto yy611; goto yy187; -yy602: - YYDEBUG(602, *YYCURSOR); +yy605: + YYDEBUG(605, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy603; + if (yych == 'A') goto yy606; if (yych != 'a') goto yy187; -yy603: - YYDEBUG(603, *YYCURSOR); +yy606: + YYDEBUG(606, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'D') goto yy604; + if (yych == 'D') goto yy607; if (yych != 'd') goto yy187; -yy604: - YYDEBUG(604, *YYCURSOR); +yy607: + YYDEBUG(607, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'O') goto yy605; + if (yych == 'O') goto yy608; if (yych != 'o') goto yy187; -yy605: - YYDEBUG(605, *YYCURSOR); +yy608: + YYDEBUG(608, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'F') goto yy606; + if (yych == 'F') goto yy609; if (yych != 'f') goto yy187; -yy606: - YYDEBUG(606, *YYCURSOR); +yy609: + YYDEBUG(609, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(607, *YYCURSOR); + YYDEBUG(610, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1275 "Zend/zend_language_scanner.l" +#line 1278 "Zend/zend_language_scanner.l" { return T_INSTEADOF; } -#line 5928 "Zend/zend_language_scanner.c" -yy608: - YYDEBUG(608, *YYCURSOR); +#line 5946 "Zend/zend_language_scanner.c" +yy611: + YYDEBUG(611, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'C') goto yy609; + if (yych == 'C') goto yy612; if (yych != 'c') goto yy187; -yy609: - YYDEBUG(609, *YYCURSOR); +yy612: + YYDEBUG(612, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy610; + if (yych == 'E') goto yy613; if (yych != 'e') goto yy187; -yy610: - YYDEBUG(610, *YYCURSOR); +yy613: + YYDEBUG(613, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'O') goto yy611; + if (yych == 'O') goto yy614; if (yych != 'o') goto yy187; -yy611: - YYDEBUG(611, *YYCURSOR); +yy614: + YYDEBUG(614, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'F') goto yy612; + if (yych == 'F') goto yy615; if (yych != 'f') goto yy187; -yy612: - YYDEBUG(612, *YYCURSOR); +yy615: + YYDEBUG(615, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(613, *YYCURSOR); + YYDEBUG(616, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1107 "Zend/zend_language_scanner.l" +#line 1106 "Zend/zend_language_scanner.l" { return T_INSTANCEOF; } -#line 5961 "Zend/zend_language_scanner.c" -yy614: - YYDEBUG(614, *YYCURSOR); +#line 5979 "Zend/zend_language_scanner.c" +yy617: + YYDEBUG(617, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'L') goto yy615; + if (yych == 'L') goto yy618; if (yych != 'l') goto yy187; -yy615: - YYDEBUG(615, *YYCURSOR); +yy618: + YYDEBUG(618, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy616; + if (yych == 'E') goto yy619; if (yych != 'e') goto yy187; -yy616: - YYDEBUG(616, *YYCURSOR); +yy619: + YYDEBUG(619, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'M') goto yy617; + if (yych == 'M') goto yy620; if (yych != 'm') goto yy187; -yy617: - YYDEBUG(617, *YYCURSOR); +yy620: + YYDEBUG(620, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy618; + if (yych == 'E') goto yy621; if (yych != 'e') goto yy187; -yy618: - YYDEBUG(618, *YYCURSOR); +yy621: + YYDEBUG(621, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'N') goto yy619; + if (yych == 'N') goto yy622; if (yych != 'n') goto yy187; -yy619: - YYDEBUG(619, *YYCURSOR); +yy622: + YYDEBUG(622, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy620; + if (yych == 'T') goto yy623; if (yych != 't') goto yy187; -yy620: - YYDEBUG(620, *YYCURSOR); +yy623: + YYDEBUG(623, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'S') goto yy621; + if (yych == 'S') goto yy624; if (yych != 's') goto yy187; -yy621: - YYDEBUG(621, *YYCURSOR); +yy624: + YYDEBUG(624, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(622, *YYCURSOR); + YYDEBUG(625, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1167 "Zend/zend_language_scanner.l" +#line 1166 "Zend/zend_language_scanner.l" { return T_IMPLEMENTS; } -#line 6009 "Zend/zend_language_scanner.c" -yy623: - YYDEBUG(623, *YYCURSOR); +#line 6027 "Zend/zend_language_scanner.c" +yy626: + YYDEBUG(626, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'R') goto yy631; - if (yych == 'r') goto yy631; + if (yych == 'R') goto yy634; + if (yych == 'r') goto yy634; goto yy187; -yy624: - YYDEBUG(624, *YYCURSOR); +yy627: + YYDEBUG(627, *YYCURSOR); yych = *++YYCURSOR; if (yych <= 'Y') { - if (yych == 'A') goto yy627; + if (yych == 'A') goto yy630; if (yych <= 'X') goto yy187; } else { if (yych <= 'a') { if (yych <= '`') goto yy187; - goto yy627; + goto yy630; } else { if (yych != 'y') goto yy187; } } - YYDEBUG(625, *YYCURSOR); + YYDEBUG(628, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(626, *YYCURSOR); + YYDEBUG(629, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1039 "Zend/zend_language_scanner.l" +#line 1038 "Zend/zend_language_scanner.l" { return T_TRY; } -#line 6041 "Zend/zend_language_scanner.c" -yy627: - YYDEBUG(627, *YYCURSOR); +#line 6059 "Zend/zend_language_scanner.c" +yy630: + YYDEBUG(630, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'I') goto yy628; + if (yych == 'I') goto yy631; if (yych != 'i') goto yy187; -yy628: - YYDEBUG(628, *YYCURSOR); +yy631: + YYDEBUG(631, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy629; + if (yych == 'T') goto yy632; if (yych != 't') goto yy187; -yy629: - YYDEBUG(629, *YYCURSOR); +yy632: + YYDEBUG(632, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(630, *YYCURSOR); + YYDEBUG(633, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1159 "Zend/zend_language_scanner.l" +#line 1158 "Zend/zend_language_scanner.l" { return T_TRAIT; } -#line 6064 "Zend/zend_language_scanner.c" -yy631: - YYDEBUG(631, *YYCURSOR); +#line 6082 "Zend/zend_language_scanner.c" +yy634: + YYDEBUG(634, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'O') goto yy632; + if (yych == 'O') goto yy635; if (yych != 'o') goto yy187; -yy632: - YYDEBUG(632, *YYCURSOR); +yy635: + YYDEBUG(635, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'W') goto yy633; + if (yych == 'W') goto yy636; if (yych != 'w') goto yy187; -yy633: - YYDEBUG(633, *YYCURSOR); +yy636: + YYDEBUG(636, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(634, *YYCURSOR); + YYDEBUG(637, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1051 "Zend/zend_language_scanner.l" +#line 1050 "Zend/zend_language_scanner.l" { return T_THROW; } -#line 6087 "Zend/zend_language_scanner.c" -yy635: - YYDEBUG(635, *YYCURSOR); +#line 6105 "Zend/zend_language_scanner.c" +yy638: + YYDEBUG(638, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy636; + if (yych == 'E') goto yy639; if (yych != 'e') goto yy187; -yy636: - YYDEBUG(636, *YYCURSOR); +yy639: + YYDEBUG(639, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'L') goto yy637; + if (yych == 'L') goto yy640; if (yych != 'l') goto yy187; -yy637: - YYDEBUG(637, *YYCURSOR); +yy640: + YYDEBUG(640, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'D') goto yy638; + if (yych == 'D') goto yy641; if (yych != 'd') goto yy187; -yy638: - YYDEBUG(638, *YYCURSOR); +yy641: + YYDEBUG(641, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(639, *YYCURSOR); + YYDEBUG(642, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1035 "Zend/zend_language_scanner.l" +#line 1034 "Zend/zend_language_scanner.l" { return T_YIELD; } -#line 6115 "Zend/zend_language_scanner.c" -yy640: - YYDEBUG(640, *YYCURSOR); +#line 6133 "Zend/zend_language_scanner.c" +yy643: + YYDEBUG(643, *YYCURSOR); yych = *++YYCURSOR; if (yych <= 'T') { - if (yych == 'Q') goto yy642; + if (yych == 'Q') goto yy645; if (yych <= 'S') goto yy187; } else { if (yych <= 'q') { if (yych <= 'p') goto yy187; - goto yy642; + goto yy645; } else { if (yych != 't') goto yy187; } } - YYDEBUG(641, *YYCURSOR); + YYDEBUG(644, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'U') goto yy654; - if (yych == 'u') goto yy654; + if (yych == 'U') goto yy657; + if (yych == 'u') goto yy657; goto yy187; -yy642: - YYDEBUG(642, *YYCURSOR); +yy645: + YYDEBUG(645, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'U') goto yy643; + if (yych == 'U') goto yy646; if (yych != 'u') goto yy187; -yy643: - YYDEBUG(643, *YYCURSOR); +yy646: + YYDEBUG(646, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'I') goto yy644; + if (yych == 'I') goto yy647; if (yych != 'i') goto yy187; -yy644: - YYDEBUG(644, *YYCURSOR); +yy647: + YYDEBUG(647, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'R') goto yy645; + if (yych == 'R') goto yy648; if (yych != 'r') goto yy187; -yy645: - YYDEBUG(645, *YYCURSOR); +yy648: + YYDEBUG(648, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy646; + if (yych == 'E') goto yy649; if (yych != 'e') goto yy187; -yy646: - YYDEBUG(646, *YYCURSOR); +yy649: + YYDEBUG(649, *YYCURSOR); ++YYCURSOR; if ((yych = *YYCURSOR) <= '^') { if (yych <= '9') { if (yych >= '0') goto yy186; } else { - if (yych <= '@') goto yy647; + if (yych <= '@') goto yy650; if (yych <= 'Z') goto yy186; } } else { if (yych <= '`') { - if (yych <= '_') goto yy648; + if (yych <= '_') goto yy651; } else { if (yych <= 'z') goto yy186; if (yych >= 0x7F) goto yy186; } } -yy647: - YYDEBUG(647, *YYCURSOR); +yy650: + YYDEBUG(650, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1259 "Zend/zend_language_scanner.l" +#line 1262 "Zend/zend_language_scanner.l" { return T_REQUIRE; } -#line 6180 "Zend/zend_language_scanner.c" -yy648: - YYDEBUG(648, *YYCURSOR); +#line 6198 "Zend/zend_language_scanner.c" +yy651: + YYDEBUG(651, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'O') goto yy649; + if (yych == 'O') goto yy652; if (yych != 'o') goto yy187; -yy649: - YYDEBUG(649, *YYCURSOR); +yy652: + YYDEBUG(652, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'N') goto yy650; + if (yych == 'N') goto yy653; if (yych != 'n') goto yy187; -yy650: - YYDEBUG(650, *YYCURSOR); +yy653: + YYDEBUG(653, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'C') goto yy651; + if (yych == 'C') goto yy654; if (yych != 'c') goto yy187; -yy651: - YYDEBUG(651, *YYCURSOR); +yy654: + YYDEBUG(654, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy652; + if (yych == 'E') goto yy655; if (yych != 'e') goto yy187; -yy652: - YYDEBUG(652, *YYCURSOR); +yy655: + YYDEBUG(655, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(653, *YYCURSOR); + YYDEBUG(656, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1263 "Zend/zend_language_scanner.l" +#line 1266 "Zend/zend_language_scanner.l" { return T_REQUIRE_ONCE; } -#line 6213 "Zend/zend_language_scanner.c" -yy654: - YYDEBUG(654, *YYCURSOR); +#line 6231 "Zend/zend_language_scanner.c" +yy657: + YYDEBUG(657, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'R') goto yy655; + if (yych == 'R') goto yy658; if (yych != 'r') goto yy187; -yy655: - YYDEBUG(655, *YYCURSOR); +yy658: + YYDEBUG(658, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'N') goto yy656; + if (yych == 'N') goto yy659; if (yych != 'n') goto yy187; -yy656: - YYDEBUG(656, *YYCURSOR); +yy659: + YYDEBUG(659, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(657, *YYCURSOR); + YYDEBUG(660, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1031 "Zend/zend_language_scanner.l" +#line 1030 "Zend/zend_language_scanner.l" { return T_RETURN; } -#line 6236 "Zend/zend_language_scanner.c" -yy658: - YYDEBUG(658, *YYCURSOR); +#line 6254 "Zend/zend_language_scanner.c" +yy661: + YYDEBUG(661, *YYCURSOR); yych = *++YYCURSOR; if (yych <= 'T') { if (yych <= 'L') { if (yych <= 'K') goto yy187; - goto yy681; + goto yy684; } else { if (yych <= 'R') goto yy187; - if (yych <= 'S') goto yy680; - goto yy679; + if (yych <= 'S') goto yy683; + goto yy682; } } else { if (yych <= 'r') { - if (yych == 'l') goto yy681; + if (yych == 'l') goto yy684; goto yy187; } else { - if (yych <= 's') goto yy680; - if (yych <= 't') goto yy679; + if (yych <= 's') goto yy683; + if (yych <= 't') goto yy682; goto yy187; } } -yy659: - YYDEBUG(659, *YYCURSOR); +yy662: + YYDEBUG(662, *YYCURSOR); yych = *++YYCURSOR; if (yych <= 'O') { - if (yych == 'A') goto yy671; + if (yych == 'A') goto yy674; if (yych <= 'N') goto yy187; - goto yy672; + goto yy675; } else { if (yych <= 'a') { if (yych <= '`') goto yy187; - goto yy671; + goto yy674; } else { - if (yych == 'o') goto yy672; + if (yych == 'o') goto yy675; goto yy187; } } -yy660: - YYDEBUG(660, *YYCURSOR); +yy663: + YYDEBUG(663, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'N') goto yy661; + if (yych == 'N') goto yy664; if (yych != 'n') goto yy187; -yy661: - YYDEBUG(661, *YYCURSOR); +yy664: + YYDEBUG(664, *YYCURSOR); yych = *++YYCURSOR; if (yych <= 'T') { if (yych <= 'R') goto yy187; - if (yych >= 'T') goto yy663; + if (yych >= 'T') goto yy666; } else { if (yych <= 'r') goto yy187; - if (yych <= 's') goto yy662; - if (yych <= 't') goto yy663; + if (yych <= 's') goto yy665; + if (yych <= 't') goto yy666; goto yy187; } -yy662: - YYDEBUG(662, *YYCURSOR); +yy665: + YYDEBUG(665, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy669; - if (yych == 't') goto yy669; + if (yych == 'T') goto yy672; + if (yych == 't') goto yy672; goto yy187; -yy663: - YYDEBUG(663, *YYCURSOR); +yy666: + YYDEBUG(666, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'I') goto yy664; + if (yych == 'I') goto yy667; if (yych != 'i') goto yy187; -yy664: - YYDEBUG(664, *YYCURSOR); +yy667: + YYDEBUG(667, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'N') goto yy665; + if (yych == 'N') goto yy668; if (yych != 'n') goto yy187; -yy665: - YYDEBUG(665, *YYCURSOR); +yy668: + YYDEBUG(668, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'U') goto yy666; + if (yych == 'U') goto yy669; if (yych != 'u') goto yy187; -yy666: - YYDEBUG(666, *YYCURSOR); +yy669: + YYDEBUG(669, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy667; + if (yych == 'E') goto yy670; if (yych != 'e') goto yy187; -yy667: - YYDEBUG(667, *YYCURSOR); +yy670: + YYDEBUG(670, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(668, *YYCURSOR); + YYDEBUG(671, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1135 "Zend/zend_language_scanner.l" +#line 1134 "Zend/zend_language_scanner.l" { return T_CONTINUE; } -#line 6330 "Zend/zend_language_scanner.c" -yy669: - YYDEBUG(669, *YYCURSOR); +#line 6348 "Zend/zend_language_scanner.c" +yy672: + YYDEBUG(672, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(670, *YYCURSOR); + YYDEBUG(673, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1027 "Zend/zend_language_scanner.l" +#line 1026 "Zend/zend_language_scanner.l" { return T_CONST; } -#line 6343 "Zend/zend_language_scanner.c" -yy671: - YYDEBUG(671, *YYCURSOR); +#line 6361 "Zend/zend_language_scanner.c" +yy674: + YYDEBUG(674, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'S') goto yy676; - if (yych == 's') goto yy676; + if (yych == 'S') goto yy679; + if (yych == 's') goto yy679; goto yy187; -yy672: - YYDEBUG(672, *YYCURSOR); +yy675: + YYDEBUG(675, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'N') goto yy673; + if (yych == 'N') goto yy676; if (yych != 'n') goto yy187; -yy673: - YYDEBUG(673, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'E') goto yy674; - if (yych != 'e') goto yy187; -yy674: - YYDEBUG(674, *YYCURSOR); - ++YYCURSOR; - if (yybm[0+(yych = *YYCURSOR)] & 4) { - goto yy186; - } - YYDEBUG(675, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 1211 "Zend/zend_language_scanner.l" - { - return T_CLONE; -} -#line 6372 "Zend/zend_language_scanner.c" yy676: YYDEBUG(676, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'S') goto yy677; - if (yych != 's') goto yy187; + if (yych == 'E') goto yy677; + if (yych != 'e') goto yy187; yy677: YYDEBUG(677, *YYCURSOR); ++YYCURSOR; @@ -6382,38 +6382,41 @@ int lex_scan(zval *zendlval TSRMLS_DC) } YYDEBUG(678, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1151 "Zend/zend_language_scanner.l" +#line 1214 "Zend/zend_language_scanner.l" { - return T_CLASS; + return T_CLONE; } #line 6390 "Zend/zend_language_scanner.c" yy679: YYDEBUG(679, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'C') goto yy690; - if (yych == 'c') goto yy690; - goto yy187; + if (yych == 'S') goto yy680; + if (yych != 's') goto yy187; yy680: YYDEBUG(680, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'E') goto yy688; - if (yych == 'e') goto yy688; - goto yy187; -yy681: + ++YYCURSOR; + if (yybm[0+(yych = *YYCURSOR)] & 4) { + goto yy186; + } YYDEBUG(681, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'L') goto yy682; - if (yych != 'l') goto yy187; + yyleng = YYCURSOR - SCNG(yy_text); +#line 1150 "Zend/zend_language_scanner.l" + { + return T_CLASS; +} +#line 6408 "Zend/zend_language_scanner.c" yy682: YYDEBUG(682, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy683; - if (yych != 'a') goto yy187; + if (yych == 'C') goto yy693; + if (yych == 'c') goto yy693; + goto yy187; yy683: YYDEBUG(683, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'B') goto yy684; - if (yych != 'b') goto yy187; + if (yych == 'E') goto yy691; + if (yych == 'e') goto yy691; + goto yy187; yy684: YYDEBUG(684, *YYCURSOR); yych = *++YYCURSOR; @@ -6422,760 +6425,775 @@ int lex_scan(zval *zendlval TSRMLS_DC) yy685: YYDEBUG(685, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy686; - if (yych != 'e') goto yy187; + if (yych == 'A') goto yy686; + if (yych != 'a') goto yy187; yy686: YYDEBUG(686, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'B') goto yy687; + if (yych != 'b') goto yy187; +yy687: + YYDEBUG(687, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'L') goto yy688; + if (yych != 'l') goto yy187; +yy688: + YYDEBUG(688, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'E') goto yy689; + if (yych != 'e') goto yy187; +yy689: + YYDEBUG(689, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(687, *YYCURSOR); + YYDEBUG(690, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1335 "Zend/zend_language_scanner.l" +#line 1338 "Zend/zend_language_scanner.l" { return T_CALLABLE; } -#line 6440 "Zend/zend_language_scanner.c" -yy688: - YYDEBUG(688, *YYCURSOR); +#line 6458 "Zend/zend_language_scanner.c" +yy691: + YYDEBUG(691, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(689, *YYCURSOR); + YYDEBUG(692, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1123 "Zend/zend_language_scanner.l" +#line 1122 "Zend/zend_language_scanner.l" { return T_CASE; } -#line 6453 "Zend/zend_language_scanner.c" -yy690: - YYDEBUG(690, *YYCURSOR); +#line 6471 "Zend/zend_language_scanner.c" +yy693: + YYDEBUG(693, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'H') goto yy691; + if (yych == 'H') goto yy694; if (yych != 'h') goto yy187; -yy691: - YYDEBUG(691, *YYCURSOR); +yy694: + YYDEBUG(694, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(692, *YYCURSOR); + YYDEBUG(695, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1043 "Zend/zend_language_scanner.l" +#line 1042 "Zend/zend_language_scanner.l" { return T_CATCH; } -#line 6471 "Zend/zend_language_scanner.c" -yy693: - YYDEBUG(693, *YYCURSOR); +#line 6489 "Zend/zend_language_scanner.c" +yy696: + YYDEBUG(696, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'N') goto yy710; - if (yych == 'n') goto yy710; + if (yych == 'N') goto yy713; + if (yych == 'n') goto yy713; goto yy187; -yy694: - YYDEBUG(694, *YYCURSOR); +yy697: + YYDEBUG(697, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'R') goto yy703; - if (yych == 'r') goto yy703; + if (yych == 'R') goto yy706; + if (yych == 'r') goto yy706; goto yy187; -yy695: - YYDEBUG(695, *YYCURSOR); +yy698: + YYDEBUG(698, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'N') goto yy696; + if (yych == 'N') goto yy699; if (yych != 'n') goto yy187; -yy696: - YYDEBUG(696, *YYCURSOR); +yy699: + YYDEBUG(699, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'C') goto yy697; + if (yych == 'C') goto yy700; if (yych != 'c') goto yy187; -yy697: - YYDEBUG(697, *YYCURSOR); +yy700: + YYDEBUG(700, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy698; + if (yych == 'T') goto yy701; if (yych != 't') goto yy187; -yy698: - YYDEBUG(698, *YYCURSOR); +yy701: + YYDEBUG(701, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'I') goto yy699; + if (yych == 'I') goto yy702; if (yych != 'i') goto yy187; -yy699: - YYDEBUG(699, *YYCURSOR); +yy702: + YYDEBUG(702, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'O') goto yy700; + if (yych == 'O') goto yy703; if (yych != 'o') goto yy187; -yy700: - YYDEBUG(700, *YYCURSOR); +yy703: + YYDEBUG(703, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'N') goto yy701; + if (yych == 'N') goto yy704; if (yych != 'n') goto yy187; -yy701: - YYDEBUG(701, *YYCURSOR); +yy704: + YYDEBUG(704, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(702, *YYCURSOR); + YYDEBUG(705, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1023 "Zend/zend_language_scanner.l" +#line 1022 "Zend/zend_language_scanner.l" { return T_FUNCTION; } -#line 6526 "Zend/zend_language_scanner.c" -yy703: - YYDEBUG(703, *YYCURSOR); +#line 6544 "Zend/zend_language_scanner.c" +yy706: + YYDEBUG(706, *YYCURSOR); ++YYCURSOR; if ((yych = *YYCURSOR) <= '^') { if (yych <= '@') { - if (yych <= '/') goto yy704; + if (yych <= '/') goto yy707; if (yych <= '9') goto yy186; } else { - if (yych == 'E') goto yy705; + if (yych == 'E') goto yy708; if (yych <= 'Z') goto yy186; } } else { if (yych <= 'd') { if (yych != '`') goto yy186; } else { - if (yych <= 'e') goto yy705; + if (yych <= 'e') goto yy708; if (yych <= 'z') goto yy186; if (yych >= 0x7F) goto yy186; } } -yy704: - YYDEBUG(704, *YYCURSOR); +yy707: + YYDEBUG(707, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1083 "Zend/zend_language_scanner.l" +#line 1082 "Zend/zend_language_scanner.l" { return T_FOR; } -#line 6554 "Zend/zend_language_scanner.c" -yy705: - YYDEBUG(705, *YYCURSOR); +#line 6572 "Zend/zend_language_scanner.c" +yy708: + YYDEBUG(708, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy706; + if (yych == 'A') goto yy709; if (yych != 'a') goto yy187; -yy706: - YYDEBUG(706, *YYCURSOR); +yy709: + YYDEBUG(709, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'C') goto yy707; + if (yych == 'C') goto yy710; if (yych != 'c') goto yy187; -yy707: - YYDEBUG(707, *YYCURSOR); +yy710: + YYDEBUG(710, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'H') goto yy708; + if (yych == 'H') goto yy711; if (yych != 'h') goto yy187; -yy708: - YYDEBUG(708, *YYCURSOR); +yy711: + YYDEBUG(711, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(709, *YYCURSOR); + YYDEBUG(712, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1091 "Zend/zend_language_scanner.l" +#line 1090 "Zend/zend_language_scanner.l" { return T_FOREACH; } -#line 6582 "Zend/zend_language_scanner.c" -yy710: - YYDEBUG(710, *YYCURSOR); +#line 6600 "Zend/zend_language_scanner.c" +yy713: + YYDEBUG(713, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy711; + if (yych == 'A') goto yy714; if (yych != 'a') goto yy187; -yy711: - YYDEBUG(711, *YYCURSOR); +yy714: + YYDEBUG(714, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'L') goto yy712; + if (yych == 'L') goto yy715; if (yych != 'l') goto yy187; -yy712: - YYDEBUG(712, *YYCURSOR); +yy715: + YYDEBUG(715, *YYCURSOR); ++YYCURSOR; if ((yych = *YYCURSOR) <= '^') { if (yych <= '@') { - if (yych <= '/') goto yy713; + if (yych <= '/') goto yy716; if (yych <= '9') goto yy186; } else { - if (yych == 'L') goto yy714; + if (yych == 'L') goto yy717; if (yych <= 'Z') goto yy186; } } else { if (yych <= 'k') { if (yych != '`') goto yy186; } else { - if (yych <= 'l') goto yy714; + if (yych <= 'l') goto yy717; if (yych <= 'z') goto yy186; if (yych >= 0x7F) goto yy186; } } -yy713: - YYDEBUG(713, *YYCURSOR); +yy716: + YYDEBUG(716, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1303 "Zend/zend_language_scanner.l" +#line 1306 "Zend/zend_language_scanner.l" { return T_FINAL; } -#line 6620 "Zend/zend_language_scanner.c" -yy714: - YYDEBUG(714, *YYCURSOR); +#line 6638 "Zend/zend_language_scanner.c" +yy717: + YYDEBUG(717, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'Y') goto yy715; + if (yych == 'Y') goto yy718; if (yych != 'y') goto yy187; -yy715: - YYDEBUG(715, *YYCURSOR); +yy718: + YYDEBUG(718, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(716, *YYCURSOR); + YYDEBUG(719, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1047 "Zend/zend_language_scanner.l" +#line 1046 "Zend/zend_language_scanner.l" { return T_FINALLY; } -#line 6638 "Zend/zend_language_scanner.c" -yy717: - YYDEBUG(717, *YYCURSOR); +#line 6656 "Zend/zend_language_scanner.c" +yy720: + YYDEBUG(720, *YYCURSOR); yych = *++YYCURSOR; if (yych <= 'F') { - if (yych == 'C') goto yy723; + if (yych == 'C') goto yy726; if (yych <= 'E') goto yy187; - goto yy724; + goto yy727; } else { if (yych <= 'c') { if (yych <= 'b') goto yy187; - goto yy723; + goto yy726; } else { - if (yych == 'f') goto yy724; + if (yych == 'f') goto yy727; goto yy187; } } -yy718: - YYDEBUG(718, *YYCURSOR); +yy721: + YYDEBUG(721, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy721; - if (yych == 'e') goto yy721; + if (yych == 'E') goto yy724; + if (yych == 'e') goto yy724; goto yy187; -yy719: - YYDEBUG(719, *YYCURSOR); +yy722: + YYDEBUG(722, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(720, *YYCURSOR); + YYDEBUG(723, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1079 "Zend/zend_language_scanner.l" +#line 1078 "Zend/zend_language_scanner.l" { return T_DO; } -#line 6673 "Zend/zend_language_scanner.c" -yy721: - YYDEBUG(721, *YYCURSOR); +#line 6691 "Zend/zend_language_scanner.c" +yy724: + YYDEBUG(724, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(722, *YYCURSOR); + YYDEBUG(725, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1019 "Zend/zend_language_scanner.l" +#line 1018 "Zend/zend_language_scanner.l" { return T_EXIT; } -#line 6686 "Zend/zend_language_scanner.c" -yy723: - YYDEBUG(723, *YYCURSOR); +#line 6704 "Zend/zend_language_scanner.c" +yy726: + YYDEBUG(726, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'L') goto yy730; - if (yych == 'l') goto yy730; + if (yych == 'L') goto yy733; + if (yych == 'l') goto yy733; goto yy187; -yy724: - YYDEBUG(724, *YYCURSOR); +yy727: + YYDEBUG(727, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy725; + if (yych == 'A') goto yy728; if (yych != 'a') goto yy187; -yy725: - YYDEBUG(725, *YYCURSOR); +yy728: + YYDEBUG(728, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'U') goto yy726; + if (yych == 'U') goto yy729; if (yych != 'u') goto yy187; -yy726: - YYDEBUG(726, *YYCURSOR); +yy729: + YYDEBUG(729, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'L') goto yy727; + if (yych == 'L') goto yy730; if (yych != 'l') goto yy187; -yy727: - YYDEBUG(727, *YYCURSOR); +yy730: + YYDEBUG(730, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy728; + if (yych == 'T') goto yy731; if (yych != 't') goto yy187; -yy728: - YYDEBUG(728, *YYCURSOR); +yy731: + YYDEBUG(731, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(729, *YYCURSOR); + YYDEBUG(732, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1127 "Zend/zend_language_scanner.l" +#line 1126 "Zend/zend_language_scanner.l" { return T_DEFAULT; } -#line 6725 "Zend/zend_language_scanner.c" -yy730: - YYDEBUG(730, *YYCURSOR); +#line 6743 "Zend/zend_language_scanner.c" +yy733: + YYDEBUG(733, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy731; + if (yych == 'A') goto yy734; if (yych != 'a') goto yy187; -yy731: - YYDEBUG(731, *YYCURSOR); +yy734: + YYDEBUG(734, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'R') goto yy732; + if (yych == 'R') goto yy735; if (yych != 'r') goto yy187; -yy732: - YYDEBUG(732, *YYCURSOR); +yy735: + YYDEBUG(735, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy733; + if (yych == 'E') goto yy736; if (yych != 'e') goto yy187; -yy733: - YYDEBUG(733, *YYCURSOR); +yy736: + YYDEBUG(736, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(734, *YYCURSOR); + YYDEBUG(737, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1099 "Zend/zend_language_scanner.l" +#line 1098 "Zend/zend_language_scanner.l" { return T_DECLARE; } -#line 6753 "Zend/zend_language_scanner.c" -yy735: - YYDEBUG(735, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'H') goto yy797; - if (yych == 'h') goto yy797; - goto yy187; -yy736: - YYDEBUG(736, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'S') goto yy791; - if (yych == 's') goto yy791; - goto yy187; -yy737: - YYDEBUG(737, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'P') goto yy787; - if (yych == 'p') goto yy787; - goto yy187; +#line 6771 "Zend/zend_language_scanner.c" yy738: YYDEBUG(738, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'D') goto yy753; - if (yych == 'd') goto yy753; + if (yych == 'H') goto yy800; + if (yych == 'h') goto yy800; goto yy187; yy739: YYDEBUG(739, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy750; - if (yych == 'a') goto yy750; + if (yych == 'S') goto yy794; + if (yych == 's') goto yy794; goto yy187; yy740: YYDEBUG(740, *YYCURSOR); yych = *++YYCURSOR; + if (yych == 'P') goto yy790; + if (yych == 'p') goto yy790; + goto yy187; +yy741: + YYDEBUG(741, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'D') goto yy756; + if (yych == 'd') goto yy756; + goto yy187; +yy742: + YYDEBUG(742, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'A') goto yy753; + if (yych == 'a') goto yy753; + goto yy187; +yy743: + YYDEBUG(743, *YYCURSOR); + yych = *++YYCURSOR; if (yych <= 'T') { - if (yych == 'I') goto yy741; + if (yych == 'I') goto yy744; if (yych <= 'S') goto yy187; - goto yy742; + goto yy745; } else { if (yych <= 'i') { if (yych <= 'h') goto yy187; } else { - if (yych == 't') goto yy742; + if (yych == 't') goto yy745; goto yy187; } } -yy741: - YYDEBUG(741, *YYCURSOR); +yy744: + YYDEBUG(744, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy748; - if (yych == 't') goto yy748; + if (yych == 'T') goto yy751; + if (yych == 't') goto yy751; goto yy187; -yy742: - YYDEBUG(742, *YYCURSOR); +yy745: + YYDEBUG(745, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy743; + if (yych == 'E') goto yy746; if (yych != 'e') goto yy187; -yy743: - YYDEBUG(743, *YYCURSOR); +yy746: + YYDEBUG(746, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'N') goto yy744; + if (yych == 'N') goto yy747; if (yych != 'n') goto yy187; -yy744: - YYDEBUG(744, *YYCURSOR); +yy747: + YYDEBUG(747, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'D') goto yy745; + if (yych == 'D') goto yy748; if (yych != 'd') goto yy187; -yy745: - YYDEBUG(745, *YYCURSOR); +yy748: + YYDEBUG(748, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'S') goto yy746; + if (yych == 'S') goto yy749; if (yych != 's') goto yy187; -yy746: - YYDEBUG(746, *YYCURSOR); +yy749: + YYDEBUG(749, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(747, *YYCURSOR); + YYDEBUG(750, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1163 "Zend/zend_language_scanner.l" +#line 1162 "Zend/zend_language_scanner.l" { return T_EXTENDS; } -#line 6837 "Zend/zend_language_scanner.c" -yy748: - YYDEBUG(748, *YYCURSOR); +#line 6855 "Zend/zend_language_scanner.c" +yy751: + YYDEBUG(751, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(749, *YYCURSOR); + YYDEBUG(752, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1015 "Zend/zend_language_scanner.l" +#line 1014 "Zend/zend_language_scanner.l" { return T_EXIT; } -#line 6850 "Zend/zend_language_scanner.c" -yy750: - YYDEBUG(750, *YYCURSOR); +#line 6868 "Zend/zend_language_scanner.c" +yy753: + YYDEBUG(753, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'L') goto yy751; + if (yych == 'L') goto yy754; if (yych != 'l') goto yy187; -yy751: - YYDEBUG(751, *YYCURSOR); +yy754: + YYDEBUG(754, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(752, *YYCURSOR); + YYDEBUG(755, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1247 "Zend/zend_language_scanner.l" +#line 1250 "Zend/zend_language_scanner.l" { return T_EVAL; } -#line 6868 "Zend/zend_language_scanner.c" -yy753: - YYDEBUG(753, *YYCURSOR); +#line 6886 "Zend/zend_language_scanner.c" +yy756: + YYDEBUG(756, *YYCURSOR); yych = *++YYCURSOR; YYDEBUG(-1, yych); switch (yych) { case 'D': - case 'd': goto yy754; + case 'd': goto yy757; case 'F': - case 'f': goto yy755; + case 'f': goto yy758; case 'I': - case 'i': goto yy756; + case 'i': goto yy759; case 'S': - case 's': goto yy757; + case 's': goto yy760; case 'W': - case 'w': goto yy758; + case 'w': goto yy761; default: goto yy187; } -yy754: - YYDEBUG(754, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'E') goto yy780; - if (yych == 'e') goto yy780; - goto yy187; -yy755: - YYDEBUG(755, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'O') goto yy772; - if (yych == 'o') goto yy772; - goto yy187; -yy756: - YYDEBUG(756, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'F') goto yy770; - if (yych == 'f') goto yy770; - goto yy187; yy757: YYDEBUG(757, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'W') goto yy764; - if (yych == 'w') goto yy764; + if (yych == 'E') goto yy783; + if (yych == 'e') goto yy783; goto yy187; yy758: YYDEBUG(758, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'H') goto yy759; - if (yych != 'h') goto yy187; + if (yych == 'O') goto yy775; + if (yych == 'o') goto yy775; + goto yy187; yy759: YYDEBUG(759, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'I') goto yy760; - if (yych != 'i') goto yy187; + if (yych == 'F') goto yy773; + if (yych == 'f') goto yy773; + goto yy187; yy760: YYDEBUG(760, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'L') goto yy761; - if (yych != 'l') goto yy187; + if (yych == 'W') goto yy767; + if (yych == 'w') goto yy767; + goto yy187; yy761: YYDEBUG(761, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy762; - if (yych != 'e') goto yy187; + if (yych == 'H') goto yy762; + if (yych != 'h') goto yy187; yy762: YYDEBUG(762, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'I') goto yy763; + if (yych != 'i') goto yy187; +yy763: + YYDEBUG(763, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'L') goto yy764; + if (yych != 'l') goto yy187; +yy764: + YYDEBUG(764, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'E') goto yy765; + if (yych != 'e') goto yy187; +yy765: + YYDEBUG(765, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(763, *YYCURSOR); + YYDEBUG(766, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1075 "Zend/zend_language_scanner.l" +#line 1074 "Zend/zend_language_scanner.l" { return T_ENDWHILE; } -#line 6942 "Zend/zend_language_scanner.c" -yy764: - YYDEBUG(764, *YYCURSOR); +#line 6960 "Zend/zend_language_scanner.c" +yy767: + YYDEBUG(767, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'I') goto yy765; + if (yych == 'I') goto yy768; if (yych != 'i') goto yy187; -yy765: - YYDEBUG(765, *YYCURSOR); +yy768: + YYDEBUG(768, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy766; + if (yych == 'T') goto yy769; if (yych != 't') goto yy187; -yy766: - YYDEBUG(766, *YYCURSOR); +yy769: + YYDEBUG(769, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'C') goto yy767; + if (yych == 'C') goto yy770; if (yych != 'c') goto yy187; -yy767: - YYDEBUG(767, *YYCURSOR); +yy770: + YYDEBUG(770, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'H') goto yy768; + if (yych == 'H') goto yy771; if (yych != 'h') goto yy187; -yy768: - YYDEBUG(768, *YYCURSOR); +yy771: + YYDEBUG(771, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(769, *YYCURSOR); + YYDEBUG(772, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1119 "Zend/zend_language_scanner.l" +#line 1118 "Zend/zend_language_scanner.l" { return T_ENDSWITCH; } -#line 6975 "Zend/zend_language_scanner.c" -yy770: - YYDEBUG(770, *YYCURSOR); +#line 6993 "Zend/zend_language_scanner.c" +yy773: + YYDEBUG(773, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(771, *YYCURSOR); + YYDEBUG(774, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1063 "Zend/zend_language_scanner.l" +#line 1062 "Zend/zend_language_scanner.l" { return T_ENDIF; } -#line 6988 "Zend/zend_language_scanner.c" -yy772: - YYDEBUG(772, *YYCURSOR); +#line 7006 "Zend/zend_language_scanner.c" +yy775: + YYDEBUG(775, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'R') goto yy773; + if (yych == 'R') goto yy776; if (yych != 'r') goto yy187; -yy773: - YYDEBUG(773, *YYCURSOR); +yy776: + YYDEBUG(776, *YYCURSOR); ++YYCURSOR; if ((yych = *YYCURSOR) <= '^') { if (yych <= '@') { - if (yych <= '/') goto yy774; + if (yych <= '/') goto yy777; if (yych <= '9') goto yy186; } else { - if (yych == 'E') goto yy775; + if (yych == 'E') goto yy778; if (yych <= 'Z') goto yy186; } } else { if (yych <= 'd') { if (yych != '`') goto yy186; } else { - if (yych <= 'e') goto yy775; + if (yych <= 'e') goto yy778; if (yych <= 'z') goto yy186; if (yych >= 0x7F) goto yy186; } } -yy774: - YYDEBUG(774, *YYCURSOR); +yy777: + YYDEBUG(777, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1087 "Zend/zend_language_scanner.l" +#line 1086 "Zend/zend_language_scanner.l" { return T_ENDFOR; } -#line 7021 "Zend/zend_language_scanner.c" -yy775: - YYDEBUG(775, *YYCURSOR); +#line 7039 "Zend/zend_language_scanner.c" +yy778: + YYDEBUG(778, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy776; + if (yych == 'A') goto yy779; if (yych != 'a') goto yy187; -yy776: - YYDEBUG(776, *YYCURSOR); +yy779: + YYDEBUG(779, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'C') goto yy777; + if (yych == 'C') goto yy780; if (yych != 'c') goto yy187; -yy777: - YYDEBUG(777, *YYCURSOR); +yy780: + YYDEBUG(780, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'H') goto yy778; + if (yych == 'H') goto yy781; if (yych != 'h') goto yy187; -yy778: - YYDEBUG(778, *YYCURSOR); +yy781: + YYDEBUG(781, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(779, *YYCURSOR); + YYDEBUG(782, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1095 "Zend/zend_language_scanner.l" +#line 1094 "Zend/zend_language_scanner.l" { return T_ENDFOREACH; } -#line 7049 "Zend/zend_language_scanner.c" -yy780: - YYDEBUG(780, *YYCURSOR); +#line 7067 "Zend/zend_language_scanner.c" +yy783: + YYDEBUG(783, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'C') goto yy781; + if (yych == 'C') goto yy784; if (yych != 'c') goto yy187; -yy781: - YYDEBUG(781, *YYCURSOR); +yy784: + YYDEBUG(784, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'L') goto yy782; + if (yych == 'L') goto yy785; if (yych != 'l') goto yy187; -yy782: - YYDEBUG(782, *YYCURSOR); +yy785: + YYDEBUG(785, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy783; + if (yych == 'A') goto yy786; if (yych != 'a') goto yy187; -yy783: - YYDEBUG(783, *YYCURSOR); +yy786: + YYDEBUG(786, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'R') goto yy784; + if (yych == 'R') goto yy787; if (yych != 'r') goto yy187; -yy784: - YYDEBUG(784, *YYCURSOR); +yy787: + YYDEBUG(787, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy785; + if (yych == 'E') goto yy788; if (yych != 'e') goto yy187; -yy785: - YYDEBUG(785, *YYCURSOR); +yy788: + YYDEBUG(788, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(786, *YYCURSOR); + YYDEBUG(789, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1103 "Zend/zend_language_scanner.l" +#line 1102 "Zend/zend_language_scanner.l" { return T_ENDDECLARE; } -#line 7087 "Zend/zend_language_scanner.c" -yy787: - YYDEBUG(787, *YYCURSOR); +#line 7105 "Zend/zend_language_scanner.c" +yy790: + YYDEBUG(790, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'T') goto yy788; + if (yych == 'T') goto yy791; if (yych != 't') goto yy187; -yy788: - YYDEBUG(788, *YYCURSOR); +yy791: + YYDEBUG(791, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'Y') goto yy789; + if (yych == 'Y') goto yy792; if (yych != 'y') goto yy187; -yy789: - YYDEBUG(789, *YYCURSOR); +yy792: + YYDEBUG(792, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(790, *YYCURSOR); + YYDEBUG(793, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1287 "Zend/zend_language_scanner.l" +#line 1290 "Zend/zend_language_scanner.l" { return T_EMPTY; } -#line 7110 "Zend/zend_language_scanner.c" -yy791: - YYDEBUG(791, *YYCURSOR); +#line 7128 "Zend/zend_language_scanner.c" +yy794: + YYDEBUG(794, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy792; + if (yych == 'E') goto yy795; if (yych != 'e') goto yy187; -yy792: - YYDEBUG(792, *YYCURSOR); +yy795: + YYDEBUG(795, *YYCURSOR); ++YYCURSOR; if ((yych = *YYCURSOR) <= '^') { if (yych <= '@') { - if (yych <= '/') goto yy793; + if (yych <= '/') goto yy796; if (yych <= '9') goto yy186; } else { - if (yych == 'I') goto yy794; + if (yych == 'I') goto yy797; if (yych <= 'Z') goto yy186; } } else { if (yych <= 'h') { if (yych != '`') goto yy186; } else { - if (yych <= 'i') goto yy794; + if (yych <= 'i') goto yy797; if (yych <= 'z') goto yy186; if (yych >= 0x7F) goto yy186; } } -yy793: - YYDEBUG(793, *YYCURSOR); +yy796: + YYDEBUG(796, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1067 "Zend/zend_language_scanner.l" +#line 1066 "Zend/zend_language_scanner.l" { return T_ELSE; } -#line 7143 "Zend/zend_language_scanner.c" -yy794: - YYDEBUG(794, *YYCURSOR); +#line 7161 "Zend/zend_language_scanner.c" +yy797: + YYDEBUG(797, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'F') goto yy795; + if (yych == 'F') goto yy798; if (yych != 'f') goto yy187; -yy795: - YYDEBUG(795, *YYCURSOR); +yy798: + YYDEBUG(798, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(796, *YYCURSOR); + YYDEBUG(799, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1059 "Zend/zend_language_scanner.l" +#line 1058 "Zend/zend_language_scanner.l" { return T_ELSEIF; } -#line 7161 "Zend/zend_language_scanner.c" -yy797: - YYDEBUG(797, *YYCURSOR); +#line 7179 "Zend/zend_language_scanner.c" +yy800: + YYDEBUG(800, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'O') goto yy798; + if (yych == 'O') goto yy801; if (yych != 'o') goto yy187; -yy798: - YYDEBUG(798, *YYCURSOR); +yy801: + YYDEBUG(801, *YYCURSOR); ++YYCURSOR; if (yybm[0+(yych = *YYCURSOR)] & 4) { goto yy186; } - YYDEBUG(799, *YYCURSOR); + YYDEBUG(802, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1143 "Zend/zend_language_scanner.l" +#line 1142 "Zend/zend_language_scanner.l" { return T_ECHO; } -#line 7179 "Zend/zend_language_scanner.c" +#line 7197 "Zend/zend_language_scanner.c" } /* *********************************** */ yyc_ST_LOOKING_FOR_PROPERTY: @@ -7214,113 +7232,113 @@ int lex_scan(zval *zendlval TSRMLS_DC) 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, }; - YYDEBUG(800, *YYCURSOR); + YYDEBUG(803, *YYCURSOR); YYFILL(2); yych = *YYCURSOR; if (yych <= '-') { if (yych <= '\r') { - if (yych <= 0x08) goto yy808; - if (yych <= '\n') goto yy802; - if (yych <= '\f') goto yy808; + if (yych <= 0x08) goto yy811; + if (yych <= '\n') goto yy805; + if (yych <= '\f') goto yy811; } else { - if (yych == ' ') goto yy802; - if (yych <= ',') goto yy808; - goto yy804; + if (yych == ' ') goto yy805; + if (yych <= ',') goto yy811; + goto yy807; } } else { if (yych <= '_') { - if (yych <= '@') goto yy808; - if (yych <= 'Z') goto yy806; - if (yych <= '^') goto yy808; - goto yy806; + if (yych <= '@') goto yy811; + if (yych <= 'Z') goto yy809; + if (yych <= '^') goto yy811; + goto yy809; } else { - if (yych <= '`') goto yy808; - if (yych <= 'z') goto yy806; - if (yych <= '~') goto yy808; - goto yy806; + if (yych <= '`') goto yy811; + if (yych <= 'z') goto yy809; + if (yych <= '~') goto yy811; + goto yy809; } } -yy802: - YYDEBUG(802, *YYCURSOR); +yy805: + YYDEBUG(805, *YYCURSOR); ++YYCURSOR; yych = *YYCURSOR; - goto yy814; -yy803: - YYDEBUG(803, *YYCURSOR); + goto yy817; +yy806: + YYDEBUG(806, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1176 "Zend/zend_language_scanner.l" +#line 1175 "Zend/zend_language_scanner.l" { ZVAL_STRINGL(zendlval, yytext, yyleng, 0); /* no copying - intentional */ HANDLE_NEWLINES(yytext, yyleng); return T_WHITESPACE; } -#line 7258 "Zend/zend_language_scanner.c" -yy804: - YYDEBUG(804, *YYCURSOR); +#line 7276 "Zend/zend_language_scanner.c" +yy807: + YYDEBUG(807, *YYCURSOR); ++YYCURSOR; - if ((yych = *YYCURSOR) == '>') goto yy811; -yy805: - YYDEBUG(805, *YYCURSOR); + if ((yych = *YYCURSOR) == '>') goto yy814; +yy808: + YYDEBUG(808, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1193 "Zend/zend_language_scanner.l" +#line 1192 "Zend/zend_language_scanner.l" { yyless(0); yy_pop_state(TSRMLS_C); goto restart; } -#line 7272 "Zend/zend_language_scanner.c" -yy806: - YYDEBUG(806, *YYCURSOR); +#line 7290 "Zend/zend_language_scanner.c" +yy809: + YYDEBUG(809, *YYCURSOR); ++YYCURSOR; yych = *YYCURSOR; - goto yy810; -yy807: - YYDEBUG(807, *YYCURSOR); + goto yy813; +yy810: + YYDEBUG(810, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1186 "Zend/zend_language_scanner.l" +#line 1185 "Zend/zend_language_scanner.l" { yy_pop_state(TSRMLS_C); zend_copy_value(zendlval, yytext, yyleng); zendlval->type = IS_STRING; return T_STRING; } -#line 7288 "Zend/zend_language_scanner.c" -yy808: - YYDEBUG(808, *YYCURSOR); +#line 7306 "Zend/zend_language_scanner.c" +yy811: + YYDEBUG(811, *YYCURSOR); yych = *++YYCURSOR; - goto yy805; -yy809: - YYDEBUG(809, *YYCURSOR); + goto yy808; +yy812: + YYDEBUG(812, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; -yy810: - YYDEBUG(810, *YYCURSOR); +yy813: + YYDEBUG(813, *YYCURSOR); if (yybm[0+yych] & 64) { - goto yy809; + goto yy812; } - goto yy807; -yy811: - YYDEBUG(811, *YYCURSOR); + goto yy810; +yy814: + YYDEBUG(814, *YYCURSOR); ++YYCURSOR; - YYDEBUG(812, *YYCURSOR); + YYDEBUG(815, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1182 "Zend/zend_language_scanner.l" +#line 1181 "Zend/zend_language_scanner.l" { return T_OBJECT_OPERATOR; } -#line 7313 "Zend/zend_language_scanner.c" -yy813: - YYDEBUG(813, *YYCURSOR); +#line 7331 "Zend/zend_language_scanner.c" +yy816: + YYDEBUG(816, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; -yy814: - YYDEBUG(814, *YYCURSOR); +yy817: + YYDEBUG(817, *YYCURSOR); if (yybm[0+yych] & 128) { - goto yy813; + goto yy816; } - goto yy803; + goto yy806; } /* *********************************** */ yyc_ST_LOOKING_FOR_VARNAME: @@ -7359,74 +7377,74 @@ int lex_scan(zval *zendlval TSRMLS_DC) 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, }; - YYDEBUG(815, *YYCURSOR); + YYDEBUG(818, *YYCURSOR); YYFILL(2); yych = *YYCURSOR; if (yych <= '_') { - if (yych <= '@') goto yy819; - if (yych <= 'Z') goto yy817; - if (yych <= '^') goto yy819; + if (yych <= '@') goto yy822; + if (yych <= 'Z') goto yy820; + if (yych <= '^') goto yy822; } else { - if (yych <= '`') goto yy819; - if (yych <= 'z') goto yy817; - if (yych <= '~') goto yy819; + if (yych <= '`') goto yy822; + if (yych <= 'z') goto yy820; + if (yych <= '~') goto yy822; } -yy817: - YYDEBUG(817, *YYCURSOR); +yy820: + YYDEBUG(820, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); if (yych <= '_') { if (yych <= '@') { - if (yych <= '/') goto yy818; - if (yych <= '9') goto yy821; + if (yych <= '/') goto yy821; + if (yych <= '9') goto yy824; } else { - if (yych <= '[') goto yy821; - if (yych >= '_') goto yy821; + if (yych <= '[') goto yy824; + if (yych >= '_') goto yy824; } } else { if (yych <= '|') { - if (yych <= '`') goto yy818; - if (yych <= 'z') goto yy821; + if (yych <= '`') goto yy821; + if (yych <= 'z') goto yy824; } else { - if (yych != '~') goto yy821; + if (yych != '~') goto yy824; } } -yy818: - YYDEBUG(818, *YYCURSOR); +yy821: + YYDEBUG(821, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1479 "Zend/zend_language_scanner.l" +#line 1482 "Zend/zend_language_scanner.l" { yyless(0); yy_pop_state(TSRMLS_C); yy_push_state(ST_IN_SCRIPTING TSRMLS_CC); goto restart; } -#line 7405 "Zend/zend_language_scanner.c" -yy819: - YYDEBUG(819, *YYCURSOR); +#line 7423 "Zend/zend_language_scanner.c" +yy822: + YYDEBUG(822, *YYCURSOR); yych = *++YYCURSOR; - goto yy818; -yy820: - YYDEBUG(820, *YYCURSOR); + goto yy821; +yy823: + YYDEBUG(823, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; -yy821: - YYDEBUG(821, *YYCURSOR); +yy824: + YYDEBUG(824, *YYCURSOR); if (yybm[0+yych] & 128) { - goto yy820; + goto yy823; } - if (yych == '[') goto yy823; - if (yych == '}') goto yy823; - YYDEBUG(822, *YYCURSOR); + if (yych == '[') goto yy826; + if (yych == '}') goto yy826; + YYDEBUG(825, *YYCURSOR); YYCURSOR = YYMARKER; - goto yy818; -yy823: - YYDEBUG(823, *YYCURSOR); + goto yy821; +yy826: + YYDEBUG(826, *YYCURSOR); ++YYCURSOR; - YYDEBUG(824, *YYCURSOR); + YYDEBUG(827, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1469 "Zend/zend_language_scanner.l" +#line 1472 "Zend/zend_language_scanner.l" { yyless(yyleng - 1); zend_copy_value(zendlval, yytext, yyleng); @@ -7435,18 +7453,18 @@ int lex_scan(zval *zendlval TSRMLS_DC) yy_push_state(ST_IN_SCRIPTING TSRMLS_CC); return T_STRING_VARNAME; } -#line 7439 "Zend/zend_language_scanner.c" +#line 7457 "Zend/zend_language_scanner.c" } /* *********************************** */ yyc_ST_NOWDOC: - YYDEBUG(825, *YYCURSOR); + YYDEBUG(828, *YYCURSOR); YYFILL(1); yych = *YYCURSOR; - YYDEBUG(827, *YYCURSOR); + YYDEBUG(830, *YYCURSOR); ++YYCURSOR; - YYDEBUG(828, *YYCURSOR); + YYDEBUG(831, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2299 "Zend/zend_language_scanner.l" +#line 2302 "Zend/zend_language_scanner.l" { int newline = 0; @@ -7503,7 +7521,7 @@ int lex_scan(zval *zendlval TSRMLS_DC) HANDLE_NEWLINES(yytext, yyleng - newline); return T_ENCAPSED_AND_WHITESPACE; } -#line 7507 "Zend/zend_language_scanner.c" +#line 7525 "Zend/zend_language_scanner.c" /* *********************************** */ yyc_ST_VAR_OFFSET: { @@ -7541,76 +7559,76 @@ int lex_scan(zval *zendlval TSRMLS_DC) 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, }; - YYDEBUG(829, *YYCURSOR); + YYDEBUG(832, *YYCURSOR); YYFILL(3); yych = *YYCURSOR; if (yych <= '/') { if (yych <= ' ') { if (yych <= '\f') { - if (yych <= 0x08) goto yy843; - if (yych <= '\n') goto yy839; - goto yy843; + if (yych <= 0x08) goto yy846; + if (yych <= '\n') goto yy842; + goto yy846; } else { - if (yych <= '\r') goto yy839; - if (yych <= 0x1F) goto yy843; - goto yy839; + if (yych <= '\r') goto yy842; + if (yych <= 0x1F) goto yy846; + goto yy842; } } else { if (yych <= '$') { - if (yych <= '"') goto yy838; - if (yych <= '#') goto yy839; - goto yy834; + if (yych <= '"') goto yy841; + if (yych <= '#') goto yy842; + goto yy837; } else { - if (yych == '\'') goto yy839; - goto yy838; + if (yych == '\'') goto yy842; + goto yy841; } } } else { if (yych <= '\\') { if (yych <= '@') { - if (yych <= '0') goto yy831; - if (yych <= '9') goto yy833; - goto yy838; + if (yych <= '0') goto yy834; + if (yych <= '9') goto yy836; + goto yy841; } else { - if (yych <= 'Z') goto yy841; - if (yych <= '[') goto yy838; - goto yy839; + if (yych <= 'Z') goto yy844; + if (yych <= '[') goto yy841; + goto yy842; } } else { if (yych <= '_') { - if (yych <= ']') goto yy836; - if (yych <= '^') goto yy838; - goto yy841; + if (yych <= ']') goto yy839; + if (yych <= '^') goto yy841; + goto yy844; } else { - if (yych <= '`') goto yy838; - if (yych <= 'z') goto yy841; - if (yych <= '~') goto yy838; - goto yy841; + if (yych <= '`') goto yy841; + if (yych <= 'z') goto yy844; + if (yych <= '~') goto yy841; + goto yy844; } } } -yy831: - YYDEBUG(831, *YYCURSOR); +yy834: + YYDEBUG(834, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); if (yych <= 'W') { if (yych <= '9') { - if (yych >= '0') goto yy855; + if (yych >= '0') goto yy858; } else { - if (yych == 'B') goto yy852; + if (yych == 'B') goto yy855; } } else { if (yych <= 'b') { - if (yych <= 'X') goto yy854; - if (yych >= 'b') goto yy852; + if (yych <= 'X') goto yy857; + if (yych >= 'b') goto yy855; } else { - if (yych == 'x') goto yy854; + if (yych == 'x') goto yy857; } } -yy832: - YYDEBUG(832, *YYCURSOR); +yy835: + YYDEBUG(835, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1555 "Zend/zend_language_scanner.l" +#line 1558 "Zend/zend_language_scanner.l" { /* Offset could be treated as a long */ if (yyleng < MAX_LENGTH_OF_LONG - 1 || (yyleng == MAX_LENGTH_OF_LONG - 1 && strcmp(yytext, long_min_digits) < 0)) { ZVAL_LONG(zendlval, strtol(yytext, NULL, 10)); @@ -7619,81 +7637,81 @@ int lex_scan(zval *zendlval TSRMLS_DC) } return T_NUM_STRING; } -#line 7623 "Zend/zend_language_scanner.c" -yy833: - YYDEBUG(833, *YYCURSOR); +#line 7641 "Zend/zend_language_scanner.c" +yy836: + YYDEBUG(836, *YYCURSOR); yych = *++YYCURSOR; - goto yy851; -yy834: - YYDEBUG(834, *YYCURSOR); + goto yy854; +yy837: + YYDEBUG(837, *YYCURSOR); ++YYCURSOR; if ((yych = *YYCURSOR) <= '_') { - if (yych <= '@') goto yy835; - if (yych <= 'Z') goto yy847; - if (yych >= '_') goto yy847; + if (yych <= '@') goto yy838; + if (yych <= 'Z') goto yy850; + if (yych >= '_') goto yy850; } else { - if (yych <= '`') goto yy835; - if (yych <= 'z') goto yy847; - if (yych >= 0x7F) goto yy847; + if (yych <= '`') goto yy838; + if (yych <= 'z') goto yy850; + if (yych >= 0x7F) goto yy850; } -yy835: - YYDEBUG(835, *YYCURSOR); +yy838: + YYDEBUG(838, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1831 "Zend/zend_language_scanner.l" +#line 1834 "Zend/zend_language_scanner.l" { /* Only '[' can be valid, but returning other tokens will allow a more explicit parse error */ return yytext[0]; } -#line 7648 "Zend/zend_language_scanner.c" -yy836: - YYDEBUG(836, *YYCURSOR); +#line 7666 "Zend/zend_language_scanner.c" +yy839: + YYDEBUG(839, *YYCURSOR); ++YYCURSOR; - YYDEBUG(837, *YYCURSOR); + YYDEBUG(840, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1826 "Zend/zend_language_scanner.l" +#line 1829 "Zend/zend_language_scanner.l" { yy_pop_state(TSRMLS_C); return ']'; } -#line 7659 "Zend/zend_language_scanner.c" -yy838: - YYDEBUG(838, *YYCURSOR); +#line 7677 "Zend/zend_language_scanner.c" +yy841: + YYDEBUG(841, *YYCURSOR); yych = *++YYCURSOR; - goto yy835; -yy839: - YYDEBUG(839, *YYCURSOR); + goto yy838; +yy842: + YYDEBUG(842, *YYCURSOR); ++YYCURSOR; - YYDEBUG(840, *YYCURSOR); + YYDEBUG(843, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1836 "Zend/zend_language_scanner.l" +#line 1839 "Zend/zend_language_scanner.l" { /* Invalid rule to return a more explicit parse error with proper line number */ yyless(0); yy_pop_state(TSRMLS_C); return T_ENCAPSED_AND_WHITESPACE; } -#line 7676 "Zend/zend_language_scanner.c" -yy841: - YYDEBUG(841, *YYCURSOR); +#line 7694 "Zend/zend_language_scanner.c" +yy844: + YYDEBUG(844, *YYCURSOR); ++YYCURSOR; yych = *YYCURSOR; - goto yy846; -yy842: - YYDEBUG(842, *YYCURSOR); + goto yy849; +yy845: + YYDEBUG(845, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1843 "Zend/zend_language_scanner.l" +#line 1846 "Zend/zend_language_scanner.l" { zend_copy_value(zendlval, yytext, yyleng); zendlval->type = IS_STRING; return T_STRING; } -#line 7691 "Zend/zend_language_scanner.c" -yy843: - YYDEBUG(843, *YYCURSOR); +#line 7709 "Zend/zend_language_scanner.c" +yy846: + YYDEBUG(846, *YYCURSOR); ++YYCURSOR; - YYDEBUG(844, *YYCURSOR); + YYDEBUG(847, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2357 "Zend/zend_language_scanner.l" +#line 2360 "Zend/zend_language_scanner.l" { if (YYCURSOR > YYLIMIT) { return 0; @@ -7702,116 +7720,116 @@ int lex_scan(zval *zendlval TSRMLS_DC) zend_error(E_COMPILE_WARNING,"Unexpected character in input: '%c' (ASCII=%d) state=%d", yytext[0], yytext[0], YYSTATE); goto restart; } -#line 7706 "Zend/zend_language_scanner.c" -yy845: - YYDEBUG(845, *YYCURSOR); +#line 7724 "Zend/zend_language_scanner.c" +yy848: + YYDEBUG(848, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; -yy846: - YYDEBUG(846, *YYCURSOR); +yy849: + YYDEBUG(849, *YYCURSOR); if (yybm[0+yych] & 16) { - goto yy845; + goto yy848; } - goto yy842; -yy847: - YYDEBUG(847, *YYCURSOR); + goto yy845; +yy850: + YYDEBUG(850, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(848, *YYCURSOR); + YYDEBUG(851, *YYCURSOR); if (yych <= '^') { if (yych <= '9') { - if (yych >= '0') goto yy847; + if (yych >= '0') goto yy850; } else { - if (yych <= '@') goto yy849; - if (yych <= 'Z') goto yy847; + if (yych <= '@') goto yy852; + if (yych <= 'Z') goto yy850; } } else { if (yych <= '`') { - if (yych <= '_') goto yy847; + if (yych <= '_') goto yy850; } else { - if (yych <= 'z') goto yy847; - if (yych >= 0x7F) goto yy847; + if (yych <= 'z') goto yy850; + if (yych >= 0x7F) goto yy850; } } -yy849: - YYDEBUG(849, *YYCURSOR); +yy852: + YYDEBUG(852, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1820 "Zend/zend_language_scanner.l" +#line 1823 "Zend/zend_language_scanner.l" { zend_copy_value(zendlval, (yytext+1), (yyleng-1)); zendlval->type = IS_STRING; return T_VARIABLE; } -#line 7748 "Zend/zend_language_scanner.c" -yy850: - YYDEBUG(850, *YYCURSOR); +#line 7766 "Zend/zend_language_scanner.c" +yy853: + YYDEBUG(853, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; -yy851: - YYDEBUG(851, *YYCURSOR); +yy854: + YYDEBUG(854, *YYCURSOR); if (yybm[0+yych] & 32) { - goto yy850; + goto yy853; } - goto yy832; -yy852: - YYDEBUG(852, *YYCURSOR); + goto yy835; +yy855: + YYDEBUG(855, *YYCURSOR); yych = *++YYCURSOR; if (yybm[0+yych] & 128) { - goto yy860; + goto yy863; } -yy853: - YYDEBUG(853, *YYCURSOR); +yy856: + YYDEBUG(856, *YYCURSOR); YYCURSOR = YYMARKER; - goto yy832; -yy854: - YYDEBUG(854, *YYCURSOR); + goto yy835; +yy857: + YYDEBUG(857, *YYCURSOR); yych = *++YYCURSOR; if (yybm[0+yych] & 64) { - goto yy858; + goto yy861; } - goto yy853; -yy855: - YYDEBUG(855, *YYCURSOR); + goto yy856; +yy858: + YYDEBUG(858, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(856, *YYCURSOR); - if (yych <= '/') goto yy857; - if (yych <= '9') goto yy855; -yy857: - YYDEBUG(857, *YYCURSOR); + YYDEBUG(859, *YYCURSOR); + if (yych <= '/') goto yy860; + if (yych <= '9') goto yy858; +yy860: + YYDEBUG(860, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1564 "Zend/zend_language_scanner.l" +#line 1567 "Zend/zend_language_scanner.l" { /* Offset must be treated as a string */ ZVAL_STRINGL(zendlval, yytext, yyleng, 1); return T_NUM_STRING; } -#line 7793 "Zend/zend_language_scanner.c" -yy858: - YYDEBUG(858, *YYCURSOR); +#line 7811 "Zend/zend_language_scanner.c" +yy861: + YYDEBUG(861, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(859, *YYCURSOR); + YYDEBUG(862, *YYCURSOR); if (yybm[0+yych] & 64) { - goto yy858; + goto yy861; } - goto yy857; -yy860: - YYDEBUG(860, *YYCURSOR); + goto yy860; +yy863: + YYDEBUG(863, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(861, *YYCURSOR); + YYDEBUG(864, *YYCURSOR); if (yybm[0+yych] & 128) { - goto yy860; + goto yy863; } - goto yy857; + goto yy860; } } -#line 2366 "Zend/zend_language_scanner.l" +#line 2369 "Zend/zend_language_scanner.l" } diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l index f9c421fe8805a..736d7712d5ab8 100644 --- a/Zend/zend_language_scanner.l +++ b/Zend/zend_language_scanner.l @@ -47,7 +47,7 @@ #include "zend_API.h" #include "zend_strtod.h" #include "zend_exceptions.h" -#include "tsrm_virtual_cwd.h" +#include "zend_virtual_cwd.h" #include "tsrm_config_common.h" #define YYCTYPE unsigned char @@ -1011,7 +1011,6 @@ NEWLINE ("\r"|"\n"|"\r\n") /* compute yyleng before each rule */ := yyleng = YYCURSOR - SCNG(yy_text); - "exit" { return T_EXIT; } @@ -1204,6 +1203,10 @@ NEWLINE ("\r"|"\n"|"\r\n") return T_NS_SEPARATOR; } +"..." { + return T_ELLIPSIS; +} + "new" { return T_NEW; } diff --git a/Zend/zend_modules.h b/Zend/zend_modules.h index d4adcf5aac982..00209a0ddc81d 100644 --- a/Zend/zend_modules.h +++ b/Zend/zend_modules.h @@ -33,7 +33,7 @@ #define ZEND_MODULE_INFO_FUNC_ARGS zend_module_entry *zend_module TSRMLS_DC #define ZEND_MODULE_INFO_FUNC_ARGS_PASSTHRU zend_module TSRMLS_CC -#define ZEND_MODULE_API_NO 20121212 +#define ZEND_MODULE_API_NO 20131106 #ifdef ZTS #define USING_ZTS 1 #else diff --git a/Zend/zend_multibyte.c b/Zend/zend_multibyte.c index dafcf18393578..a75d074936ec8 100644 --- a/Zend/zend_multibyte.c +++ b/Zend/zend_multibyte.c @@ -53,7 +53,7 @@ static size_t dummy_encoding_converter(unsigned char **to, size_t *to_length, co static int dummy_encoding_list_parser(const char *encoding_list, size_t encoding_list_len, const zend_encoding ***return_list, size_t *return_size, int persistent TSRMLS_DC) { *return_list = pemalloc(0, persistent); - return_size = 0; + *return_size = 0; return SUCCESS; } diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 8beacdfd352b4..b3afe1e4f70e6 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -29,6 +29,7 @@ #include "zend_interfaces.h" #include "zend_closures.h" #include "zend_compile.h" +#include "zend_hash.h" #define DEBUG_OBJECT_HANDLERS 0 @@ -188,7 +189,7 @@ static int zend_std_call_setter(zval *object, zval *member, zval *value TSRMLS_D zval_ptr_dtor(&value); if (retval) { - result = i_zend_is_true(retval) ? SUCCESS : FAILURE; + result = i_zend_is_true(retval TSRMLS_CC) ? SUCCESS : FAILURE; zval_ptr_dtor(&retval); return result; } else { @@ -693,12 +694,12 @@ static int zend_std_has_dimension(zval *object, zval *offset, int check_empty TS SEPARATE_ARG_IF_REF(offset); zend_call_method_with_1_params(&object, ce, NULL, "offsetexists", &retval, offset); if (EXPECTED(retval != NULL)) { - result = i_zend_is_true(retval); + result = i_zend_is_true(retval TSRMLS_CC); zval_ptr_dtor(&retval); if (check_empty && result && EXPECTED(!EG(exception))) { zend_call_method_with_1_params(&object, ce, NULL, "offsetget", &retval, offset); if (retval) { - result = i_zend_is_true(retval); + result = i_zend_is_true(retval TSRMLS_CC); zval_ptr_dtor(&retval); } } @@ -1446,7 +1447,7 @@ static int zend_std_has_property(zval *object, zval *member, int has_set_exists, guard->in_isset = 1; /* prevent circular getting */ rv = zend_std_call_issetter(object, member TSRMLS_CC); if (rv) { - result = zend_is_true(rv); + result = zend_is_true(rv TSRMLS_CC); zval_ptr_dtor(&rv); if (has_set_exists && result) { if (EXPECTED(!EG(exception)) && zobj->ce->__get && !guard->in_get) { @@ -1455,7 +1456,7 @@ static int zend_std_has_property(zval *object, zval *member, int has_set_exists, guard->in_get = 0; if (rv) { Z_ADDREF_P(rv); - result = i_zend_is_true(rv); + result = i_zend_is_true(rv TSRMLS_CC); zval_ptr_dtor(&rv); } else { result = 0; @@ -1474,7 +1475,7 @@ static int zend_std_has_property(zval *object, zval *member, int has_set_exists, result = (Z_TYPE_PP(value) != IS_NULL); break; default: - result = zend_is_true(*value); + result = zend_is_true(*value TSRMLS_CC); break; case 2: result = 1; diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index 41b4bd25710fd..ac16e81ef1857 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -489,17 +489,22 @@ static void zend_check_finally_breakout(zend_op_array *op_array, zend_uint op_nu zend_uint i; for (i = 0; i < op_array->last_try_catch; i++) { - if (op_array->try_catch_array[i].try_op > op_num) { - break; - } - if ((op_num >= op_array->try_catch_array[i].finally_op + if ((op_num < op_array->try_catch_array[i].finally_op || + op_num >= op_array->try_catch_array[i].finally_end) + && (dst_num >= op_array->try_catch_array[i].finally_op && + dst_num <= op_array->try_catch_array[i].finally_end)) { + CG(in_compilation) = 1; + CG(active_op_array) = op_array; + CG(zend_lineno) = op_array->opcodes[op_num].lineno; + zend_error_noreturn(E_COMPILE_ERROR, "jump into a finally block is disallowed"); + } else if ((op_num >= op_array->try_catch_array[i].finally_op && op_num <= op_array->try_catch_array[i].finally_end) && (dst_num > op_array->try_catch_array[i].finally_end || dst_num < op_array->try_catch_array[i].finally_op)) { CG(in_compilation) = 1; CG(active_op_array) = op_array; CG(zend_lineno) = op_array->opcodes[op_num].lineno; - zend_error(E_COMPILE_ERROR, "jump out of a finally block is disallowed"); + zend_error_noreturn(E_COMPILE_ERROR, "jump out of a finally block is disallowed"); } } } @@ -541,11 +546,11 @@ static void zend_resolve_finally_call(zend_op_array *op_array, zend_uint op_num, while (i > 0) { i--; if (op_array->try_catch_array[i].finally_op && - op_num >= op_array->try_catch_array[i].try_op && - op_num < op_array->try_catch_array[i].finally_op - 1 && - (dst_num < op_array->try_catch_array[i].try_op || - dst_num > op_array->try_catch_array[i].finally_end)) { - + op_num >= op_array->try_catch_array[i].try_op && + op_num < op_array->try_catch_array[i].finally_op - 1 && + (dst_num < op_array->try_catch_array[i].try_op || + dst_num > op_array->try_catch_array[i].finally_end)) { + opline = get_next_op(op_array TSRMLS_CC); opline->opcode = ZEND_FAST_CALL; SET_UNUSED(opline->op1); @@ -565,7 +570,7 @@ static void zend_resolve_finally_call(zend_op_array *op_array, zend_uint op_num, SET_UNUSED(opline->op2); opline->op1.opline_num = start_op; - break; + break; } } } @@ -710,7 +715,7 @@ ZEND_API int pass_two(zend_op_array *op_array TSRMLS_DC) if (op_array->fn_flags & ZEND_ACC_GENERATOR) { if (opline->op1_type != IS_CONST || Z_TYPE_P(opline->op1.zv) != IS_NULL) { CG(zend_lineno) = opline->lineno; - zend_error(E_COMPILE_ERROR, "Generators cannot return values using \"return\""); + zend_error_noreturn(E_COMPILE_ERROR, "Generators cannot return values using \"return\""); } opline->opcode = ZEND_GENERATOR_RETURN; diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h index 15ad79e4dbfc5..5c6fc869e7db2 100644 --- a/Zend/zend_operators.h +++ b/Zend/zend_operators.h @@ -443,6 +443,7 @@ END_EXTERN_C() #define Z_STRVAL(zval) (zval).value.str.val #define Z_STRLEN(zval) (zval).value.str.len #define Z_ARRVAL(zval) (zval).value.ht +#define Z_AST(zval) (zval).value.ast #define Z_OBJVAL(zval) (zval).value.obj #define Z_OBJ_HANDLE(zval) Z_OBJVAL(zval).handle #define Z_OBJ_HT(zval) Z_OBJVAL(zval).handlers @@ -458,6 +459,7 @@ END_EXTERN_C() #define Z_STRVAL_P(zval_p) Z_STRVAL(*zval_p) #define Z_STRLEN_P(zval_p) Z_STRLEN(*zval_p) #define Z_ARRVAL_P(zval_p) Z_ARRVAL(*zval_p) +#define Z_AST_P(zval_p) Z_AST(*zval_p) #define Z_OBJPROP_P(zval_p) Z_OBJPROP(*zval_p) #define Z_OBJCE_P(zval_p) Z_OBJCE(*zval_p) #define Z_RESVAL_P(zval_p) Z_RESVAL(*zval_p) @@ -473,6 +475,7 @@ END_EXTERN_C() #define Z_STRVAL_PP(zval_pp) Z_STRVAL(**zval_pp) #define Z_STRLEN_PP(zval_pp) Z_STRLEN(**zval_pp) #define Z_ARRVAL_PP(zval_pp) Z_ARRVAL(**zval_pp) +#define Z_AST_PP(zval_p) Z_AST(**zval_p) #define Z_OBJPROP_PP(zval_pp) Z_OBJPROP(**zval_pp) #define Z_OBJCE_PP(zval_pp) Z_OBJCE(**zval_pp) #define Z_RESVAL_PP(zval_pp) Z_RESVAL(**zval_pp) @@ -640,13 +643,18 @@ static zend_always_inline int fast_add_function(zval *result, zval *op1, zval *o "n"(ZVAL_OFFSETOF_TYPE) : "rax","cc"); #else - Z_LVAL_P(result) = Z_LVAL_P(op1) + Z_LVAL_P(op2); + /* + * 'result' may alias with op1 or op2, so we need to + * ensure that 'result' is not updated until after we + * have read the values of op1 and op2. + */ if (UNEXPECTED((Z_LVAL_P(op1) & LONG_SIGN_MASK) == (Z_LVAL_P(op2) & LONG_SIGN_MASK) - && (Z_LVAL_P(op1) & LONG_SIGN_MASK) != (Z_LVAL_P(result) & LONG_SIGN_MASK))) { + && (Z_LVAL_P(op1) & LONG_SIGN_MASK) != ((Z_LVAL_P(op1) + Z_LVAL_P(op2)) & LONG_SIGN_MASK))) { Z_DVAL_P(result) = (double) Z_LVAL_P(op1) + (double) Z_LVAL_P(op2); Z_TYPE_P(result) = IS_DOUBLE; } else { + Z_LVAL_P(result) = Z_LVAL_P(op1) + Z_LVAL_P(op2); Z_TYPE_P(result) = IS_LONG; } #endif @@ -789,6 +797,7 @@ static zend_always_inline int fast_mul_function(zval *result, zval *op1, zval *o static zend_always_inline int fast_div_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) { +#if 0 if (EXPECTED(Z_TYPE_P(op1) == IS_LONG) && 0) { if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { if (UNEXPECTED(Z_LVAL_P(op2) == 0)) { @@ -843,6 +852,7 @@ static zend_always_inline int fast_div_function(zval *result, zval *op1, zval *o return SUCCESS; } } +#endif return div_function(result, op1, op2 TSRMLS_CC); } diff --git a/Zend/zend_strtod.c b/Zend/zend_strtod.c index d6e5ccf9604a7..4546614cfdf7f 100644 --- a/Zend/zend_strtod.c +++ b/Zend/zend_strtod.c @@ -267,8 +267,7 @@ BEGIN_EXTERN_C() #if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN) + defined(VAX) + \ defined(IBM) != 1 - Exactly one of IEEE_LITTLE_ENDIAN IEEE_BIG_ENDIAN, VAX, or - IBM should be defined. +#error "Exactly one of IEEE_LITTLE_ENDIAN IEEE_BIG_ENDIAN, VAX, or IBM should be defined." #endif typedef union { diff --git a/Zend/zend_ts_hash.c b/Zend/zend_ts_hash.c index f517fe8560515..337e28915647c 100644 --- a/Zend/zend_ts_hash.c +++ b/Zend/zend_ts_hash.c @@ -59,24 +59,24 @@ static void end_write(TsHashTable *ht) } /* delegates */ -ZEND_API int _zend_ts_hash_init(TsHashTable *ht, uint nSize, hash_func_t pHashFunction, dtor_func_t pDestructor, zend_bool persistent ZEND_FILE_LINE_DC) +ZEND_API int _zend_ts_hash_init(TsHashTable *ht, uint nSize, dtor_func_t pDestructor, zend_bool persistent ZEND_FILE_LINE_DC) { #ifdef ZTS ht->mx_reader = tsrm_mutex_alloc(); ht->mx_writer = tsrm_mutex_alloc(); ht->reader = 0; #endif - return _zend_hash_init(TS_HASH(ht), nSize, pHashFunction, pDestructor, persistent ZEND_FILE_LINE_RELAY_CC); + return _zend_hash_init(TS_HASH(ht), nSize, pDestructor, persistent ZEND_FILE_LINE_RELAY_CC); } -ZEND_API int _zend_ts_hash_init_ex(TsHashTable *ht, uint nSize, hash_func_t pHashFunction, dtor_func_t pDestructor, zend_bool persistent, zend_bool bApplyProtection ZEND_FILE_LINE_DC) +ZEND_API int _zend_ts_hash_init_ex(TsHashTable *ht, uint nSize, dtor_func_t pDestructor, zend_bool persistent, zend_bool bApplyProtection ZEND_FILE_LINE_DC) { #ifdef ZTS ht->mx_reader = tsrm_mutex_alloc(); ht->mx_writer = tsrm_mutex_alloc(); ht->reader = 0; #endif - return _zend_hash_init_ex(TS_HASH(ht), nSize, pHashFunction, pDestructor, persistent, bApplyProtection ZEND_FILE_LINE_RELAY_CC); + return _zend_hash_init_ex(TS_HASH(ht), nSize, pDestructor, persistent, bApplyProtection ZEND_FILE_LINE_RELAY_CC); } ZEND_API void zend_ts_hash_destroy(TsHashTable *ht) diff --git a/Zend/zend_ts_hash.h b/Zend/zend_ts_hash.h index 9a849e15aed5f..eda71c608110a 100644 --- a/Zend/zend_ts_hash.h +++ b/Zend/zend_ts_hash.h @@ -37,15 +37,15 @@ BEGIN_EXTERN_C() #define TS_HASH(table) (&(table->hash)) /* startup/shutdown */ -ZEND_API int _zend_ts_hash_init(TsHashTable *ht, uint nSize, hash_func_t pHashFunction, dtor_func_t pDestructor, zend_bool persistent ZEND_FILE_LINE_DC); -ZEND_API int _zend_ts_hash_init_ex(TsHashTable *ht, uint nSize, hash_func_t pHashFunction, dtor_func_t pDestructor, zend_bool persistent, zend_bool bApplyProtection ZEND_FILE_LINE_DC); +ZEND_API int _zend_ts_hash_init(TsHashTable *ht, uint nSize, dtor_func_t pDestructor, zend_bool persistent ZEND_FILE_LINE_DC); +ZEND_API int _zend_ts_hash_init_ex(TsHashTable *ht, uint nSize, dtor_func_t pDestructor, zend_bool persistent, zend_bool bApplyProtection ZEND_FILE_LINE_DC); ZEND_API void zend_ts_hash_destroy(TsHashTable *ht); ZEND_API void zend_ts_hash_clean(TsHashTable *ht); #define zend_ts_hash_init(ht, nSize, pHashFunction, pDestructor, persistent) \ - _zend_ts_hash_init(ht, nSize, pHashFunction, pDestructor, persistent ZEND_FILE_LINE_CC) + _zend_ts_hash_init(ht, nSize, pDestructor, persistent ZEND_FILE_LINE_CC) #define zend_ts_hash_init_ex(ht, nSize, pHashFunction, pDestructor, persistent, bApplyProtection) \ - _zend_ts_hash_init_ex(ht, nSize, pHashFunction, pDestructor, persistent, bApplyProtection ZEND_FILE_LINE_CC) + _zend_ts_hash_init_ex(ht, nSize, pDestructor, persistent, bApplyProtection ZEND_FILE_LINE_CC) /* additions/updates/changes */ diff --git a/Zend/zend_variables.c b/Zend/zend_variables.c index d82e1642e78b0..3fa1b063a183f 100644 --- a/Zend/zend_variables.c +++ b/Zend/zend_variables.c @@ -22,6 +22,7 @@ #include #include "zend.h" #include "zend_API.h" +#include "zend_ast.h" #include "zend_globals.h" #include "zend_constants.h" #include "zend_list.h" @@ -47,6 +48,9 @@ ZEND_API void _zval_dtor_func(zval *zvalue ZEND_FILE_LINE_DC) } } break; + case IS_CONSTANT_AST: + zend_ast_destroy(Z_AST_P(zvalue)); + break; case IS_OBJECT: { TSRMLS_FETCH(); @@ -83,6 +87,7 @@ ZEND_API void _zval_internal_dtor(zval *zvalue ZEND_FILE_LINE_DC) break; case IS_ARRAY: case IS_CONSTANT_ARRAY: + case IS_CONSTANT_AST: case IS_OBJECT: case IS_RESOURCE: zend_error(E_CORE_ERROR, "Internal zval's can't be arrays, objects or resources"); @@ -139,6 +144,9 @@ ZEND_API void _zval_copy_ctor_func(zval *zvalue ZEND_FILE_LINE_DC) zvalue->value.ht = tmp_ht; } break; + case IS_CONSTANT_AST: + Z_AST_P(zvalue) = zend_ast_copy(Z_AST_P(zvalue)); + break; case IS_OBJECT: { TSRMLS_FETCH(); diff --git a/TSRM/tsrm_virtual_cwd.c b/Zend/zend_virtual_cwd.c similarity index 92% rename from TSRM/tsrm_virtual_cwd.c rename to Zend/zend_virtual_cwd.c index a7d09630a26c7..d9da5cf4c0c8e 100644 --- a/TSRM/tsrm_virtual_cwd.c +++ b/Zend/zend_virtual_cwd.c @@ -30,7 +30,8 @@ #include #include -#include "tsrm_virtual_cwd.h" +#include "zend.h" +#include "zend_virtual_cwd.h" #include "tsrm_strtok_r.h" #ifdef TSRM_WIN32 @@ -126,7 +127,6 @@ static int php_check_dots(const char *element, int n) #define TOKENIZER_STRING "/" #endif - /* default macros */ #ifndef IS_DIRECTORY_UP @@ -149,11 +149,21 @@ static int php_check_dots(const char *element, int n) #define CWD_STATE_COPY(d, s) \ (d)->cwd_length = (s)->cwd_length; \ - (d)->cwd = (char *) malloc((s)->cwd_length+1); \ + (d)->cwd = (char *) emalloc((s)->cwd_length+1); \ memcpy((d)->cwd, (s)->cwd, (s)->cwd_length+1); #define CWD_STATE_FREE(s) \ - free((s)->cwd); + efree((s)->cwd); + +#ifdef TSRM_WIN32 +# define CWD_STATE_FREE_ERR(state) do { \ + DWORD last_error = GetLastError(); \ + CWD_STATE_FREE(state); \ + SetLastError(last_error); \ + } while (0) +#else +# define CWD_STATE_FREE_ERR(state) CWD_STATE_FREE(state) +#endif #ifdef TSRM_WIN32 @@ -286,6 +296,7 @@ CWD_API int php_sys_stat_ex(const char *path, struct stat *buf, int lstat) /* {{ WIN32_FILE_ATTRIBUTE_DATA data; __int64 t; const size_t path_len = strlen(path); + ALLOCA_FLAG(use_heap_large); if (!GetFileAttributesEx(path, GetFileExInfoStandard, &data)) { return stat(path, buf); @@ -337,16 +348,15 @@ CWD_API int php_sys_stat_ex(const char *path, struct stat *buf, int lstat) /* {{ HANDLE hLink = NULL; REPARSE_DATA_BUFFER * pbuffer; unsigned int retlength = 0; - TSRM_ALLOCA_FLAG(use_heap_large); hLink = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, NULL); if(hLink == INVALID_HANDLE_VALUE) { return -1; } - pbuffer = (REPARSE_DATA_BUFFER *)tsrm_do_alloca(MAXIMUM_REPARSE_DATA_BUFFER_SIZE, use_heap_large); + pbuffer = (REPARSE_DATA_BUFFER *)do_alloca(MAXIMUM_REPARSE_DATA_BUFFER_SIZE, use_heap_large); if(!DeviceIoControl(hLink, FSCTL_GET_REPARSE_POINT, NULL, 0, pbuffer, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &retlength, NULL)) { - tsrm_free_alloca(pbuffer, use_heap_large); + free_alloca(pbuffer, use_heap_large); CloseHandle(hLink); return -1; } @@ -363,7 +373,7 @@ CWD_API int php_sys_stat_ex(const char *path, struct stat *buf, int lstat) /* {{ buf->st_mode |=; } #endif - tsrm_free_alloca(pbuffer, use_heap_large); + free_alloca(pbuffer, use_heap_large); } else { buf->st_mode = (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? (S_IFDIR|S_IEXEC|(S_IEXEC>>3)|(S_IEXEC>>6)) : S_IFREG; buf->st_mode |= (data.dwFileAttributes & FILE_ATTRIBUTE_READONLY) ? (S_IREAD|(S_IREAD>>3)|(S_IREAD>>6)) : (S_IREAD|(S_IREAD>>3)|(S_IREAD>>6)|S_IWRITE|(S_IWRITE>>3)|(S_IWRITE>>6)); @@ -429,7 +439,6 @@ static void cwd_globals_ctor(virtual_cwd_globals *cwd_g TSRMLS_DC) /* {{{ */ static void cwd_globals_dtor(virtual_cwd_globals *cwd_g TSRMLS_DC) /* {{{ */ { - CWD_STATE_FREE(&cwd_g->cwd); realpath_cache_clean(TSRMLS_C); } /* }}} */ @@ -490,6 +499,25 @@ CWD_API void virtual_cwd_shutdown(void) /* {{{ */ } /* }}} */ +CWD_API int virtual_cwd_activate(TSRMLS_D) /* {{{ */ +{ + if (CWDG(cwd).cwd == NULL) { + CWD_STATE_COPY(&CWDG(cwd), &main_cwd_state); + } + return 0; +} +/* }}} */ + +CWD_API int virtual_cwd_deactivate(TSRMLS_D) /* {{{ */ +{ + if (CWDG(cwd).cwd != NULL) { + CWD_STATE_FREE(&CWDG(cwd)); + CWDG(cwd).cwd = NULL; + } + return 0; +} +/* }}} */ + CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC) /* {{{ */ { cwd_state *state; @@ -500,7 +528,7 @@ CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC) /* {{{ */ char *retval; *length = 1; - retval = (char *) malloc(2); + retval = (char *) emalloc(2); if (retval == NULL) { return NULL; } @@ -515,7 +543,7 @@ CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC) /* {{{ */ char *retval; *length = state->cwd_length+1; - retval = (char *) malloc(*length+1); + retval = (char *) emalloc(*length+1); if (retval == NULL) { return NULL; } @@ -527,7 +555,7 @@ CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC) /* {{{ */ } #endif *length = state->cwd_length; - return strdup(state->cwd); + return estrdup(state->cwd); } /* }}} */ @@ -543,12 +571,12 @@ CWD_API char *virtual_getcwd(char *buf, size_t size TSRMLS_DC) /* {{{ */ return cwd; } if (length > size-1) { - free(cwd); + efree(cwd); errno = ERANGE; /* Is this OK? */ return NULL; } memcpy(buf, cwd, length+1); - free(cwd); + efree(cwd); return buf; } /* }}} */ @@ -754,13 +782,13 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i #ifdef TSRM_WIN32 WIN32_FIND_DATA data; HANDLE hFind; - TSRM_ALLOCA_FLAG(use_heap_large) + ALLOCA_FLAG(use_heap_large) #else struct stat st; #endif realpath_cache_bucket *bucket; char *tmp; - TSRM_ALLOCA_FLAG(use_heap) + ALLOCA_FLAG(use_heap) while (1) { if (len <= start) { @@ -860,7 +888,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i FindClose(hFind); } - tmp = tsrm_do_alloca(len+1, use_heap); + tmp = do_alloca(len+1, use_heap); memcpy(tmp, path, len+1); if(save && @@ -887,12 +915,12 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i return -1; } - pbuffer = (REPARSE_DATA_BUFFER *)tsrm_do_alloca(MAXIMUM_REPARSE_DATA_BUFFER_SIZE, use_heap_large); + pbuffer = (REPARSE_DATA_BUFFER *)do_alloca(MAXIMUM_REPARSE_DATA_BUFFER_SIZE, use_heap_large); if (pbuffer == NULL) { return -1; } if(!DeviceIoControl(hLink, FSCTL_GET_REPARSE_POINT, NULL, 0, pbuffer, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &retlength, NULL)) { - tsrm_free_alloca(pbuffer, use_heap_large); + free_alloca(pbuffer, use_heap_large); CloseHandle(hLink); return -1; } @@ -908,7 +936,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i printname_len + 1, printname, MAX_PATH, NULL, NULL )) { - tsrm_free_alloca(pbuffer, use_heap_large); + free_alloca(pbuffer, use_heap_large); return -1; }; printname_len = pbuffer->MountPointReparseBuffer.PrintNameLength / sizeof(WCHAR); @@ -920,7 +948,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i substitutename_len + 1, substitutename, MAX_PATH, NULL, NULL )) { - tsrm_free_alloca(pbuffer, use_heap_large); + free_alloca(pbuffer, use_heap_large); return -1; }; substitutename[substitutename_len] = 0; @@ -934,7 +962,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i printname_len + 1, printname, MAX_PATH, NULL, NULL )) { - tsrm_free_alloca(pbuffer, use_heap_large); + free_alloca(pbuffer, use_heap_large); return -1; }; printname[pbuffer->MountPointReparseBuffer.PrintNameLength / sizeof(WCHAR)] = 0; @@ -945,7 +973,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i substitutename_len + 1, substitutename, MAX_PATH, NULL, NULL )) { - tsrm_free_alloca(pbuffer, use_heap_large); + free_alloca(pbuffer, use_heap_large); return -1; }; substitutename[substitutename_len] = 0; @@ -955,7 +983,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i memcpy(substitutename, path, len + 1); substitutename_len = len; } else { - tsrm_free_alloca(pbuffer, use_heap_large); + free_alloca(pbuffer, use_heap_large); return -1; } @@ -999,21 +1027,21 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i fprintf(stderr, "sub: %s ", substitutename); fprintf(stderr, "resolved: %s ", path); #endif - tsrm_free_alloca(pbuffer, use_heap_large); + free_alloca(pbuffer, use_heap_large); if(isabsolute == 1) { if (!((j == 3) && (path[1] == ':') && (path[2] == '\\'))) { /* use_realpath is 0 in the call below coz path is absolute*/ j = tsrm_realpath_r(path, 0, j, ll, t, 0, is_dir, &directory TSRMLS_CC); if(j < 0) { - tsrm_free_alloca(tmp, use_heap); + free_alloca(tmp, use_heap); return -1; } } } else { if(i + j >= MAXPATHLEN - 1) { - tsrm_free_alloca(tmp, use_heap); + free_alloca(tmp, use_heap); return -1; } @@ -1022,7 +1050,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i path[i-1] = DEFAULT_SLASH; j = tsrm_realpath_r(path, start, i + j, ll, t, use_realpath, is_dir, &directory TSRMLS_CC); if(j < 0) { - tsrm_free_alloca(tmp, use_heap); + free_alloca(tmp, use_heap); return -1; } } @@ -1043,7 +1071,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i #elif defined(NETWARE) save = 0; - tmp = tsrm_do_alloca(len+1, use_heap); + tmp = do_alloca(len+1, use_heap); memcpy(tmp, path, len+1); #else if (save && php_sys_lstat(path, &st) < 0) { @@ -1055,25 +1083,25 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i save = 0; } - tmp = tsrm_do_alloca(len+1, use_heap); + tmp = do_alloca(len+1, use_heap); memcpy(tmp, path, len+1); if (save && S_ISLNK(st.st_mode)) { if (++(*ll) > LINK_MAX || (j = php_sys_readlink(tmp, path, MAXPATHLEN)) < 0) { /* too many links or broken symlinks */ - tsrm_free_alloca(tmp, use_heap); + free_alloca(tmp, use_heap); return -1; } path[j] = 0; if (IS_ABSOLUTE_PATH(path, j)) { j = tsrm_realpath_r(path, 1, j, ll, t, use_realpath, is_dir, &directory TSRMLS_CC); if (j < 0) { - tsrm_free_alloca(tmp, use_heap); + free_alloca(tmp, use_heap); return -1; } } else { if (i + j >= MAXPATHLEN-1) { - tsrm_free_alloca(tmp, use_heap); + free_alloca(tmp, use_heap); return -1; /* buffer overflow */ } memmove(path+i, path, j+1); @@ -1081,7 +1109,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i path[i-1] = DEFAULT_SLASH; j = tsrm_realpath_r(path, start, i + j, ll, t, use_realpath, is_dir, &directory TSRMLS_CC); if (j < 0) { - tsrm_free_alloca(tmp, use_heap); + free_alloca(tmp, use_heap); return -1; } } @@ -1096,7 +1124,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i } if (is_dir && !directory) { /* not a directory */ - tsrm_free_alloca(tmp, use_heap); + free_alloca(tmp, use_heap); return -1; } } @@ -1112,7 +1140,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i } #ifdef TSRM_WIN32 if (j < 0 || j + len - i >= MAXPATHLEN-1) { - tsrm_free_alloca(tmp, use_heap); + free_alloca(tmp, use_heap); return -1; } if (save) { @@ -1127,7 +1155,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i } #else if (j < 0 || j + len - i >= MAXPATHLEN-1) { - tsrm_free_alloca(tmp, use_heap); + free_alloca(tmp, use_heap); return -1; } memcpy(path+j, tmp+i, len-i+1); @@ -1140,7 +1168,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i realpath_cache_add(tmp, len, path, j, directory, *t TSRMLS_CC); } - tsrm_free_alloca(tmp, use_heap); + free_alloca(tmp, use_heap); return j; } } @@ -1316,7 +1344,7 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func CWD_STATE_COPY(&old_state, state); state->cwd_length = path_length; - tmp = realloc(state->cwd, state->cwd_length+1); + tmp = erealloc(state->cwd, state->cwd_length+1); if (tmp == NULL) { #if VIRTUAL_CWD_DEBUG fprintf (stderr, "Out of memory\n"); @@ -1336,7 +1364,7 @@ CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func } } else { state->cwd_length = path_length; - tmp = realloc(state->cwd, state->cwd_length+1); + tmp = erealloc(state->cwd, state->cwd_length+1); if (tmp == NULL) { #if VIRTUAL_CWD_DEBUG fprintf (stderr, "Out of memory\n"); @@ -1367,7 +1395,7 @@ CWD_API int virtual_chdir_file(const char *path, int (*p_chdir)(const char *path int length = strlen(path); char *temp; int retval; - TSRM_ALLOCA_FLAG(use_heap) + ALLOCA_FLAG(use_heap) if (length == 0) { return 1; /* Can't cd to empty string */ @@ -1384,14 +1412,14 @@ CWD_API int virtual_chdir_file(const char *path, int (*p_chdir)(const char *path if (length == COPY_WHEN_ABSOLUTE(path) && IS_ABSOLUTE_PATH(path, length+1)) { /* Also use trailing slash if this is absolute */ length++; } - temp = (char *) tsrm_do_alloca(length+1, use_heap); + temp = (char *) do_alloca(length+1, use_heap); memcpy(temp, path, length); temp[length] = 0; #if VIRTUAL_CWD_DEBUG fprintf (stderr, "Changing directory to %s\n", temp); #endif retval = p_chdir(temp TSRMLS_CC); - tsrm_free_alloca(temp, use_heap); + free_alloca(temp, use_heap); return retval; } /* }}} */ @@ -1404,7 +1432,7 @@ CWD_API char *virtual_realpath(const char *path, char *real_path TSRMLS_DC) /* { /* realpath("") returns CWD */ if (!*path) { - new_state.cwd = (char*)malloc(1); + new_state.cwd = (char*)emalloc(1); if (new_state.cwd == NULL) { retval = NULL; goto end; @@ -1417,7 +1445,7 @@ CWD_API char *virtual_realpath(const char *path, char *real_path TSRMLS_DC) /* { } else if (!IS_ABSOLUTE_PATH(path, strlen(path))) { CWD_STATE_COPY(&new_state, &CWDG(cwd)); } else { - new_state.cwd = (char*)malloc(1); + new_state.cwd = (char*)emalloc(1); if (new_state.cwd == NULL) { retval = NULL; goto end; @@ -1474,13 +1502,14 @@ CWD_API FILE *virtual_fopen(const char *path, const char *mode TSRMLS_DC) /* {{{ CWD_STATE_COPY(&new_state, &CWDG(cwd)); if (virtual_file_ex(&new_state, path, NULL, CWD_EXPAND TSRMLS_CC)) { - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return NULL; } f = fopen(new_state.cwd, mode); - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); + return f; } /* }}} */ @@ -1492,7 +1521,7 @@ CWD_API int virtual_access(const char *pathname, int mode TSRMLS_DC) /* {{{ */ CWD_STATE_COPY(&new_state, &CWDG(cwd)); if (virtual_file_ex(&new_state, pathname, NULL, CWD_REALPATH TSRMLS_CC)) { - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return -1; } @@ -1502,7 +1531,7 @@ CWD_API int virtual_access(const char *pathname, int mode TSRMLS_DC) /* {{{ */ ret = access(new_state.cwd, mode); #endif - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return ret; } @@ -1565,7 +1594,7 @@ CWD_API int virtual_utime(const char *filename, struct utimbuf *buf TSRMLS_DC) / CWD_STATE_COPY(&new_state, &CWDG(cwd)); if (virtual_file_ex(&new_state, filename, NULL, CWD_REALPATH TSRMLS_CC)) { - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return -1; } @@ -1575,7 +1604,7 @@ CWD_API int virtual_utime(const char *filename, struct utimbuf *buf TSRMLS_DC) / ret = utime(new_state.cwd, buf); #endif - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return ret; } /* }}} */ @@ -1588,13 +1617,13 @@ CWD_API int virtual_chmod(const char *filename, mode_t mode TSRMLS_DC) /* {{{ */ CWD_STATE_COPY(&new_state, &CWDG(cwd)); if (virtual_file_ex(&new_state, filename, NULL, CWD_REALPATH TSRMLS_CC)) { - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return -1; } ret = chmod(new_state.cwd, mode); - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return ret; } /* }}} */ @@ -1607,7 +1636,7 @@ CWD_API int virtual_chown(const char *filename, uid_t owner, gid_t group, int li CWD_STATE_COPY(&new_state, &CWDG(cwd)); if (virtual_file_ex(&new_state, filename, NULL, CWD_REALPATH TSRMLS_CC)) { - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return -1; } @@ -1621,7 +1650,7 @@ CWD_API int virtual_chown(const char *filename, uid_t owner, gid_t group, int li ret = chown(new_state.cwd, owner, group); } - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return ret; } /* }}} */ @@ -1634,7 +1663,7 @@ CWD_API int virtual_open(const char *path TSRMLS_DC, int flags, ...) /* {{{ */ CWD_STATE_COPY(&new_state, &CWDG(cwd)); if (virtual_file_ex(&new_state, path, NULL, CWD_FILEPATH TSRMLS_CC)) { - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return -1; } @@ -1650,7 +1679,7 @@ CWD_API int virtual_open(const char *path TSRMLS_DC, int flags, ...) /* {{{ */ } else { f = open(new_state.cwd, flags); } - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return f; } /* }}} */ @@ -1662,13 +1691,13 @@ CWD_API int virtual_creat(const char *path, mode_t mode TSRMLS_DC) /* {{{ */ CWD_STATE_COPY(&new_state, &CWDG(cwd)); if (virtual_file_ex(&new_state, path, NULL, CWD_FILEPATH TSRMLS_CC)) { - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return -1; } f = creat(new_state.cwd, mode); - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return f; } /* }}} */ @@ -1681,15 +1710,15 @@ CWD_API int virtual_rename(const char *oldname, const char *newname TSRMLS_DC) / CWD_STATE_COPY(&old_state, &CWDG(cwd)); if (virtual_file_ex(&old_state, oldname, NULL, CWD_EXPAND TSRMLS_CC)) { - CWD_STATE_FREE(&old_state); + CWD_STATE_FREE_ERR(&old_state); return -1; } oldname = old_state.cwd; CWD_STATE_COPY(&new_state, &CWDG(cwd)); if (virtual_file_ex(&new_state, newname, NULL, CWD_EXPAND TSRMLS_CC)) { - CWD_STATE_FREE(&old_state); - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&old_state); + CWD_STATE_FREE_ERR(&new_state); return -1; } newname = new_state.cwd; @@ -1703,8 +1732,8 @@ CWD_API int virtual_rename(const char *oldname, const char *newname TSRMLS_DC) / retval = rename(oldname, newname); #endif - CWD_STATE_FREE(&old_state); - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&old_state); + CWD_STATE_FREE_ERR(&new_state); return retval; } @@ -1717,13 +1746,13 @@ CWD_API int virtual_stat(const char *path, struct stat *buf TSRMLS_DC) /* {{{ */ CWD_STATE_COPY(&new_state, &CWDG(cwd)); if (virtual_file_ex(&new_state, path, NULL, CWD_REALPATH TSRMLS_CC)) { - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return -1; } retval = php_sys_stat(new_state.cwd, buf); - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return retval; } /* }}} */ @@ -1735,13 +1764,13 @@ CWD_API int virtual_lstat(const char *path, struct stat *buf TSRMLS_DC) /* {{{ * CWD_STATE_COPY(&new_state, &CWDG(cwd)); if (virtual_file_ex(&new_state, path, NULL, CWD_EXPAND TSRMLS_CC)) { - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return -1; } retval = php_sys_lstat(new_state.cwd, buf); - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return retval; } /* }}} */ @@ -1753,13 +1782,13 @@ CWD_API int virtual_unlink(const char *path TSRMLS_DC) /* {{{ */ CWD_STATE_COPY(&new_state, &CWDG(cwd)); if (virtual_file_ex(&new_state, path, NULL, CWD_EXPAND TSRMLS_CC)) { - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return -1; } retval = unlink(new_state.cwd); - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return retval; } /* }}} */ @@ -1771,7 +1800,7 @@ CWD_API int virtual_mkdir(const char *pathname, mode_t mode TSRMLS_DC) /* {{{ */ CWD_STATE_COPY(&new_state, &CWDG(cwd)); if (virtual_file_ex(&new_state, pathname, NULL, CWD_FILEPATH TSRMLS_CC)) { - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return -1; } @@ -1780,7 +1809,7 @@ CWD_API int virtual_mkdir(const char *pathname, mode_t mode TSRMLS_DC) /* {{{ */ #else retval = mkdir(new_state.cwd, mode); #endif - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return retval; } /* }}} */ @@ -1792,13 +1821,13 @@ CWD_API int virtual_rmdir(const char *pathname TSRMLS_DC) /* {{{ */ CWD_STATE_COPY(&new_state, &CWDG(cwd)); if (virtual_file_ex(&new_state, pathname, NULL, CWD_EXPAND TSRMLS_CC)) { - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return -1; } retval = rmdir(new_state.cwd); - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return retval; } /* }}} */ @@ -1814,13 +1843,13 @@ CWD_API DIR *virtual_opendir(const char *pathname TSRMLS_DC) /* {{{ */ CWD_STATE_COPY(&new_state, &CWDG(cwd)); if (virtual_file_ex(&new_state, pathname, NULL, CWD_REALPATH TSRMLS_CC)) { - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return NULL; } retval = opendir(new_state.cwd); - CWD_STATE_FREE(&new_state); + CWD_STATE_FREE_ERR(&new_state); return retval; } /* }}} */ @@ -1882,7 +1911,7 @@ CWD_API FILE *virtual_popen(const char *command, const char *type TSRMLS_DC) /* dir_length = CWDG(cwd).cwd_length; dir = CWDG(cwd).cwd; - ptr = command_line = (char *) malloc(command_length + sizeof("cd '' ; ") + dir_length + extra+1+1); + ptr = command_line = (char *) emalloc(command_length + sizeof("cd '' ; ") + dir_length + extra+1+1); if (!command_line) { return NULL; } @@ -1916,7 +1945,7 @@ CWD_API FILE *virtual_popen(const char *command, const char *type TSRMLS_DC) /* memcpy(ptr, command, command_length+1); retval = popen(command_line, type); - free(command_line); + efree(command_line); return retval; } /* }}} */ @@ -1929,7 +1958,7 @@ CWD_API char *tsrm_realpath(const char *path, char *real_path TSRMLS_DC) /* {{{ /* realpath("") returns CWD */ if (!*path) { - new_state.cwd = (char*)malloc(1); + new_state.cwd = (char*)emalloc(1); if (new_state.cwd == NULL) { return NULL; } @@ -1940,10 +1969,10 @@ CWD_API char *tsrm_realpath(const char *path, char *real_path TSRMLS_DC) /* {{{ } } else if (!IS_ABSOLUTE_PATH(path, strlen(path)) && VCWD_GETCWD(cwd, MAXPATHLEN)) { - new_state.cwd = strdup(cwd); + new_state.cwd = estrdup(cwd); new_state.cwd_length = strlen(cwd); } else { - new_state.cwd = (char*)malloc(1); + new_state.cwd = (char*)emalloc(1); if (new_state.cwd == NULL) { return NULL; } @@ -1952,7 +1981,7 @@ CWD_API char *tsrm_realpath(const char *path, char *real_path TSRMLS_DC) /* {{{ } if (virtual_file_ex(&new_state, path, NULL, CWD_REALPATH TSRMLS_CC)) { - free(new_state.cwd); + efree(new_state.cwd); return NULL; } @@ -1960,7 +1989,7 @@ CWD_API char *tsrm_realpath(const char *path, char *real_path TSRMLS_DC) /* {{{ int copy_len = new_state.cwd_length>MAXPATHLEN-1 ? MAXPATHLEN-1 : new_state.cwd_length; memcpy(real_path, new_state.cwd, copy_len); real_path[copy_len] = '\0'; - free(new_state.cwd); + efree(new_state.cwd); return real_path; } else { return new_state.cwd; diff --git a/TSRM/tsrm_virtual_cwd.h b/Zend/zend_virtual_cwd.h similarity index 99% rename from TSRM/tsrm_virtual_cwd.h rename to Zend/zend_virtual_cwd.h index 72c4424670566..a6ac0aeef7162 100644 --- a/TSRM/tsrm_virtual_cwd.h +++ b/Zend/zend_virtual_cwd.h @@ -151,6 +151,8 @@ typedef int (*verify_path_func)(const cwd_state *); CWD_API void virtual_cwd_startup(void); CWD_API void virtual_cwd_shutdown(void); +CWD_API int virtual_cwd_activate(TSRMLS_D); +CWD_API int virtual_cwd_deactivate(TSRMLS_D); CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC); CWD_API char *virtual_getcwd(char *buf, size_t size TSRMLS_DC); CWD_API int virtual_chdir(const char *path TSRMLS_DC); diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 4621b47e0e69e..d669c134b929c 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -352,7 +352,6 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMP|VAR if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); - EX_T(opline->result.var).var.ptr_ptr = NULL; } } else { /* here we are sure we are dealing with an object */ @@ -372,7 +371,6 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMP|VAR if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*zptr); EX_T(opline->result.var).var.ptr = *zptr; - EX_T(opline->result.var).var.ptr_ptr = NULL; } } } @@ -411,7 +409,6 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMP|VAR if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(z); EX_T(opline->result.var).var.ptr = z; - EX_T(opline->result.var).var.ptr_ptr = NULL; } zval_ptr_dtor(&z); } else { @@ -419,7 +416,6 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMP|VAR if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); - EX_T(opline->result.var).var.ptr_ptr = NULL; } } } @@ -484,7 +480,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_helper, VAR|UNUSED|CV, CONST|TMP|VAR|UNU if (UNEXPECTED(*var_ptr == &EG(error_zval))) { if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } FREE_OP2(); FREE_OP1_VAR_PTR(); @@ -512,7 +508,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_helper, VAR|UNUSED|CV, CONST|TMP|VAR|UNU if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*var_ptr); - AI_SET_PTR(&EX_T(opline->result.var), *var_ptr); + EX_T(opline->result.var).var.ptr = *var_ptr; } FREE_OP2(); @@ -805,7 +801,7 @@ ZEND_VM_HANDLER(34, ZEND_PRE_INC, VAR|CV, ANY) if (OP1_TYPE == IS_VAR && UNEXPECTED(*var_ptr == &EG(error_zval))) { if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } FREE_OP1_VAR_PTR(); CHECK_EXCEPTION(); @@ -829,7 +825,7 @@ ZEND_VM_HANDLER(34, ZEND_PRE_INC, VAR|CV, ANY) if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*var_ptr); - AI_SET_PTR(&EX_T(opline->result.var), *var_ptr); + EX_T(opline->result.var).var.ptr = *var_ptr; } FREE_OP1_VAR_PTR(); @@ -852,7 +848,7 @@ ZEND_VM_HANDLER(35, ZEND_PRE_DEC, VAR|CV, ANY) if (OP1_TYPE == IS_VAR && UNEXPECTED(*var_ptr == &EG(error_zval))) { if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } FREE_OP1_VAR_PTR(); CHECK_EXCEPTION(); @@ -876,7 +872,7 @@ ZEND_VM_HANDLER(35, ZEND_PRE_DEC, VAR|CV, ANY) if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*var_ptr); - AI_SET_PTR(&EX_T(opline->result.var), *var_ptr); + EX_T(opline->result.var).var.ptr = *var_ptr; } FREE_OP1_VAR_PTR(); @@ -1106,7 +1102,7 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMP|VAR|CV, UNUSED|CONST| switch (type) { case BP_VAR_R: case BP_VAR_IS: - AI_SET_PTR(&EX_T(opline->result.var), *retval); + EX_T(opline->result.var).var.ptr = *retval; break; case BP_VAR_UNSET: { zend_free_op free_res; @@ -1147,7 +1143,7 @@ ZEND_VM_HANDLER(92, ZEND_FETCH_FUNC_ARG, CONST|TMP|VAR|CV, UNUSED|CONST|VAR) USE_OPLINE ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, - ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R); + zend_is_by_ref_func_arg_fetch(opline, EX(call) TSRMLS_CC) ? BP_VAR_W : BP_VAR_R); } ZEND_VM_HANDLER(95, ZEND_FETCH_UNSET, CONST|TMP|VAR|CV, UNUSED|CONST|VAR) @@ -1164,24 +1160,15 @@ ZEND_VM_HANDLER(81, ZEND_FETCH_DIM_R, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV) { USE_OPLINE zend_free_op free_op1, free_op2; - zval **container; + zval *container; SAVE_OPLINE(); - - if (OP1_TYPE == IS_TMP_VAR || OP1_TYPE == IS_CONST) { - zval *container = GET_OP1_ZVAL_PTR(BP_VAR_R); - zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_R TSRMLS_CC); - FREE_OP2(); + container = GET_OP1_ZVAL_PTR(BP_VAR_R); + zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_R TSRMLS_CC); + FREE_OP2(); + if (OP1_TYPE != IS_VAR || !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { FREE_OP1(); - } else { - container = GET_OP1_ZVAL_PTR_PTR_FAST(BP_VAR_R); - zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_R TSRMLS_CC); - FREE_OP2(); - if (OP1_TYPE == IS_VAR && !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { - FREE_OP1_VAR_PTR_FAST(); - } } - CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -1246,13 +1233,13 @@ ZEND_VM_HANDLER(90, ZEND_FETCH_DIM_IS, VAR|CV, CONST|TMP|VAR|CV) { USE_OPLINE zend_free_op free_op1, free_op2; - zval **container; + zval *container; SAVE_OPLINE(); - container = GET_OP1_ZVAL_PTR_PTR_FAST(BP_VAR_IS); + container = GET_OP1_ZVAL_PTR(BP_VAR_IS); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_IS TSRMLS_CC); FREE_OP2(); - FREE_OP1_VAR_PTR_FAST(); + FREE_OP1(); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -1261,12 +1248,11 @@ ZEND_VM_HANDLER(93, ZEND_FETCH_DIM_FUNC_ARG, VAR|CV, CONST|TMP|VAR|UNUSED|CV) { USE_OPLINE zend_free_op free_op1, free_op2; - zval **container; SAVE_OPLINE(); - if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) { - container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W); + if (zend_is_by_ref_func_arg_fetch(opline, EX(call) TSRMLS_CC)) { + zval **container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W); if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } @@ -1277,13 +1263,15 @@ ZEND_VM_HANDLER(93, ZEND_FETCH_DIM_FUNC_ARG, VAR|CV, CONST|TMP|VAR|UNUSED|CV) FREE_OP2(); FREE_OP1_VAR_PTR(); } else { + zval *container; + if (OP2_TYPE == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } - container = GET_OP1_ZVAL_PTR_PTR_FAST(BP_VAR_R); + container = GET_OP1_ZVAL_PTR(BP_VAR_R); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_R TSRMLS_CC); FREE_OP2(); - FREE_OP1_VAR_PTR_FAST(); + FREE_OP1(); } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -1346,7 +1334,7 @@ ZEND_VM_HELPER(zend_fetch_property_address_read_helper, VAR|UNUSED|CV, CONST|TMP UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { zend_error(E_NOTICE, "Trying to get property of non-object"); PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); FREE_OP2(); } else { zval *retval; @@ -1359,7 +1347,7 @@ ZEND_VM_HELPER(zend_fetch_property_address_read_helper, VAR|UNUSED|CV, CONST|TMP retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); PZVAL_LOCK(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; if (IS_OP2_TMP_FREE()) { zval_ptr_dtor(&offset); @@ -1388,11 +1376,6 @@ ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|CV, CONST|TMP|VAR|CV) SAVE_OPLINE(); property = GET_OP2_ZVAL_PTR(BP_VAR_R); - if (OP1_TYPE == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) { - PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); - EX_T(opline->op1.var).var.ptr = *EX_T(opline->op1.var).var.ptr_ptr; - } - if (IS_OP2_TMP_FREE()) { MAKE_REAL_ZVAL_PTR(property); } @@ -1473,7 +1456,7 @@ ZEND_VM_HANDLER(91, ZEND_FETCH_OBJ_IS, VAR|UNUSED|CV, CONST|TMP|VAR|CV) if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); FREE_OP2(); } else { zval *retval; @@ -1486,7 +1469,7 @@ ZEND_VM_HANDLER(91, ZEND_FETCH_OBJ_IS, VAR|UNUSED|CV, CONST|TMP|VAR|CV) retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); PZVAL_LOCK(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; if (IS_OP2_TMP_FREE()) { zval_ptr_dtor(&offset); @@ -1504,7 +1487,7 @@ ZEND_VM_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, VAR|UNUSED|CV, CONST|TMP|VAR|CV) { USE_OPLINE - if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) { + if (zend_is_by_ref_func_arg_fetch(opline, EX(call) TSRMLS_CC)) { /* Behave like FETCH_OBJ_W */ zend_free_op free_op1, free_op2; zval *property; @@ -1591,13 +1574,13 @@ ZEND_VM_HANDLER(98, ZEND_FETCH_DIM_TMP_VAR, CONST|TMP, CONST) if (UNEXPECTED(Z_TYPE_P(container) != IS_ARRAY)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } else { zend_free_op free_op2; zval *value = *zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_R TSRMLS_CC); PZVAL_LOCK(value); - AI_SET_PTR(&EX_T(opline->result.var), value); + EX_T(opline->result.var).var.ptr = value; FREE_OP2(); } CHECK_EXCEPTION(); @@ -1678,11 +1661,11 @@ ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMP|VAR|UNUSED|CV) ALLOC_ZVAL(retval); ZVAL_STRINGL(retval, Z_STRVAL_P(EX_T((opline+1)->op2.var).str_offset.str)+EX_T((opline+1)->op2.var).str_offset.offset, 1, 1); INIT_PZVAL(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; } } else if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } } else if (UNEXPECTED(*variable_ptr_ptr == &EG(error_zval))) { if (IS_TMP_FREE(free_op_data1)) { @@ -1690,7 +1673,7 @@ ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMP|VAR|UNUSED|CV) } if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } } else { if ((opline+1)->op1_type == IS_TMP_VAR) { @@ -1702,7 +1685,7 @@ ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMP|VAR|UNUSED|CV) } if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(value); - AI_SET_PTR(&EX_T(opline->result.var), value); + EX_T(opline->result.var).var.ptr = value; } } FREE_OP_VAR_PTR(free_op_data2); @@ -1734,11 +1717,11 @@ ZEND_VM_HANDLER(38, ZEND_ASSIGN, VAR|CV, CONST|TMP|VAR|CV) ALLOC_ZVAL(retval); ZVAL_STRINGL(retval, Z_STRVAL_P(EX_T(opline->op1.var).str_offset.str)+EX_T(opline->op1.var).str_offset.offset, 1, 1); INIT_PZVAL(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; } } else if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } } else if (OP1_TYPE == IS_VAR && UNEXPECTED(*variable_ptr_ptr == &EG(error_zval))) { if (IS_OP2_TMP_FREE()) { @@ -1746,7 +1729,7 @@ ZEND_VM_HANDLER(38, ZEND_ASSIGN, VAR|CV, CONST|TMP|VAR|CV) } if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } } else { if (OP2_TYPE == IS_TMP_VAR) { @@ -1758,7 +1741,7 @@ ZEND_VM_HANDLER(38, ZEND_ASSIGN, VAR|CV, CONST|TMP|VAR|CV) } if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(value); - AI_SET_PTR(&EX_T(opline->result.var), value); + EX_T(opline->result.var).var.ptr = value; } } @@ -1815,7 +1798,7 @@ ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VAR|CV, VAR|CV) if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*variable_ptr_ptr); - AI_SET_PTR(&EX_T(opline->result.var), *variable_ptr_ptr); + EX_T(opline->result.var).var.ptr = *variable_ptr_ptr; } FREE_OP1_VAR_PTR(); @@ -1918,6 +1901,7 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY) USE_OPLINE zend_bool should_change_scope = 0; zend_function *fbc = EX(function_state).function; + zend_uint num_args; SAVE_OPLINE(); EX(object) = EX(call)->object; @@ -1962,19 +1946,18 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY) EG(called_scope) = EX(call)->called_scope; } + num_args = opline->extended_value + EX(call)->num_additional_args; EX(function_state).arguments = zend_vm_stack_top(TSRMLS_C); - zend_vm_stack_push((void*)(zend_uintptr_t)opline->extended_value TSRMLS_CC); + zend_vm_stack_push((void*)(zend_uintptr_t) num_args TSRMLS_CC); LOAD_OPLINE(); if (fbc->type == ZEND_INTERNAL_FUNCTION) { - if (fbc->common.arg_info) { - zend_uint i=0; - zval **p = (zval**)EX(function_state).arguments; - ulong arg_count = opline->extended_value; - - while (arg_count>0) { - zend_verify_arg_type(fbc, ++i, *(p-arg_count), 0 TSRMLS_CC); - arg_count--; + if (fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) { + zend_uint i; + void **p = EX(function_state).arguments - num_args; + + for (i = 0; i < num_args; ++i, ++p) { + zend_verify_arg_type(fbc, i + 1, (zval *) *p, 0 TSRMLS_CC); } } @@ -1988,7 +1971,7 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY) if (!zend_execute_internal) { /* saves one function call if zend_execute_internal is not used */ - fbc->internal_function.handler(opline->extended_value, ret->var.ptr, &ret->var.ptr, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC); + fbc->internal_function.handler(num_args, ret->var.ptr, &ret->var.ptr, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC); } else { zend_execute_internal(execute_data, NULL, RETURN_VALUE_USED(opline) TSRMLS_CC); } @@ -2038,7 +2021,7 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY) /* Not sure what should be done here if it's a static method */ if (EXPECTED(EX(object) != NULL)) { - Z_OBJ_HT_P(EX(object))->call_method(fbc->common.function_name, opline->extended_value, EX_T(opline->result.var).var.ptr, &EX_T(opline->result.var).var.ptr, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC); + Z_OBJ_HT_P(EX(object))->call_method(fbc->common.function_name, num_args, EX_T(opline->result.var).var.ptr, &EX_T(opline->result.var).var.ptr, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC); } else { zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object"); } @@ -2117,7 +2100,7 @@ ZEND_VM_HANDLER(43, ZEND_JMPZ, CONST|TMP|VAR|CV, ANY) if (OP1_TYPE == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) { ret = Z_LVAL_P(val); } else { - ret = i_zend_is_true(val); + ret = i_zend_is_true(val TSRMLS_CC); FREE_OP1(); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); @@ -2147,7 +2130,7 @@ ZEND_VM_HANDLER(44, ZEND_JMPNZ, CONST|TMP|VAR|CV, ANY) if (OP1_TYPE == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) { ret = Z_LVAL_P(val); } else { - ret = i_zend_is_true(val); + ret = i_zend_is_true(val TSRMLS_CC); FREE_OP1(); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); @@ -2177,7 +2160,7 @@ ZEND_VM_HANDLER(45, ZEND_JMPZNZ, CONST|TMP|VAR|CV, ANY) if (OP1_TYPE == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) { retval = Z_LVAL_P(val); } else { - retval = i_zend_is_true(val); + retval = i_zend_is_true(val TSRMLS_CC); FREE_OP1(); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); @@ -2211,7 +2194,7 @@ ZEND_VM_HANDLER(46, ZEND_JMPZ_EX, CONST|TMP|VAR|CV, ANY) if (OP1_TYPE == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) { retval = Z_LVAL_P(val); } else { - retval = i_zend_is_true(val); + retval = i_zend_is_true(val TSRMLS_CC); FREE_OP1(); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); @@ -2242,7 +2225,7 @@ ZEND_VM_HANDLER(47, ZEND_JMPNZ_EX, CONST|TMP|VAR|CV, ANY) if (OP1_TYPE == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) { retval = Z_LVAL_P(val); } else { - retval = i_zend_is_true(val); + retval = i_zend_is_true(val TSRMLS_CC); FREE_OP1(); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); @@ -2492,6 +2475,8 @@ ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV) call->object = this_ptr; } } + + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; @@ -2618,6 +2603,8 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, CONST|VAR, CONST|TMP|VAR|UNUS call->called_scope = Z_OBJCE_P(call->object); } } + + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; @@ -2641,10 +2628,13 @@ ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMP|VAR|CV) } else { CACHE_PTR(opline->op2.literal->cache_slot, call->fbc); } + call->object = NULL; call->called_scope = NULL; + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; + /*CHECK_EXCEPTION();*/ ZEND_VM_NEXT_OPCODE(); } else { @@ -2669,10 +2659,13 @@ ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMP|VAR|CV) } efree(lcname); FREE_OP2(); + call->object = NULL; call->called_scope = NULL; + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; + CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } else if (OP2_TYPE != IS_CONST && OP2_TYPE != IS_TMP_VAR && @@ -2689,8 +2682,11 @@ ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMP|VAR|CV) } else { FREE_OP2(); } + + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; + CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } else if (OP2_TYPE != IS_CONST && @@ -2756,8 +2752,11 @@ ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMP|VAR|CV) if (UNEXPECTED(call->fbc == NULL)) { zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, Z_STRVAL_PP(method)); } + + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; + FREE_OP2(); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -2795,7 +2794,9 @@ ZEND_VM_HANDLER(69, ZEND_INIT_NS_FCALL_BY_NAME, ANY, CONST) call->object = NULL; call->called_scope = NULL; + call->num_additional_args = 0; call->is_ctor_call = 0; + EX(call) = call; ZEND_VM_NEXT_OPCODE(); } @@ -2821,9 +2822,11 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, CONST, ANY) } else { CACHE_PTR(opline->op1.literal->cache_slot, EX(function_state).function); } + call->fbc = EX(function_state).function; call->object = NULL; call->called_scope = NULL; + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; @@ -2885,7 +2888,8 @@ ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY) SAVE_OPLINE(); do { - if (OP1_TYPE == IS_CONST || OP1_TYPE == IS_TMP_VAR) { + if (OP1_TYPE == IS_CONST || OP1_TYPE == IS_TMP_VAR || + (OP1_TYPE == IS_VAR && opline->extended_value == ZEND_RETURNS_VALUE)) { /* Not supposed to happen, but we'll allow it */ zend_error(E_NOTICE, "Only variable references should be returned by reference"); @@ -3054,10 +3058,13 @@ ZEND_VM_HANDLER(65, ZEND_SEND_VAL, CONST|TMP, ANY) USE_OPLINE SAVE_OPLINE(); - if (opline->extended_value==ZEND_DO_FCALL_BY_NAME - && ARG_MUST_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.opline_num)) { - zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.opline_num); + if (opline->extended_value == ZEND_DO_FCALL_BY_NAME) { + int arg_num = opline->op2.num + EX(call)->num_additional_args; + if (ARG_MUST_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { + zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", arg_num); + } } + { zval *valptr; zval *value; @@ -3115,14 +3122,18 @@ ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR|CV, ANY) USE_OPLINE zend_free_op free_op1; zval *varptr; + int arg_num; SAVE_OPLINE(); if (opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) { /* Had function_ptr at compile_time */ if (!(opline->extended_value & ZEND_ARG_SEND_BY_REF)) { ZEND_VM_DISPATCH_TO_HELPER(zend_send_by_var_helper); } - } else if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.opline_num)) { - ZEND_VM_DISPATCH_TO_HELPER(zend_send_by_var_helper); + } else { + arg_num = opline->op2.num + EX(call)->num_additional_args; + if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { + ZEND_VM_DISPATCH_TO_HELPER(zend_send_by_var_helper); + } } varptr = GET_OP1_ZVAL_PTR(BP_VAR_R); @@ -3140,7 +3151,7 @@ ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR|CV, ANY) if ((opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) ? !(opline->extended_value & ZEND_ARG_SEND_SILENT) : - !ARG_MAY_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.opline_num)) { + !ARG_MAY_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { zend_error(E_STRICT, "Only variables should be passed by reference"); } ALLOC_ZVAL(valptr); @@ -3177,9 +3188,11 @@ ZEND_VM_HANDLER(67, ZEND_SEND_REF, VAR|CV, ANY) } if (opline->extended_value == ZEND_DO_FCALL_BY_NAME && - EX(function_state).function->type == ZEND_INTERNAL_FUNCTION && - !ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.opline_num)) { - ZEND_VM_DISPATCH_TO_HELPER(zend_send_by_var_helper); + EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) { + int arg_num = opline->op2.num + EX(call)->num_additional_args; + if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { + ZEND_VM_DISPATCH_TO_HELPER(zend_send_by_var_helper); + } } SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr_ptr); @@ -3196,14 +3209,164 @@ ZEND_VM_HANDLER(66, ZEND_SEND_VAR, VAR|CV, ANY) { USE_OPLINE - if ((opline->extended_value == ZEND_DO_FCALL_BY_NAME) - && ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.opline_num)) { - ZEND_VM_DISPATCH_TO_HANDLER(ZEND_SEND_REF); + if (opline->extended_value == ZEND_DO_FCALL_BY_NAME) { + int arg_num = opline->op2.num + EX(call)->num_additional_args; + if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { + ZEND_VM_DISPATCH_TO_HANDLER(ZEND_SEND_REF); + } } SAVE_OPLINE(); ZEND_VM_DISPATCH_TO_HELPER(zend_send_by_var_helper); } +ZEND_VM_HANDLER(165, ZEND_SEND_UNPACK, ANY, ANY) +{ + USE_OPLINE + zend_free_op free_op1; + zval *args; + int arg_num; + SAVE_OPLINE(); + + args = GET_OP1_ZVAL_PTR(BP_VAR_R); + arg_num = opline->op2.num + EX(call)->num_additional_args + 1; + + switch (Z_TYPE_P(args)) { + case IS_ARRAY: { + HashTable *ht = Z_ARRVAL_P(args); + HashPosition pos; + zval **arg_ptr, *arg; + + ZEND_VM_STACK_GROW_IF_NEEDED(zend_hash_num_elements(ht)); + + for (zend_hash_internal_pointer_reset_ex(ht, &pos); + zend_hash_get_current_data_ex(ht, (void **) &arg_ptr, &pos) == SUCCESS; + zend_hash_move_forward_ex(ht, &pos), ++arg_num + ) { + char *name; + zend_uint name_len; + zend_ulong index; + + if (zend_hash_get_current_key_ex(ht, &name, &name_len, &index, 0, &pos) == HASH_KEY_IS_STRING) { + zend_error(E_RECOVERABLE_ERROR, "Cannot unpack array with string keys"); + FREE_OP1(); + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); + } + + if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { + SEPARATE_ZVAL_TO_MAKE_IS_REF(arg_ptr); + arg = *arg_ptr; + Z_ADDREF_P(arg); + } else if (Z_ISREF_PP(arg_ptr)) { + ALLOC_ZVAL(arg); + MAKE_COPY_ZVAL(arg_ptr, arg); + } else { + arg = *arg_ptr; + Z_ADDREF_P(arg); + } + + zend_vm_stack_push(arg TSRMLS_CC); + EX(call)->num_additional_args++; + } + break; + } + case IS_OBJECT: { + zend_class_entry *ce = Z_OBJCE_P(args); + zend_object_iterator *iter; + + if (!ce || !ce->get_iterator) { + zend_error(E_WARNING, "Only arrays and Traversables can be unpacked"); + break; + } + + iter = ce->get_iterator(ce, args, 0 TSRMLS_CC); + if (UNEXPECTED(!iter)) { + FREE_OP1(); + if (!EG(exception)) { + zend_throw_exception_ex( + NULL, 0 TSRMLS_CC, "Object of type %s did not create an Iterator", ce->name + ); + } + HANDLE_EXCEPTION(); + } + + if (iter->funcs->rewind) { + iter->funcs->rewind(iter TSRMLS_CC); + if (UNEXPECTED(EG(exception) != NULL)) { + ZEND_VM_C_GOTO(unpack_iter_dtor); + } + } + + for (; iter->funcs->valid(iter TSRMLS_CC) == SUCCESS; ++arg_num) { + zval **arg_ptr, *arg; + + if (UNEXPECTED(EG(exception) != NULL)) { + ZEND_VM_C_GOTO(unpack_iter_dtor); + } + + iter->funcs->get_current_data(iter, &arg_ptr TSRMLS_CC); + if (UNEXPECTED(EG(exception) != NULL)) { + ZEND_VM_C_GOTO(unpack_iter_dtor); + } + + if (iter->funcs->get_current_key) { + zval key; + iter->funcs->get_current_key(iter, &key TSRMLS_CC); + if (UNEXPECTED(EG(exception) != NULL)) { + ZEND_VM_C_GOTO(unpack_iter_dtor); + } + + if (Z_TYPE(key) == IS_STRING) { + zend_error(E_RECOVERABLE_ERROR, + "Cannot unpack Traversable with string keys"); + zval_dtor(&key); + ZEND_VM_C_GOTO(unpack_iter_dtor); + } + + zval_dtor(&key); + } + + if (ARG_MUST_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { + zend_error( + E_WARNING, "Cannot pass by-reference argument %d of %s%s%s()" + " by unpacking a Traversable, passing by-value instead", arg_num, + EX(call)->fbc->common.scope ? EX(call)->fbc->common.scope->name : "", + EX(call)->fbc->common.scope ? "::" : "", + EX(call)->fbc->common.function_name + ); + } + + if (Z_ISREF_PP(arg_ptr)) { + ALLOC_ZVAL(arg); + MAKE_COPY_ZVAL(arg_ptr, arg); + } else { + arg = *arg_ptr; + Z_ADDREF_P(arg); + } + + ZEND_VM_STACK_GROW_IF_NEEDED(1); + zend_vm_stack_push(arg TSRMLS_CC); + EX(call)->num_additional_args++; + + iter->funcs->move_forward(iter TSRMLS_CC); + if (UNEXPECTED(EG(exception) != NULL)) { + ZEND_VM_C_GOTO(unpack_iter_dtor); + } + } + +ZEND_VM_C_LABEL(unpack_iter_dtor): + iter->funcs->dtor(iter TSRMLS_CC); + break; + } + default: + zend_error(E_WARNING, "Only arrays and Traversables can be unpacked"); + } + + FREE_OP1(); + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + ZEND_VM_HANDLER(63, ZEND_RECV, ANY, ANY) { USE_OPLINE @@ -3257,8 +3420,7 @@ ZEND_VM_HANDLER(64, ZEND_RECV_INIT, ANY, CONST) if (param == NULL) { ALLOC_ZVAL(assignment_value); *assignment_value = *opline->op2.zv; - if ((Z_TYPE_P(assignment_value) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT || - Z_TYPE_P(assignment_value)==IS_CONSTANT_ARRAY) { + if (IS_CONSTANT_TYPE(Z_TYPE_P(assignment_value))) { Z_SET_REFCOUNT_P(assignment_value, 1); zval_update_constant(&assignment_value, 0 TSRMLS_CC); } else { @@ -3279,6 +3441,37 @@ ZEND_VM_HANDLER(64, ZEND_RECV_INIT, ANY, CONST) ZEND_VM_NEXT_OPCODE(); } +ZEND_VM_HANDLER(164, ZEND_RECV_VARIADIC, ANY, ANY) +{ + USE_OPLINE + zend_uint arg_num = opline->op1.num; + zend_uint arg_count = zend_vm_stack_get_args_count(TSRMLS_C); + zval **var_ptr, *params; + + SAVE_OPLINE(); + + var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC); + Z_DELREF_PP(var_ptr); + MAKE_STD_ZVAL(params); + *var_ptr = params; + + if (arg_num <= arg_count) { + array_init_size(params, arg_count - arg_num + 1); + } else { + array_init(params); + } + + for (; arg_num <= arg_count; ++arg_num) { + zval **param = zend_vm_stack_get_arg(arg_num TSRMLS_CC); + zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, *param, opline->extended_value TSRMLS_CC); + zend_hash_next_index_insert(Z_ARRVAL_P(params), param, sizeof(zval *), NULL); + Z_ADDREF_PP(param); + } + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + ZEND_VM_HANDLER(52, ZEND_BOOL, CONST|TMP|VAR|CV, ANY) { USE_OPLINE @@ -3287,7 +3480,7 @@ ZEND_VM_HANDLER(52, ZEND_BOOL, CONST|TMP|VAR|CV, ANY) SAVE_OPLINE(); /* PHP 3.0 returned "" for false and 1 for true, here we use 0 and 1 for now */ - ZVAL_BOOL(retval, i_zend_is_true(GET_OP1_ZVAL_PTR(BP_VAR_R))); + ZVAL_BOOL(retval, i_zend_is_true(GET_OP1_ZVAL_PTR(BP_VAR_R) TSRMLS_CC)); FREE_OP1(); CHECK_EXCEPTION(); @@ -3409,6 +3602,7 @@ ZEND_VM_HANDLER(68, ZEND_NEW, ANY, ANY) call->fbc = constructor; call->object = object_zval; call->called_scope = EX_T(opline->op1.var).class_entry; + call->num_additional_args = 0; call->is_ctor_call = 1; call->is_ctor_result_used = RETURN_VALUE_USED(opline); EX(call) = call; @@ -3476,7 +3670,7 @@ ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMP|VAR|UNUSED|CV, ANY) if (!RETURN_VALUE_USED(opline) || UNEXPECTED(EG(exception) != NULL)) { zval_ptr_dtor(&retval); } else { - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; } } FREE_OP1_IF_VAR(); @@ -3554,8 +3748,7 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, VAR|CONST|UNUSED, CONST) } if (EXPECTED(zend_hash_quick_find(&ce->constants_table, Z_STRVAL_P(opline->op2.zv), Z_STRLEN_P(opline->op2.zv)+1, Z_HASH_P(opline->op2.zv), (void **) &value) == SUCCESS)) { - if (Z_TYPE_PP(value) == IS_CONSTANT_ARRAY || - (Z_TYPE_PP(value) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) { + if (IS_CONSTANT_TYPE(Z_TYPE_PP(value))) { zend_class_entry *old_scope = EG(scope); EG(scope) = ce; @@ -3569,7 +3762,7 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, VAR|CONST|UNUSED, CONST) } ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, *value); zval_copy_ctor(&EX_T(opline->result.var).tmp_var); - } else if (Z_STRLEN_P(opline->op2.zv) == sizeof("class")-1 && strcmp(Z_STRVAL_P(opline->op2.zv), "class") == 0) { + } else if (Z_STRLEN_P(opline->op2.zv) == sizeof("class")-1 && memcmp(Z_STRVAL_P(opline->op2.zv), "class", sizeof("class") - 1) == 0) { /* "class" is assigned as a case-sensitive keyword from zend_do_resolve_class_name */ ZVAL_STRINGL(&EX_T(opline->result.var).tmp_var, ce->name, ce->name_length, 1); } else { @@ -3826,7 +4019,6 @@ ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMP|VAR|CV, ANY) EX(original_return_value) = EG(return_value_ptr_ptr); EG(active_op_array) = new_op_array; if (RETURN_VALUE_USED(opline)) { - EX_T(opline->result.var).var.ptr = NULL; EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr; EG(return_value_ptr_ptr) = EX_T(opline->result.var).var.ptr_ptr; } else { @@ -3864,7 +4056,7 @@ ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMP|VAR|CV, ANY) ALLOC_ZVAL(retval); ZVAL_BOOL(retval, failure_retval); INIT_PZVAL(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; } ZEND_VM_NEXT_OPCODE(); } @@ -4369,7 +4561,7 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY) Z_ADDREF_PP(value); } else { PZVAL_LOCK(*value); - AI_SET_PTR(&EX_T(opline->result.var), *value); + EX_T(opline->result.var).var.ptr = *value; } CHECK_EXCEPTION(); @@ -4451,7 +4643,7 @@ ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMP|VAR|CV, UNUSED|CONST|VAR) ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 0); } } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - if (!isset || !i_zend_is_true(*value)) { + if (!isset || !i_zend_is_true(*value TSRMLS_CC)) { ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 1); } else { ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 0); @@ -4466,22 +4658,21 @@ ZEND_VM_HELPER_EX(zend_isset_isempty_dim_prop_obj_handler, VAR|UNUSED|CV, CONST| { USE_OPLINE zend_free_op free_op1, free_op2; - zval **container; + zval *container; zval **value = NULL; int result = 0; ulong hval; zval *offset; SAVE_OPLINE(); - container = GET_OP1_OBJ_ZVAL_PTR_PTR_FAST(BP_VAR_IS); - + container = GET_OP1_OBJ_ZVAL_PTR(BP_VAR_IS); offset = GET_OP2_ZVAL_PTR(BP_VAR_R); - if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) { + if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) { HashTable *ht; int isset = 0; - ht = Z_ARRVAL_PP(container); + ht = Z_ARRVAL_P(container); switch (Z_TYPE_P(offset)) { case IS_DOUBLE: @@ -4500,9 +4691,7 @@ ZEND_VM_C_LABEL(num_index_prop): if (OP2_TYPE == IS_CONST) { hval = Z_HASH_P(offset); } else { - if (!prop_dim) { - ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, ZEND_VM_C_GOTO(num_index_prop)); - } + ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, ZEND_VM_C_GOTO(num_index_prop)); hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } if (zend_hash_quick_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, (void **) &value) == SUCCESS) { @@ -4526,27 +4715,27 @@ ZEND_VM_C_LABEL(num_index_prop): result = isset; } } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - if (!isset || !i_zend_is_true(*value)) { + if (!isset || !i_zend_is_true(*value TSRMLS_CC)) { result = 0; } else { result = 1; } } FREE_OP2(); - } else if (Z_TYPE_PP(container) == IS_OBJECT) { + } else if (Z_TYPE_P(container) == IS_OBJECT) { if (IS_OP2_TMP_FREE()) { MAKE_REAL_ZVAL_PTR(offset); } if (prop_dim) { - if (Z_OBJ_HT_P(*container)->has_property) { - result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + if (Z_OBJ_HT_P(container)->has_property) { + result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); } else { zend_error(E_NOTICE, "Trying to check property of non-object"); result = 0; } } else { - if (Z_OBJ_HT_P(*container)->has_dimension) { - result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC); + if (Z_OBJ_HT_P(container)->has_dimension) { + result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC); } else { zend_error(E_NOTICE, "Trying to check element of non-array"); result = 0; @@ -4557,7 +4746,7 @@ ZEND_VM_C_LABEL(num_index_prop): } else { FREE_OP2(); } - } else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */ + } else if (Z_TYPE_P(container) == IS_STRING && !prop_dim) { /* string offsets */ zval tmp; if (Z_TYPE_P(offset) != IS_LONG) { @@ -4575,11 +4764,11 @@ ZEND_VM_C_LABEL(num_index_prop): } if (Z_TYPE_P(offset) == IS_LONG) { if (opline->extended_value & ZEND_ISSET) { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) { + if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) { result = 1; } } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') { + if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container) && Z_STRVAL_P(container)[offset->value.lval] != '0') { result = 1; } } @@ -4596,7 +4785,7 @@ ZEND_VM_C_LABEL(num_index_prop): Z_LVAL(EX_T(opline->result.var).tmp_var) = !result; } - FREE_OP1_VAR_PTR_FAST(); + FREE_OP1_IF_VAR(); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -4720,7 +4909,7 @@ ZEND_VM_HANDLER(152, ZEND_JMP_SET, CONST|TMP|VAR|CV, ANY) SAVE_OPLINE(); value = GET_OP1_ZVAL_PTR(BP_VAR_R); - if (i_zend_is_true(value)) { + if (i_zend_is_true(value TSRMLS_CC)) { ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, value); if (!IS_OP1_TMP_FREE()) { zendi_zval_copy_ctor(EX_T(opline->result.var).tmp_var); @@ -4746,7 +4935,7 @@ ZEND_VM_HANDLER(158, ZEND_JMP_SET_VAR, CONST|TMP|VAR|CV, ANY) SAVE_OPLINE(); value = GET_OP1_ZVAL_PTR(BP_VAR_R); - if (i_zend_is_true(value)) { + if (i_zend_is_true(value TSRMLS_CC)) { if (OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) { Z_ADDREF_P(value); EX_T(opline->result.var).var.ptr = value; @@ -4901,7 +5090,7 @@ ZEND_VM_HANDLER(105, ZEND_TICKS, ANY, ANY) if (++EG(ticks_count)>=opline->extended_value) { EG(ticks_count)=0; if (zend_ticks_function) { - zend_ticks_function(opline->extended_value); + zend_ticks_function(opline->extended_value TSRMLS_CC); } } CHECK_EXCEPTION(); @@ -5011,7 +5200,7 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY) { zend_uint op_num = EG(opline_before_exception)-EG(active_op_array)->opcodes; int i; - zend_uint catch_op_num = 0, finally_op_num = 0; + zend_uint catch_op_num = 0, finally_op_num = 0, finally_op_end = 0; void **stack_frame; /* Figure out where the next stack frame (which maybe contains pushed @@ -5036,6 +5225,10 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY) if (op_num < EG(active_op_array)->try_catch_array[i].finally_op) { finally_op_num = EX(op_array)->try_catch_array[i].finally_op; } + if (op_num >= EG(active_op_array)->try_catch_array[i].finally_op && + op_num < EG(active_op_array)->try_catch_array[i].finally_end) { + finally_op_end = EG(active_op_array)->try_catch_array[i].finally_end; + } } if (EX(call) >= EX(call_slots)) { @@ -5097,14 +5290,29 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY) EX(old_error_reporting) = NULL; if (finally_op_num && (!catch_op_num || catch_op_num >= finally_op_num)) { - zend_exception_save(TSRMLS_C); + if (EX(delayed_exception)) { + zend_exception_set_previous(EG(exception), EX(delayed_exception) TSRMLS_CC); + } + EX(delayed_exception) = EG(exception); + EG(exception) = NULL; EX(fast_ret) = NULL; ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]); ZEND_VM_CONTINUE(); } else if (catch_op_num) { + if (finally_op_end && catch_op_num > finally_op_end) { + /* we are going out of current finally scope */ + if (EX(delayed_exception)) { + zend_exception_set_previous(EG(exception), EX(delayed_exception) TSRMLS_CC); + EX(delayed_exception) = NULL; + } + } ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]); ZEND_VM_CONTINUE(); } else { + if (EX(delayed_exception)) { + zend_exception_set_previous(EG(exception), EX(delayed_exception) TSRMLS_CC); + EX(delayed_exception) = NULL; + } if (UNEXPECTED((EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) != 0)) { ZEND_VM_DISPATCH_TO_HANDLER(ZEND_GENERATOR_RETURN); } else { @@ -5164,7 +5372,7 @@ ZEND_VM_HANDLER(143, ZEND_DECLARE_CONST, CONST, CONST) name = GET_OP1_ZVAL_PTR(BP_VAR_R); val = GET_OP2_ZVAL_PTR(BP_VAR_R); - if ((Z_TYPE_P(val) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT || Z_TYPE_P(val) == IS_CONSTANT_ARRAY) { + if (IS_CONSTANT_TYPE(Z_TYPE_P(val))) { zval tmp; zval *tmp_ptr = &tmp; @@ -5372,11 +5580,15 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSE ZVAL_LONG(generator->key, generator->largest_used_integer_key); } - /* If a value is sent it should go into the result var */ - generator->send_target = &EX_T(opline->result.var); - - /* Initialize the sent value to NULL */ - EX_T(opline->result.var).tmp_var = EG(uninitialized_zval); + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = &EX_T(opline->result.var).var.ptr; + Z_ADDREF(EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); + } else { + generator->send_target = NULL; + } /* We increment to the next op, so we are at the correct position when the * generator is resumed. */ @@ -5391,10 +5603,10 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSE ZEND_VM_HANDLER(159, ZEND_DISCARD_EXCEPTION, ANY, ANY) { - if (EG(prev_exception) != NULL) { + if (EX(delayed_exception) != NULL) { /* discard the previously thrown exception */ - zval_ptr_dtor(&EG(prev_exception)); - EG(prev_exception) = NULL; + zval_ptr_dtor(&EX(delayed_exception)); + EX(delayed_exception) = NULL; } ZEND_VM_NEXT_OPCODE(); @@ -5411,6 +5623,7 @@ ZEND_VM_HANDLER(162, ZEND_FAST_CALL, ANY, ANY) ZEND_VM_CONTINUE(); } EX(fast_ret) = opline + 1; + EX(delayed_exception) = NULL; ZEND_VM_SET_OPCODE(opline->op1.jmp_addr); ZEND_VM_CONTINUE(); } @@ -5427,16 +5640,17 @@ ZEND_VM_HANDLER(163, ZEND_FAST_RET, ANY, ANY) if (opline->extended_value == ZEND_FAST_RET_TO_FINALLY) { ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->op2.opline_num]); ZEND_VM_CONTINUE(); - } else if (opline->extended_value == ZEND_FAST_RET_TO_CATCH) { - zend_exception_restore(TSRMLS_C); - ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->op2.opline_num]); - ZEND_VM_CONTINUE(); - } else if (UNEXPECTED((EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) != 0)) { - zend_exception_restore(TSRMLS_C); - ZEND_VM_DISPATCH_TO_HANDLER(ZEND_GENERATOR_RETURN); } else { - zend_exception_restore(TSRMLS_C); - ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper); + EG(exception) = EX(delayed_exception); + EX(delayed_exception) = NULL; + if (opline->extended_value == ZEND_FAST_RET_TO_CATCH) { + ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->op2.opline_num]); + ZEND_VM_CONTINUE(); + } else if (UNEXPECTED((EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) != 0)) { + ZEND_VM_DISPATCH_TO_HANDLER(ZEND_GENERATOR_RETURN); + } else { + ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper); + } } } } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 677cabe2a947f..b356cad73b295 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -481,6 +481,7 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR USE_OPLINE zend_bool should_change_scope = 0; zend_function *fbc = EX(function_state).function; + zend_uint num_args; SAVE_OPLINE(); EX(object) = EX(call)->object; @@ -525,19 +526,18 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR EG(called_scope) = EX(call)->called_scope; } + num_args = opline->extended_value + EX(call)->num_additional_args; EX(function_state).arguments = zend_vm_stack_top(TSRMLS_C); - zend_vm_stack_push((void*)(zend_uintptr_t)opline->extended_value TSRMLS_CC); + zend_vm_stack_push((void*)(zend_uintptr_t) num_args TSRMLS_CC); LOAD_OPLINE(); if (fbc->type == ZEND_INTERNAL_FUNCTION) { - if (fbc->common.arg_info) { - zend_uint i=0; - zval **p = (zval**)EX(function_state).arguments; - ulong arg_count = opline->extended_value; + if (fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) { + zend_uint i; + void **p = EX(function_state).arguments - num_args; - while (arg_count>0) { - zend_verify_arg_type(fbc, ++i, *(p-arg_count), 0 TSRMLS_CC); - arg_count--; + for (i = 0; i < num_args; ++i, ++p) { + zend_verify_arg_type(fbc, i + 1, (zval *) *p, 0 TSRMLS_CC); } } @@ -551,7 +551,7 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR if (!zend_execute_internal) { /* saves one function call if zend_execute_internal is not used */ - fbc->internal_function.handler(opline->extended_value, ret->var.ptr, &ret->var.ptr, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC); + fbc->internal_function.handler(num_args, ret->var.ptr, &ret->var.ptr, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC); } else { zend_execute_internal(execute_data, NULL, RETURN_VALUE_USED(opline) TSRMLS_CC); } @@ -601,7 +601,7 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR /* Not sure what should be done here if it's a static method */ if (EXPECTED(EX(object) != NULL)) { - Z_OBJ_HT_P(EX(object))->call_method(fbc->common.function_name, opline->extended_value, EX_T(opline->result.var).var.ptr, &EX_T(opline->result.var).var.ptr, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC); + Z_OBJ_HT_P(EX(object))->call_method(fbc->common.function_name, num_args, EX_T(opline->result.var).var.ptr, &EX_T(opline->result.var).var.ptr, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC); } else { zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object"); } @@ -701,6 +701,154 @@ static int ZEND_FASTCALL ZEND_GENERATOR_RETURN_SPEC_HANDLER(ZEND_OPCODE_HANDLER ZEND_VM_RETURN(); } +static int ZEND_FASTCALL ZEND_SEND_UNPACK_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *args; + int arg_num; + SAVE_OPLINE(); + + args = get_zval_ptr(opline->op1_type, &opline->op1, execute_data, &free_op1, BP_VAR_R); + arg_num = opline->op2.num + EX(call)->num_additional_args + 1; + + switch (Z_TYPE_P(args)) { + case IS_ARRAY: { + HashTable *ht = Z_ARRVAL_P(args); + HashPosition pos; + zval **arg_ptr, *arg; + + ZEND_VM_STACK_GROW_IF_NEEDED(zend_hash_num_elements(ht)); + + for (zend_hash_internal_pointer_reset_ex(ht, &pos); + zend_hash_get_current_data_ex(ht, (void **) &arg_ptr, &pos) == SUCCESS; + zend_hash_move_forward_ex(ht, &pos), ++arg_num + ) { + char *name; + zend_uint name_len; + zend_ulong index; + + if (zend_hash_get_current_key_ex(ht, &name, &name_len, &index, 0, &pos) == HASH_KEY_IS_STRING) { + zend_error(E_RECOVERABLE_ERROR, "Cannot unpack array with string keys"); + FREE_OP(free_op1); + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); + } + + if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { + SEPARATE_ZVAL_TO_MAKE_IS_REF(arg_ptr); + arg = *arg_ptr; + Z_ADDREF_P(arg); + } else if (Z_ISREF_PP(arg_ptr)) { + ALLOC_ZVAL(arg); + MAKE_COPY_ZVAL(arg_ptr, arg); + } else { + arg = *arg_ptr; + Z_ADDREF_P(arg); + } + + zend_vm_stack_push(arg TSRMLS_CC); + EX(call)->num_additional_args++; + } + break; + } + case IS_OBJECT: { + zend_class_entry *ce = Z_OBJCE_P(args); + zend_object_iterator *iter; + + if (!ce || !ce->get_iterator) { + zend_error(E_WARNING, "Only arrays and Traversables can be unpacked"); + break; + } + + iter = ce->get_iterator(ce, args, 0 TSRMLS_CC); + if (UNEXPECTED(!iter)) { + FREE_OP(free_op1); + if (!EG(exception)) { + zend_throw_exception_ex( + NULL, 0 TSRMLS_CC, "Object of type %s did not create an Iterator", ce->name + ); + } + HANDLE_EXCEPTION(); + } + + if (iter->funcs->rewind) { + iter->funcs->rewind(iter TSRMLS_CC); + if (UNEXPECTED(EG(exception) != NULL)) { + goto unpack_iter_dtor; + } + } + + for (; iter->funcs->valid(iter TSRMLS_CC) == SUCCESS; ++arg_num) { + zval **arg_ptr, *arg; + + if (UNEXPECTED(EG(exception) != NULL)) { + goto unpack_iter_dtor; + } + + iter->funcs->get_current_data(iter, &arg_ptr TSRMLS_CC); + if (UNEXPECTED(EG(exception) != NULL)) { + goto unpack_iter_dtor; + } + + if (iter->funcs->get_current_key) { + zval key; + iter->funcs->get_current_key(iter, &key TSRMLS_CC); + if (UNEXPECTED(EG(exception) != NULL)) { + goto unpack_iter_dtor; + } + + if (Z_TYPE(key) == IS_STRING) { + zend_error(E_RECOVERABLE_ERROR, + "Cannot unpack Traversable with string keys"); + zval_dtor(&key); + goto unpack_iter_dtor; + } + + zval_dtor(&key); + } + + if (ARG_MUST_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { + zend_error( + E_WARNING, "Cannot pass by-reference argument %d of %s%s%s()" + " by unpacking a Traversable, passing by-value instead", arg_num, + EX(call)->fbc->common.scope ? EX(call)->fbc->common.scope->name : "", + EX(call)->fbc->common.scope ? "::" : "", + EX(call)->fbc->common.function_name + ); + } + + if (Z_ISREF_PP(arg_ptr)) { + ALLOC_ZVAL(arg); + MAKE_COPY_ZVAL(arg_ptr, arg); + } else { + arg = *arg_ptr; + Z_ADDREF_P(arg); + } + + ZEND_VM_STACK_GROW_IF_NEEDED(1); + zend_vm_stack_push(arg TSRMLS_CC); + EX(call)->num_additional_args++; + + iter->funcs->move_forward(iter TSRMLS_CC); + if (UNEXPECTED(EG(exception) != NULL)) { + goto unpack_iter_dtor; + } + } + +unpack_iter_dtor: + iter->funcs->dtor(iter TSRMLS_CC); + break; + } + default: + zend_error(E_WARNING, "Only arrays and Traversables can be unpacked"); + } + + FREE_OP(free_op1); + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + static int ZEND_FASTCALL ZEND_RECV_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -742,6 +890,37 @@ static int ZEND_FASTCALL ZEND_RECV_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) ZEND_VM_NEXT_OPCODE(); } +static int ZEND_FASTCALL ZEND_RECV_VARIADIC_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_uint arg_num = opline->op1.num; + zend_uint arg_count = zend_vm_stack_get_args_count(TSRMLS_C); + zval **var_ptr, *params; + + SAVE_OPLINE(); + + var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC); + Z_DELREF_PP(var_ptr); + MAKE_STD_ZVAL(params); + *var_ptr = params; + + if (arg_num <= arg_count) { + array_init_size(params, arg_count - arg_num + 1); + } else { + array_init(params); + } + + for (; arg_num <= arg_count; ++arg_num) { + zval **param = zend_vm_stack_get_arg(arg_num TSRMLS_CC); + zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, *param, opline->extended_value TSRMLS_CC); + zend_hash_next_index_insert(Z_ARRVAL_P(params), param, sizeof(zval *), NULL); + Z_ADDREF_PP(param); + } + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + static int ZEND_FASTCALL ZEND_NEW_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -783,6 +962,7 @@ static int ZEND_FASTCALL ZEND_NEW_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) call->fbc = constructor; call->object = object_zval; call->called_scope = EX_T(opline->op1.var).class_entry; + call->num_additional_args = 0; call->is_ctor_call = 1; call->is_ctor_result_used = RETURN_VALUE_USED(opline); EX(call) = call; @@ -923,7 +1103,7 @@ static int ZEND_FASTCALL ZEND_TICKS_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (++EG(ticks_count)>=opline->extended_value) { EG(ticks_count)=0; if (zend_ticks_function) { - zend_ticks_function(opline->extended_value); + zend_ticks_function(opline->extended_value TSRMLS_CC); } } CHECK_EXCEPTION(); @@ -985,7 +1165,7 @@ static int ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER { zend_uint op_num = EG(opline_before_exception)-EG(active_op_array)->opcodes; int i; - zend_uint catch_op_num = 0, finally_op_num = 0; + zend_uint catch_op_num = 0, finally_op_num = 0, finally_op_end = 0; void **stack_frame; /* Figure out where the next stack frame (which maybe contains pushed @@ -1010,6 +1190,10 @@ static int ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER if (op_num < EG(active_op_array)->try_catch_array[i].finally_op) { finally_op_num = EX(op_array)->try_catch_array[i].finally_op; } + if (op_num >= EG(active_op_array)->try_catch_array[i].finally_op && + op_num < EG(active_op_array)->try_catch_array[i].finally_end) { + finally_op_end = EG(active_op_array)->try_catch_array[i].finally_end; + } } if (EX(call) >= EX(call_slots)) { @@ -1071,14 +1255,29 @@ static int ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER EX(old_error_reporting) = NULL; if (finally_op_num && (!catch_op_num || catch_op_num >= finally_op_num)) { - zend_exception_save(TSRMLS_C); + if (EX(delayed_exception)) { + zend_exception_set_previous(EG(exception), EX(delayed_exception) TSRMLS_CC); + } + EX(delayed_exception) = EG(exception); + EG(exception) = NULL; EX(fast_ret) = NULL; ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]); ZEND_VM_CONTINUE(); } else if (catch_op_num) { + if (finally_op_end && catch_op_num > finally_op_end) { + /* we are going out of current finally scope */ + if (EX(delayed_exception)) { + zend_exception_set_previous(EG(exception), EX(delayed_exception) TSRMLS_CC); + EX(delayed_exception) = NULL; + } + } ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]); ZEND_VM_CONTINUE(); } else { + if (EX(delayed_exception)) { + zend_exception_set_previous(EG(exception), EX(delayed_exception) TSRMLS_CC); + EX(delayed_exception) = NULL; + } if (UNEXPECTED((EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) != 0)) { return ZEND_GENERATOR_RETURN_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } else { @@ -1128,10 +1327,10 @@ static int ZEND_FASTCALL ZEND_USER_OPCODE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS static int ZEND_FASTCALL ZEND_DISCARD_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - if (EG(prev_exception) != NULL) { + if (EX(delayed_exception) != NULL) { /* discard the previously thrown exception */ - zval_ptr_dtor(&EG(prev_exception)); - EG(prev_exception) = NULL; + zval_ptr_dtor(&EX(delayed_exception)); + EX(delayed_exception) = NULL; } ZEND_VM_NEXT_OPCODE(); @@ -1148,6 +1347,7 @@ static int ZEND_FASTCALL ZEND_FAST_CALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) ZEND_VM_CONTINUE(); } EX(fast_ret) = opline + 1; + EX(delayed_exception) = NULL; ZEND_VM_SET_OPCODE(opline->op1.jmp_addr); ZEND_VM_CONTINUE(); } @@ -1164,16 +1364,17 @@ static int ZEND_FASTCALL ZEND_FAST_RET_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (opline->extended_value == ZEND_FAST_RET_TO_FINALLY) { ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->op2.opline_num]); ZEND_VM_CONTINUE(); - } else if (opline->extended_value == ZEND_FAST_RET_TO_CATCH) { - zend_exception_restore(TSRMLS_C); - ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->op2.opline_num]); - ZEND_VM_CONTINUE(); - } else if (UNEXPECTED((EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) != 0)) { - zend_exception_restore(TSRMLS_C); - return ZEND_GENERATOR_RETURN_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } else { - zend_exception_restore(TSRMLS_C); - return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + EG(exception) = EX(delayed_exception); + EX(delayed_exception) = NULL; + if (opline->extended_value == ZEND_FAST_RET_TO_CATCH) { + ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->op2.opline_num]); + ZEND_VM_CONTINUE(); + } else if (UNEXPECTED((EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) != 0)) { + return ZEND_GENERATOR_RETURN_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + } else { + return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + } } } } @@ -1233,10 +1434,13 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE } else { CACHE_PTR(opline->op2.literal->cache_slot, call->fbc); } + call->object = NULL; call->called_scope = NULL; + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; + /*CHECK_EXCEPTION();*/ ZEND_VM_NEXT_OPCODE(); } else { @@ -1263,8 +1467,10 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE call->object = NULL; call->called_scope = NULL; + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; + CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } else if (IS_CONST != IS_CONST && IS_CONST != IS_TMP_VAR && @@ -1281,8 +1487,11 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE } else { } + + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; + CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } else if (IS_CONST != IS_CONST && @@ -1348,6 +1557,8 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE if (UNEXPECTED(call->fbc == NULL)) { zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, Z_STRVAL_PP(method)); } + + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; @@ -1387,7 +1598,9 @@ static int ZEND_FASTCALL ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPC call->object = NULL; call->called_scope = NULL; + call->num_additional_args = 0; call->is_ctor_call = 0; + EX(call) = call; ZEND_VM_NEXT_OPCODE(); } @@ -1404,8 +1617,7 @@ static int ZEND_FASTCALL ZEND_RECV_INIT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ if (param == NULL) { ALLOC_ZVAL(assignment_value); *assignment_value = *opline->op2.zv; - if ((Z_TYPE_P(assignment_value) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT || - Z_TYPE_P(assignment_value)==IS_CONSTANT_ARRAY) { + if (IS_CONSTANT_TYPE(Z_TYPE_P(assignment_value))) { Z_SET_REFCOUNT_P(assignment_value, 1); zval_update_constant(&assignment_value, 0 TSRMLS_CC); } else { @@ -1558,10 +1770,13 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_H } else { CACHE_PTR(opline->op2.literal->cache_slot, call->fbc); } + call->object = NULL; call->called_scope = NULL; + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; + /*CHECK_EXCEPTION();*/ ZEND_VM_NEXT_OPCODE(); } else { @@ -1586,10 +1801,13 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_H } efree(lcname); zval_dtor(free_op2.var); + call->object = NULL; call->called_scope = NULL; + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; + CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } else if (IS_TMP_VAR != IS_CONST && IS_TMP_VAR != IS_TMP_VAR && @@ -1606,8 +1824,11 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_H } else { zval_dtor(free_op2.var); } + + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; + CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } else if (IS_TMP_VAR != IS_CONST && @@ -1673,8 +1894,11 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_H if (UNEXPECTED(call->fbc == NULL)) { zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, Z_STRVAL_PP(method)); } + + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; + zval_dtor(free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -1723,7 +1947,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ zend_error_noreturn(E_ERROR, "Class name must be a valid object or a string"); } - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -1745,10 +1969,13 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_H } else { CACHE_PTR(opline->op2.literal->cache_slot, call->fbc); } + call->object = NULL; call->called_scope = NULL; + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; + /*CHECK_EXCEPTION();*/ ZEND_VM_NEXT_OPCODE(); } else { @@ -1772,11 +1999,14 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_H zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval); } efree(lcname); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); + call->object = NULL; call->called_scope = NULL; + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; + CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } else if (IS_VAR != IS_CONST && IS_VAR != IS_TMP_VAR && @@ -1791,10 +2021,13 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_H /* Delay closure destruction until its invocation */ call->fbc->common.prototype = (zend_function*)function_name; } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } + + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; + CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } else if (IS_VAR != IS_CONST && @@ -1860,9 +2093,12 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_H if (UNEXPECTED(call->fbc == NULL)) { zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, Z_STRVAL_PP(method)); } + + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; - zval_ptr_dtor(&free_op2.var); + + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } else { @@ -1970,10 +2206,13 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HA } else { CACHE_PTR(opline->op2.literal->cache_slot, call->fbc); } + call->object = NULL; call->called_scope = NULL; + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; + /*CHECK_EXCEPTION();*/ ZEND_VM_NEXT_OPCODE(); } else { @@ -2000,8 +2239,10 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HA call->object = NULL; call->called_scope = NULL; + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; + CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } else if (IS_CV != IS_CONST && IS_CV != IS_TMP_VAR && @@ -2018,8 +2259,11 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HA } else { } + + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; + CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } else if (IS_CV != IS_CONST && @@ -2085,6 +2329,8 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HA if (UNEXPECTED(call->fbc == NULL)) { zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, Z_STRVAL_PP(method)); } + + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; @@ -2166,7 +2412,7 @@ static int ZEND_FASTCALL ZEND_JMPZ_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (IS_CONST == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) { ret = Z_LVAL_P(val); } else { - ret = i_zend_is_true(val); + ret = i_zend_is_true(val TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); @@ -2196,7 +2442,7 @@ static int ZEND_FASTCALL ZEND_JMPNZ_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS if (IS_CONST == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) { ret = Z_LVAL_P(val); } else { - ret = i_zend_is_true(val); + ret = i_zend_is_true(val TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); @@ -2226,7 +2472,7 @@ static int ZEND_FASTCALL ZEND_JMPZNZ_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG if (IS_CONST == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) { retval = Z_LVAL_P(val); } else { - retval = i_zend_is_true(val); + retval = i_zend_is_true(val TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); @@ -2260,7 +2506,7 @@ static int ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR if (IS_CONST == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) { retval = Z_LVAL_P(val); } else { - retval = i_zend_is_true(val); + retval = i_zend_is_true(val TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); @@ -2291,7 +2537,7 @@ static int ZEND_FASTCALL ZEND_JMPNZ_EX_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A if (IS_CONST == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) { retval = Z_LVAL_P(val); } else { - retval = i_zend_is_true(val); + retval = i_zend_is_true(val TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); @@ -2324,9 +2570,11 @@ static int ZEND_FASTCALL ZEND_DO_FCALL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A } else { CACHE_PTR(opline->op1.literal->cache_slot, EX(function_state).function); } + call->fbc = EX(function_state).function; call->object = NULL; call->called_scope = NULL; + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; @@ -2386,7 +2634,8 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CONST_HANDLER(ZEND_OPCODE_HAND SAVE_OPLINE(); do { - if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR) { + if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR || + (IS_CONST == IS_VAR && opline->extended_value == ZEND_RETURNS_VALUE)) { /* Not supposed to happen, but we'll allow it */ zend_error(E_NOTICE, "Only variable references should be returned by reference"); @@ -2482,10 +2731,13 @@ static int ZEND_FASTCALL ZEND_SEND_VAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A USE_OPLINE SAVE_OPLINE(); - if (opline->extended_value==ZEND_DO_FCALL_BY_NAME - && ARG_MUST_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.opline_num)) { - zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.opline_num); + if (opline->extended_value == ZEND_DO_FCALL_BY_NAME) { + int arg_num = opline->op2.num + EX(call)->num_additional_args; + if (ARG_MUST_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { + zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", arg_num); + } } + { zval *valptr; zval *value; @@ -2513,7 +2765,7 @@ static int ZEND_FASTCALL ZEND_BOOL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); /* PHP 3.0 returned "" for false and 1 for true, here we use 0 and 1 for now */ - ZVAL_BOOL(retval, i_zend_is_true(opline->op1.zv)); + ZVAL_BOOL(retval, i_zend_is_true(opline->op1.zv TSRMLS_CC)); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -2577,7 +2829,7 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS if (!RETURN_VALUE_USED(opline) || UNEXPECTED(EG(exception) != NULL)) { zval_ptr_dtor(&retval); } else { - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; } } @@ -2735,7 +2987,6 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HA EX(original_return_value) = EG(return_value_ptr_ptr); EG(active_op_array) = new_op_array; if (RETURN_VALUE_USED(opline)) { - EX_T(opline->result.var).var.ptr = NULL; EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr; EG(return_value_ptr_ptr) = EX_T(opline->result.var).var.ptr_ptr; } else { @@ -2773,7 +3024,7 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HA ALLOC_ZVAL(retval); ZVAL_BOOL(retval, failure_retval); INIT_PZVAL(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; } ZEND_VM_NEXT_OPCODE(); } @@ -2971,7 +3222,7 @@ static int ZEND_FASTCALL ZEND_JMP_SET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); value = opline->op1.zv; - if (i_zend_is_true(value)) { + if (i_zend_is_true(value TSRMLS_CC)) { ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, value); if (!0) { zendi_zval_copy_ctor(EX_T(opline->result.var).tmp_var); @@ -2996,7 +3247,7 @@ static int ZEND_FASTCALL ZEND_JMP_SET_VAR_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLE SAVE_OPLINE(); value = opline->op1.zv; - if (i_zend_is_true(value)) { + if (i_zend_is_true(value TSRMLS_CC)) { if (IS_CONST == IS_VAR || IS_CONST == IS_CV) { Z_ADDREF_P(value); EX_T(opline->result.var).var.ptr = value; @@ -3451,7 +3702,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_CONST(int type switch (type) { case BP_VAR_R: case BP_VAR_IS: - AI_SET_PTR(&EX_T(opline->result.var), *retval); + EX_T(opline->result.var).var.ptr = *retval; break; case BP_VAR_UNSET: { zend_free_op free_res; @@ -3491,7 +3742,7 @@ static int ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_CONST_CONST_HANDLER(ZEND_OPCO { USE_OPLINE - return zend_fetch_var_address_helper_SPEC_CONST_CONST(ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + return zend_fetch_var_address_helper_SPEC_CONST_CONST(zend_is_by_ref_func_arg_fetch(opline, EX(call) TSRMLS_CC) ? BP_VAR_W : BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } static int ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -3508,24 +3759,15 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_ { USE_OPLINE - zval **container; + zval *container; SAVE_OPLINE(); + container = opline->op1.zv; + zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC); - if (IS_CONST == IS_TMP_VAR || IS_CONST == IS_CONST) { - zval *container = opline->op1.zv; - zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC); - - - } else { - container = NULL; - zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC); - - if (IS_CONST == IS_VAR && !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { + if (IS_CONST != IS_VAR || !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { - } } - CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -3541,13 +3783,13 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_TMP_VAR_SPEC_CONST_CONST_HANDLER(ZEND_O if (UNEXPECTED(Z_TYPE_P(container) != IS_ARRAY)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } else { zval *value = *zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC); PZVAL_LOCK(value); - AI_SET_PTR(&EX_T(opline->result.var), value); + EX_T(opline->result.var).var.ptr = value; } CHECK_EXCEPTION(); @@ -3670,6 +3912,8 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER( call->called_scope = Z_OBJCE_P(call->object); } } + + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; @@ -3761,8 +4005,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_CONST_CONST_HANDLER(ZEND_OPCO } if (EXPECTED(zend_hash_quick_find(&ce->constants_table, Z_STRVAL_P(opline->op2.zv), Z_STRLEN_P(opline->op2.zv)+1, Z_HASH_P(opline->op2.zv), (void **) &value) == SUCCESS)) { - if (Z_TYPE_PP(value) == IS_CONSTANT_ARRAY || - (Z_TYPE_PP(value) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) { + if (IS_CONSTANT_TYPE(Z_TYPE_PP(value))) { zend_class_entry *old_scope = EG(scope); EG(scope) = ce; @@ -3776,7 +4019,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_CONST_CONST_HANDLER(ZEND_OPCO } ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, *value); zval_copy_ctor(&EX_T(opline->result.var).tmp_var); - } else if (Z_STRLEN_P(opline->op2.zv) == sizeof("class")-1 && strcmp(Z_STRVAL_P(opline->op2.zv), "class") == 0) { + } else if (Z_STRLEN_P(opline->op2.zv) == sizeof("class")-1 && memcmp(Z_STRVAL_P(opline->op2.zv), "class", sizeof("class") - 1) == 0) { /* "class" is assigned as a case-sensitive keyword from zend_do_resolve_class_name */ ZVAL_STRINGL(&EX_T(opline->result.var).tmp_var, ce->name, ce->name_length, 1); } else { @@ -4035,7 +4278,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_CONST_HANDLER(ZEND_O ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 0); } } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - if (!isset || !i_zend_is_true(*value)) { + if (!isset || !i_zend_is_true(*value TSRMLS_CC)) { ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 1); } else { ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 0); @@ -4058,7 +4301,7 @@ static int ZEND_FASTCALL ZEND_DECLARE_CONST_SPEC_CONST_CONST_HANDLER(ZEND_OPCOD name = opline->op1.zv; val = opline->op2.zv; - if ((Z_TYPE_P(val) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT || Z_TYPE_P(val) == IS_CONSTANT_ARRAY) { + if (IS_CONSTANT_TYPE(Z_TYPE_P(val))) { zval tmp; zval *tmp_ptr = &tmp; @@ -4224,11 +4467,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLE ZVAL_LONG(generator->key, generator->largest_used_integer_key); } - /* If a value is sent it should go into the result var */ - generator->send_target = &EX_T(opline->result.var); - - /* Initialize the sent value to NULL */ - EX_T(opline->result.var).tmp_var = EG(uninitialized_zval); + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = &EX_T(opline->result.var).var.ptr; + Z_ADDREF(EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); + } else { + generator->send_target = NULL; + } /* We increment to the next op, so we are at the correct position when the * generator is resumed. */ @@ -4521,24 +4768,15 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HA { USE_OPLINE zend_free_op free_op2; - zval **container; + zval *container; SAVE_OPLINE(); + container = opline->op1.zv; + zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC); + zval_dtor(free_op2.var); + if (IS_CONST != IS_VAR || !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { - if (IS_CONST == IS_TMP_VAR || IS_CONST == IS_CONST) { - zval *container = opline->op1.zv; - zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC); - zval_dtor(free_op2.var); - - } else { - container = NULL; - zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC); - zval_dtor(free_op2.var); - if (IS_CONST == IS_VAR && !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { - - } } - CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -4659,6 +4897,8 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP_HANDLER(ZE call->called_scope = Z_OBJCE_P(call->object); } } + + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; @@ -4914,11 +5154,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ ZVAL_LONG(generator->key, generator->largest_used_integer_key); } - /* If a value is sent it should go into the result var */ - generator->send_target = &EX_T(opline->result.var); - - /* Initialize the sent value to NULL */ - EX_T(opline->result.var).tmp_var = EG(uninitialized_zval); + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = &EX_T(opline->result.var).var.ptr; + Z_ADDREF(EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); + } else { + generator->send_target = NULL; + } /* We increment to the next op, so we are at the correct position when the * generator is resumed. */ @@ -4941,7 +5185,7 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR opline->op1.zv, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -4956,7 +5200,7 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR opline->op1.zv, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -4971,7 +5215,7 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR opline->op1.zv, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -4986,7 +5230,7 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR opline->op1.zv, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5001,7 +5245,7 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR opline->op1.zv, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5016,7 +5260,7 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG opline->op1.zv, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5031,7 +5275,7 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG opline->op1.zv, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5046,7 +5290,7 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER opline->op1.zv, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5061,7 +5305,7 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_H opline->op1.zv, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5078,7 +5322,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CONST_VAR_HANDLER(ZEND_OPCO _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); Z_LVAL_P(result) = !Z_LVAL_P(result); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5094,7 +5338,7 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDL opline->op1.zv, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC)); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5110,7 +5354,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_H opline->op1.zv, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC)); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5126,7 +5370,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HAN opline->op1.zv, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC)); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5142,7 +5386,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_VAR_HANDLER(ZEND_O opline->op1.zv, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC)); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5157,7 +5401,7 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ opline->op1.zv, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5172,7 +5416,7 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER opline->op1.zv, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5187,7 +5431,7 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER opline->op1.zv, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5202,7 +5446,7 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDL opline->op1.zv, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5316,7 +5560,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_VAR(int type, switch (type) { case BP_VAR_R: case BP_VAR_IS: - AI_SET_PTR(&EX_T(opline->result.var), *retval); + EX_T(opline->result.var).var.ptr = *retval; break; case BP_VAR_UNSET: { zend_free_op free_res; @@ -5356,7 +5600,7 @@ static int ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE { USE_OPLINE - return zend_fetch_var_address_helper_SPEC_CONST_VAR(ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + return zend_fetch_var_address_helper_SPEC_CONST_VAR(zend_is_by_ref_func_arg_fetch(opline, EX(call) TSRMLS_CC) ? BP_VAR_W : BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } static int ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -5373,24 +5617,15 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HA { USE_OPLINE zend_free_op free_op2; - zval **container; + zval *container; SAVE_OPLINE(); + container = opline->op1.zv; + zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC); + zval_ptr_dtor_nogc(&free_op2.var); + if (IS_CONST != IS_VAR || !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { - if (IS_CONST == IS_TMP_VAR || IS_CONST == IS_CONST) { - zval *container = opline->op1.zv; - zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); - - } else { - container = NULL; - zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); - if (IS_CONST == IS_VAR && !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { - - } } - CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5479,7 +5714,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_VAR_HANDLER(ZE } } if (IS_VAR != IS_CONST) { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } } else { if (UNEXPECTED(ce->constructor == NULL)) { @@ -5511,6 +5746,8 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_VAR_HANDLER(ZE call->called_scope = Z_OBJCE_P(call->object); } } + + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; @@ -5528,7 +5765,7 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_A opline->op1.zv, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5603,7 +5840,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_VAR_HANDLER(ZEND_OPC /* do nothing */ break; } - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } else { zend_hash_next_index_insert(Z_ARRVAL(EX_T(opline->result.var).tmp_var), &expr_ptr, sizeof(zval *), NULL); } @@ -5780,7 +6017,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_VAR_HANDLER(ZEND_OPC ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 0); } } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - if (!isset || !i_zend_is_true(*value)) { + if (!isset || !i_zend_is_true(*value TSRMLS_CC)) { ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 1); } else { ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 0); @@ -5921,7 +6158,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ generator->largest_used_integer_key = Z_LVAL_P(generator->key); } - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } else { /* If no key was specified we use auto-increment keys */ generator->largest_used_integer_key++; @@ -5930,11 +6167,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ ZVAL_LONG(generator->key, generator->largest_used_integer_key); } - /* If a value is sent it should go into the result var */ - generator->send_target = &EX_T(opline->result.var); - - /* Initialize the sent value to NULL */ - EX_T(opline->result.var).tmp_var = EG(uninitialized_zval); + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = &EX_T(opline->result.var).var.ptr; + Z_ADDREF(EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); + } else { + generator->send_target = NULL; + } /* We increment to the next op, so we are at the correct position when the * generator is resumed. */ @@ -6056,7 +6297,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_UNUSED(int typ switch (type) { case BP_VAR_R: case BP_VAR_IS: - AI_SET_PTR(&EX_T(opline->result.var), *retval); + EX_T(opline->result.var).var.ptr = *retval; break; case BP_VAR_UNSET: { zend_free_op free_res; @@ -6096,7 +6337,7 @@ static int ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_CONST_UNUSED_HANDLER(ZEND_OPC { USE_OPLINE - return zend_fetch_var_address_helper_SPEC_CONST_UNUSED(ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + return zend_fetch_var_address_helper_SPEC_CONST_UNUSED(zend_is_by_ref_func_arg_fetch(opline, EX(call) TSRMLS_CC) ? BP_VAR_W : BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } static int ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -6225,6 +6466,8 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED_HANDLER call->called_scope = Z_OBJCE_P(call->object); } } + + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; @@ -6479,7 +6722,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_UNUSED_HANDLER(ZEND_ ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 0); } } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - if (!isset || !i_zend_is_true(*value)) { + if (!isset || !i_zend_is_true(*value TSRMLS_CC)) { ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 1); } else { ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 0); @@ -6646,11 +6889,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDL ZVAL_LONG(generator->key, generator->largest_used_integer_key); } - /* If a value is sent it should go into the result var */ - generator->send_target = &EX_T(opline->result.var); - - /* Initialize the sent value to NULL */ - EX_T(opline->result.var).tmp_var = EG(uninitialized_zval); + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = &EX_T(opline->result.var).var.ptr; + Z_ADDREF(EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); + } else { + generator->send_target = NULL; + } /* We increment to the next op, so we are at the correct position when the * generator is resumed. */ @@ -6943,24 +7190,15 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HAN { USE_OPLINE - zval **container; + zval *container; SAVE_OPLINE(); + container = opline->op1.zv; + zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC); - if (IS_CONST == IS_TMP_VAR || IS_CONST == IS_CONST) { - zval *container = opline->op1.zv; - zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC); - - - } else { - container = NULL; - zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC); - - if (IS_CONST == IS_VAR && !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { + if (IS_CONST != IS_VAR || !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { - } } - CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -7081,6 +7319,8 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_HANDLER(ZEN call->called_scope = Z_OBJCE_P(call->object); } } + + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; @@ -7395,11 +7635,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_A ZVAL_LONG(generator->key, generator->largest_used_integer_key); } - /* If a value is sent it should go into the result var */ - generator->send_target = &EX_T(opline->result.var); - - /* Initialize the sent value to NULL */ - EX_T(opline->result.var).tmp_var = EG(uninitialized_zval); + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = &EX_T(opline->result.var).var.ptr; + Z_ADDREF(EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); + } else { + generator->send_target = NULL; + } /* We increment to the next op, so we are at the correct position when the * generator is resumed. */ @@ -7478,7 +7722,7 @@ static int ZEND_FASTCALL ZEND_JMPZ_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (IS_TMP_VAR == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) { ret = Z_LVAL_P(val); } else { - ret = i_zend_is_true(val); + ret = i_zend_is_true(val TSRMLS_CC); zval_dtor(free_op1.var); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); @@ -7508,7 +7752,7 @@ static int ZEND_FASTCALL ZEND_JMPNZ_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (IS_TMP_VAR == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) { ret = Z_LVAL_P(val); } else { - ret = i_zend_is_true(val); + ret = i_zend_is_true(val TSRMLS_CC); zval_dtor(free_op1.var); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); @@ -7538,7 +7782,7 @@ static int ZEND_FASTCALL ZEND_JMPZNZ_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (IS_TMP_VAR == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) { retval = Z_LVAL_P(val); } else { - retval = i_zend_is_true(val); + retval = i_zend_is_true(val TSRMLS_CC); zval_dtor(free_op1.var); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); @@ -7572,7 +7816,7 @@ static int ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS if (IS_TMP_VAR == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) { retval = Z_LVAL_P(val); } else { - retval = i_zend_is_true(val); + retval = i_zend_is_true(val TSRMLS_CC); zval_dtor(free_op1.var); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); @@ -7603,7 +7847,7 @@ static int ZEND_FASTCALL ZEND_JMPNZ_EX_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG if (IS_TMP_VAR == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) { retval = Z_LVAL_P(val); } else { - retval = i_zend_is_true(val); + retval = i_zend_is_true(val TSRMLS_CC); zval_dtor(free_op1.var); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); @@ -7688,7 +7932,8 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLE SAVE_OPLINE(); do { - if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR) { + if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR || + (IS_TMP_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_VALUE)) { /* Not supposed to happen, but we'll allow it */ zend_error(E_NOTICE, "Only variable references should be returned by reference"); @@ -7784,10 +8029,13 @@ static int ZEND_FASTCALL ZEND_SEND_VAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG USE_OPLINE SAVE_OPLINE(); - if (opline->extended_value==ZEND_DO_FCALL_BY_NAME - && ARG_MUST_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.opline_num)) { - zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.opline_num); + if (opline->extended_value == ZEND_DO_FCALL_BY_NAME) { + int arg_num = opline->op2.num + EX(call)->num_additional_args; + if (ARG_MUST_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { + zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", arg_num); + } } + { zval *valptr; zval *value; @@ -7815,7 +8063,7 @@ static int ZEND_FASTCALL ZEND_BOOL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); /* PHP 3.0 returned "" for false and 1 for true, here we use 0 and 1 for now */ - ZVAL_BOOL(retval, i_zend_is_true(_get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC))); + ZVAL_BOOL(retval, i_zend_is_true(_get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC) TSRMLS_CC)); zval_dtor(free_op1.var); CHECK_EXCEPTION(); @@ -7880,7 +8128,7 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (!RETURN_VALUE_USED(opline) || UNEXPECTED(EG(exception) != NULL)) { zval_ptr_dtor(&retval); } else { - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; } } @@ -8038,7 +8286,6 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HAND EX(original_return_value) = EG(return_value_ptr_ptr); EG(active_op_array) = new_op_array; if (RETURN_VALUE_USED(opline)) { - EX_T(opline->result.var).var.ptr = NULL; EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr; EG(return_value_ptr_ptr) = EX_T(opline->result.var).var.ptr_ptr; } else { @@ -8076,7 +8323,7 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HAND ALLOC_ZVAL(retval); ZVAL_BOOL(retval, failure_retval); INIT_PZVAL(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; } ZEND_VM_NEXT_OPCODE(); } @@ -8303,7 +8550,7 @@ static int ZEND_FASTCALL ZEND_JMP_SET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS SAVE_OPLINE(); value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (i_zend_is_true(value)) { + if (i_zend_is_true(value TSRMLS_CC)) { ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, value); if (!1) { zendi_zval_copy_ctor(EX_T(opline->result.var).tmp_var); @@ -8329,7 +8576,7 @@ static int ZEND_FASTCALL ZEND_JMP_SET_VAR_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ SAVE_OPLINE(); value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (i_zend_is_true(value)) { + if (i_zend_is_true(value TSRMLS_CC)) { if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) { Z_ADDREF_P(value); EX_T(opline->result.var).var.ptr = value; @@ -8806,7 +9053,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_CONST(int type, switch (type) { case BP_VAR_R: case BP_VAR_IS: - AI_SET_PTR(&EX_T(opline->result.var), *retval); + EX_T(opline->result.var).var.ptr = *retval; break; case BP_VAR_UNSET: { zend_free_op free_res; @@ -8846,7 +9093,7 @@ static int ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE { USE_OPLINE - return zend_fetch_var_address_helper_SPEC_TMP_CONST(ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + return zend_fetch_var_address_helper_SPEC_TMP_CONST(zend_is_by_ref_func_arg_fetch(opline, EX(call) TSRMLS_CC) ? BP_VAR_W : BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } static int ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -8863,24 +9110,15 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HA { USE_OPLINE zend_free_op free_op1; - zval **container; + zval *container; SAVE_OPLINE(); + container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC); - if (IS_TMP_VAR == IS_TMP_VAR || IS_TMP_VAR == IS_CONST) { - zval *container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC); - + if (IS_TMP_VAR != IS_VAR || !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { zval_dtor(free_op1.var); - } else { - container = NULL; - zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC); - - if (IS_TMP_VAR == IS_VAR && !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { - - } } - CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -8896,13 +9134,13 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_TMP_VAR_SPEC_TMP_CONST_HANDLER(ZEND_OPC if (UNEXPECTED(Z_TYPE_P(container) != IS_ARRAY)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } else { zval *value = *zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC); PZVAL_LOCK(value); - AI_SET_PTR(&EX_T(opline->result.var), value); + EX_T(opline->result.var).var.ptr = value; } CHECK_EXCEPTION(); @@ -9026,6 +9264,8 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_CONST_HANDLER(ZEND_OPCO call->object = this_ptr; } } + + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; @@ -9295,7 +9535,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_CONST_HANDLER(ZEND_OPC ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 0); } } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - if (!isset || !i_zend_is_true(*value)) { + if (!isset || !i_zend_is_true(*value TSRMLS_CC)) { ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 1); } else { ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 0); @@ -9444,11 +9684,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ ZVAL_LONG(generator->key, generator->largest_used_integer_key); } - /* If a value is sent it should go into the result var */ - generator->send_target = &EX_T(opline->result.var); - - /* Initialize the sent value to NULL */ - EX_T(opline->result.var).tmp_var = EG(uninitialized_zval); + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = &EX_T(opline->result.var).var.ptr; + Z_ADDREF(EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); + } else { + generator->send_target = NULL; + } /* We increment to the next op, so we are at the correct position when the * generator is resumed. */ @@ -9741,24 +9985,15 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HAND { USE_OPLINE zend_free_op free_op1, free_op2; - zval **container; + zval *container; SAVE_OPLINE(); - - if (IS_TMP_VAR == IS_TMP_VAR || IS_TMP_VAR == IS_CONST) { - zval *container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC); - zval_dtor(free_op2.var); + container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC); + zval_dtor(free_op2.var); + if (IS_TMP_VAR != IS_VAR || !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { zval_dtor(free_op1.var); - } else { - container = NULL; - zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC); - zval_dtor(free_op2.var); - if (IS_TMP_VAR == IS_VAR && !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { - - } } - CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -9879,6 +10114,8 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE call->object = this_ptr; } } + + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; @@ -10136,11 +10373,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR ZVAL_LONG(generator->key, generator->largest_used_integer_key); } - /* If a value is sent it should go into the result var */ - generator->send_target = &EX_T(opline->result.var); - - /* Initialize the sent value to NULL */ - EX_T(opline->result.var).tmp_var = EG(uninitialized_zval); + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = &EX_T(opline->result.var).var.ptr; + Z_ADDREF(EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); + } else { + generator->send_target = NULL; + } /* We increment to the next op, so we are at the correct position when the * generator is resumed. */ @@ -10163,7 +10404,7 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); zval_dtor(free_op1.var); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10178,7 +10419,7 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); zval_dtor(free_op1.var); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10193,7 +10434,7 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); zval_dtor(free_op1.var); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10208,7 +10449,7 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); zval_dtor(free_op1.var); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10223,7 +10464,7 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); zval_dtor(free_op1.var); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10238,7 +10479,7 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); zval_dtor(free_op1.var); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10253,7 +10494,7 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); zval_dtor(free_op1.var); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10268,7 +10509,7 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_A _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); zval_dtor(free_op1.var); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10283,7 +10524,7 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HAN _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); zval_dtor(free_op1.var); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10300,7 +10541,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); Z_LVAL_P(result) = !Z_LVAL_P(result); zval_dtor(free_op1.var); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10316,7 +10557,7 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC)); zval_dtor(free_op1.var); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10332,7 +10573,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HAN _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC)); zval_dtor(free_op1.var); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10348,7 +10589,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDL _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC)); zval_dtor(free_op1.var); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10364,7 +10605,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMP_VAR_HANDLER(ZEND_OPC _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC)); zval_dtor(free_op1.var); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10379,7 +10620,7 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); zval_dtor(free_op1.var); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10394,7 +10635,7 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_A _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); zval_dtor(free_op1.var); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10409,7 +10650,7 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_A _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); zval_dtor(free_op1.var); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10424,7 +10665,7 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); zval_dtor(free_op1.var); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10538,7 +10779,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_VAR(int type, ZE switch (type) { case BP_VAR_R: case BP_VAR_IS: - AI_SET_PTR(&EX_T(opline->result.var), *retval); + EX_T(opline->result.var).var.ptr = *retval; break; case BP_VAR_UNSET: { zend_free_op free_res; @@ -10578,7 +10819,7 @@ static int ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_H { USE_OPLINE - return zend_fetch_var_address_helper_SPEC_TMP_VAR(ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + return zend_fetch_var_address_helper_SPEC_TMP_VAR(zend_is_by_ref_func_arg_fetch(opline, EX(call) TSRMLS_CC) ? BP_VAR_W : BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } static int ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -10595,24 +10836,15 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HAND { USE_OPLINE zend_free_op free_op1, free_op2; - zval **container; + zval *container; SAVE_OPLINE(); - - if (IS_TMP_VAR == IS_TMP_VAR || IS_TMP_VAR == IS_CONST) { - zval *container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); + container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC); + zval_ptr_dtor_nogc(&free_op2.var); + if (IS_TMP_VAR != IS_VAR || !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { zval_dtor(free_op1.var); - } else { - container = NULL; - zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); - if (IS_TMP_VAR == IS_VAR && !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { - - } } - CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10656,7 +10888,7 @@ static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ * which aren't affected by FREE_OP(Ts, )'s anyway, unless they're * string offsets or overloaded objects */ - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -10714,7 +10946,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE } } else { if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); HANDLE_EXCEPTION(); } zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval); @@ -10733,10 +10965,12 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE call->object = this_ptr; } } + + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -10752,7 +10986,7 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10827,7 +11061,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_VAR_HANDLER(ZEND_OPCOD /* do nothing */ break; } - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } else { zend_hash_next_index_insert(Z_ARRVAL(EX_T(opline->result.var).tmp_var), &expr_ptr, sizeof(zval *), NULL); } @@ -11004,7 +11238,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_VAR_HANDLER(ZEND_OPCOD ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 0); } } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - if (!isset || !i_zend_is_true(*value)) { + if (!isset || !i_zend_is_true(*value TSRMLS_CC)) { ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 1); } else { ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 0); @@ -11145,7 +11379,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR generator->largest_used_integer_key = Z_LVAL_P(generator->key); } - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } else { /* If no key was specified we use auto-increment keys */ generator->largest_used_integer_key++; @@ -11154,11 +11388,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR ZVAL_LONG(generator->key, generator->largest_used_integer_key); } - /* If a value is sent it should go into the result var */ - generator->send_target = &EX_T(opline->result.var); - - /* Initialize the sent value to NULL */ - EX_T(opline->result.var).tmp_var = EG(uninitialized_zval); + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = &EX_T(opline->result.var).var.ptr; + Z_ADDREF(EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); + } else { + generator->send_target = NULL; + } /* We increment to the next op, so we are at the correct position when the * generator is resumed. */ @@ -11280,7 +11518,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_UNUSED(int type, switch (type) { case BP_VAR_R: case BP_VAR_IS: - AI_SET_PTR(&EX_T(opline->result.var), *retval); + EX_T(opline->result.var).var.ptr = *retval; break; case BP_VAR_UNSET: { zend_free_op free_res; @@ -11320,7 +11558,7 @@ static int ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCOD { USE_OPLINE - return zend_fetch_var_address_helper_SPEC_TMP_UNUSED(ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + return zend_fetch_var_address_helper_SPEC_TMP_UNUSED(zend_is_by_ref_func_arg_fetch(opline, EX(call) TSRMLS_CC) ? BP_VAR_W : BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } static int ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -11580,7 +11818,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_UNUSED_HANDLER(ZEND_OP ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 0); } } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - if (!isset || !i_zend_is_true(*value)) { + if (!isset || !i_zend_is_true(*value TSRMLS_CC)) { ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 1); } else { ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 0); @@ -11729,11 +11967,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER ZVAL_LONG(generator->key, generator->largest_used_integer_key); } - /* If a value is sent it should go into the result var */ - generator->send_target = &EX_T(opline->result.var); - - /* Initialize the sent value to NULL */ - EX_T(opline->result.var).tmp_var = EG(uninitialized_zval); + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = &EX_T(opline->result.var).var.ptr; + Z_ADDREF(EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); + } else { + generator->send_target = NULL; + } /* We increment to the next op, so we are at the correct position when the * generator is resumed. */ @@ -12026,24 +12268,15 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDL { USE_OPLINE zend_free_op free_op1; - zval **container; + zval *container; SAVE_OPLINE(); + container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC); - if (IS_TMP_VAR == IS_TMP_VAR || IS_TMP_VAR == IS_CONST) { - zval *container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC); - + if (IS_TMP_VAR != IS_VAR || !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { zval_dtor(free_op1.var); - } else { - container = NULL; - zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC); - - if (IS_TMP_VAR == IS_VAR && !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { - - } } - CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12163,6 +12396,8 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_ call->object = this_ptr; } } + + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; @@ -12418,11 +12653,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG ZVAL_LONG(generator->key, generator->largest_used_integer_key); } - /* If a value is sent it should go into the result var */ - generator->send_target = &EX_T(opline->result.var); - - /* Initialize the sent value to NULL */ - EX_T(opline->result.var).tmp_var = EG(uninitialized_zval); + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = &EX_T(opline->result.var).var.ptr; + Z_ADDREF(EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); + } else { + generator->send_target = NULL; + } /* We increment to the next op, so we are at the correct position when the * generator is resumed. */ @@ -12443,7 +12682,7 @@ static int ZEND_FASTCALL ZEND_BW_NOT_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); bitwise_not_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12456,7 +12695,7 @@ static int ZEND_FASTCALL ZEND_BOOL_NOT_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG SAVE_OPLINE(); boolean_not_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12476,9 +12715,9 @@ static int ZEND_FASTCALL ZEND_PRE_INC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS if (IS_VAR == IS_VAR && UNEXPECTED(*var_ptr == &EG(error_zval))) { if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12500,10 +12739,10 @@ static int ZEND_FASTCALL ZEND_PRE_INC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*var_ptr); - AI_SET_PTR(&EX_T(opline->result.var), *var_ptr); + EX_T(opline->result.var).var.ptr = *var_ptr; } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12523,9 +12762,9 @@ static int ZEND_FASTCALL ZEND_PRE_DEC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS if (IS_VAR == IS_VAR && UNEXPECTED(*var_ptr == &EG(error_zval))) { if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12547,10 +12786,10 @@ static int ZEND_FASTCALL ZEND_PRE_DEC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*var_ptr); - AI_SET_PTR(&EX_T(opline->result.var), *var_ptr); + EX_T(opline->result.var).var.ptr = *var_ptr; } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12569,7 +12808,7 @@ static int ZEND_FASTCALL ZEND_POST_INC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG } if (IS_VAR == IS_VAR && UNEXPECTED(*var_ptr == &EG(error_zval))) { ZVAL_NULL(&EX_T(opline->result.var).tmp_var); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12593,7 +12832,7 @@ static int ZEND_FASTCALL ZEND_POST_INC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG fast_increment_function(*var_ptr); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12612,7 +12851,7 @@ static int ZEND_FASTCALL ZEND_POST_DEC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG } if (IS_VAR == IS_VAR && UNEXPECTED(*var_ptr == &EG(error_zval))) { ZVAL_NULL(&EX_T(opline->result.var).tmp_var); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12636,7 +12875,7 @@ static int ZEND_FASTCALL ZEND_POST_DEC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG fast_decrement_function(*var_ptr); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12655,7 +12894,7 @@ static int ZEND_FASTCALL ZEND_ECHO_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } zend_print_variable(z); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12681,8 +12920,8 @@ static int ZEND_FASTCALL ZEND_JMPZ_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (IS_VAR == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) { ret = Z_LVAL_P(val); } else { - ret = i_zend_is_true(val); - zval_ptr_dtor(&free_op1.var); + ret = i_zend_is_true(val TSRMLS_CC); + zval_ptr_dtor_nogc(&free_op1.var); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } @@ -12711,8 +12950,8 @@ static int ZEND_FASTCALL ZEND_JMPNZ_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (IS_VAR == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) { ret = Z_LVAL_P(val); } else { - ret = i_zend_is_true(val); - zval_ptr_dtor(&free_op1.var); + ret = i_zend_is_true(val TSRMLS_CC); + zval_ptr_dtor_nogc(&free_op1.var); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } @@ -12741,8 +12980,8 @@ static int ZEND_FASTCALL ZEND_JMPZNZ_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (IS_VAR == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) { retval = Z_LVAL_P(val); } else { - retval = i_zend_is_true(val); - zval_ptr_dtor(&free_op1.var); + retval = i_zend_is_true(val TSRMLS_CC); + zval_ptr_dtor_nogc(&free_op1.var); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } @@ -12775,8 +13014,8 @@ static int ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS if (IS_VAR == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) { retval = Z_LVAL_P(val); } else { - retval = i_zend_is_true(val); - zval_ptr_dtor(&free_op1.var); + retval = i_zend_is_true(val TSRMLS_CC); + zval_ptr_dtor_nogc(&free_op1.var); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } @@ -12806,8 +13045,8 @@ static int ZEND_FASTCALL ZEND_JMPNZ_EX_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG if (IS_VAR == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) { retval = Z_LVAL_P(val); } else { - retval = i_zend_is_true(val); - zval_ptr_dtor(&free_op1.var); + retval = i_zend_is_true(val TSRMLS_CC); + zval_ptr_dtor_nogc(&free_op1.var); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } @@ -12848,7 +13087,7 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) retval_ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); if (!EG(return_value_ptr_ptr)) { - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); } else { if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR || @@ -12861,7 +13100,7 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zval_copy_ctor(ret); } *EG(return_value_ptr_ptr) = ret; - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); } else if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && retval_ptr == &EG(uninitialized_zval)) { zval *ret; @@ -12891,14 +13130,15 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLE SAVE_OPLINE(); do { - if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) { + if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR || + (IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_VALUE)) { /* Not supposed to happen, but we'll allow it */ zend_error(E_NOTICE, "Only variable references should be returned by reference"); retval_ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); if (!EG(return_value_ptr_ptr)) { if (IS_VAR == IS_TMP_VAR) { - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); } } else if (!0) { /* Not a temp var */ zval *ret; @@ -12948,7 +13188,7 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLE } } while (0); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } @@ -12979,7 +13219,7 @@ static int ZEND_FASTCALL ZEND_THROW_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_throw_exception_object(exception TSRMLS_CC); zend_exception_restore(TSRMLS_C); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); HANDLE_EXCEPTION(); } @@ -13003,7 +13243,7 @@ static int ZEND_FASTCALL zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_AR ALLOC_ZVAL(varptr); INIT_PZVAL_COPY(varptr, original_var); zval_copy_ctor(varptr); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); } else { Z_UNSET_ISREF_P(varptr); } @@ -13021,14 +13261,18 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HAND USE_OPLINE zend_free_op free_op1; zval *varptr; + int arg_num; SAVE_OPLINE(); if (opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) { /* Had function_ptr at compile_time */ if (!(opline->extended_value & ZEND_ARG_SEND_BY_REF)) { return zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } - } else if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.opline_num)) { - return zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + } else { + arg_num = opline->op2.num + EX(call)->num_additional_args; + if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { + return zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + } } varptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); @@ -13046,7 +13290,7 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HAND if ((opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) ? !(opline->extended_value & ZEND_ARG_SEND_SILENT) : - !ARG_MAY_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.opline_num)) { + !ARG_MAY_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { zend_error(E_STRICT, "Only variables should be passed by reference"); } ALLOC_ZVAL(valptr); @@ -13054,7 +13298,7 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HAND if (!0) { zval_copy_ctor(valptr); } - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); zend_vm_stack_push(valptr TSRMLS_CC); } CHECK_EXCEPTION(); @@ -13083,9 +13327,11 @@ static int ZEND_FASTCALL ZEND_SEND_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG } if (opline->extended_value == ZEND_DO_FCALL_BY_NAME && - EX(function_state).function->type == ZEND_INTERNAL_FUNCTION && - !ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.opline_num)) { - return zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) { + int arg_num = opline->op2.num + EX(call)->num_additional_args; + if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { + return zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + } } SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr_ptr); @@ -13093,7 +13339,7 @@ static int ZEND_FASTCALL ZEND_SEND_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG Z_ADDREF_P(varptr); zend_vm_stack_push(varptr TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -13102,9 +13348,11 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG { USE_OPLINE - if ((opline->extended_value == ZEND_DO_FCALL_BY_NAME) - && ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.opline_num)) { - return ZEND_SEND_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + if (opline->extended_value == ZEND_DO_FCALL_BY_NAME) { + int arg_num = opline->op2.num + EX(call)->num_additional_args; + if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { + return ZEND_SEND_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + } } SAVE_OPLINE(); return zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -13118,8 +13366,8 @@ static int ZEND_FASTCALL ZEND_BOOL_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); /* PHP 3.0 returned "" for false and 1 for true, here we use 0 and 1 for now */ - ZVAL_BOOL(retval, i_zend_is_true(_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC))); - zval_ptr_dtor(&free_op1.var); + ZVAL_BOOL(retval, i_zend_is_true(_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC) TSRMLS_CC)); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -13193,10 +13441,10 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (!RETURN_VALUE_USED(opline) || UNEXPECTED(EG(exception) != NULL)) { zval_ptr_dtor(&retval); } else { - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; } } - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -13238,7 +13486,7 @@ static int ZEND_FASTCALL ZEND_CAST_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (use_copy) { ZVAL_COPY_VALUE(result, &var_copy); if (0) { - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); } } else { ZVAL_COPY_VALUE(result, expr); @@ -13255,7 +13503,7 @@ static int ZEND_FASTCALL ZEND_CAST_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) convert_to_object(result); break; } - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -13344,14 +13592,13 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_VAR_HANDLER(ZEND_OPCODE_HAND if (tmp_inc_filename) { zval_ptr_dtor(&tmp_inc_filename); } - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } else if (EXPECTED(new_op_array != NULL)) { EX(original_return_value) = EG(return_value_ptr_ptr); EG(active_op_array) = new_op_array; if (RETURN_VALUE_USED(opline)) { - EX_T(opline->result.var).var.ptr = NULL; EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr; EG(return_value_ptr_ptr) = EX_T(opline->result.var).var.ptr_ptr; } else { @@ -13389,7 +13636,7 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_VAR_HANDLER(ZEND_OPCODE_HAND ALLOC_ZVAL(retval); ZVAL_BOOL(retval, failure_retval); INIT_PZVAL(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; } ZEND_VM_NEXT_OPCODE(); } @@ -13480,13 +13727,13 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG iter = ce->get_iterator(ce, array_ptr, opline->extended_value & ZEND_FE_RESET_REFERENCE TSRMLS_CC); if (IS_VAR == IS_VAR && !(opline->extended_value & ZEND_FE_RESET_VARIABLE)) { - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); } if (iter && EXPECTED(EG(exception) == NULL)) { array_ptr = zend_iterator_wrap(iter TSRMLS_CC); } else { if (IS_VAR == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; } if (!EG(exception)) { zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Object of type %s did not create an Iterator", ce->name); @@ -13505,7 +13752,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG if (UNEXPECTED(EG(exception) != NULL)) { zval_ptr_dtor(&array_ptr); if (IS_VAR == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; } HANDLE_EXCEPTION(); } @@ -13514,7 +13761,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG if (UNEXPECTED(EG(exception) != NULL)) { zval_ptr_dtor(&array_ptr); if (IS_VAR == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; } HANDLE_EXCEPTION(); } @@ -13546,7 +13793,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG } if (IS_VAR == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; } if (is_empty) { ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num); @@ -13679,7 +13926,7 @@ static int ZEND_FASTCALL ZEND_FE_FETCH_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG Z_ADDREF_PP(value); } else { PZVAL_LOCK(*value); - AI_SET_PTR(&EX_T(opline->result.var), *value); + EX_T(opline->result.var).var.ptr = *value; } CHECK_EXCEPTION(); @@ -13702,7 +13949,7 @@ static int ZEND_FASTCALL ZEND_EXIT_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } else { zend_print_variable(ptr); } - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); } #endif zend_bailout(); @@ -13718,19 +13965,19 @@ static int ZEND_FASTCALL ZEND_JMP_SET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS SAVE_OPLINE(); value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (i_zend_is_true(value)) { + if (i_zend_is_true(value TSRMLS_CC)) { ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, value); if (!0) { zendi_zval_copy_ctor(EX_T(opline->result.var).tmp_var); } - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); #if DEBUG_ZEND>=2 printf("Conditional jmp to %d\n", opline->op2.opline_num); #endif ZEND_VM_JMP(opline->op2.jmp_addr); } - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -13744,7 +13991,7 @@ static int ZEND_FASTCALL ZEND_JMP_SET_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ SAVE_OPLINE(); value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (i_zend_is_true(value)) { + if (i_zend_is_true(value TSRMLS_CC)) { if (IS_VAR == IS_VAR || IS_VAR == IS_CV) { Z_ADDREF_P(value); EX_T(opline->result.var).var.ptr = value; @@ -13758,14 +14005,14 @@ static int ZEND_FASTCALL ZEND_JMP_SET_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ zval_copy_ctor(EX_T(opline->result.var).var.ptr); } } - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); #if DEBUG_ZEND>=2 printf("Conditional jmp to %d\n", opline->op2.opline_num); #endif ZEND_VM_JMP(opline->op2.jmp_addr); } - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -13783,7 +14030,7 @@ static int ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR if (!0) { zval_copy_ctor(&EX_T(opline->result.var).tmp_var); } - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -13811,7 +14058,7 @@ static int ZEND_FASTCALL ZEND_QM_ASSIGN_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLE } } - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -13832,7 +14079,7 @@ static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_A result = 0; } ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, result); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -13846,7 +14093,7 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR fast_add_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -13861,7 +14108,7 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR fast_sub_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -13876,7 +14123,7 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR fast_mul_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -13891,7 +14138,7 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR fast_div_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -13906,7 +14153,7 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR fast_mod_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -13921,7 +14168,7 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG shift_left_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -13936,7 +14183,7 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG shift_right_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -13951,7 +14198,7 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER concat_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -13966,7 +14213,7 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H is_identical_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -13983,7 +14230,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CONST_HANDLER(ZEND_OPCO _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), opline->op2.zv TSRMLS_CC); Z_LVAL_P(result) = !Z_LVAL_P(result); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -13999,7 +14246,7 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDL ZVAL_BOOL(result, fast_equal_function(result, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), opline->op2.zv TSRMLS_CC)); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -14015,7 +14262,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H ZVAL_BOOL(result, fast_not_equal_function(result, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), opline->op2.zv TSRMLS_CC)); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -14031,7 +14278,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN ZVAL_BOOL(result, fast_is_smaller_function(result, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), opline->op2.zv TSRMLS_CC)); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -14047,7 +14294,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_VAR_CONST_HANDLER(ZEND_O ZVAL_BOOL(result, fast_is_smaller_or_equal_function(result, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), opline->op2.zv TSRMLS_CC)); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -14062,7 +14309,7 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ bitwise_or_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -14077,7 +14324,7 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER bitwise_and_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -14092,7 +14339,7 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER bitwise_xor_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -14107,7 +14354,7 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDL boolean_xor_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -14138,7 +14385,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*b if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); - EX_T(opline->result.var).var.ptr_ptr = NULL; } } else { /* here we are sure we are dealing with an object */ @@ -14158,7 +14404,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*b if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*zptr); EX_T(opline->result.var).var.ptr = *zptr; - EX_T(opline->result.var).var.ptr_ptr = NULL; } } } @@ -14197,7 +14442,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*b if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(z); EX_T(opline->result.var).var.ptr = z; - EX_T(opline->result.var).var.ptr_ptr = NULL; } zval_ptr_dtor(&z); } else { @@ -14205,7 +14449,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*b if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); - EX_T(opline->result.var).var.ptr_ptr = NULL; } } } @@ -14218,7 +14461,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*b FREE_OP(free_op_data1); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* assign_obj has two opcodes! */ CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -14270,10 +14513,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_CONST(int (*binar if (UNEXPECTED(*var_ptr == &EG(error_zval))) { if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); if (opline->extended_value == ZEND_ASSIGN_DIM) { ZEND_VM_INC_OPCODE(); @@ -14298,17 +14541,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_CONST(int (*binar if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*var_ptr); - AI_SET_PTR(&EX_T(opline->result.var), *var_ptr); + EX_T(opline->result.var).var.ptr = *var_ptr; } if (opline->extended_value == ZEND_ASSIGN_DIM) { FREE_OP(free_op_data1); FREE_OP_VAR_PTR(free_op_data2); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); } else { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); } ZEND_VM_NEXT_OPCODE(); @@ -14398,7 +14641,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CONST(incdec_t PZVAL_LOCK(&EG(uninitialized_zval)); *retval = &EG(uninitialized_zval); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -14458,7 +14701,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CONST(incdec_t } else { } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -14499,7 +14742,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CONST(incdec_ zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); ZVAL_NULL(retval); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -14560,7 +14803,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CONST(incdec_ } else { } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -14609,7 +14852,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_CONST(int type, if (IS_VAR != IS_CONST && varname == &tmp_varname) { zval_dtor(&tmp_varname); } - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -14619,7 +14862,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_CONST(int type, ce = EX_T(opline->op2.var).class_entry; } retval = zend_std_get_static_property(ce, Z_STRVAL_P(varname), Z_STRLEN_P(varname), 0, ((IS_VAR == IS_CONST) ? opline->op1.literal : NULL) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); } else { target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC); /* @@ -14656,11 +14899,11 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_CONST(int type, switch (opline->extended_value & ZEND_FETCH_TYPE_MASK) { case ZEND_FETCH_GLOBAL: if (IS_VAR != IS_TMP_VAR) { - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); } break; case ZEND_FETCH_LOCAL: - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); break; case ZEND_FETCH_STATIC: zval_update_constant(retval, (void*) 1 TSRMLS_CC); @@ -14684,7 +14927,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_CONST(int type, switch (type) { case BP_VAR_R: case BP_VAR_IS: - AI_SET_PTR(&EX_T(opline->result.var), *retval); + EX_T(opline->result.var).var.ptr = *retval; break; case BP_VAR_UNSET: { zend_free_op free_res; @@ -14724,7 +14967,7 @@ static int ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE { USE_OPLINE - return zend_fetch_var_address_helper_SPEC_VAR_CONST(ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + return zend_fetch_var_address_helper_SPEC_VAR_CONST(zend_is_by_ref_func_arg_fetch(opline, EX(call) TSRMLS_CC) ? BP_VAR_W : BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } static int ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -14741,24 +14984,15 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA { USE_OPLINE zend_free_op free_op1; - zval **container; + zval *container; SAVE_OPLINE(); + container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC); - if (IS_VAR == IS_TMP_VAR || IS_VAR == IS_CONST) { - zval *container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC); - - zval_ptr_dtor(&free_op1.var); - } else { - container = _get_zval_ptr_ptr_var_fast(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC); - - if (IS_VAR == IS_VAR && !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { - zval_ptr_dtor(&free_op1.var); - } + if (IS_VAR != IS_VAR || !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { + zval_ptr_dtor_nogc(&free_op1.var); } - CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -14780,7 +15014,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* We are going to assign the result by reference */ if (UNEXPECTED(opline->extended_value != 0)) { @@ -14814,7 +15048,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -14823,13 +15057,13 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H { USE_OPLINE zend_free_op free_op1; - zval **container; + zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var_fast(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_IS TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -14838,12 +15072,11 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OP { USE_OPLINE zend_free_op free_op1; - zval **container; SAVE_OPLINE(); - if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) { - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + if (zend_is_by_ref_func_arg_fetch(opline, EX(call) TSRMLS_CC)) { + zval **container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } @@ -14852,15 +15085,17 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OP EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; } else { + zval *container; + if (IS_CONST == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } - container = _get_zval_ptr_ptr_var_fast(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -14888,7 +15123,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCOD if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; if (UNEXPECTED(EX_T(opline->result.var).var.ptr_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); ZEND_VM_NEXT_OPCODE(); @@ -14923,7 +15158,7 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_VAR_CONST( UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { zend_error(E_NOTICE, "Trying to get property of non-object"); PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } else { zval *retval; @@ -14936,7 +15171,7 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_VAR_CONST( retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); PZVAL_LOCK(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; if (0) { zval_ptr_dtor(&offset); @@ -14945,7 +15180,7 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_VAR_CONST( } } - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -14965,11 +15200,6 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA SAVE_OPLINE(); property = opline->op2.zv; - if (IS_VAR == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) { - PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); - EX_T(opline->op1.var).var.ptr = *EX_T(opline->op1.var).var.ptr_ptr; - } - if (0) { MAKE_REAL_ZVAL_PTR(property); } @@ -14987,7 +15217,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* We are going to assign the result by reference */ if (opline->extended_value & ZEND_FETCH_MAKE_REF) { @@ -15030,7 +15260,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -15050,7 +15280,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } else { zval *retval; @@ -15063,7 +15293,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); PZVAL_LOCK(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; if (0) { zval_ptr_dtor(&offset); @@ -15072,7 +15302,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H } } - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -15081,7 +15311,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OP { USE_OPLINE - if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) { + if (zend_is_by_ref_func_arg_fetch(opline, EX(call) TSRMLS_CC)) { /* Behave like FETCH_OBJ_W */ zend_free_op free_op1; zval *property; @@ -15106,7 +15336,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OP if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } else { @@ -15145,7 +15375,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCOD if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; PZVAL_UNLOCK(*EX_T(opline->result.var).var.ptr_ptr, &free_res); if (EX_T(opline->result.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) { @@ -15180,7 +15410,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN } else { } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* assign_obj has two opcodes! */ CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -15230,11 +15460,11 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN ALLOC_ZVAL(retval); ZVAL_STRINGL(retval, Z_STRVAL_P(EX_T((opline+1)->op2.var).str_offset.str)+EX_T((opline+1)->op2.var).str_offset.offset, 1, 1); INIT_PZVAL(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; } } else if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } } else if (UNEXPECTED(*variable_ptr_ptr == &EG(error_zval))) { if (IS_TMP_FREE(free_op_data1)) { @@ -15242,7 +15472,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN } if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } } else { if ((opline+1)->op1_type == IS_TMP_VAR) { @@ -15254,13 +15484,13 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN } if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(value); - AI_SET_PTR(&EX_T(opline->result.var), value); + EX_T(opline->result.var).var.ptr = value; } } FREE_OP_VAR_PTR(free_op_data2); FREE_OP_IF_VAR(free_op_data1); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* assign_dim has two opcodes! */ CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -15286,11 +15516,11 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER ALLOC_ZVAL(retval); ZVAL_STRINGL(retval, Z_STRVAL_P(EX_T(opline->op1.var).str_offset.str)+EX_T(opline->op1.var).str_offset.offset, 1, 1); INIT_PZVAL(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; } } else if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } } else if (IS_VAR == IS_VAR && UNEXPECTED(*variable_ptr_ptr == &EG(error_zval))) { if (0) { @@ -15298,7 +15528,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER } if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } } else { if (IS_CONST == IS_TMP_VAR) { @@ -15310,11 +15540,11 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER } if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(value); - AI_SET_PTR(&EX_T(opline->result.var), value); + EX_T(opline->result.var).var.ptr = value; } } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* zend_assign_to_variable() always takes care of op2, never free it! */ @@ -15393,10 +15623,12 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZEND_OPCO call->object = this_ptr; } } + + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -15518,6 +15750,8 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZE call->called_scope = Z_OBJCE_P(call->object); } } + + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; @@ -15609,8 +15843,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE } if (EXPECTED(zend_hash_quick_find(&ce->constants_table, Z_STRVAL_P(opline->op2.zv), Z_STRLEN_P(opline->op2.zv)+1, Z_HASH_P(opline->op2.zv), (void **) &value) == SUCCESS)) { - if (Z_TYPE_PP(value) == IS_CONSTANT_ARRAY || - (Z_TYPE_PP(value) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) { + if (IS_CONSTANT_TYPE(Z_TYPE_PP(value))) { zend_class_entry *old_scope = EG(scope); EG(scope) = ce; @@ -15624,7 +15857,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE } ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, *value); zval_copy_ctor(&EX_T(opline->result.var).tmp_var); - } else if (Z_STRLEN_P(opline->op2.zv) == sizeof("class")-1 && strcmp(Z_STRVAL_P(opline->op2.zv), "class") == 0) { + } else if (Z_STRLEN_P(opline->op2.zv) == sizeof("class")-1 && memcmp(Z_STRVAL_P(opline->op2.zv), "class", sizeof("class") - 1) == 0) { /* "class" is assigned as a case-sensitive keyword from zend_do_resolve_class_name */ ZVAL_STRINGL(&EX_T(opline->result.var).tmp_var, ce->name, ce->name_length, 1); } else { @@ -15667,7 +15900,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPC INIT_PZVAL_COPY(new_expr, expr_ptr); expr_ptr = new_expr; zendi_zval_copy_ctor(*expr_ptr); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); } else if (IS_VAR == IS_CV) { Z_ADDREF_P(expr_ptr); } @@ -15711,7 +15944,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPC zend_hash_next_index_insert(Z_ARRVAL(EX_T(opline->result.var).tmp_var), &expr_ptr, sizeof(zval *), NULL); } if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && opline->extended_value) { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -15780,7 +16013,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) { zval_ptr_dtor(&varname); } - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); HANDLE_EXCEPTION(); } if (UNEXPECTED(ce == NULL)) { @@ -15804,7 +16037,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) { zval_ptr_dtor(&varname); } - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -15899,7 +16132,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND } else { } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -15940,7 +16173,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND } else { } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -16010,7 +16243,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_VAR_CONST_HANDLER(ZEND_OPC if (IS_VAR != IS_CONST && varname == &tmp) { zval_dtor(&tmp); } - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); } if (opline->extended_value & ZEND_ISSET) { @@ -16020,7 +16253,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_VAR_CONST_HANDLER(ZEND_OPC ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 0); } } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - if (!isset || !i_zend_is_true(*value)) { + if (!isset || !i_zend_is_true(*value TSRMLS_CC)) { ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 1); } else { ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 0); @@ -16035,22 +16268,21 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CONST( { USE_OPLINE zend_free_op free_op1; - zval **container; + zval *container; zval **value = NULL; int result = 0; ulong hval; zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var_fast(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - + container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); offset = opline->op2.zv; - if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) { + if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) { HashTable *ht; int isset = 0; - ht = Z_ARRVAL_PP(container); + ht = Z_ARRVAL_P(container); switch (Z_TYPE_P(offset)) { case IS_DOUBLE: @@ -16069,9 +16301,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CONST( if (IS_CONST == IS_CONST) { hval = Z_HASH_P(offset); } else { - if (!prop_dim) { - ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop); - } + ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop); hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } if (zend_hash_quick_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, (void **) &value) == SUCCESS) { @@ -16095,27 +16325,27 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CONST( result = isset; } } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - if (!isset || !i_zend_is_true(*value)) { + if (!isset || !i_zend_is_true(*value TSRMLS_CC)) { result = 0; } else { result = 1; } } - } else if (Z_TYPE_PP(container) == IS_OBJECT) { + } else if (Z_TYPE_P(container) == IS_OBJECT) { if (0) { MAKE_REAL_ZVAL_PTR(offset); } if (prop_dim) { - if (Z_OBJ_HT_P(*container)->has_property) { - result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + if (Z_OBJ_HT_P(container)->has_property) { + result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); } else { zend_error(E_NOTICE, "Trying to check property of non-object"); result = 0; } } else { - if (Z_OBJ_HT_P(*container)->has_dimension) { - result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC); + if (Z_OBJ_HT_P(container)->has_dimension) { + result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC); } else { zend_error(E_NOTICE, "Trying to check element of non-array"); result = 0; @@ -16126,7 +16356,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CONST( } else { } - } else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */ + } else if (Z_TYPE_P(container) == IS_STRING && !prop_dim) { /* string offsets */ zval tmp; if (Z_TYPE_P(offset) != IS_LONG) { @@ -16144,11 +16374,11 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CONST( } if (Z_TYPE_P(offset) == IS_LONG) { if (opline->extended_value & ZEND_ISSET) { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) { + if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) { result = 1; } } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') { + if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container) && Z_STRVAL_P(container)[offset->value.lval] != '0') { result = 1; } } @@ -16165,7 +16395,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CONST( Z_LVAL(EX_T(opline->result.var).tmp_var) = !result; } - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -16247,7 +16477,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ generator->value = *value_ptr; } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; } } else { zval *value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); @@ -16267,7 +16497,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ } generator->value = copy; - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); } else { if (IS_VAR == IS_CV) { Z_ADDREF_P(value); @@ -16320,11 +16550,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ ZVAL_LONG(generator->key, generator->largest_used_integer_key); } - /* If a value is sent it should go into the result var */ - generator->send_target = &EX_T(opline->result.var); - - /* Initialize the sent value to NULL */ - EX_T(opline->result.var).tmp_var = EG(uninitialized_zval); + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = &EX_T(opline->result.var).var.ptr; + Z_ADDREF(EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); + } else { + generator->send_target = NULL; + } /* We increment to the next op, so we are at the correct position when the * generator is resumed. */ @@ -16346,7 +16580,7 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS fast_add_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); zval_dtor(free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -16361,7 +16595,7 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS fast_sub_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); zval_dtor(free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -16376,7 +16610,7 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS fast_mul_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); zval_dtor(free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -16391,7 +16625,7 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS fast_div_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); zval_dtor(free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -16406,7 +16640,7 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS fast_mod_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); zval_dtor(free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -16421,7 +16655,7 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) shift_left_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); zval_dtor(free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -16436,7 +16670,7 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) shift_right_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); zval_dtor(free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -16451,7 +16685,7 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_A concat_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); zval_dtor(free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -16466,7 +16700,7 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN is_identical_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); zval_dtor(free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -16483,7 +16717,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); Z_LVAL_P(result) = !Z_LVAL_P(result); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); zval_dtor(free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -16499,7 +16733,7 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER ZVAL_BOOL(result, fast_equal_function(result, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC)); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); zval_dtor(free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -16515,7 +16749,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN ZVAL_BOOL(result, fast_not_equal_function(result, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC)); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); zval_dtor(free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -16531,7 +16765,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL ZVAL_BOOL(result, fast_is_smaller_function(result, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC)); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); zval_dtor(free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -16547,7 +16781,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_VAR_TMP_HANDLER(ZEND_OPC ZVAL_BOOL(result, fast_is_smaller_or_equal_function(result, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC)); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); zval_dtor(free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -16562,7 +16796,7 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR bitwise_or_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); zval_dtor(free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -16577,7 +16811,7 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_A bitwise_and_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); zval_dtor(free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -16592,7 +16826,7 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_A bitwise_xor_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); zval_dtor(free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -16607,7 +16841,7 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER boolean_xor_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); zval_dtor(free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -16638,7 +16872,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(int (*bin if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); - EX_T(opline->result.var).var.ptr_ptr = NULL; } } else { /* here we are sure we are dealing with an object */ @@ -16658,7 +16891,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(int (*bin if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*zptr); EX_T(opline->result.var).var.ptr = *zptr; - EX_T(opline->result.var).var.ptr_ptr = NULL; } } } @@ -16697,7 +16929,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(int (*bin if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(z); EX_T(opline->result.var).var.ptr = z; - EX_T(opline->result.var).var.ptr_ptr = NULL; } zval_ptr_dtor(&z); } else { @@ -16705,7 +16936,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(int (*bin if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); - EX_T(opline->result.var).var.ptr_ptr = NULL; } } } @@ -16718,7 +16948,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(int (*bin FREE_OP(free_op_data1); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* assign_obj has two opcodes! */ CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -16770,10 +17000,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_TMP(int (*binary_ if (UNEXPECTED(*var_ptr == &EG(error_zval))) { if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } zval_dtor(free_op2.var); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); if (opline->extended_value == ZEND_ASSIGN_DIM) { ZEND_VM_INC_OPCODE(); @@ -16798,18 +17028,18 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_TMP(int (*binary_ if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*var_ptr); - AI_SET_PTR(&EX_T(opline->result.var), *var_ptr); + EX_T(opline->result.var).var.ptr = *var_ptr; } zval_dtor(free_op2.var); if (opline->extended_value == ZEND_ASSIGN_DIM) { FREE_OP(free_op_data1); FREE_OP_VAR_PTR(free_op_data2); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); } else { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); } ZEND_VM_NEXT_OPCODE(); @@ -16899,7 +17129,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_TMP(incdec_t i PZVAL_LOCK(&EG(uninitialized_zval)); *retval = &EG(uninitialized_zval); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -16959,7 +17189,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_TMP(incdec_t i } else { zval_dtor(free_op2.var); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -17000,7 +17230,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_TMP(incdec_t zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); zval_dtor(free_op2.var); ZVAL_NULL(retval); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -17061,7 +17291,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_TMP(incdec_t } else { zval_dtor(free_op2.var); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -17080,24 +17310,15 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAND { USE_OPLINE zend_free_op free_op1, free_op2; - zval **container; + zval *container; SAVE_OPLINE(); - - if (IS_VAR == IS_TMP_VAR || IS_VAR == IS_CONST) { - zval *container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC); - zval_dtor(free_op2.var); - zval_ptr_dtor(&free_op1.var); - } else { - container = _get_zval_ptr_ptr_var_fast(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC); - zval_dtor(free_op2.var); - if (IS_VAR == IS_VAR && !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { - zval_ptr_dtor(&free_op1.var); - } + container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC); + zval_dtor(free_op2.var); + if (IS_VAR != IS_VAR || !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { + zval_ptr_dtor_nogc(&free_op1.var); } - CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -17119,7 +17340,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAND if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* We are going to assign the result by reference */ if (UNEXPECTED(opline->extended_value != 0)) { @@ -17153,7 +17374,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -17162,13 +17383,13 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN { USE_OPLINE zend_free_op free_op1, free_op2; - zval **container; + zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var_fast(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_IS TSRMLS_CC); zval_dtor(free_op2.var); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -17177,12 +17398,11 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCO { USE_OPLINE zend_free_op free_op1, free_op2; - zval **container; SAVE_OPLINE(); - if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) { - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + if (zend_is_by_ref_func_arg_fetch(opline, EX(call) TSRMLS_CC)) { + zval **container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } @@ -17191,15 +17411,17 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCO EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } zval_dtor(free_op2.var); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; } else { + zval *container; + if (IS_TMP_VAR == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } - container = _get_zval_ptr_ptr_var_fast(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC); zval_dtor(free_op2.var); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -17227,7 +17449,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_ if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; if (UNEXPECTED(EX_T(opline->result.var).var.ptr_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); ZEND_VM_NEXT_OPCODE(); @@ -17262,7 +17484,7 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_VAR_TMP(ZE UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { zend_error(E_NOTICE, "Trying to get property of non-object"); PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); zval_dtor(free_op2.var); } else { zval *retval; @@ -17275,7 +17497,7 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_VAR_TMP(ZE retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); PZVAL_LOCK(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; if (1) { zval_ptr_dtor(&offset); @@ -17284,7 +17506,7 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_VAR_TMP(ZE } } - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -17304,11 +17526,6 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAND SAVE_OPLINE(); property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (IS_VAR == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) { - PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); - EX_T(opline->op1.var).var.ptr = *EX_T(opline->op1.var).var.ptr_ptr; - } - if (1) { MAKE_REAL_ZVAL_PTR(property); } @@ -17326,7 +17543,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAND if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* We are going to assign the result by reference */ if (opline->extended_value & ZEND_FETCH_MAKE_REF) { @@ -17369,7 +17586,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -17389,7 +17606,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); zval_dtor(free_op2.var); } else { zval *retval; @@ -17402,7 +17619,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); PZVAL_LOCK(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; if (1) { zval_ptr_dtor(&offset); @@ -17411,7 +17628,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN } } - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -17420,7 +17637,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCO { USE_OPLINE - if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) { + if (zend_is_by_ref_func_arg_fetch(opline, EX(call) TSRMLS_CC)) { /* Behave like FETCH_OBJ_W */ zend_free_op free_op1, free_op2; zval *property; @@ -17445,7 +17662,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCO if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } else { @@ -17484,7 +17701,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_ if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; PZVAL_UNLOCK(*EX_T(opline->result.var).var.ptr_ptr, &free_res); if (EX_T(opline->result.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) { @@ -17519,7 +17736,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL } else { zval_dtor(free_op2.var); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* assign_obj has two opcodes! */ CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -17570,11 +17787,11 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL ALLOC_ZVAL(retval); ZVAL_STRINGL(retval, Z_STRVAL_P(EX_T((opline+1)->op2.var).str_offset.str)+EX_T((opline+1)->op2.var).str_offset.offset, 1, 1); INIT_PZVAL(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; } } else if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } } else if (UNEXPECTED(*variable_ptr_ptr == &EG(error_zval))) { if (IS_TMP_FREE(free_op_data1)) { @@ -17582,7 +17799,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL } if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } } else { if ((opline+1)->op1_type == IS_TMP_VAR) { @@ -17594,13 +17811,13 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL } if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(value); - AI_SET_PTR(&EX_T(opline->result.var), value); + EX_T(opline->result.var).var.ptr = value; } } FREE_OP_VAR_PTR(free_op_data2); FREE_OP_IF_VAR(free_op_data1); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* assign_dim has two opcodes! */ CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -17626,11 +17843,11 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_A ALLOC_ZVAL(retval); ZVAL_STRINGL(retval, Z_STRVAL_P(EX_T(opline->op1.var).str_offset.str)+EX_T(opline->op1.var).str_offset.offset, 1, 1); INIT_PZVAL(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; } } else if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } } else if (IS_VAR == IS_VAR && UNEXPECTED(*variable_ptr_ptr == &EG(error_zval))) { if (1) { @@ -17638,7 +17855,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_A } if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } } else { if (IS_TMP_VAR == IS_TMP_VAR) { @@ -17650,11 +17867,11 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_A } if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(value); - AI_SET_PTR(&EX_T(opline->result.var), value); + EX_T(opline->result.var).var.ptr = value; } } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* zend_assign_to_variable() always takes care of op2, never free it! */ @@ -17733,11 +17950,13 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE call->object = this_ptr; } } + + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; zval_dtor(free_op2.var); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -17859,6 +18078,8 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND call->called_scope = Z_OBJCE_P(call->object); } } + + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; @@ -17912,7 +18133,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP_HANDLER(ZEND_OPCOD INIT_PZVAL_COPY(new_expr, expr_ptr); expr_ptr = new_expr; zendi_zval_copy_ctor(*expr_ptr); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); } else if (IS_VAR == IS_CV) { Z_ADDREF_P(expr_ptr); } @@ -17956,7 +18177,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP_HANDLER(ZEND_OPCOD zend_hash_next_index_insert(Z_ARRVAL(EX_T(opline->result.var).tmp_var), &expr_ptr, sizeof(zval *), NULL); } if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && opline->extended_value) { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -18066,7 +18287,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLE } else { zval_dtor(free_op2.var); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -18107,7 +18328,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLE } else { zval_dtor(free_op2.var); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -18117,22 +18338,21 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_TMP(in { USE_OPLINE zend_free_op free_op1, free_op2; - zval **container; + zval *container; zval **value = NULL; int result = 0; ulong hval; zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var_fast(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - + container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) { + if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) { HashTable *ht; int isset = 0; - ht = Z_ARRVAL_PP(container); + ht = Z_ARRVAL_P(container); switch (Z_TYPE_P(offset)) { case IS_DOUBLE: @@ -18151,9 +18371,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_TMP(in if (IS_TMP_VAR == IS_CONST) { hval = Z_HASH_P(offset); } else { - if (!prop_dim) { - ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop); - } + ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop); hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } if (zend_hash_quick_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, (void **) &value) == SUCCESS) { @@ -18177,27 +18395,27 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_TMP(in result = isset; } } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - if (!isset || !i_zend_is_true(*value)) { + if (!isset || !i_zend_is_true(*value TSRMLS_CC)) { result = 0; } else { result = 1; } } zval_dtor(free_op2.var); - } else if (Z_TYPE_PP(container) == IS_OBJECT) { + } else if (Z_TYPE_P(container) == IS_OBJECT) { if (1) { MAKE_REAL_ZVAL_PTR(offset); } if (prop_dim) { - if (Z_OBJ_HT_P(*container)->has_property) { - result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + if (Z_OBJ_HT_P(container)->has_property) { + result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); } else { zend_error(E_NOTICE, "Trying to check property of non-object"); result = 0; } } else { - if (Z_OBJ_HT_P(*container)->has_dimension) { - result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC); + if (Z_OBJ_HT_P(container)->has_dimension) { + result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC); } else { zend_error(E_NOTICE, "Trying to check element of non-array"); result = 0; @@ -18208,7 +18426,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_TMP(in } else { zval_dtor(free_op2.var); } - } else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */ + } else if (Z_TYPE_P(container) == IS_STRING && !prop_dim) { /* string offsets */ zval tmp; if (Z_TYPE_P(offset) != IS_LONG) { @@ -18226,11 +18444,11 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_TMP(in } if (Z_TYPE_P(offset) == IS_LONG) { if (opline->extended_value & ZEND_ISSET) { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) { + if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) { result = 1; } } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') { + if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container) && Z_STRVAL_P(container)[offset->value.lval] != '0') { result = 1; } } @@ -18247,7 +18465,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_TMP(in Z_LVAL(EX_T(opline->result.var).tmp_var) = !result; } - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -18329,7 +18547,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR generator->value = *value_ptr; } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; } } else { zval *value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); @@ -18349,7 +18567,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR } generator->value = copy; - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); } else { if (IS_VAR == IS_CV) { Z_ADDREF_P(value); @@ -18402,11 +18620,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR ZVAL_LONG(generator->key, generator->largest_used_integer_key); } - /* If a value is sent it should go into the result var */ - generator->send_target = &EX_T(opline->result.var); - - /* Initialize the sent value to NULL */ - EX_T(opline->result.var).tmp_var = EG(uninitialized_zval); + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = &EX_T(opline->result.var).var.ptr; + Z_ADDREF(EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); + } else { + generator->send_target = NULL; + } /* We increment to the next op, so we are at the correct position when the * generator is resumed. */ @@ -18428,8 +18650,8 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS fast_add_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op1.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18443,8 +18665,8 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS fast_sub_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op1.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18458,8 +18680,8 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS fast_mul_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op1.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18473,8 +18695,8 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS fast_div_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op1.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18488,8 +18710,8 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS fast_mod_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op1.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18503,8 +18725,8 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) shift_left_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op1.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18518,8 +18740,8 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) shift_right_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op1.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18533,8 +18755,8 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_A concat_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op1.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18548,8 +18770,8 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN is_identical_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op1.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18565,8 +18787,8 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); Z_LVAL_P(result) = !Z_LVAL_P(result); - zval_ptr_dtor(&free_op1.var); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op1.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18581,8 +18803,8 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER ZVAL_BOOL(result, fast_equal_function(result, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC)); - zval_ptr_dtor(&free_op1.var); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op1.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18597,8 +18819,8 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN ZVAL_BOOL(result, fast_not_equal_function(result, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC)); - zval_ptr_dtor(&free_op1.var); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op1.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18613,8 +18835,8 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL ZVAL_BOOL(result, fast_is_smaller_function(result, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC)); - zval_ptr_dtor(&free_op1.var); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op1.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18629,8 +18851,8 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_VAR_VAR_HANDLER(ZEND_OPC ZVAL_BOOL(result, fast_is_smaller_or_equal_function(result, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC)); - zval_ptr_dtor(&free_op1.var); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op1.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18644,8 +18866,8 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR bitwise_or_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op1.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18659,8 +18881,8 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_A bitwise_and_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op1.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18674,8 +18896,8 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_A bitwise_xor_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op1.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18689,8 +18911,8 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER boolean_xor_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op1.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18714,13 +18936,12 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(int (*bin if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to assign property of non-object"); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); FREE_OP(free_op_data1); if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); - EX_T(opline->result.var).var.ptr_ptr = NULL; } } else { /* here we are sure we are dealing with an object */ @@ -18740,7 +18961,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(int (*bin if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*zptr); EX_T(opline->result.var).var.ptr = *zptr; - EX_T(opline->result.var).var.ptr_ptr = NULL; } } } @@ -18779,7 +18999,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(int (*bin if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(z); EX_T(opline->result.var).var.ptr = z; - EX_T(opline->result.var).var.ptr_ptr = NULL; } zval_ptr_dtor(&z); } else { @@ -18787,7 +19006,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(int (*bin if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); - EX_T(opline->result.var).var.ptr_ptr = NULL; } } } @@ -18795,12 +19013,12 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(int (*bin if (0) { zval_ptr_dtor(&property); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } FREE_OP(free_op_data1); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* assign_obj has two opcodes! */ CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -18852,10 +19070,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_VAR(int (*binary_ if (UNEXPECTED(*var_ptr == &EG(error_zval))) { if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } - zval_ptr_dtor(&free_op2.var); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op2.var); + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); if (opline->extended_value == ZEND_ASSIGN_DIM) { ZEND_VM_INC_OPCODE(); @@ -18880,18 +19098,18 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_VAR(int (*binary_ if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*var_ptr); - AI_SET_PTR(&EX_T(opline->result.var), *var_ptr); + EX_T(opline->result.var).var.ptr = *var_ptr; } - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); if (opline->extended_value == ZEND_ASSIGN_DIM) { FREE_OP(free_op_data1); FREE_OP_VAR_PTR(free_op_data2); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); } else { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); } ZEND_VM_NEXT_OPCODE(); @@ -18976,12 +19194,12 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_VAR(incdec_t i if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); *retval = &EG(uninitialized_zval); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19039,9 +19257,9 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_VAR(incdec_t i if (0) { zval_ptr_dtor(&property); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19080,9 +19298,9 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_VAR(incdec_t if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); ZVAL_NULL(retval); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19141,9 +19359,9 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_VAR(incdec_t if (0) { zval_ptr_dtor(&property); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19192,7 +19410,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_VAR(int type, ZE if (IS_VAR != IS_CONST && varname == &tmp_varname) { zval_dtor(&tmp_varname); } - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19202,7 +19420,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_VAR(int type, ZE ce = EX_T(opline->op2.var).class_entry; } retval = zend_std_get_static_property(ce, Z_STRVAL_P(varname), Z_STRLEN_P(varname), 0, ((IS_VAR == IS_CONST) ? opline->op1.literal : NULL) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); } else { target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC); /* @@ -19239,11 +19457,11 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_VAR(int type, ZE switch (opline->extended_value & ZEND_FETCH_TYPE_MASK) { case ZEND_FETCH_GLOBAL: if (IS_VAR != IS_TMP_VAR) { - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); } break; case ZEND_FETCH_LOCAL: - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); break; case ZEND_FETCH_STATIC: zval_update_constant(retval, (void*) 1 TSRMLS_CC); @@ -19267,7 +19485,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_VAR(int type, ZE switch (type) { case BP_VAR_R: case BP_VAR_IS: - AI_SET_PTR(&EX_T(opline->result.var), *retval); + EX_T(opline->result.var).var.ptr = *retval; break; case BP_VAR_UNSET: { zend_free_op free_res; @@ -19307,7 +19525,7 @@ static int ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_H { USE_OPLINE - return zend_fetch_var_address_helper_SPEC_VAR_VAR(ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + return zend_fetch_var_address_helper_SPEC_VAR_VAR(zend_is_by_ref_func_arg_fetch(opline, EX(call) TSRMLS_CC) ? BP_VAR_W : BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } static int ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -19324,24 +19542,15 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAND { USE_OPLINE zend_free_op free_op1, free_op2; - zval **container; + zval *container; SAVE_OPLINE(); - - if (IS_VAR == IS_TMP_VAR || IS_VAR == IS_CONST) { - zval *container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); - zval_ptr_dtor(&free_op1.var); - } else { - container = _get_zval_ptr_ptr_var_fast(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); - if (IS_VAR == IS_VAR && !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { - zval_ptr_dtor(&free_op1.var); - } + container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC); + zval_ptr_dtor_nogc(&free_op2.var); + if (IS_VAR != IS_VAR || !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { + zval_ptr_dtor_nogc(&free_op1.var); } - CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19359,11 +19568,11 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAND zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_W TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* We are going to assign the result by reference */ if (UNEXPECTED(opline->extended_value != 0)) { @@ -19393,11 +19602,11 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_RW TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19406,13 +19615,13 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN { USE_OPLINE zend_free_op free_op1, free_op2; - zval **container; + zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var_fast(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_IS TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op2.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19421,12 +19630,11 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_VAR_HANDLER(ZEND_OPCO { USE_OPLINE zend_free_op free_op1, free_op2; - zval **container; SAVE_OPLINE(); - if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) { - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + if (zend_is_by_ref_func_arg_fetch(opline, EX(call) TSRMLS_CC)) { + zval **container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } @@ -19434,16 +19642,18 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_VAR_HANDLER(ZEND_OPCO if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - zval_ptr_dtor(&free_op2.var); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + zval_ptr_dtor_nogc(&free_op2.var); + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; } else { + zval *container; + if (IS_VAR == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } - container = _get_zval_ptr_ptr_var_fast(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op2.var); + zval_ptr_dtor_nogc(&free_op1.var); } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -19467,11 +19677,11 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_ zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_UNSET TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; if (UNEXPECTED(EX_T(opline->result.var).var.ptr_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); ZEND_VM_NEXT_OPCODE(); @@ -19506,8 +19716,8 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_VAR_VAR(ZE UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { zend_error(E_NOTICE, "Trying to get property of non-object"); PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); - zval_ptr_dtor(&free_op2.var); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); + zval_ptr_dtor_nogc(&free_op2.var); } else { zval *retval; @@ -19519,16 +19729,16 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_VAR_VAR(ZE retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); PZVAL_LOCK(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; if (0) { zval_ptr_dtor(&offset); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } } - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19548,11 +19758,6 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAND SAVE_OPLINE(); property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (IS_VAR == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) { - PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); - EX_T(opline->op1.var).var.ptr = *EX_T(opline->op1.var).var.ptr_ptr; - } - if (0) { MAKE_REAL_ZVAL_PTR(property); } @@ -19565,12 +19770,12 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAND if (0) { zval_ptr_dtor(&property); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* We are going to assign the result by reference */ if (opline->extended_value & ZEND_FETCH_MAKE_REF) { @@ -19608,12 +19813,12 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN if (0) { zval_ptr_dtor(&property); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19633,8 +19838,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); - zval_ptr_dtor(&free_op2.var); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); + zval_ptr_dtor_nogc(&free_op2.var); } else { zval *retval; @@ -19646,16 +19851,16 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); PZVAL_LOCK(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; if (0) { zval_ptr_dtor(&offset); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } } - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19664,7 +19869,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_VAR_HANDLER(ZEND_OPCO { USE_OPLINE - if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) { + if (zend_is_by_ref_func_arg_fetch(opline, EX(call) TSRMLS_CC)) { /* Behave like FETCH_OBJ_W */ zend_free_op free_op1, free_op2; zval *property; @@ -19684,12 +19889,12 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_VAR_HANDLER(ZEND_OPCO if (0) { zval_ptr_dtor(&property); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } else { @@ -19723,12 +19928,12 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_ if (0) { zval_ptr_dtor(&property); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; PZVAL_UNLOCK(*EX_T(opline->result.var).var.ptr_ptr, &free_res); if (EX_T(opline->result.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) { @@ -19761,9 +19966,9 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL if (0) { zval_ptr_dtor(&property_name); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* assign_obj has two opcodes! */ CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -19793,7 +19998,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL if (0) { zval_ptr_dtor(&property_name); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } } else { zend_free_op free_op2, free_op_data1, free_op_data2; @@ -19802,7 +20007,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL zval **variable_ptr_ptr; zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), object_ptr, dim, IS_VAR, BP_VAR_W TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); @@ -19814,11 +20019,11 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL ALLOC_ZVAL(retval); ZVAL_STRINGL(retval, Z_STRVAL_P(EX_T((opline+1)->op2.var).str_offset.str)+EX_T((opline+1)->op2.var).str_offset.offset, 1, 1); INIT_PZVAL(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; } } else if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } } else if (UNEXPECTED(*variable_ptr_ptr == &EG(error_zval))) { if (IS_TMP_FREE(free_op_data1)) { @@ -19826,7 +20031,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL } if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } } else { if ((opline+1)->op1_type == IS_TMP_VAR) { @@ -19838,13 +20043,13 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL } if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(value); - AI_SET_PTR(&EX_T(opline->result.var), value); + EX_T(opline->result.var).var.ptr = value; } } FREE_OP_VAR_PTR(free_op_data2); FREE_OP_IF_VAR(free_op_data1); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* assign_dim has two opcodes! */ CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -19870,11 +20075,11 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_A ALLOC_ZVAL(retval); ZVAL_STRINGL(retval, Z_STRVAL_P(EX_T(opline->op1.var).str_offset.str)+EX_T(opline->op1.var).str_offset.offset, 1, 1); INIT_PZVAL(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; } } else if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } } else if (IS_VAR == IS_VAR && UNEXPECTED(*variable_ptr_ptr == &EG(error_zval))) { if (0) { @@ -19882,7 +20087,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_A } if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } } else { if (IS_VAR == IS_TMP_VAR) { @@ -19894,14 +20099,14 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_A } if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(value); - AI_SET_PTR(&EX_T(opline->result.var), value); + EX_T(opline->result.var).var.ptr = value; } } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* zend_assign_to_variable() always takes care of op2, never free it! */ - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -19927,7 +20132,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL } zend_error(E_STRICT, "Only variables should be assigned by reference"); if (UNEXPECTED(EG(exception) != NULL)) { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + if (free_op2.var) {zval_ptr_dtor_nogc(&free_op2.var);}; HANDLE_EXCEPTION(); } return ZEND_ASSIGN_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -19951,11 +20156,11 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*variable_ptr_ptr); - AI_SET_PTR(&EX_T(opline->result.var), *variable_ptr_ptr); + EX_T(opline->result.var).var.ptr = *variable_ptr_ptr; } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; + if (free_op2.var) {zval_ptr_dtor_nogc(&free_op2.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -20013,7 +20218,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE } } else { if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); HANDLE_EXCEPTION(); } zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval); @@ -20032,11 +20237,13 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE call->object = this_ptr; } } + + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; - zval_ptr_dtor(&free_op2.var); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op2.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -20126,7 +20333,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND } } if (IS_VAR != IS_CONST) { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } } else { if (UNEXPECTED(ce->constructor == NULL)) { @@ -20158,6 +20365,8 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND call->called_scope = Z_OBJCE_P(call->object); } } + + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; @@ -20175,7 +20384,7 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -20211,7 +20420,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_VAR_HANDLER(ZEND_OPCOD INIT_PZVAL_COPY(new_expr, expr_ptr); expr_ptr = new_expr; zendi_zval_copy_ctor(*expr_ptr); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); } else if (IS_VAR == IS_CV) { Z_ADDREF_P(expr_ptr); } @@ -20250,12 +20459,12 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_VAR_HANDLER(ZEND_OPCOD /* do nothing */ break; } - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } else { zend_hash_next_index_insert(Z_ARRVAL(EX_T(opline->result.var).tmp_var), &expr_ptr, sizeof(zval *), NULL); } if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && opline->extended_value) { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -20324,7 +20533,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) { zval_ptr_dtor(&varname); } - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); HANDLE_EXCEPTION(); } if (UNEXPECTED(ce == NULL)) { @@ -20348,7 +20557,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) { zval_ptr_dtor(&varname); } - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -20416,7 +20625,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE zend_error(E_WARNING, "Illegal offset type in unset"); break; } - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); break; } case IS_OBJECT: @@ -20430,20 +20639,20 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE if (0) { zval_ptr_dtor(&offset); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } break; case IS_STRING: zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); ZEND_VM_CONTINUE(); /* bailed out before */ default: - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); break; } } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -20476,15 +20685,15 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE if (0) { zval_ptr_dtor(&offset); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -20554,7 +20763,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_VAR_VAR_HANDLER(ZEND_OPCOD if (IS_VAR != IS_CONST && varname == &tmp) { zval_dtor(&tmp); } - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); } if (opline->extended_value & ZEND_ISSET) { @@ -20564,7 +20773,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_VAR_VAR_HANDLER(ZEND_OPCOD ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 0); } } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - if (!isset || !i_zend_is_true(*value)) { + if (!isset || !i_zend_is_true(*value TSRMLS_CC)) { ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 1); } else { ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 0); @@ -20579,22 +20788,21 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_VAR(in { USE_OPLINE zend_free_op free_op1, free_op2; - zval **container; + zval *container; zval **value = NULL; int result = 0; ulong hval; zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var_fast(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - + container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) { + if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) { HashTable *ht; int isset = 0; - ht = Z_ARRVAL_PP(container); + ht = Z_ARRVAL_P(container); switch (Z_TYPE_P(offset)) { case IS_DOUBLE: @@ -20613,9 +20821,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_VAR(in if (IS_VAR == IS_CONST) { hval = Z_HASH_P(offset); } else { - if (!prop_dim) { - ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop); - } + ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop); hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } if (zend_hash_quick_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, (void **) &value) == SUCCESS) { @@ -20639,27 +20845,27 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_VAR(in result = isset; } } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - if (!isset || !i_zend_is_true(*value)) { + if (!isset || !i_zend_is_true(*value TSRMLS_CC)) { result = 0; } else { result = 1; } } - zval_ptr_dtor(&free_op2.var); - } else if (Z_TYPE_PP(container) == IS_OBJECT) { + zval_ptr_dtor_nogc(&free_op2.var); + } else if (Z_TYPE_P(container) == IS_OBJECT) { if (0) { MAKE_REAL_ZVAL_PTR(offset); } if (prop_dim) { - if (Z_OBJ_HT_P(*container)->has_property) { - result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + if (Z_OBJ_HT_P(container)->has_property) { + result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); } else { zend_error(E_NOTICE, "Trying to check property of non-object"); result = 0; } } else { - if (Z_OBJ_HT_P(*container)->has_dimension) { - result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC); + if (Z_OBJ_HT_P(container)->has_dimension) { + result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC); } else { zend_error(E_NOTICE, "Trying to check element of non-array"); result = 0; @@ -20668,9 +20874,9 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_VAR(in if (0) { zval_ptr_dtor(&offset); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } - } else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */ + } else if (Z_TYPE_P(container) == IS_STRING && !prop_dim) { /* string offsets */ zval tmp; if (Z_TYPE_P(offset) != IS_LONG) { @@ -20688,18 +20894,18 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_VAR(in } if (Z_TYPE_P(offset) == IS_LONG) { if (opline->extended_value & ZEND_ISSET) { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) { + if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) { result = 1; } } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') { + if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container) && Z_STRVAL_P(container)[offset->value.lval] != '0') { result = 1; } } } - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } Z_TYPE(EX_T(opline->result.var).tmp_var) = IS_BOOL; @@ -20709,7 +20915,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_VAR(in Z_LVAL(EX_T(opline->result.var).tmp_var) = !result; } - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -20791,7 +20997,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR generator->value = *value_ptr; } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; } } else { zval *value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); @@ -20811,7 +21017,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR } generator->value = copy; - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); } else { if (IS_VAR == IS_CV) { Z_ADDREF_P(value); @@ -20856,7 +21062,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR generator->largest_used_integer_key = Z_LVAL_P(generator->key); } - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } else { /* If no key was specified we use auto-increment keys */ generator->largest_used_integer_key++; @@ -20865,11 +21071,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR ZVAL_LONG(generator->key, generator->largest_used_integer_key); } - /* If a value is sent it should go into the result var */ - generator->send_target = &EX_T(opline->result.var); - - /* Initialize the sent value to NULL */ - EX_T(opline->result.var).tmp_var = EG(uninitialized_zval); + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = &EX_T(opline->result.var).var.ptr; + Z_ADDREF(EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); + } else { + generator->send_target = NULL; + } /* We increment to the next op, so we are at the correct position when the * generator is resumed. */ @@ -20907,7 +21117,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(int (* if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); - EX_T(opline->result.var).var.ptr_ptr = NULL; } } else { /* here we are sure we are dealing with an object */ @@ -20927,7 +21136,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(int (* if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*zptr); EX_T(opline->result.var).var.ptr = *zptr; - EX_T(opline->result.var).var.ptr_ptr = NULL; } } } @@ -20966,7 +21174,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(int (* if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(z); EX_T(opline->result.var).var.ptr = z; - EX_T(opline->result.var).var.ptr_ptr = NULL; } zval_ptr_dtor(&z); } else { @@ -20974,7 +21181,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(int (* if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); - EX_T(opline->result.var).var.ptr_ptr = NULL; } } } @@ -20987,7 +21193,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(int (* FREE_OP(free_op_data1); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* assign_obj has two opcodes! */ CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -21039,10 +21245,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_UNUSED(int (*bina if (UNEXPECTED(*var_ptr == &EG(error_zval))) { if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); if (opline->extended_value == ZEND_ASSIGN_DIM) { ZEND_VM_INC_OPCODE(); @@ -21067,17 +21273,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_UNUSED(int (*bina if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*var_ptr); - AI_SET_PTR(&EX_T(opline->result.var), *var_ptr); + EX_T(opline->result.var).var.ptr = *var_ptr; } if (opline->extended_value == ZEND_ASSIGN_DIM) { FREE_OP(free_op_data1); FREE_OP_VAR_PTR(free_op_data2); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); } else { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); } ZEND_VM_NEXT_OPCODE(); @@ -21172,7 +21378,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_UNUSED(int type, if (IS_VAR != IS_CONST && varname == &tmp_varname) { zval_dtor(&tmp_varname); } - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -21182,7 +21388,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_UNUSED(int type, ce = EX_T(opline->op2.var).class_entry; } retval = zend_std_get_static_property(ce, Z_STRVAL_P(varname), Z_STRLEN_P(varname), 0, ((IS_VAR == IS_CONST) ? opline->op1.literal : NULL) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); } else { target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC); /* @@ -21219,11 +21425,11 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_UNUSED(int type, switch (opline->extended_value & ZEND_FETCH_TYPE_MASK) { case ZEND_FETCH_GLOBAL: if (IS_VAR != IS_TMP_VAR) { - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); } break; case ZEND_FETCH_LOCAL: - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); break; case ZEND_FETCH_STATIC: zval_update_constant(retval, (void*) 1 TSRMLS_CC); @@ -21247,7 +21453,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_UNUSED(int type, switch (type) { case BP_VAR_R: case BP_VAR_IS: - AI_SET_PTR(&EX_T(opline->result.var), *retval); + EX_T(opline->result.var).var.ptr = *retval; break; case BP_VAR_UNSET: { zend_free_op free_res; @@ -21287,7 +21493,7 @@ static int ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCOD { USE_OPLINE - return zend_fetch_var_address_helper_SPEC_VAR_UNUSED(ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + return zend_fetch_var_address_helper_SPEC_VAR_UNUSED(zend_is_by_ref_func_arg_fetch(opline, EX(call) TSRMLS_CC) ? BP_VAR_W : BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } static int ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -21317,7 +21523,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_H if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* We are going to assign the result by reference */ if (UNEXPECTED(opline->extended_value != 0)) { @@ -21351,7 +21557,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_ if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -21360,12 +21566,11 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED_HANDLER(ZEND_O { USE_OPLINE zend_free_op free_op1; - zval **container; SAVE_OPLINE(); - if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) { - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + if (zend_is_by_ref_func_arg_fetch(opline, EX(call) TSRMLS_CC)) { + zval **container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } @@ -21374,15 +21579,17 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED_HANDLER(ZEND_O EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; } else { + zval *container; + if (IS_UNUSED == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } - container = _get_zval_ptr_ptr_var_fast(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, NULL, IS_UNUSED, BP_VAR_R TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -21431,11 +21638,11 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HA ALLOC_ZVAL(retval); ZVAL_STRINGL(retval, Z_STRVAL_P(EX_T((opline+1)->op2.var).str_offset.str)+EX_T((opline+1)->op2.var).str_offset.offset, 1, 1); INIT_PZVAL(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; } } else if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } } else if (UNEXPECTED(*variable_ptr_ptr == &EG(error_zval))) { if (IS_TMP_FREE(free_op_data1)) { @@ -21443,7 +21650,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HA } if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } } else { if ((opline+1)->op1_type == IS_TMP_VAR) { @@ -21455,13 +21662,13 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HA } if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(value); - AI_SET_PTR(&EX_T(opline->result.var), value); + EX_T(opline->result.var).var.ptr = value; } } FREE_OP_VAR_PTR(free_op_data2); FREE_OP_IF_VAR(free_op_data1); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* assign_dim has two opcodes! */ CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -21584,6 +21791,8 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED_HANDLER(Z call->called_scope = Z_OBJCE_P(call->object); } } + + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; @@ -21622,7 +21831,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OP INIT_PZVAL_COPY(new_expr, expr_ptr); expr_ptr = new_expr; zendi_zval_copy_ctor(*expr_ptr); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); } else if (IS_VAR == IS_CV) { Z_ADDREF_P(expr_ptr); } @@ -21666,7 +21875,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OP zend_hash_next_index_insert(Z_ARRVAL(EX_T(opline->result.var).tmp_var), &expr_ptr, sizeof(zval *), NULL); } if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && opline->extended_value) { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -21735,7 +21944,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HAN } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) { zval_ptr_dtor(&varname); } - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); HANDLE_EXCEPTION(); } if (UNEXPECTED(ce == NULL)) { @@ -21759,7 +21968,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HAN } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) { zval_ptr_dtor(&varname); } - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -21828,7 +22037,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_VAR_UNUSED_HANDLER(ZEND_OP if (IS_VAR != IS_CONST && varname == &tmp) { zval_dtor(&tmp); } - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); } if (opline->extended_value & ZEND_ISSET) { @@ -21838,7 +22047,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_VAR_UNUSED_HANDLER(ZEND_OP ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 0); } } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - if (!isset || !i_zend_is_true(*value)) { + if (!isset || !i_zend_is_true(*value TSRMLS_CC)) { ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 1); } else { ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 0); @@ -21936,7 +22145,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER generator->value = *value_ptr; } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; } } else { zval *value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); @@ -21956,7 +22165,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER } generator->value = copy; - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); } else { if (IS_VAR == IS_CV) { Z_ADDREF_P(value); @@ -22009,11 +22218,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER ZVAL_LONG(generator->key, generator->largest_used_integer_key); } - /* If a value is sent it should go into the result var */ - generator->send_target = &EX_T(opline->result.var); - - /* Initialize the sent value to NULL */ - EX_T(opline->result.var).tmp_var = EG(uninitialized_zval); + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = &EX_T(opline->result.var).var.ptr; + Z_ADDREF(EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); + } else { + generator->send_target = NULL; + } /* We increment to the next op, so we are at the correct position when the * generator is resumed. */ @@ -22035,7 +22248,7 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) fast_add_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -22050,7 +22263,7 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) fast_sub_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -22065,7 +22278,7 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) fast_mul_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -22080,7 +22293,7 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) fast_div_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -22095,7 +22308,7 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) fast_mod_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -22110,7 +22323,7 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) shift_left_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -22125,7 +22338,7 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) shift_right_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -22140,7 +22353,7 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_AR concat_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -22155,7 +22368,7 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND is_identical_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -22172,7 +22385,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); Z_LVAL_P(result) = !Z_LVAL_P(result); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -22188,7 +22401,7 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ ZVAL_BOOL(result, fast_equal_function(result, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC)); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -22204,7 +22417,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND ZVAL_BOOL(result, fast_not_equal_function(result, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC)); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -22220,7 +22433,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE ZVAL_BOOL(result, fast_is_smaller_function(result, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC)); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -22236,7 +22449,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_VAR_CV_HANDLER(ZEND_OPCO ZVAL_BOOL(result, fast_is_smaller_or_equal_function(result, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC)); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -22251,7 +22464,7 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG bitwise_or_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -22266,7 +22479,7 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_AR bitwise_and_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -22281,7 +22494,7 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_AR bitwise_xor_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -22296,7 +22509,7 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ boolean_xor_function(&EX_T(opline->result.var).tmp_var, _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -22327,7 +22540,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*bina if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); - EX_T(opline->result.var).var.ptr_ptr = NULL; } } else { /* here we are sure we are dealing with an object */ @@ -22347,7 +22559,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*bina if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*zptr); EX_T(opline->result.var).var.ptr = *zptr; - EX_T(opline->result.var).var.ptr_ptr = NULL; } } } @@ -22386,7 +22597,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*bina if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(z); EX_T(opline->result.var).var.ptr = z; - EX_T(opline->result.var).var.ptr_ptr = NULL; } zval_ptr_dtor(&z); } else { @@ -22394,7 +22604,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*bina if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); - EX_T(opline->result.var).var.ptr_ptr = NULL; } } } @@ -22407,7 +22616,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*bina FREE_OP(free_op_data1); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* assign_obj has two opcodes! */ CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -22459,10 +22668,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_CV(int (*binary_o if (UNEXPECTED(*var_ptr == &EG(error_zval))) { if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); if (opline->extended_value == ZEND_ASSIGN_DIM) { ZEND_VM_INC_OPCODE(); @@ -22487,17 +22696,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_CV(int (*binary_o if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*var_ptr); - AI_SET_PTR(&EX_T(opline->result.var), *var_ptr); + EX_T(opline->result.var).var.ptr = *var_ptr; } if (opline->extended_value == ZEND_ASSIGN_DIM) { FREE_OP(free_op_data1); FREE_OP_VAR_PTR(free_op_data2); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); } else { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); } ZEND_VM_NEXT_OPCODE(); @@ -22587,7 +22796,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CV(incdec_t in PZVAL_LOCK(&EG(uninitialized_zval)); *retval = &EG(uninitialized_zval); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -22647,7 +22856,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CV(incdec_t in } else { } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -22688,7 +22897,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CV(incdec_t i zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); ZVAL_NULL(retval); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -22749,7 +22958,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CV(incdec_t i } else { } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -22768,24 +22977,15 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL { USE_OPLINE zend_free_op free_op1; - zval **container; + zval *container; SAVE_OPLINE(); + container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC); - if (IS_VAR == IS_TMP_VAR || IS_VAR == IS_CONST) { - zval *container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC); - - zval_ptr_dtor(&free_op1.var); - } else { - container = _get_zval_ptr_ptr_var_fast(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC); - - if (IS_VAR == IS_VAR && !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { - zval_ptr_dtor(&free_op1.var); - } + if (IS_VAR != IS_VAR || !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { + zval_ptr_dtor_nogc(&free_op1.var); } - CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -22807,7 +23007,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* We are going to assign the result by reference */ if (UNEXPECTED(opline->extended_value != 0)) { @@ -22841,7 +23041,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -22850,13 +23050,13 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND { USE_OPLINE zend_free_op free_op1; - zval **container; + zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var_fast(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_IS TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -22865,12 +23065,11 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCOD { USE_OPLINE zend_free_op free_op1; - zval **container; SAVE_OPLINE(); - if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) { - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + if (zend_is_by_ref_func_arg_fetch(opline, EX(call) TSRMLS_CC)) { + zval **container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } @@ -22879,15 +23078,17 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCOD EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; } else { + zval *container; + if (IS_CV == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } - container = _get_zval_ptr_ptr_var_fast(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -22915,7 +23116,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_H if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; if (UNEXPECTED(EX_T(opline->result.var).var.ptr_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); ZEND_VM_NEXT_OPCODE(); @@ -22950,7 +23151,7 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_VAR_CV(ZEN UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { zend_error(E_NOTICE, "Trying to get property of non-object"); PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } else { zval *retval; @@ -22963,7 +23164,7 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_VAR_CV(ZEN retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); PZVAL_LOCK(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; if (0) { zval_ptr_dtor(&offset); @@ -22972,7 +23173,7 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_VAR_CV(ZEN } } - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -22992,11 +23193,6 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL SAVE_OPLINE(); property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - if (IS_VAR == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) { - PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); - EX_T(opline->op1.var).var.ptr = *EX_T(opline->op1.var).var.ptr_ptr; - } - if (0) { MAKE_REAL_ZVAL_PTR(property); } @@ -23014,7 +23210,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* We are going to assign the result by reference */ if (opline->extended_value & ZEND_FETCH_MAKE_REF) { @@ -23057,7 +23253,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -23077,7 +23273,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } else { zval *retval; @@ -23090,7 +23286,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); PZVAL_LOCK(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; if (0) { zval_ptr_dtor(&offset); @@ -23099,7 +23295,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND } } - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -23108,7 +23304,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCOD { USE_OPLINE - if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) { + if (zend_is_by_ref_func_arg_fetch(opline, EX(call) TSRMLS_CC)) { /* Behave like FETCH_OBJ_W */ zend_free_op free_op1; zval *property; @@ -23133,7 +23329,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCOD if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } else { @@ -23172,7 +23368,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_H if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; PZVAL_UNLOCK(*EX_T(opline->result.var).var.ptr_ptr, &free_res); if (EX_T(opline->result.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) { @@ -23207,7 +23403,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE } else { } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* assign_obj has two opcodes! */ CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -23257,11 +23453,11 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE ALLOC_ZVAL(retval); ZVAL_STRINGL(retval, Z_STRVAL_P(EX_T((opline+1)->op2.var).str_offset.str)+EX_T((opline+1)->op2.var).str_offset.offset, 1, 1); INIT_PZVAL(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; } } else if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } } else if (UNEXPECTED(*variable_ptr_ptr == &EG(error_zval))) { if (IS_TMP_FREE(free_op_data1)) { @@ -23269,7 +23465,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE } if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } } else { if ((opline+1)->op1_type == IS_TMP_VAR) { @@ -23281,13 +23477,13 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE } if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(value); - AI_SET_PTR(&EX_T(opline->result.var), value); + EX_T(opline->result.var).var.ptr = value; } } FREE_OP_VAR_PTR(free_op_data2); FREE_OP_IF_VAR(free_op_data1); } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* assign_dim has two opcodes! */ CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -23313,11 +23509,11 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_AR ALLOC_ZVAL(retval); ZVAL_STRINGL(retval, Z_STRVAL_P(EX_T(opline->op1.var).str_offset.str)+EX_T(opline->op1.var).str_offset.offset, 1, 1); INIT_PZVAL(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; } } else if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } } else if (IS_VAR == IS_VAR && UNEXPECTED(*variable_ptr_ptr == &EG(error_zval))) { if (0) { @@ -23325,7 +23521,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_AR } if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } } else { if (IS_CV == IS_TMP_VAR) { @@ -23337,11 +23533,11 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_AR } if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(value); - AI_SET_PTR(&EX_T(opline->result.var), value); + EX_T(opline->result.var).var.ptr = value; } } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; /* zend_assign_to_variable() always takes care of op2, never free it! */ @@ -23393,10 +23589,10 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*variable_ptr_ptr); - AI_SET_PTR(&EX_T(opline->result.var), *variable_ptr_ptr); + EX_T(opline->result.var).var.ptr = *variable_ptr_ptr; } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -23473,10 +23669,12 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_ call->object = this_ptr; } } + + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -23598,6 +23796,8 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_ call->called_scope = Z_OBJCE_P(call->object); } } + + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; @@ -23650,7 +23850,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE INIT_PZVAL_COPY(new_expr, expr_ptr); expr_ptr = new_expr; zendi_zval_copy_ctor(*expr_ptr); - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); } else if (IS_VAR == IS_CV) { Z_ADDREF_P(expr_ptr); } @@ -23694,7 +23894,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE zend_hash_next_index_insert(Z_ARRVAL(EX_T(opline->result.var).tmp_var), &expr_ptr, sizeof(zval *), NULL); } if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && opline->extended_value) { - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -23804,7 +24004,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER } else { } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -23845,7 +24045,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER } else { } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -23855,22 +24055,21 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CV(int { USE_OPLINE zend_free_op free_op1; - zval **container; + zval *container; zval **value = NULL; int result = 0; ulong hval; zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var_fast(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - + container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) { + if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) { HashTable *ht; int isset = 0; - ht = Z_ARRVAL_PP(container); + ht = Z_ARRVAL_P(container); switch (Z_TYPE_P(offset)) { case IS_DOUBLE: @@ -23889,9 +24088,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CV(int if (IS_CV == IS_CONST) { hval = Z_HASH_P(offset); } else { - if (!prop_dim) { - ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop); - } + ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop); hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } if (zend_hash_quick_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, (void **) &value) == SUCCESS) { @@ -23915,27 +24112,27 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CV(int result = isset; } } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - if (!isset || !i_zend_is_true(*value)) { + if (!isset || !i_zend_is_true(*value TSRMLS_CC)) { result = 0; } else { result = 1; } } - } else if (Z_TYPE_PP(container) == IS_OBJECT) { + } else if (Z_TYPE_P(container) == IS_OBJECT) { if (0) { MAKE_REAL_ZVAL_PTR(offset); } if (prop_dim) { - if (Z_OBJ_HT_P(*container)->has_property) { - result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + if (Z_OBJ_HT_P(container)->has_property) { + result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); } else { zend_error(E_NOTICE, "Trying to check property of non-object"); result = 0; } } else { - if (Z_OBJ_HT_P(*container)->has_dimension) { - result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC); + if (Z_OBJ_HT_P(container)->has_dimension) { + result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC); } else { zend_error(E_NOTICE, "Trying to check element of non-array"); result = 0; @@ -23946,7 +24143,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CV(int } else { } - } else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */ + } else if (Z_TYPE_P(container) == IS_STRING && !prop_dim) { /* string offsets */ zval tmp; if (Z_TYPE_P(offset) != IS_LONG) { @@ -23964,11 +24161,11 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CV(int } if (Z_TYPE_P(offset) == IS_LONG) { if (opline->extended_value & ZEND_ISSET) { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) { + if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) { result = 1; } } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') { + if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container) && Z_STRVAL_P(container)[offset->value.lval] != '0') { result = 1; } } @@ -23985,7 +24182,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CV(int Z_LVAL(EX_T(opline->result.var).tmp_var) = !result; } - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -24067,7 +24264,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG generator->value = *value_ptr; } - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}; } } else { zval *value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); @@ -24087,7 +24284,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG } generator->value = copy; - zval_ptr_dtor(&free_op1.var); + zval_ptr_dtor_nogc(&free_op1.var); } else { if (IS_VAR == IS_CV) { Z_ADDREF_P(value); @@ -24140,11 +24337,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG ZVAL_LONG(generator->key, generator->largest_used_integer_key); } - /* If a value is sent it should go into the result var */ - generator->send_target = &EX_T(opline->result.var); - - /* Initialize the sent value to NULL */ - EX_T(opline->result.var).tmp_var = EG(uninitialized_zval); + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = &EX_T(opline->result.var).var.ptr; + Z_ADDREF(EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); + } else { + generator->send_target = NULL; + } /* We increment to the next op, so we are at the correct position when the * generator is resumed. */ @@ -24215,7 +24416,7 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARG if (!RETURN_VALUE_USED(opline) || UNEXPECTED(EG(exception) != NULL)) { zval_ptr_dtor(&retval); } else { - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; } } @@ -24270,7 +24471,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(int if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); - EX_T(opline->result.var).var.ptr_ptr = NULL; } } else { /* here we are sure we are dealing with an object */ @@ -24290,7 +24490,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(int if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*zptr); EX_T(opline->result.var).var.ptr = *zptr; - EX_T(opline->result.var).var.ptr_ptr = NULL; } } } @@ -24329,7 +24528,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(int if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(z); EX_T(opline->result.var).var.ptr = z; - EX_T(opline->result.var).var.ptr_ptr = NULL; } zval_ptr_dtor(&z); } else { @@ -24337,7 +24535,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(int if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); - EX_T(opline->result.var).var.ptr_ptr = NULL; } } } @@ -24401,7 +24598,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_CONST(int (*bi if (UNEXPECTED(*var_ptr == &EG(error_zval))) { if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } @@ -24429,7 +24626,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_CONST(int (*bi if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*var_ptr); - AI_SET_PTR(&EX_T(opline->result.var), *var_ptr); + EX_T(opline->result.var).var.ptr = *var_ptr; } if (opline->extended_value == ZEND_ASSIGN_DIM) { @@ -24722,7 +24919,7 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_UNUSED_CON UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { zend_error(E_NOTICE, "Trying to get property of non-object"); PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } else { zval *retval; @@ -24735,7 +24932,7 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_UNUSED_CON retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); PZVAL_LOCK(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; if (0) { zval_ptr_dtor(&offset); @@ -24763,11 +24960,6 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE SAVE_OPLINE(); property = opline->op2.zv; - if (IS_UNUSED == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) { - PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); - EX_T(opline->op1.var).var.ptr = *EX_T(opline->op1.var).var.ptr_ptr; - } - if (0) { MAKE_REAL_ZVAL_PTR(property); } @@ -24847,7 +25039,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCOD if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } else { zval *retval; @@ -24860,7 +25052,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCOD retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); PZVAL_LOCK(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; if (0) { zval_ptr_dtor(&offset); @@ -24877,7 +25069,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CONST_HANDLER(ZEND { USE_OPLINE - if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) { + if (zend_is_by_ref_func_arg_fetch(opline, EX(call) TSRMLS_CC)) { /* Behave like FETCH_OBJ_W */ zend_free_op free_op1; zval *property; @@ -25099,6 +25291,8 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER(ZEND_O call->object = this_ptr; } } + + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; @@ -25177,8 +25371,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPC } if (EXPECTED(zend_hash_quick_find(&ce->constants_table, Z_STRVAL_P(opline->op2.zv), Z_STRLEN_P(opline->op2.zv)+1, Z_HASH_P(opline->op2.zv), (void **) &value) == SUCCESS)) { - if (Z_TYPE_PP(value) == IS_CONSTANT_ARRAY || - (Z_TYPE_PP(value) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) { + if (IS_CONSTANT_TYPE(Z_TYPE_PP(value))) { zend_class_entry *old_scope = EG(scope); EG(scope) = ce; @@ -25192,7 +25385,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPC } ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, *value); zval_copy_ctor(&EX_T(opline->result.var).tmp_var); - } else if (Z_STRLEN_P(opline->op2.zv) == sizeof("class")-1 && strcmp(Z_STRVAL_P(opline->op2.zv), "class") == 0) { + } else if (Z_STRLEN_P(opline->op2.zv) == sizeof("class")-1 && memcmp(Z_STRVAL_P(opline->op2.zv), "class", sizeof("class") - 1) == 0) { /* "class" is assigned as a case-sensitive keyword from zend_do_resolve_class_name */ ZVAL_STRINGL(&EX_T(opline->result.var).tmp_var, ce->name, ce->name_length, 1); } else { @@ -25357,22 +25550,21 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_CON { USE_OPLINE - zval **container; + zval *container; zval **value = NULL; int result = 0; ulong hval; zval *offset; SAVE_OPLINE(); - container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C); - + container = _get_obj_zval_ptr_unused(TSRMLS_C); offset = opline->op2.zv; - if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) { + if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) { HashTable *ht; int isset = 0; - ht = Z_ARRVAL_PP(container); + ht = Z_ARRVAL_P(container); switch (Z_TYPE_P(offset)) { case IS_DOUBLE: @@ -25391,9 +25583,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_CON if (IS_CONST == IS_CONST) { hval = Z_HASH_P(offset); } else { - if (!prop_dim) { - ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop); - } + ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop); hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } if (zend_hash_quick_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, (void **) &value) == SUCCESS) { @@ -25417,27 +25607,27 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_CON result = isset; } } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - if (!isset || !i_zend_is_true(*value)) { + if (!isset || !i_zend_is_true(*value TSRMLS_CC)) { result = 0; } else { result = 1; } } - } else if (Z_TYPE_PP(container) == IS_OBJECT) { + } else if (Z_TYPE_P(container) == IS_OBJECT) { if (0) { MAKE_REAL_ZVAL_PTR(offset); } if (prop_dim) { - if (Z_OBJ_HT_P(*container)->has_property) { - result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + if (Z_OBJ_HT_P(container)->has_property) { + result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); } else { zend_error(E_NOTICE, "Trying to check property of non-object"); result = 0; } } else { - if (Z_OBJ_HT_P(*container)->has_dimension) { - result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC); + if (Z_OBJ_HT_P(container)->has_dimension) { + result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC); } else { zend_error(E_NOTICE, "Trying to check element of non-array"); result = 0; @@ -25448,7 +25638,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_CON } else { } - } else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */ + } else if (Z_TYPE_P(container) == IS_STRING && !prop_dim) { /* string offsets */ zval tmp; if (Z_TYPE_P(offset) != IS_LONG) { @@ -25466,11 +25656,11 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_CON } if (Z_TYPE_P(offset) == IS_LONG) { if (opline->extended_value & ZEND_ISSET) { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) { + if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) { result = 1; } } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') { + if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container) && Z_STRVAL_P(container)[offset->value.lval] != '0') { result = 1; } } @@ -25639,11 +25829,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDL ZVAL_LONG(generator->key, generator->largest_used_integer_key); } - /* If a value is sent it should go into the result var */ - generator->send_target = &EX_T(opline->result.var); - - /* Initialize the sent value to NULL */ - EX_T(opline->result.var).tmp_var = EG(uninitialized_zval); + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = &EX_T(opline->result.var).var.ptr; + Z_ADDREF(EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); + } else { + generator->send_target = NULL; + } /* We increment to the next op, so we are at the correct position when the * generator is resumed. */ @@ -25681,7 +25875,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(int (* if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); - EX_T(opline->result.var).var.ptr_ptr = NULL; } } else { /* here we are sure we are dealing with an object */ @@ -25701,7 +25894,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(int (* if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*zptr); EX_T(opline->result.var).var.ptr = *zptr; - EX_T(opline->result.var).var.ptr_ptr = NULL; } } } @@ -25740,7 +25932,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(int (* if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(z); EX_T(opline->result.var).var.ptr = z; - EX_T(opline->result.var).var.ptr_ptr = NULL; } zval_ptr_dtor(&z); } else { @@ -25748,7 +25939,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(int (* if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); - EX_T(opline->result.var).var.ptr_ptr = NULL; } } } @@ -25812,7 +26002,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_TMP(int (*bina if (UNEXPECTED(*var_ptr == &EG(error_zval))) { if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } zval_dtor(free_op2.var); @@ -25840,7 +26030,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_TMP(int (*bina if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*var_ptr); - AI_SET_PTR(&EX_T(opline->result.var), *var_ptr); + EX_T(opline->result.var).var.ptr = *var_ptr; } zval_dtor(free_op2.var); @@ -26134,7 +26324,7 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_UNUSED_TMP UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { zend_error(E_NOTICE, "Trying to get property of non-object"); PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); zval_dtor(free_op2.var); } else { zval *retval; @@ -26147,7 +26337,7 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_UNUSED_TMP retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); PZVAL_LOCK(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; if (1) { zval_ptr_dtor(&offset); @@ -26175,11 +26365,6 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_H SAVE_OPLINE(); property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (IS_UNUSED == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) { - PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); - EX_T(opline->op1.var).var.ptr = *EX_T(opline->op1.var).var.ptr_ptr; - } - if (1) { MAKE_REAL_ZVAL_PTR(property); } @@ -26259,7 +26444,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_ if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); zval_dtor(free_op2.var); } else { zval *retval; @@ -26272,7 +26457,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_ retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); PZVAL_LOCK(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; if (1) { zval_ptr_dtor(&offset); @@ -26289,7 +26474,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMP_HANDLER(ZEND_O { USE_OPLINE - if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) { + if (zend_is_by_ref_func_arg_fetch(opline, EX(call) TSRMLS_CC)) { /* Behave like FETCH_OBJ_W */ zend_free_op free_op1, free_op2; zval *property; @@ -26510,6 +26695,8 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMP_HANDLER(ZEND_OPC call->object = this_ptr; } } + + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; @@ -26672,22 +26859,21 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_TMP { USE_OPLINE zend_free_op free_op2; - zval **container; + zval *container; zval **value = NULL; int result = 0; ulong hval; zval *offset; SAVE_OPLINE(); - container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C); - + container = _get_obj_zval_ptr_unused(TSRMLS_C); offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) { + if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) { HashTable *ht; int isset = 0; - ht = Z_ARRVAL_PP(container); + ht = Z_ARRVAL_P(container); switch (Z_TYPE_P(offset)) { case IS_DOUBLE: @@ -26706,9 +26892,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_TMP if (IS_TMP_VAR == IS_CONST) { hval = Z_HASH_P(offset); } else { - if (!prop_dim) { - ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop); - } + ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop); hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } if (zend_hash_quick_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, (void **) &value) == SUCCESS) { @@ -26732,27 +26916,27 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_TMP result = isset; } } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - if (!isset || !i_zend_is_true(*value)) { + if (!isset || !i_zend_is_true(*value TSRMLS_CC)) { result = 0; } else { result = 1; } } zval_dtor(free_op2.var); - } else if (Z_TYPE_PP(container) == IS_OBJECT) { + } else if (Z_TYPE_P(container) == IS_OBJECT) { if (1) { MAKE_REAL_ZVAL_PTR(offset); } if (prop_dim) { - if (Z_OBJ_HT_P(*container)->has_property) { - result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + if (Z_OBJ_HT_P(container)->has_property) { + result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); } else { zend_error(E_NOTICE, "Trying to check property of non-object"); result = 0; } } else { - if (Z_OBJ_HT_P(*container)->has_dimension) { - result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC); + if (Z_OBJ_HT_P(container)->has_dimension) { + result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC); } else { zend_error(E_NOTICE, "Trying to check element of non-array"); result = 0; @@ -26763,7 +26947,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_TMP } else { zval_dtor(free_op2.var); } - } else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */ + } else if (Z_TYPE_P(container) == IS_STRING && !prop_dim) { /* string offsets */ zval tmp; if (Z_TYPE_P(offset) != IS_LONG) { @@ -26781,11 +26965,11 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_TMP } if (Z_TYPE_P(offset) == IS_LONG) { if (opline->extended_value & ZEND_ISSET) { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) { + if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) { result = 1; } } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') { + if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container) && Z_STRVAL_P(container)[offset->value.lval] != '0') { result = 1; } } @@ -26954,11 +27138,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER ZVAL_LONG(generator->key, generator->largest_used_integer_key); } - /* If a value is sent it should go into the result var */ - generator->send_target = &EX_T(opline->result.var); - - /* Initialize the sent value to NULL */ - EX_T(opline->result.var).tmp_var = EG(uninitialized_zval); + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = &EX_T(opline->result.var).var.ptr; + Z_ADDREF(EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); + } else { + generator->send_target = NULL; + } /* We increment to the next op, so we are at the correct position when the * generator is resumed. */ @@ -26990,13 +27178,12 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(int (* if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to assign property of non-object"); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); FREE_OP(free_op_data1); if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); - EX_T(opline->result.var).var.ptr_ptr = NULL; } } else { /* here we are sure we are dealing with an object */ @@ -27016,7 +27203,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(int (* if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*zptr); EX_T(opline->result.var).var.ptr = *zptr; - EX_T(opline->result.var).var.ptr_ptr = NULL; } } } @@ -27055,7 +27241,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(int (* if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(z); EX_T(opline->result.var).var.ptr = z; - EX_T(opline->result.var).var.ptr_ptr = NULL; } zval_ptr_dtor(&z); } else { @@ -27063,7 +27248,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(int (* if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); - EX_T(opline->result.var).var.ptr_ptr = NULL; } } } @@ -27071,7 +27255,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(int (* if (0) { zval_ptr_dtor(&property); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } FREE_OP(free_op_data1); } @@ -27127,9 +27311,9 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_VAR(int (*bina if (UNEXPECTED(*var_ptr == &EG(error_zval))) { if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); if (opline->extended_value == ZEND_ASSIGN_DIM) { @@ -27155,9 +27339,9 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_VAR(int (*bina if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*var_ptr); - AI_SET_PTR(&EX_T(opline->result.var), *var_ptr); + EX_T(opline->result.var).var.ptr = *var_ptr; } - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); if (opline->extended_value == ZEND_ASSIGN_DIM) { FREE_OP(free_op_data1); @@ -27251,7 +27435,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_VAR(incdec_ if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); *retval = &EG(uninitialized_zval); @@ -27314,7 +27498,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_VAR(incdec_ if (0) { zval_ptr_dtor(&property); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } CHECK_EXCEPTION(); @@ -27355,7 +27539,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_VAR(incdec if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); ZVAL_NULL(retval); CHECK_EXCEPTION(); @@ -27416,7 +27600,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_VAR(incdec if (0) { zval_ptr_dtor(&property); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } CHECK_EXCEPTION(); @@ -27449,8 +27633,8 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_UNUSED_VAR UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { zend_error(E_NOTICE, "Trying to get property of non-object"); PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); - zval_ptr_dtor(&free_op2.var); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); + zval_ptr_dtor_nogc(&free_op2.var); } else { zval *retval; @@ -27462,12 +27646,12 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_UNUSED_VAR retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); PZVAL_LOCK(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; if (0) { zval_ptr_dtor(&offset); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } } @@ -27490,11 +27674,6 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_H SAVE_OPLINE(); property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (IS_UNUSED == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) { - PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); - EX_T(opline->op1.var).var.ptr = *EX_T(opline->op1.var).var.ptr_ptr; - } - if (0) { MAKE_REAL_ZVAL_PTR(property); } @@ -27507,7 +27686,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_H if (0) { zval_ptr_dtor(&property); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } if (IS_UNUSED == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); @@ -27549,7 +27728,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_ if (0) { zval_ptr_dtor(&property); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } if (IS_UNUSED == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); @@ -27574,8 +27753,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_ if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); - zval_ptr_dtor(&free_op2.var); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); + zval_ptr_dtor_nogc(&free_op2.var); } else { zval *retval; @@ -27587,12 +27766,12 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_ retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); PZVAL_LOCK(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; if (0) { zval_ptr_dtor(&offset); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } } @@ -27604,7 +27783,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_VAR_HANDLER(ZEND_O { USE_OPLINE - if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) { + if (zend_is_by_ref_func_arg_fetch(opline, EX(call) TSRMLS_CC)) { /* Behave like FETCH_OBJ_W */ zend_free_op free_op1, free_op2; zval *property; @@ -27624,7 +27803,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_VAR_HANDLER(ZEND_O if (0) { zval_ptr_dtor(&property); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } if (IS_UNUSED == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); @@ -27663,7 +27842,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCO if (0) { zval_ptr_dtor(&property); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } if (IS_UNUSED == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); @@ -27700,7 +27879,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HA if (0) { zval_ptr_dtor(&property_name); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } /* assign_obj has two opcodes! */ @@ -27748,7 +27927,7 @@ static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDL * which aren't affected by FREE_OP(Ts, )'s anyway, unless they're * string offsets or overloaded objects */ - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -27806,7 +27985,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_VAR_HANDLER(ZEND_OPC } } else { if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); HANDLE_EXCEPTION(); } zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval); @@ -27825,10 +28004,12 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_VAR_HANDLER(ZEND_OPC call->object = this_ptr; } } + + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -27911,7 +28092,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HAN zend_error(E_WARNING, "Illegal offset type in unset"); break; } - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); break; } case IS_OBJECT: @@ -27925,18 +28106,18 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HAN if (0) { zval_ptr_dtor(&offset); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } break; case IS_STRING: zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); ZEND_VM_CONTINUE(); /* bailed out before */ default: - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); break; } } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } CHECK_EXCEPTION(); @@ -27970,13 +28151,13 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HAN if (0) { zval_ptr_dtor(&offset); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } CHECK_EXCEPTION(); @@ -27987,22 +28168,21 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_VAR { USE_OPLINE zend_free_op free_op2; - zval **container; + zval *container; zval **value = NULL; int result = 0; ulong hval; zval *offset; SAVE_OPLINE(); - container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C); - + container = _get_obj_zval_ptr_unused(TSRMLS_C); offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) { + if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) { HashTable *ht; int isset = 0; - ht = Z_ARRVAL_PP(container); + ht = Z_ARRVAL_P(container); switch (Z_TYPE_P(offset)) { case IS_DOUBLE: @@ -28021,9 +28201,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_VAR if (IS_VAR == IS_CONST) { hval = Z_HASH_P(offset); } else { - if (!prop_dim) { - ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop); - } + ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop); hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } if (zend_hash_quick_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, (void **) &value) == SUCCESS) { @@ -28047,27 +28225,27 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_VAR result = isset; } } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - if (!isset || !i_zend_is_true(*value)) { + if (!isset || !i_zend_is_true(*value TSRMLS_CC)) { result = 0; } else { result = 1; } } - zval_ptr_dtor(&free_op2.var); - } else if (Z_TYPE_PP(container) == IS_OBJECT) { + zval_ptr_dtor_nogc(&free_op2.var); + } else if (Z_TYPE_P(container) == IS_OBJECT) { if (0) { MAKE_REAL_ZVAL_PTR(offset); } if (prop_dim) { - if (Z_OBJ_HT_P(*container)->has_property) { - result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + if (Z_OBJ_HT_P(container)->has_property) { + result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); } else { zend_error(E_NOTICE, "Trying to check property of non-object"); result = 0; } } else { - if (Z_OBJ_HT_P(*container)->has_dimension) { - result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC); + if (Z_OBJ_HT_P(container)->has_dimension) { + result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC); } else { zend_error(E_NOTICE, "Trying to check element of non-array"); result = 0; @@ -28076,9 +28254,9 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_VAR if (0) { zval_ptr_dtor(&offset); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } - } else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */ + } else if (Z_TYPE_P(container) == IS_STRING && !prop_dim) { /* string offsets */ zval tmp; if (Z_TYPE_P(offset) != IS_LONG) { @@ -28096,18 +28274,18 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_VAR } if (Z_TYPE_P(offset) == IS_LONG) { if (opline->extended_value & ZEND_ISSET) { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) { + if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) { result = 1; } } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') { + if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container) && Z_STRVAL_P(container)[offset->value.lval] != '0') { result = 1; } } } - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } Z_TYPE(EX_T(opline->result.var).tmp_var) = IS_BOOL; @@ -28261,7 +28439,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER generator->largest_used_integer_key = Z_LVAL_P(generator->key); } - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } else { /* If no key was specified we use auto-increment keys */ generator->largest_used_integer_key++; @@ -28270,11 +28448,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER ZVAL_LONG(generator->key, generator->largest_used_integer_key); } - /* If a value is sent it should go into the result var */ - generator->send_target = &EX_T(opline->result.var); - - /* Initialize the sent value to NULL */ - EX_T(opline->result.var).tmp_var = EG(uninitialized_zval); + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = &EX_T(opline->result.var).var.ptr; + Z_ADDREF(EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); + } else { + generator->send_target = NULL; + } /* We increment to the next op, so we are at the correct position when the * generator is resumed. */ @@ -28312,7 +28494,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(int if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); - EX_T(opline->result.var).var.ptr_ptr = NULL; } } else { /* here we are sure we are dealing with an object */ @@ -28332,7 +28513,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(int if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*zptr); EX_T(opline->result.var).var.ptr = *zptr; - EX_T(opline->result.var).var.ptr_ptr = NULL; } } } @@ -28371,7 +28551,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(int if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(z); EX_T(opline->result.var).var.ptr = z; - EX_T(opline->result.var).var.ptr_ptr = NULL; } zval_ptr_dtor(&z); } else { @@ -28379,7 +28558,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(int if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); - EX_T(opline->result.var).var.ptr_ptr = NULL; } } } @@ -28443,7 +28621,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_UNUSED(int (*b if (UNEXPECTED(*var_ptr == &EG(error_zval))) { if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } @@ -28471,7 +28649,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_UNUSED(int (*b if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*var_ptr); - AI_SET_PTR(&EX_T(opline->result.var), *var_ptr); + EX_T(opline->result.var).var.ptr = *var_ptr; } if (opline->extended_value == ZEND_ASSIGN_DIM) { @@ -28694,11 +28872,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HAND ZVAL_LONG(generator->key, generator->largest_used_integer_key); } - /* If a value is sent it should go into the result var */ - generator->send_target = &EX_T(opline->result.var); - - /* Initialize the sent value to NULL */ - EX_T(opline->result.var).tmp_var = EG(uninitialized_zval); + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = &EX_T(opline->result.var).var.ptr; + Z_ADDREF(EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); + } else { + generator->send_target = NULL; + } /* We increment to the next op, so we are at the correct position when the * generator is resumed. */ @@ -28736,7 +28918,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(int (*b if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); - EX_T(opline->result.var).var.ptr_ptr = NULL; } } else { /* here we are sure we are dealing with an object */ @@ -28756,7 +28937,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(int (*b if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*zptr); EX_T(opline->result.var).var.ptr = *zptr; - EX_T(opline->result.var).var.ptr_ptr = NULL; } } } @@ -28795,7 +28975,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(int (*b if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(z); EX_T(opline->result.var).var.ptr = z; - EX_T(opline->result.var).var.ptr_ptr = NULL; } zval_ptr_dtor(&z); } else { @@ -28803,7 +28982,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(int (*b if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); - EX_T(opline->result.var).var.ptr_ptr = NULL; } } } @@ -28867,7 +29045,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_CV(int (*binar if (UNEXPECTED(*var_ptr == &EG(error_zval))) { if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } @@ -28895,7 +29073,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_CV(int (*binar if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*var_ptr); - AI_SET_PTR(&EX_T(opline->result.var), *var_ptr); + EX_T(opline->result.var).var.ptr = *var_ptr; } if (opline->extended_value == ZEND_ASSIGN_DIM) { @@ -29188,7 +29366,7 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_UNUSED_CV( UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { zend_error(E_NOTICE, "Trying to get property of non-object"); PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } else { zval *retval; @@ -29201,7 +29379,7 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_UNUSED_CV( retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); PZVAL_LOCK(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; if (0) { zval_ptr_dtor(&offset); @@ -29229,11 +29407,6 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HA SAVE_OPLINE(); property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - if (IS_UNUSED == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) { - PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); - EX_T(opline->op1.var).var.ptr = *EX_T(opline->op1.var).var.ptr_ptr; - } - if (0) { MAKE_REAL_ZVAL_PTR(property); } @@ -29313,7 +29486,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_H if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } else { zval *retval; @@ -29326,7 +29499,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_H retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); PZVAL_LOCK(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; if (0) { zval_ptr_dtor(&offset); @@ -29343,7 +29516,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CV_HANDLER(ZEND_OP { USE_OPLINE - if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) { + if (zend_is_by_ref_func_arg_fetch(opline, EX(call) TSRMLS_CC)) { /* Behave like FETCH_OBJ_W */ zend_free_op free_op1; zval *property; @@ -29563,6 +29736,8 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV_HANDLER(ZEND_OPCO call->object = this_ptr; } } + + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; @@ -29724,22 +29899,21 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_CV( { USE_OPLINE - zval **container; + zval *container; zval **value = NULL; int result = 0; ulong hval; zval *offset; SAVE_OPLINE(); - container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C); - + container = _get_obj_zval_ptr_unused(TSRMLS_C); offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) { + if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) { HashTable *ht; int isset = 0; - ht = Z_ARRVAL_PP(container); + ht = Z_ARRVAL_P(container); switch (Z_TYPE_P(offset)) { case IS_DOUBLE: @@ -29758,9 +29932,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_CV( if (IS_CV == IS_CONST) { hval = Z_HASH_P(offset); } else { - if (!prop_dim) { - ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop); - } + ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop); hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } if (zend_hash_quick_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, (void **) &value) == SUCCESS) { @@ -29784,27 +29956,27 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_CV( result = isset; } } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - if (!isset || !i_zend_is_true(*value)) { + if (!isset || !i_zend_is_true(*value TSRMLS_CC)) { result = 0; } else { result = 1; } } - } else if (Z_TYPE_PP(container) == IS_OBJECT) { + } else if (Z_TYPE_P(container) == IS_OBJECT) { if (0) { MAKE_REAL_ZVAL_PTR(offset); } if (prop_dim) { - if (Z_OBJ_HT_P(*container)->has_property) { - result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + if (Z_OBJ_HT_P(container)->has_property) { + result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); } else { zend_error(E_NOTICE, "Trying to check property of non-object"); result = 0; } } else { - if (Z_OBJ_HT_P(*container)->has_dimension) { - result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC); + if (Z_OBJ_HT_P(container)->has_dimension) { + result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC); } else { zend_error(E_NOTICE, "Trying to check element of non-array"); result = 0; @@ -29815,7 +29987,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_CV( } else { } - } else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */ + } else if (Z_TYPE_P(container) == IS_STRING && !prop_dim) { /* string offsets */ zval tmp; if (Z_TYPE_P(offset) != IS_LONG) { @@ -29833,11 +30005,11 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_CV( } if (Z_TYPE_P(offset) == IS_LONG) { if (opline->extended_value & ZEND_ISSET) { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) { + if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) { result = 1; } } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') { + if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container) && Z_STRVAL_P(container)[offset->value.lval] != '0') { result = 1; } } @@ -30006,11 +30178,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ ZVAL_LONG(generator->key, generator->largest_used_integer_key); } - /* If a value is sent it should go into the result var */ - generator->send_target = &EX_T(opline->result.var); - - /* Initialize the sent value to NULL */ - EX_T(opline->result.var).tmp_var = EG(uninitialized_zval); + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = &EX_T(opline->result.var).var.ptr; + Z_ADDREF(EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); + } else { + generator->send_target = NULL; + } /* We increment to the next op, so we are at the correct position when the * generator is resumed. */ @@ -30064,7 +30240,7 @@ static int ZEND_FASTCALL ZEND_PRE_INC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (IS_CV == IS_VAR && UNEXPECTED(*var_ptr == &EG(error_zval))) { if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } CHECK_EXCEPTION(); @@ -30088,7 +30264,7 @@ static int ZEND_FASTCALL ZEND_PRE_INC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*var_ptr); - AI_SET_PTR(&EX_T(opline->result.var), *var_ptr); + EX_T(opline->result.var).var.ptr = *var_ptr; } CHECK_EXCEPTION(); @@ -30110,7 +30286,7 @@ static int ZEND_FASTCALL ZEND_PRE_DEC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (IS_CV == IS_VAR && UNEXPECTED(*var_ptr == &EG(error_zval))) { if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } CHECK_EXCEPTION(); @@ -30134,7 +30310,7 @@ static int ZEND_FASTCALL ZEND_PRE_DEC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*var_ptr); - AI_SET_PTR(&EX_T(opline->result.var), *var_ptr); + EX_T(opline->result.var).var.ptr = *var_ptr; } CHECK_EXCEPTION(); @@ -30264,7 +30440,7 @@ static int ZEND_FASTCALL ZEND_JMPZ_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (IS_CV == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) { ret = Z_LVAL_P(val); } else { - ret = i_zend_is_true(val); + ret = i_zend_is_true(val TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); @@ -30294,7 +30470,7 @@ static int ZEND_FASTCALL ZEND_JMPNZ_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (IS_CV == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) { ret = Z_LVAL_P(val); } else { - ret = i_zend_is_true(val); + ret = i_zend_is_true(val TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); @@ -30324,7 +30500,7 @@ static int ZEND_FASTCALL ZEND_JMPZNZ_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (IS_CV == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) { retval = Z_LVAL_P(val); } else { - retval = i_zend_is_true(val); + retval = i_zend_is_true(val TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); @@ -30358,7 +30534,7 @@ static int ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (IS_CV == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) { retval = Z_LVAL_P(val); } else { - retval = i_zend_is_true(val); + retval = i_zend_is_true(val TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); @@ -30389,7 +30565,7 @@ static int ZEND_FASTCALL ZEND_JMPNZ_EX_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS if (IS_CV == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) { retval = Z_LVAL_P(val); } else { - retval = i_zend_is_true(val); + retval = i_zend_is_true(val TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); @@ -30460,7 +30636,8 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER SAVE_OPLINE(); do { - if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) { + if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR || + (IS_CV == IS_VAR && opline->extended_value == ZEND_RETURNS_VALUE)) { /* Not supposed to happen, but we'll allow it */ zend_error(E_NOTICE, "Only variable references should be returned by reference"); @@ -30589,14 +30766,18 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDL USE_OPLINE zval *varptr; + int arg_num; SAVE_OPLINE(); if (opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) { /* Had function_ptr at compile_time */ if (!(opline->extended_value & ZEND_ARG_SEND_BY_REF)) { return zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } - } else if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.opline_num)) { - return zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + } else { + arg_num = opline->op2.num + EX(call)->num_additional_args; + if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { + return zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + } } varptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); @@ -30614,7 +30795,7 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDL if ((opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) ? !(opline->extended_value & ZEND_ARG_SEND_SILENT) : - !ARG_MAY_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.opline_num)) { + !ARG_MAY_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { zend_error(E_STRICT, "Only variables should be passed by reference"); } ALLOC_ZVAL(valptr); @@ -30651,9 +30832,11 @@ static int ZEND_FASTCALL ZEND_SEND_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS } if (opline->extended_value == ZEND_DO_FCALL_BY_NAME && - EX(function_state).function->type == ZEND_INTERNAL_FUNCTION && - !ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.opline_num)) { - return zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) { + int arg_num = opline->op2.num + EX(call)->num_additional_args; + if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { + return zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + } } SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr_ptr); @@ -30669,9 +30852,11 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS { USE_OPLINE - if ((opline->extended_value == ZEND_DO_FCALL_BY_NAME) - && ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.opline_num)) { - return ZEND_SEND_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + if (opline->extended_value == ZEND_DO_FCALL_BY_NAME) { + int arg_num = opline->op2.num + EX(call)->num_additional_args; + if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, arg_num)) { + return ZEND_SEND_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + } } SAVE_OPLINE(); return zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -30685,7 +30870,7 @@ static int ZEND_FASTCALL ZEND_BOOL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); /* PHP 3.0 returned "" for false and 1 for true, here we use 0 and 1 for now */ - ZVAL_BOOL(retval, i_zend_is_true(_get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC))); + ZVAL_BOOL(retval, i_zend_is_true(_get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC) TSRMLS_CC)); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -30749,7 +30934,7 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (!RETURN_VALUE_USED(opline) || UNEXPECTED(EG(exception) != NULL)) { zval_ptr_dtor(&retval); } else { - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; } } @@ -30907,7 +31092,6 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDL EX(original_return_value) = EG(return_value_ptr_ptr); EG(active_op_array) = new_op_array; if (RETURN_VALUE_USED(opline)) { - EX_T(opline->result.var).var.ptr = NULL; EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr; EG(return_value_ptr_ptr) = EX_T(opline->result.var).var.ptr_ptr; } else { @@ -30945,7 +31129,7 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDL ALLOC_ZVAL(retval); ZVAL_BOOL(retval, failure_retval); INIT_PZVAL(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; } ZEND_VM_NEXT_OPCODE(); } @@ -31143,7 +31327,7 @@ static int ZEND_FASTCALL ZEND_JMP_SET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); - if (i_zend_is_true(value)) { + if (i_zend_is_true(value TSRMLS_CC)) { ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, value); if (!0) { zendi_zval_copy_ctor(EX_T(opline->result.var).tmp_var); @@ -31168,7 +31352,7 @@ static int ZEND_FASTCALL ZEND_JMP_SET_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_A SAVE_OPLINE(); value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); - if (i_zend_is_true(value)) { + if (i_zend_is_true(value TSRMLS_CC)) { if (IS_CV == IS_VAR || IS_CV == IS_CV) { Z_ADDREF_P(value); EX_T(opline->result.var).var.ptr = value; @@ -31560,7 +31744,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CONST(int (*bi if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); - EX_T(opline->result.var).var.ptr_ptr = NULL; } } else { /* here we are sure we are dealing with an object */ @@ -31580,7 +31763,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CONST(int (*bi if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*zptr); EX_T(opline->result.var).var.ptr = *zptr; - EX_T(opline->result.var).var.ptr_ptr = NULL; } } } @@ -31619,7 +31801,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CONST(int (*bi if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(z); EX_T(opline->result.var).var.ptr = z; - EX_T(opline->result.var).var.ptr_ptr = NULL; } zval_ptr_dtor(&z); } else { @@ -31627,7 +31808,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CONST(int (*bi if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); - EX_T(opline->result.var).var.ptr_ptr = NULL; } } } @@ -31691,7 +31871,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_CONST(int (*binary if (UNEXPECTED(*var_ptr == &EG(error_zval))) { if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } @@ -31719,7 +31899,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_CONST(int (*binary if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*var_ptr); - AI_SET_PTR(&EX_T(opline->result.var), *var_ptr); + EX_T(opline->result.var).var.ptr = *var_ptr; } if (opline->extended_value == ZEND_ASSIGN_DIM) { @@ -32105,7 +32285,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_CONST(int type, Z switch (type) { case BP_VAR_R: case BP_VAR_IS: - AI_SET_PTR(&EX_T(opline->result.var), *retval); + EX_T(opline->result.var).var.ptr = *retval; break; case BP_VAR_UNSET: { zend_free_op free_res; @@ -32145,7 +32325,7 @@ static int ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_ { USE_OPLINE - return zend_fetch_var_address_helper_SPEC_CV_CONST(ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + return zend_fetch_var_address_helper_SPEC_CV_CONST(zend_is_by_ref_func_arg_fetch(opline, EX(call) TSRMLS_CC) ? BP_VAR_W : BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } static int ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -32162,24 +32342,15 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN { USE_OPLINE - zval **container; + zval *container; SAVE_OPLINE(); + container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); + zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC); - if (IS_CV == IS_TMP_VAR || IS_CV == IS_CONST) { - zval *container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); - zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC); - - - } else { - container = _get_zval_ptr_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); - zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC); - - if (IS_CV == IS_VAR && !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { + if (IS_CV != IS_VAR || !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { - } } - CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -32243,10 +32414,10 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HA { USE_OPLINE - zval **container; + zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); + container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_IS TSRMLS_CC); @@ -32258,12 +32429,11 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPC { USE_OPLINE zend_free_op free_op1; - zval **container; SAVE_OPLINE(); - if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) { - container = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); + if (zend_is_by_ref_func_arg_fetch(opline, EX(call) TSRMLS_CC)) { + zval **container = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } @@ -32274,10 +32444,12 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPC } else { + zval *container; + if (IS_CONST == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } - container = _get_zval_ptr_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); + container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC); @@ -32343,7 +32515,7 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_CV_CONST(Z UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { zend_error(E_NOTICE, "Trying to get property of non-object"); PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } else { zval *retval; @@ -32356,7 +32528,7 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_CV_CONST(Z retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); PZVAL_LOCK(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; if (0) { zval_ptr_dtor(&offset); @@ -32384,11 +32556,6 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN SAVE_OPLINE(); property = opline->op2.zv; - if (IS_CV == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) { - PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); - EX_T(opline->op1.var).var.ptr = *EX_T(opline->op1.var).var.ptr_ptr; - } - if (0) { MAKE_REAL_ZVAL_PTR(property); } @@ -32468,7 +32635,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HA if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } else { zval *retval; @@ -32481,7 +32648,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HA retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); PZVAL_LOCK(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; if (0) { zval_ptr_dtor(&offset); @@ -32498,7 +32665,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPC { USE_OPLINE - if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) { + if (zend_is_by_ref_func_arg_fetch(opline, EX(call) TSRMLS_CC)) { /* Behave like FETCH_OBJ_W */ zend_free_op free_op1; zval *property; @@ -32646,11 +32813,11 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND ALLOC_ZVAL(retval); ZVAL_STRINGL(retval, Z_STRVAL_P(EX_T((opline+1)->op2.var).str_offset.str)+EX_T((opline+1)->op2.var).str_offset.offset, 1, 1); INIT_PZVAL(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; } } else if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } } else if (UNEXPECTED(*variable_ptr_ptr == &EG(error_zval))) { if (IS_TMP_FREE(free_op_data1)) { @@ -32658,7 +32825,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND } if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } } else { if ((opline+1)->op1_type == IS_TMP_VAR) { @@ -32670,7 +32837,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND } if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(value); - AI_SET_PTR(&EX_T(opline->result.var), value); + EX_T(opline->result.var).var.ptr = value; } } FREE_OP_VAR_PTR(free_op_data2); @@ -32702,11 +32869,11 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ ALLOC_ZVAL(retval); ZVAL_STRINGL(retval, Z_STRVAL_P(EX_T(opline->op1.var).str_offset.str)+EX_T(opline->op1.var).str_offset.offset, 1, 1); INIT_PZVAL(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; } } else if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } } else if (IS_CV == IS_VAR && UNEXPECTED(*variable_ptr_ptr == &EG(error_zval))) { if (0) { @@ -32714,7 +32881,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ } if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } } else { if (IS_CONST == IS_TMP_VAR) { @@ -32726,7 +32893,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ } if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(value); - AI_SET_PTR(&EX_T(opline->result.var), value); + EX_T(opline->result.var).var.ptr = value; } } @@ -32807,6 +32974,8 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CONST_HANDLER(ZEND_OPCOD call->object = this_ptr; } } + + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; @@ -33211,7 +33380,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_CONST_HANDLER(ZEND_OPCO ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 0); } } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - if (!isset || !i_zend_is_true(*value)) { + if (!isset || !i_zend_is_true(*value TSRMLS_CC)) { ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 1); } else { ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 0); @@ -33226,22 +33395,21 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_CONST(i { USE_OPLINE - zval **container; + zval *container; zval **value = NULL; int result = 0; ulong hval; zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); - + container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); offset = opline->op2.zv; - if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) { + if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) { HashTable *ht; int isset = 0; - ht = Z_ARRVAL_PP(container); + ht = Z_ARRVAL_P(container); switch (Z_TYPE_P(offset)) { case IS_DOUBLE: @@ -33260,9 +33428,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_CONST(i if (IS_CONST == IS_CONST) { hval = Z_HASH_P(offset); } else { - if (!prop_dim) { - ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop); - } + ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop); hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } if (zend_hash_quick_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, (void **) &value) == SUCCESS) { @@ -33286,27 +33452,27 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_CONST(i result = isset; } } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - if (!isset || !i_zend_is_true(*value)) { + if (!isset || !i_zend_is_true(*value TSRMLS_CC)) { result = 0; } else { result = 1; } } - } else if (Z_TYPE_PP(container) == IS_OBJECT) { + } else if (Z_TYPE_P(container) == IS_OBJECT) { if (0) { MAKE_REAL_ZVAL_PTR(offset); } if (prop_dim) { - if (Z_OBJ_HT_P(*container)->has_property) { - result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + if (Z_OBJ_HT_P(container)->has_property) { + result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); } else { zend_error(E_NOTICE, "Trying to check property of non-object"); result = 0; } } else { - if (Z_OBJ_HT_P(*container)->has_dimension) { - result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC); + if (Z_OBJ_HT_P(container)->has_dimension) { + result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC); } else { zend_error(E_NOTICE, "Trying to check element of non-array"); result = 0; @@ -33317,7 +33483,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_CONST(i } else { } - } else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */ + } else if (Z_TYPE_P(container) == IS_STRING && !prop_dim) { /* string offsets */ zval tmp; if (Z_TYPE_P(offset) != IS_LONG) { @@ -33335,11 +33501,11 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_CONST(i } if (Z_TYPE_P(offset) == IS_LONG) { if (opline->extended_value & ZEND_ISSET) { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) { + if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) { result = 1; } } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') { + if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container) && Z_STRVAL_P(container)[offset->value.lval] != '0') { result = 1; } } @@ -33508,11 +33674,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_A ZVAL_LONG(generator->key, generator->largest_used_integer_key); } - /* If a value is sent it should go into the result var */ - generator->send_target = &EX_T(opline->result.var); - - /* Initialize the sent value to NULL */ - EX_T(opline->result.var).tmp_var = EG(uninitialized_zval); + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = &EX_T(opline->result.var).var.ptr; + Z_ADDREF(EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); + } else { + generator->send_target = NULL; + } /* We increment to the next op, so we are at the correct position when the * generator is resumed. */ @@ -33826,7 +33996,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_TMP(int (*bina if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); - EX_T(opline->result.var).var.ptr_ptr = NULL; } } else { /* here we are sure we are dealing with an object */ @@ -33846,7 +34015,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_TMP(int (*bina if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*zptr); EX_T(opline->result.var).var.ptr = *zptr; - EX_T(opline->result.var).var.ptr_ptr = NULL; } } } @@ -33885,7 +34053,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_TMP(int (*bina if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(z); EX_T(opline->result.var).var.ptr = z; - EX_T(opline->result.var).var.ptr_ptr = NULL; } zval_ptr_dtor(&z); } else { @@ -33893,7 +34060,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_TMP(int (*bina if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); - EX_T(opline->result.var).var.ptr_ptr = NULL; } } } @@ -33957,7 +34123,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_TMP(int (*binary_o if (UNEXPECTED(*var_ptr == &EG(error_zval))) { if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } zval_dtor(free_op2.var); @@ -33985,7 +34151,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_TMP(int (*binary_o if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*var_ptr); - AI_SET_PTR(&EX_T(opline->result.var), *var_ptr); + EX_T(opline->result.var).var.ptr = *var_ptr; } zval_dtor(free_op2.var); @@ -34267,24 +34433,15 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDL { USE_OPLINE zend_free_op free_op2; - zval **container; + zval *container; SAVE_OPLINE(); + container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); + zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC); + zval_dtor(free_op2.var); + if (IS_CV != IS_VAR || !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { - if (IS_CV == IS_TMP_VAR || IS_CV == IS_CONST) { - zval *container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); - zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC); - zval_dtor(free_op2.var); - - } else { - container = _get_zval_ptr_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); - zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC); - zval_dtor(free_op2.var); - if (IS_CV == IS_VAR && !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { - - } } - CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -34348,10 +34505,10 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HAND { USE_OPLINE zend_free_op free_op2; - zval **container; + zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); + container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_IS TSRMLS_CC); zval_dtor(free_op2.var); @@ -34363,12 +34520,11 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP_HANDLER(ZEND_OPCOD { USE_OPLINE zend_free_op free_op1, free_op2; - zval **container; SAVE_OPLINE(); - if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) { - container = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); + if (zend_is_by_ref_func_arg_fetch(opline, EX(call) TSRMLS_CC)) { + zval **container = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } @@ -34379,10 +34535,12 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP_HANDLER(ZEND_OPCOD zval_dtor(free_op2.var); } else { + zval *container; + if (IS_TMP_VAR == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } - container = _get_zval_ptr_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); + container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC); zval_dtor(free_op2.var); @@ -34448,7 +34606,7 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_CV_TMP(ZEN UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { zend_error(E_NOTICE, "Trying to get property of non-object"); PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); zval_dtor(free_op2.var); } else { zval *retval; @@ -34461,7 +34619,7 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_CV_TMP(ZEN retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); PZVAL_LOCK(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; if (1) { zval_ptr_dtor(&offset); @@ -34489,11 +34647,6 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDL SAVE_OPLINE(); property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (IS_CV == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) { - PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); - EX_T(opline->op1.var).var.ptr = *EX_T(opline->op1.var).var.ptr_ptr; - } - if (1) { MAKE_REAL_ZVAL_PTR(property); } @@ -34573,7 +34726,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HAND if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); zval_dtor(free_op2.var); } else { zval *retval; @@ -34586,7 +34739,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HAND retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); PZVAL_LOCK(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; if (1) { zval_ptr_dtor(&offset); @@ -34603,7 +34756,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMP_HANDLER(ZEND_OPCOD { USE_OPLINE - if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) { + if (zend_is_by_ref_func_arg_fetch(opline, EX(call) TSRMLS_CC)) { /* Behave like FETCH_OBJ_W */ zend_free_op free_op1, free_op2; zval *property; @@ -34752,11 +34905,11 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLE ALLOC_ZVAL(retval); ZVAL_STRINGL(retval, Z_STRVAL_P(EX_T((opline+1)->op2.var).str_offset.str)+EX_T((opline+1)->op2.var).str_offset.offset, 1, 1); INIT_PZVAL(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; } } else if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } } else if (UNEXPECTED(*variable_ptr_ptr == &EG(error_zval))) { if (IS_TMP_FREE(free_op_data1)) { @@ -34764,7 +34917,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLE } if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } } else { if ((opline+1)->op1_type == IS_TMP_VAR) { @@ -34776,7 +34929,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLE } if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(value); - AI_SET_PTR(&EX_T(opline->result.var), value); + EX_T(opline->result.var).var.ptr = value; } } FREE_OP_VAR_PTR(free_op_data2); @@ -34808,11 +34961,11 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR ALLOC_ZVAL(retval); ZVAL_STRINGL(retval, Z_STRVAL_P(EX_T(opline->op1.var).str_offset.str)+EX_T(opline->op1.var).str_offset.offset, 1, 1); INIT_PZVAL(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; } } else if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } } else if (IS_CV == IS_VAR && UNEXPECTED(*variable_ptr_ptr == &EG(error_zval))) { if (1) { @@ -34820,7 +34973,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR } if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } } else { if (IS_TMP_VAR == IS_TMP_VAR) { @@ -34832,7 +34985,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR } if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(value); - AI_SET_PTR(&EX_T(opline->result.var), value); + EX_T(opline->result.var).var.ptr = value; } } @@ -34913,6 +35066,8 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_ call->object = this_ptr; } } + + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; @@ -35171,22 +35326,21 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_TMP(int { USE_OPLINE zend_free_op free_op2; - zval **container; + zval *container; zval **value = NULL; int result = 0; ulong hval; zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); - + container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) { + if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) { HashTable *ht; int isset = 0; - ht = Z_ARRVAL_PP(container); + ht = Z_ARRVAL_P(container); switch (Z_TYPE_P(offset)) { case IS_DOUBLE: @@ -35205,9 +35359,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_TMP(int if (IS_TMP_VAR == IS_CONST) { hval = Z_HASH_P(offset); } else { - if (!prop_dim) { - ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop); - } + ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop); hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } if (zend_hash_quick_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, (void **) &value) == SUCCESS) { @@ -35231,27 +35383,27 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_TMP(int result = isset; } } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - if (!isset || !i_zend_is_true(*value)) { + if (!isset || !i_zend_is_true(*value TSRMLS_CC)) { result = 0; } else { result = 1; } } zval_dtor(free_op2.var); - } else if (Z_TYPE_PP(container) == IS_OBJECT) { + } else if (Z_TYPE_P(container) == IS_OBJECT) { if (1) { MAKE_REAL_ZVAL_PTR(offset); } if (prop_dim) { - if (Z_OBJ_HT_P(*container)->has_property) { - result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + if (Z_OBJ_HT_P(container)->has_property) { + result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); } else { zend_error(E_NOTICE, "Trying to check property of non-object"); result = 0; } } else { - if (Z_OBJ_HT_P(*container)->has_dimension) { - result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC); + if (Z_OBJ_HT_P(container)->has_dimension) { + result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC); } else { zend_error(E_NOTICE, "Trying to check element of non-array"); result = 0; @@ -35262,7 +35414,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_TMP(int } else { zval_dtor(free_op2.var); } - } else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */ + } else if (Z_TYPE_P(container) == IS_STRING && !prop_dim) { /* string offsets */ zval tmp; if (Z_TYPE_P(offset) != IS_LONG) { @@ -35280,11 +35432,11 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_TMP(int } if (Z_TYPE_P(offset) == IS_LONG) { if (opline->extended_value & ZEND_ISSET) { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) { + if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) { result = 1; } } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') { + if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container) && Z_STRVAL_P(container)[offset->value.lval] != '0') { result = 1; } } @@ -35453,11 +35605,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG ZVAL_LONG(generator->key, generator->largest_used_integer_key); } - /* If a value is sent it should go into the result var */ - generator->send_target = &EX_T(opline->result.var); - - /* Initialize the sent value to NULL */ - EX_T(opline->result.var).tmp_var = EG(uninitialized_zval); + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = &EX_T(opline->result.var).var.ptr; + Z_ADDREF(EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); + } else { + generator->send_target = NULL; + } /* We increment to the next op, so we are at the correct position when the * generator is resumed. */ @@ -35480,7 +35636,7 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -35495,7 +35651,7 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -35510,7 +35666,7 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -35525,7 +35681,7 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -35540,7 +35696,7 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -35555,7 +35711,7 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -35570,7 +35726,7 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -35585,7 +35741,7 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -35600,7 +35756,7 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -35617,7 +35773,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); Z_LVAL_P(result) = !Z_LVAL_P(result); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -35633,7 +35789,7 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC)); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -35649,7 +35805,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC)); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -35665,7 +35821,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC)); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -35681,7 +35837,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_VAR_HANDLER(ZEND_OPCO _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC)); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -35696,7 +35852,7 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -35711,7 +35867,7 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -35726,7 +35882,7 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -35741,7 +35897,7 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -35765,13 +35921,12 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_VAR(int (*bina if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to assign property of non-object"); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); FREE_OP(free_op_data1); if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); - EX_T(opline->result.var).var.ptr_ptr = NULL; } } else { /* here we are sure we are dealing with an object */ @@ -35791,7 +35946,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_VAR(int (*bina if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*zptr); EX_T(opline->result.var).var.ptr = *zptr; - EX_T(opline->result.var).var.ptr_ptr = NULL; } } } @@ -35830,7 +35984,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_VAR(int (*bina if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(z); EX_T(opline->result.var).var.ptr = z; - EX_T(opline->result.var).var.ptr_ptr = NULL; } zval_ptr_dtor(&z); } else { @@ -35838,7 +35991,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_VAR(int (*bina if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); - EX_T(opline->result.var).var.ptr_ptr = NULL; } } } @@ -35846,7 +35998,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_VAR(int (*bina if (0) { zval_ptr_dtor(&property); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } FREE_OP(free_op_data1); } @@ -35902,9 +36054,9 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_VAR(int (*binary_o if (UNEXPECTED(*var_ptr == &EG(error_zval))) { if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); if (opline->extended_value == ZEND_ASSIGN_DIM) { @@ -35930,9 +36082,9 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_VAR(int (*binary_o if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*var_ptr); - AI_SET_PTR(&EX_T(opline->result.var), *var_ptr); + EX_T(opline->result.var).var.ptr = *var_ptr; } - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); if (opline->extended_value == ZEND_ASSIGN_DIM) { FREE_OP(free_op_data1); @@ -36026,7 +36178,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_VAR(incdec_t in if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); *retval = &EG(uninitialized_zval); @@ -36089,7 +36241,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_VAR(incdec_t in if (0) { zval_ptr_dtor(&property); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } CHECK_EXCEPTION(); @@ -36130,7 +36282,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_VAR(incdec_t i if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); ZVAL_NULL(retval); CHECK_EXCEPTION(); @@ -36191,7 +36343,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_VAR(incdec_t i if (0) { zval_ptr_dtor(&property); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } CHECK_EXCEPTION(); @@ -36317,7 +36469,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_VAR(int type, ZEN switch (type) { case BP_VAR_R: case BP_VAR_IS: - AI_SET_PTR(&EX_T(opline->result.var), *retval); + EX_T(opline->result.var).var.ptr = *retval; break; case BP_VAR_UNSET: { zend_free_op free_res; @@ -36357,7 +36509,7 @@ static int ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HA { USE_OPLINE - return zend_fetch_var_address_helper_SPEC_CV_VAR(ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + return zend_fetch_var_address_helper_SPEC_CV_VAR(zend_is_by_ref_func_arg_fetch(opline, EX(call) TSRMLS_CC) ? BP_VAR_W : BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } static int ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -36374,24 +36526,15 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDL { USE_OPLINE zend_free_op free_op2; - zval **container; + zval *container; SAVE_OPLINE(); + container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); + zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC); + zval_ptr_dtor_nogc(&free_op2.var); + if (IS_CV != IS_VAR || !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { - if (IS_CV == IS_TMP_VAR || IS_CV == IS_CONST) { - zval *container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); - zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); - - } else { - container = _get_zval_ptr_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); - zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); - if (IS_CV == IS_VAR && !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { - - } } - CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -36409,7 +36552,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDL zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_W TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } @@ -36442,7 +36585,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_RW TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } @@ -36455,12 +36598,12 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND { USE_OPLINE zend_free_op free_op2; - zval **container; + zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); + container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_IS TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -36470,12 +36613,11 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCOD { USE_OPLINE zend_free_op free_op1, free_op2; - zval **container; SAVE_OPLINE(); - if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) { - container = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); + if (zend_is_by_ref_func_arg_fetch(opline, EX(call) TSRMLS_CC)) { + zval **container = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } @@ -36483,15 +36625,17 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCOD if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } else { + zval *container; + if (IS_VAR == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } - container = _get_zval_ptr_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); + container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } CHECK_EXCEPTION(); @@ -36516,7 +36660,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_H zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_UNSET TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); } @@ -36555,8 +36699,8 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_CV_VAR(ZEN UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { zend_error(E_NOTICE, "Trying to get property of non-object"); PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); - zval_ptr_dtor(&free_op2.var); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); + zval_ptr_dtor_nogc(&free_op2.var); } else { zval *retval; @@ -36568,12 +36712,12 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_CV_VAR(ZEN retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); PZVAL_LOCK(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; if (0) { zval_ptr_dtor(&offset); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } } @@ -36596,11 +36740,6 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDL SAVE_OPLINE(); property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (IS_CV == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) { - PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); - EX_T(opline->op1.var).var.ptr = *EX_T(opline->op1.var).var.ptr_ptr; - } - if (0) { MAKE_REAL_ZVAL_PTR(property); } @@ -36613,7 +36752,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDL if (0) { zval_ptr_dtor(&property); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); @@ -36655,7 +36794,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND if (0) { zval_ptr_dtor(&property); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); @@ -36680,8 +36819,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); - zval_ptr_dtor(&free_op2.var); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); + zval_ptr_dtor_nogc(&free_op2.var); } else { zval *retval; @@ -36693,12 +36832,12 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); PZVAL_LOCK(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; if (0) { zval_ptr_dtor(&offset); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } } @@ -36710,7 +36849,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCOD { USE_OPLINE - if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) { + if (zend_is_by_ref_func_arg_fetch(opline, EX(call) TSRMLS_CC)) { /* Behave like FETCH_OBJ_W */ zend_free_op free_op1, free_op2; zval *property; @@ -36730,7 +36869,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCOD if (0) { zval_ptr_dtor(&property); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); @@ -36769,7 +36908,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_H if (0) { zval_ptr_dtor(&property); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); @@ -36806,7 +36945,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE if (0) { zval_ptr_dtor(&property_name); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } /* assign_obj has two opcodes! */ @@ -36838,7 +36977,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE if (0) { zval_ptr_dtor(&property_name); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } } else { zend_free_op free_op2, free_op_data1, free_op_data2; @@ -36847,7 +36986,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE zval **variable_ptr_ptr; zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), object_ptr, dim, IS_VAR, BP_VAR_W TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); @@ -36859,11 +36998,11 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE ALLOC_ZVAL(retval); ZVAL_STRINGL(retval, Z_STRVAL_P(EX_T((opline+1)->op2.var).str_offset.str)+EX_T((opline+1)->op2.var).str_offset.offset, 1, 1); INIT_PZVAL(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; } } else if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } } else if (UNEXPECTED(*variable_ptr_ptr == &EG(error_zval))) { if (IS_TMP_FREE(free_op_data1)) { @@ -36871,7 +37010,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE } if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } } else { if ((opline+1)->op1_type == IS_TMP_VAR) { @@ -36883,7 +37022,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE } if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(value); - AI_SET_PTR(&EX_T(opline->result.var), value); + EX_T(opline->result.var).var.ptr = value; } } FREE_OP_VAR_PTR(free_op_data2); @@ -36915,11 +37054,11 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR ALLOC_ZVAL(retval); ZVAL_STRINGL(retval, Z_STRVAL_P(EX_T(opline->op1.var).str_offset.str)+EX_T(opline->op1.var).str_offset.offset, 1, 1); INIT_PZVAL(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; } } else if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } } else if (IS_CV == IS_VAR && UNEXPECTED(*variable_ptr_ptr == &EG(error_zval))) { if (0) { @@ -36927,7 +37066,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR } if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } } else { if (IS_VAR == IS_TMP_VAR) { @@ -36939,12 +37078,12 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR } if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(value); - AI_SET_PTR(&EX_T(opline->result.var), value); + EX_T(opline->result.var).var.ptr = value; } } /* zend_assign_to_variable() always takes care of op2, never free it! */ - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -36970,7 +37109,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE } zend_error(E_STRICT, "Only variables should be assigned by reference"); if (UNEXPECTED(EG(exception) != NULL)) { - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + if (free_op2.var) {zval_ptr_dtor_nogc(&free_op2.var);}; HANDLE_EXCEPTION(); } return ZEND_ASSIGN_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -36994,10 +37133,10 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*variable_ptr_ptr); - AI_SET_PTR(&EX_T(opline->result.var), *variable_ptr_ptr); + EX_T(opline->result.var).var.ptr = *variable_ptr_ptr; } - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + if (free_op2.var) {zval_ptr_dtor_nogc(&free_op2.var);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -37055,7 +37194,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_ } } else { if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); HANDLE_EXCEPTION(); } zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval); @@ -37074,10 +37213,12 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_ call->object = this_ptr; } } + + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -37093,7 +37234,7 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -37168,7 +37309,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_VAR_HANDLER(ZEND_OPCODE /* do nothing */ break; } - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } else { zend_hash_next_index_insert(Z_ARRVAL(EX_T(opline->result.var).tmp_var), &expr_ptr, sizeof(zval *), NULL); } @@ -37334,7 +37475,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER zend_error(E_WARNING, "Illegal offset type in unset"); break; } - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); break; } case IS_OBJECT: @@ -37348,18 +37489,18 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER if (0) { zval_ptr_dtor(&offset); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } break; case IS_STRING: zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); ZEND_VM_CONTINUE(); /* bailed out before */ default: - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); break; } } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } CHECK_EXCEPTION(); @@ -37393,13 +37534,13 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER if (0) { zval_ptr_dtor(&offset); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } CHECK_EXCEPTION(); @@ -37480,7 +37621,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 0); } } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - if (!isset || !i_zend_is_true(*value)) { + if (!isset || !i_zend_is_true(*value TSRMLS_CC)) { ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 1); } else { ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 0); @@ -37495,22 +37636,21 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_VAR(int { USE_OPLINE zend_free_op free_op2; - zval **container; + zval *container; zval **value = NULL; int result = 0; ulong hval; zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); - + container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) { + if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) { HashTable *ht; int isset = 0; - ht = Z_ARRVAL_PP(container); + ht = Z_ARRVAL_P(container); switch (Z_TYPE_P(offset)) { case IS_DOUBLE: @@ -37529,9 +37669,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_VAR(int if (IS_VAR == IS_CONST) { hval = Z_HASH_P(offset); } else { - if (!prop_dim) { - ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop); - } + ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop); hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } if (zend_hash_quick_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, (void **) &value) == SUCCESS) { @@ -37555,27 +37693,27 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_VAR(int result = isset; } } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - if (!isset || !i_zend_is_true(*value)) { + if (!isset || !i_zend_is_true(*value TSRMLS_CC)) { result = 0; } else { result = 1; } } - zval_ptr_dtor(&free_op2.var); - } else if (Z_TYPE_PP(container) == IS_OBJECT) { + zval_ptr_dtor_nogc(&free_op2.var); + } else if (Z_TYPE_P(container) == IS_OBJECT) { if (0) { MAKE_REAL_ZVAL_PTR(offset); } if (prop_dim) { - if (Z_OBJ_HT_P(*container)->has_property) { - result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + if (Z_OBJ_HT_P(container)->has_property) { + result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); } else { zend_error(E_NOTICE, "Trying to check property of non-object"); result = 0; } } else { - if (Z_OBJ_HT_P(*container)->has_dimension) { - result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC); + if (Z_OBJ_HT_P(container)->has_dimension) { + result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC); } else { zend_error(E_NOTICE, "Trying to check element of non-array"); result = 0; @@ -37584,9 +37722,9 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_VAR(int if (0) { zval_ptr_dtor(&offset); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } - } else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */ + } else if (Z_TYPE_P(container) == IS_STRING && !prop_dim) { /* string offsets */ zval tmp; if (Z_TYPE_P(offset) != IS_LONG) { @@ -37604,18 +37742,18 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_VAR(int } if (Z_TYPE_P(offset) == IS_LONG) { if (opline->extended_value & ZEND_ISSET) { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) { + if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) { result = 1; } } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') { + if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container) && Z_STRVAL_P(container)[offset->value.lval] != '0') { result = 1; } } } - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } else { - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } Z_TYPE(EX_T(opline->result.var).tmp_var) = IS_BOOL; @@ -37769,7 +37907,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG generator->largest_used_integer_key = Z_LVAL_P(generator->key); } - zval_ptr_dtor(&free_op2.var); + zval_ptr_dtor_nogc(&free_op2.var); } else { /* If no key was specified we use auto-increment keys */ generator->largest_used_integer_key++; @@ -37778,11 +37916,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG ZVAL_LONG(generator->key, generator->largest_used_integer_key); } - /* If a value is sent it should go into the result var */ - generator->send_target = &EX_T(opline->result.var); - - /* Initialize the sent value to NULL */ - EX_T(opline->result.var).tmp_var = EG(uninitialized_zval); + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = &EX_T(opline->result.var).var.ptr; + Z_ADDREF(EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); + } else { + generator->send_target = NULL; + } /* We increment to the next op, so we are at the correct position when the * generator is resumed. */ @@ -37820,7 +37962,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(int (*b if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); - EX_T(opline->result.var).var.ptr_ptr = NULL; } } else { /* here we are sure we are dealing with an object */ @@ -37840,7 +37981,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(int (*b if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*zptr); EX_T(opline->result.var).var.ptr = *zptr; - EX_T(opline->result.var).var.ptr_ptr = NULL; } } } @@ -37879,7 +38019,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(int (*b if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(z); EX_T(opline->result.var).var.ptr = z; - EX_T(opline->result.var).var.ptr_ptr = NULL; } zval_ptr_dtor(&z); } else { @@ -37887,7 +38026,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(int (*b if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); - EX_T(opline->result.var).var.ptr_ptr = NULL; } } } @@ -37951,7 +38089,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_UNUSED(int (*binar if (UNEXPECTED(*var_ptr == &EG(error_zval))) { if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } @@ -37979,7 +38117,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_UNUSED(int (*binar if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*var_ptr); - AI_SET_PTR(&EX_T(opline->result.var), *var_ptr); + EX_T(opline->result.var).var.ptr = *var_ptr; } if (opline->extended_value == ZEND_ASSIGN_DIM) { @@ -38159,7 +38297,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_UNUSED(int type, switch (type) { case BP_VAR_R: case BP_VAR_IS: - AI_SET_PTR(&EX_T(opline->result.var), *retval); + EX_T(opline->result.var).var.ptr = *retval; break; case BP_VAR_UNSET: { zend_free_op free_res; @@ -38199,7 +38337,7 @@ static int ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE { USE_OPLINE - return zend_fetch_var_address_helper_SPEC_CV_UNUSED(ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + return zend_fetch_var_address_helper_SPEC_CV_UNUSED(zend_is_by_ref_func_arg_fetch(opline, EX(call) TSRMLS_CC) ? BP_VAR_W : BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } static int ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -38271,12 +38409,11 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED_HANDLER(ZEND_OP { USE_OPLINE zend_free_op free_op1; - zval **container; SAVE_OPLINE(); - if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) { - container = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); + if (zend_is_by_ref_func_arg_fetch(opline, EX(call) TSRMLS_CC)) { + zval **container = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } @@ -38287,10 +38424,12 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED_HANDLER(ZEND_OP } else { + zval *container; + if (IS_UNUSED == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } - container = _get_zval_ptr_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); + container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, NULL, IS_UNUSED, BP_VAR_R TSRMLS_CC); @@ -38342,11 +38481,11 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAN ALLOC_ZVAL(retval); ZVAL_STRINGL(retval, Z_STRVAL_P(EX_T((opline+1)->op2.var).str_offset.str)+EX_T((opline+1)->op2.var).str_offset.offset, 1, 1); INIT_PZVAL(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; } } else if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } } else if (UNEXPECTED(*variable_ptr_ptr == &EG(error_zval))) { if (IS_TMP_FREE(free_op_data1)) { @@ -38354,7 +38493,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAN } if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } } else { if ((opline+1)->op1_type == IS_TMP_VAR) { @@ -38366,7 +38505,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAN } if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(value); - AI_SET_PTR(&EX_T(opline->result.var), value); + EX_T(opline->result.var).var.ptr = value; } } FREE_OP_VAR_PTR(free_op_data2); @@ -38626,7 +38765,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPC ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 0); } } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - if (!isset || !i_zend_is_true(*value)) { + if (!isset || !i_zend_is_true(*value TSRMLS_CC)) { ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 1); } else { ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 0); @@ -38775,11 +38914,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ ZVAL_LONG(generator->key, generator->largest_used_integer_key); } - /* If a value is sent it should go into the result var */ - generator->send_target = &EX_T(opline->result.var); - - /* Initialize the sent value to NULL */ - EX_T(opline->result.var).tmp_var = EG(uninitialized_zval); + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = &EX_T(opline->result.var).var.ptr; + Z_ADDREF(EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); + } else { + generator->send_target = NULL; + } /* We increment to the next op, so we are at the correct position when the * generator is resumed. */ @@ -39093,7 +39236,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CV(int (*binar if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); - EX_T(opline->result.var).var.ptr_ptr = NULL; } } else { /* here we are sure we are dealing with an object */ @@ -39113,7 +39255,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CV(int (*binar if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*zptr); EX_T(opline->result.var).var.ptr = *zptr; - EX_T(opline->result.var).var.ptr_ptr = NULL; } } } @@ -39152,7 +39293,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CV(int (*binar if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(z); EX_T(opline->result.var).var.ptr = z; - EX_T(opline->result.var).var.ptr_ptr = NULL; } zval_ptr_dtor(&z); } else { @@ -39160,7 +39300,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CV(int (*binar if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); - EX_T(opline->result.var).var.ptr_ptr = NULL; } } } @@ -39224,7 +39363,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_CV(int (*binary_op if (UNEXPECTED(*var_ptr == &EG(error_zval))) { if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } @@ -39252,7 +39391,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_CV(int (*binary_op if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*var_ptr); - AI_SET_PTR(&EX_T(opline->result.var), *var_ptr); + EX_T(opline->result.var).var.ptr = *var_ptr; } if (opline->extended_value == ZEND_ASSIGN_DIM) { @@ -39533,24 +39672,15 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLE { USE_OPLINE - zval **container; + zval *container; SAVE_OPLINE(); + container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); + zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC); - if (IS_CV == IS_TMP_VAR || IS_CV == IS_CONST) { - zval *container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); - zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC); - - - } else { - container = _get_zval_ptr_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); - zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC); - - if (IS_CV == IS_VAR && !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { + if (IS_CV != IS_VAR || !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { - } } - CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -39614,10 +39744,10 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDL { USE_OPLINE - zval **container; + zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); + container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_IS TSRMLS_CC); @@ -39629,12 +39759,11 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE { USE_OPLINE zend_free_op free_op1; - zval **container; SAVE_OPLINE(); - if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) { - container = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); + if (zend_is_by_ref_func_arg_fetch(opline, EX(call) TSRMLS_CC)) { + zval **container = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } @@ -39645,10 +39774,12 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE } else { + zval *container; + if (IS_CV == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } - container = _get_zval_ptr_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); + container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC); @@ -39714,7 +39845,7 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_CV_CV(ZEND UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { zend_error(E_NOTICE, "Trying to get property of non-object"); PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } else { zval *retval; @@ -39727,7 +39858,7 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_CV_CV(ZEND retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); PZVAL_LOCK(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; if (0) { zval_ptr_dtor(&offset); @@ -39755,11 +39886,6 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLE SAVE_OPLINE(); property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - if (IS_CV == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) { - PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); - EX_T(opline->op1.var).var.ptr = *EX_T(opline->op1.var).var.ptr_ptr; - } - if (0) { MAKE_REAL_ZVAL_PTR(property); } @@ -39839,7 +39965,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDL if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) || UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } else { zval *retval; @@ -39852,7 +39978,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDL retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); PZVAL_LOCK(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; if (0) { zval_ptr_dtor(&offset); @@ -39869,7 +39995,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE { USE_OPLINE - if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) { + if (zend_is_by_ref_func_arg_fetch(opline, EX(call) TSRMLS_CC)) { /* Behave like FETCH_OBJ_W */ zend_free_op free_op1; zval *property; @@ -40017,11 +40143,11 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER ALLOC_ZVAL(retval); ZVAL_STRINGL(retval, Z_STRVAL_P(EX_T((opline+1)->op2.var).str_offset.str)+EX_T((opline+1)->op2.var).str_offset.offset, 1, 1); INIT_PZVAL(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; } } else if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } } else if (UNEXPECTED(*variable_ptr_ptr == &EG(error_zval))) { if (IS_TMP_FREE(free_op_data1)) { @@ -40029,7 +40155,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER } if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } } else { if ((opline+1)->op1_type == IS_TMP_VAR) { @@ -40041,7 +40167,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER } if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(value); - AI_SET_PTR(&EX_T(opline->result.var), value); + EX_T(opline->result.var).var.ptr = value; } } FREE_OP_VAR_PTR(free_op_data2); @@ -40073,11 +40199,11 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG ALLOC_ZVAL(retval); ZVAL_STRINGL(retval, Z_STRVAL_P(EX_T(opline->op1.var).str_offset.str)+EX_T(opline->op1.var).str_offset.offset, 1, 1); INIT_PZVAL(retval); - AI_SET_PTR(&EX_T(opline->result.var), retval); + EX_T(opline->result.var).var.ptr = retval; } } else if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } } else if (IS_CV == IS_VAR && UNEXPECTED(*variable_ptr_ptr == &EG(error_zval))) { if (0) { @@ -40085,7 +40211,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG } if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(&EG(uninitialized_zval)); - AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); } } else { if (IS_CV == IS_TMP_VAR) { @@ -40097,7 +40223,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG } if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(value); - AI_SET_PTR(&EX_T(opline->result.var), value); + EX_T(opline->result.var).var.ptr = value; } } @@ -40151,7 +40277,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(*variable_ptr_ptr); - AI_SET_PTR(&EX_T(opline->result.var), *variable_ptr_ptr); + EX_T(opline->result.var).var.ptr = *variable_ptr_ptr; } @@ -40230,6 +40356,8 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_H call->object = this_ptr; } } + + call->num_additional_args = 0; call->is_ctor_call = 0; EX(call) = call; @@ -40486,22 +40614,21 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_CV(int { USE_OPLINE - zval **container; + zval *container; zval **value = NULL; int result = 0; ulong hval; zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); - + container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) { + if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) { HashTable *ht; int isset = 0; - ht = Z_ARRVAL_PP(container); + ht = Z_ARRVAL_P(container); switch (Z_TYPE_P(offset)) { case IS_DOUBLE: @@ -40520,9 +40647,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_CV(int if (IS_CV == IS_CONST) { hval = Z_HASH_P(offset); } else { - if (!prop_dim) { - ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop); - } + ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop); hval = str_hash(Z_STRVAL_P(offset), Z_STRLEN_P(offset)); } if (zend_hash_quick_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, (void **) &value) == SUCCESS) { @@ -40546,27 +40671,27 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_CV(int result = isset; } } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - if (!isset || !i_zend_is_true(*value)) { + if (!isset || !i_zend_is_true(*value TSRMLS_CC)) { result = 0; } else { result = 1; } } - } else if (Z_TYPE_PP(container) == IS_OBJECT) { + } else if (Z_TYPE_P(container) == IS_OBJECT) { if (0) { MAKE_REAL_ZVAL_PTR(offset); } if (prop_dim) { - if (Z_OBJ_HT_P(*container)->has_property) { - result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); + if (Z_OBJ_HT_P(container)->has_property) { + result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC); } else { zend_error(E_NOTICE, "Trying to check property of non-object"); result = 0; } } else { - if (Z_OBJ_HT_P(*container)->has_dimension) { - result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC); + if (Z_OBJ_HT_P(container)->has_dimension) { + result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC); } else { zend_error(E_NOTICE, "Trying to check element of non-array"); result = 0; @@ -40577,7 +40702,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_CV(int } else { } - } else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */ + } else if (Z_TYPE_P(container) == IS_STRING && !prop_dim) { /* string offsets */ zval tmp; if (Z_TYPE_P(offset) != IS_LONG) { @@ -40595,11 +40720,11 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_CV(int } if (Z_TYPE_P(offset) == IS_LONG) { if (opline->extended_value & ZEND_ISSET) { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) { + if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) { result = 1; } } else /* if (opline->extended_value & ZEND_ISEMPTY) */ { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') { + if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container) && Z_STRVAL_P(container)[offset->value.lval] != '0') { result = 1; } } @@ -40768,11 +40893,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS ZVAL_LONG(generator->key, generator->largest_used_integer_key); } - /* If a value is sent it should go into the result var */ - generator->send_target = &EX_T(opline->result.var); - - /* Initialize the sent value to NULL */ - EX_T(opline->result.var).tmp_var = EG(uninitialized_zval); + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = &EX_T(opline->result.var).var.ptr; + Z_ADDREF(EG(uninitialized_zval)); + EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval); + } else { + generator->send_target = NULL; + } /* We increment to the next op, so we are at the correct position when the * generator is resumed. */ @@ -44895,6 +45024,56 @@ void zend_init_opcodes_handlers(void) ZEND_FAST_RET_SPEC_HANDLER, ZEND_FAST_RET_SPEC_HANDLER, ZEND_FAST_RET_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_RECV_VARIADIC_SPEC_HANDLER, + ZEND_SEND_UNPACK_SPEC_HANDLER, + ZEND_SEND_UNPACK_SPEC_HANDLER, + ZEND_SEND_UNPACK_SPEC_HANDLER, + ZEND_SEND_UNPACK_SPEC_HANDLER, + ZEND_SEND_UNPACK_SPEC_HANDLER, + ZEND_SEND_UNPACK_SPEC_HANDLER, + ZEND_SEND_UNPACK_SPEC_HANDLER, + ZEND_SEND_UNPACK_SPEC_HANDLER, + ZEND_SEND_UNPACK_SPEC_HANDLER, + ZEND_SEND_UNPACK_SPEC_HANDLER, + ZEND_SEND_UNPACK_SPEC_HANDLER, + ZEND_SEND_UNPACK_SPEC_HANDLER, + ZEND_SEND_UNPACK_SPEC_HANDLER, + ZEND_SEND_UNPACK_SPEC_HANDLER, + ZEND_SEND_UNPACK_SPEC_HANDLER, + ZEND_SEND_UNPACK_SPEC_HANDLER, + ZEND_SEND_UNPACK_SPEC_HANDLER, + ZEND_SEND_UNPACK_SPEC_HANDLER, + ZEND_SEND_UNPACK_SPEC_HANDLER, + ZEND_SEND_UNPACK_SPEC_HANDLER, + ZEND_SEND_UNPACK_SPEC_HANDLER, + ZEND_SEND_UNPACK_SPEC_HANDLER, + ZEND_SEND_UNPACK_SPEC_HANDLER, + ZEND_SEND_UNPACK_SPEC_HANDLER, + ZEND_SEND_UNPACK_SPEC_HANDLER, ZEND_NULL_HANDLER }; zend_opcode_handlers = (opcode_handler_t*)labels; diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php index a65349c4ed63d..697c6504f05d3 100644 --- a/Zend/zend_vm_gen.php +++ b/Zend/zend_vm_gen.php @@ -218,7 +218,7 @@ $op1_free_op = array( "ANY" => "FREE_OP(free_op1)", "TMP" => "zval_dtor(free_op1.var)", - "VAR" => "zval_ptr_dtor(&free_op1.var)", + "VAR" => "zval_ptr_dtor_nogc(&free_op1.var)", "CONST" => "", "UNUSED" => "", "CV" => "", @@ -227,7 +227,7 @@ $op2_free_op = array( "ANY" => "FREE_OP(free_op2)", "TMP" => "zval_dtor(free_op2.var)", - "VAR" => "zval_ptr_dtor(&free_op2.var)", + "VAR" => "zval_ptr_dtor_nogc(&free_op2.var)", "CONST" => "", "UNUSED" => "", "CV" => "", @@ -236,7 +236,7 @@ $op1_free_op_if_var = array( "ANY" => "FREE_OP_IF_VAR(free_op1)", "TMP" => "", - "VAR" => "zval_ptr_dtor(&free_op1.var)", + "VAR" => "zval_ptr_dtor_nogc(&free_op1.var)", "CONST" => "", "UNUSED" => "", "CV" => "", @@ -245,33 +245,33 @@ $op2_free_op_if_var = array( "ANY" => "FREE_OP_IF_VAR(free_op2)", "TMP" => "", - "VAR" => "zval_ptr_dtor(&free_op2.var)", + "VAR" => "zval_ptr_dtor_nogc(&free_op2.var)", "CONST" => "", "UNUSED" => "", "CV" => "", ); $op1_free_op_var_ptr = array( - "ANY" => "if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}", + "ANY" => "if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}", "TMP" => "", - "VAR" => "if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}", + "VAR" => "if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}", "CONST" => "", "UNUSED" => "", "CV" => "", ); $op1_free_op_var_ptr_fast = $op1_free_op_var_ptr; -$op1_free_op_var_ptr_fast["VAR"] = "zval_ptr_dtor(&free_op1.var)"; +$op1_free_op_var_ptr_fast["VAR"] = "zval_ptr_dtor_nogc(&free_op1.var)"; $op2_free_op_var_ptr = array( - "ANY" => "if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}", + "ANY" => "if (free_op2.var) {zval_ptr_dtor_nogc(&free_op2.var);}", "TMP" => "", - "VAR" => "if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}", + "VAR" => "if (free_op2.var) {zval_ptr_dtor_nogc(&free_op2.var);}", "CONST" => "", "UNUSED" => "", "CV" => "", ); $op2_free_op_var_ptr_fast = $op2_free_op_var_ptr; -$op2_free_op_var_ptr_fast["VAR"] = "zval_ptr_dtor(&free_op2.var)"; +$op2_free_op_var_ptr_fast["VAR"] = "zval_ptr_dtor_nogc(&free_op2.var)"; $list = array(); // list of opcode handlers and helpers in original order $opcodes = array(); // opcode handlers by code @@ -911,9 +911,15 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name, out($f,"#undef CHECK_EXCEPTION\n"); out($f,"#undef HANDLE_EXCEPTION\n"); out($f,"#undef HANDLE_EXCEPTION_LEAVE\n"); - out($f,"#define CHECK_EXCEPTION() if (UNEXPECTED(EG(exception) != NULL)) goto ZEND_HANDLE_EXCEPTION_SPEC_HANDLER\n"); - out($f,"#define HANDLE_EXCEPTION() goto ZEND_HANDLE_EXCEPTION_SPEC_HANDLER\n"); - out($f,"#define HANDLE_EXCEPTION_LEAVE() goto ZEND_HANDLE_EXCEPTION_SPEC_HANDLER\n"); + if (ZEND_VM_SPEC) { + out($f,"#define CHECK_EXCEPTION() if (UNEXPECTED(EG(exception) != NULL)) goto ZEND_HANDLE_EXCEPTION_SPEC_HANDLER\n"); + out($f,"#define HANDLE_EXCEPTION() goto ZEND_HANDLE_EXCEPTION_SPEC_HANDLER\n"); + out($f,"#define HANDLE_EXCEPTION_LEAVE() goto ZEND_HANDLE_EXCEPTION_SPEC_HANDLER\n"); + } else { + out($f,"#define CHECK_EXCEPTION() if (UNEXPECTED(EG(exception) != NULL)) goto ZEND_HANDLE_EXCEPTION_HANDLER\n"); + out($f,"#define HANDLE_EXCEPTION() goto ZEND_HANDLE_EXCEPTION_HANDLER\n"); + out($f,"#define HANDLE_EXCEPTION_LEAVE() goto ZEND_HANDLE_EXCEPTION_HANDLER\n"); + } out($f,"#define LOAD_REGS()\n"); out($f,"#define ZEND_VM_CONTINUE() goto *(void**)(OPLINE->handler)\n"); out($f,"#define ZEND_VM_RETURN() EG(in_execution) = original_in_execution; return\n"); diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h index 859258a440bef..2cf345879ba21 100644 --- a/Zend/zend_vm_opcodes.h +++ b/Zend/zend_vm_opcodes.h @@ -164,3 +164,5 @@ #define ZEND_GENERATOR_RETURN 161 #define ZEND_FAST_CALL 162 #define ZEND_FAST_RET 163 +#define ZEND_RECV_VARIADIC 164 +#define ZEND_SEND_UNPACK 165 diff --git a/build/shtool b/build/shtool index 684a01f5df968..fc6ae1e6efbbb 100755 --- a/build/shtool +++ b/build/shtool @@ -1003,7 +1003,14 @@ mkdir ) if [ ".$opt_t" = .yes ]; then echo "mkdir $pathcomp" 1>&2 fi - mkdir $pathcomp || errstatus=$? + # See https://bugs.php.net/51076 + # The fix is from Debian who have sent it + # upstream, too; but upstream seems dead. + mkdir $pathcomp || { + _errstatus=$? + [ -d "$pathcomp" ] || errstatus=${_errstatus} + unset _errstatus + } if [ ".$opt_o" != . ]; then if [ ".$opt_t" = .yes ]; then echo "chown $opt_o $pathcomp" 1>&2 diff --git a/configure.in b/configure.in index 16738fe30ab67..b1da391ed6a39 100644 --- a/configure.in +++ b/configure.in @@ -118,7 +118,7 @@ int zend_sprintf(char *buffer, const char *format, ...); ]) PHP_MAJOR_VERSION=5 -PHP_MINOR_VERSION=6 +PHP_MINOR_VERSION=7 PHP_RELEASE_VERSION=0 PHP_EXTRA_VERSION="-dev" PHP_VERSION="$PHP_MAJOR_VERSION.$PHP_MINOR_VERSION.$PHP_RELEASE_VERSION$PHP_EXTRA_VERSION" @@ -1440,7 +1440,7 @@ PHP_SUBST(install_binary_targets) PHP_INSTALL_HEADERS([Zend/ TSRM/ include/ main/ main/streams/]) -PHP_ADD_SOURCES(TSRM, TSRM.c tsrm_strtok_r.c tsrm_virtual_cwd.c) +PHP_ADD_SOURCES(TSRM, TSRM.c tsrm_strtok_r.c) PHP_ADD_SOURCES(main, main.c snprintf.c spprintf.c php_sprintf.c \ fopen_wrappers.c alloca.c php_scandir.c \ @@ -1475,7 +1475,8 @@ PHP_ADD_SOURCES(Zend, \ zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \ zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \ zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_gc.c \ - zend_closures.c zend_float.c zend_string.c zend_signal.c zend_generators.c) + zend_closures.c zend_float.c zend_string.c zend_signal.c zend_generators.c \ + zend_virtual_cwd.c zend_ast.c) if test -r "$abs_srcdir/Zend/zend_objects.c"; then PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_default_classes.c) diff --git a/ext/bcmath/libbcmath/src/recmul.c b/ext/bcmath/libbcmath/src/recmul.c index c31d09dc72db5..64014f3a6e8a0 100644 --- a/ext/bcmath/libbcmath/src/recmul.c +++ b/ext/bcmath/libbcmath/src/recmul.c @@ -183,7 +183,6 @@ _bc_rec_mul (bc_num u, int ulen, bc_num v, int vlen, bc_num *prod, int full_scale TSRMLS_DC) { bc_num u0, u1, v0, v1; - int u0len, v0len; bc_num m1, m2, m3, d1, d2; int n, prodlen, m1zero; int d1len, d2len; @@ -216,10 +215,8 @@ _bc_rec_mul (bc_num u, int ulen, bc_num v, int vlen, bc_num *prod, } _bc_rm_leading_zeros (u1); _bc_rm_leading_zeros (u0); - u0len = u0->n_len; _bc_rm_leading_zeros (v1); _bc_rm_leading_zeros (v0); - v0len = v0->n_len; m1zero = bc_is_zero(u1 TSRMLS_CC) || bc_is_zero(v1 TSRMLS_CC); diff --git a/ext/bz2/bz2_filter.c b/ext/bz2/bz2_filter.c index 335600232b301..1e7837b098dae 100644 --- a/ext/bz2/bz2_filter.c +++ b/ext/bz2/bz2_filter.c @@ -97,6 +97,7 @@ static php_stream_filter_status_t php_bz2_decompress_filter( status = BZ2_bzDecompressInit(streamp, 0, data->small_footprint); if (BZ_OK != status) { + php_stream_bucket_delref(bucket TSRMLS_CC); return PSFS_ERR_FATAL; } diff --git a/ext/date/lib/dow.c b/ext/date/lib/dow.c index b6c2d69682074..6c296a2ba8a6e 100644 --- a/ext/date/lib/dow.c +++ b/ext/date/lib/dow.c @@ -25,10 +25,7 @@ static int m_table_leap[13] = { -1, 6, 2, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5 }; /* 1 static timelib_sll century_value(timelib_sll j) { - timelib_sll i = j - 17; - timelib_sll c = (4 - i * 2 + (i + 1) / 4) % 7; - - return c < 0 ? c + 7 : c; + return 6 - (j % 4) * 2; } static timelib_sll timelib_day_of_week_ex(timelib_sll y, timelib_sll m, timelib_sll d, int iso) @@ -36,11 +33,8 @@ static timelib_sll timelib_day_of_week_ex(timelib_sll y, timelib_sll m, timelib_ timelib_sll c1, y1, m1, dow; /* Only valid for Gregorian calendar, commented out as we don't handle - * julian calendar. We just return the 'wrong' day of week to be - * consistent. - if (y < 1753) { - return -1; - } */ + * Julian calendar. We just return the 'wrong' day of week to be + * consistent. */ c1 = century_value(y / 100); y1 = (y % 100); m1 = timelib_is_leap(y) ? m_table_leap[m] : m_table_common[m]; diff --git a/ext/date/lib/interval.c b/ext/date/lib/interval.c index 96867ba2b797a..dce62f3a2803d 100644 --- a/ext/date/lib/interval.c +++ b/ext/date/lib/interval.c @@ -25,7 +25,7 @@ timelib_rel_time *timelib_diff(timelib_time *one, timelib_time *two) { timelib_rel_time *rt; timelib_time *swp; - timelib_sll dst_h_corr = 0, dst_m_corr = 0; + timelib_sll dst_corr = 0 ,dst_h_corr = 0, dst_m_corr = 0; timelib_time one_backup, two_backup; rt = timelib_rel_time_ctor(); @@ -43,8 +43,9 @@ timelib_rel_time *timelib_diff(timelib_time *one, timelib_time *two) && (strcmp(one->tz_info->name, two->tz_info->name) == 0) && (one->z != two->z)) { - dst_h_corr = (two->z - one->z) / 3600; - dst_m_corr = ((two->z - one->z) % 3600) / 60; + dst_corr = two->z - one->z; + dst_h_corr = dst_corr / 3600; + dst_m_corr = (dst_corr % 3600) / 60; } /* Save old TZ info */ @@ -57,16 +58,108 @@ timelib_rel_time *timelib_diff(timelib_time *one, timelib_time *two) rt->y = two->y - one->y; rt->m = two->m - one->m; rt->d = two->d - one->d; - rt->h = two->h - one->h + dst_h_corr; - rt->i = two->i - one->i + dst_m_corr; + rt->h = two->h - one->h; + rt->i = two->i - one->i; rt->s = two->s - one->s; + if (one_backup.dst == 0 && two_backup.dst == 1 && two->sse >= one->sse + 86400 - dst_corr) { + rt->h += dst_h_corr; + rt->i += dst_m_corr; + } + rt->days = abs(floor((one->sse - two->sse - (dst_h_corr * 3600) - (dst_m_corr * 60)) / 86400)); timelib_do_rel_normalize(rt->invert ? one : two, rt); + /* We need to do this after normalisation otherwise we can't get "24H" */ + if (one_backup.dst == 1 && two_backup.dst == 0 && two->sse >= one->sse + 86400) { + if (two->sse < one->sse + 86400 - dst_corr) { + rt->d--; + rt->h = 24; + } else { + rt->h += dst_h_corr; + rt->i += dst_m_corr; + } + } + /* Restore old TZ info */ memcpy(one, &one_backup, sizeof(one_backup)); memcpy(two, &two_backup, sizeof(two_backup)); return rt; } + +timelib_time *timelib_add(timelib_time *old_time, timelib_rel_time *interval) +{ + int bias = 1; + timelib_time *t = timelib_time_clone(old_time); + + if (interval->have_weekday_relative || interval->have_special_relative) { + memcpy(&t->relative, interval, sizeof(struct timelib_rel_time)); + } else { + if (interval->invert) { + bias = -1; + } + memset(&t->relative, 0, sizeof(struct timelib_rel_time)); + t->relative.y = interval->y * bias; + t->relative.m = interval->m * bias; + t->relative.d = interval->d * bias; + t->relative.h = interval->h * bias; + t->relative.i = interval->i * bias; + t->relative.s = interval->s * bias; + } + t->have_relative = 1; + t->sse_uptodate = 0; + + timelib_update_ts(t, NULL); + +// printf("%lld %lld %d\n", old_time->dst, t->dst, (t->sse - old_time->sse)); + /* Adjust for backwards DST changeover */ + if (old_time->dst == 1 && t->dst == 0 && !interval->y && !interval->m && !interval->d) { + t->sse -= old_time->z; + t->sse += t->z; + } + + timelib_update_from_sse(t); + t->have_relative = 0; + + return t; +} + +timelib_time *timelib_sub(timelib_time *old_time, timelib_rel_time *interval) +{ + int bias = 1; + timelib_time *t = timelib_time_clone(old_time); + + if (interval->invert) { + bias = -1; + } + + memset(&t->relative, 0, sizeof(struct timelib_rel_time)); + t->relative.y = 0 - (interval->y * bias); + t->relative.m = 0 - (interval->m * bias); + t->relative.d = 0 - (interval->d * bias); + t->relative.h = 0 - (interval->h * bias); + t->relative.i = 0 - (interval->i * bias); + t->relative.s = 0 - (interval->s * bias); + t->have_relative = 1; + t->sse_uptodate = 0; + + timelib_update_ts(t, NULL); + + /* Adjust for backwards DST changeover */ + if (old_time->dst == 1 && t->dst == 0 && !interval->y && !interval->m && !interval->d) { + t->sse -= old_time->z; + t->sse += t->z; + } + /* Adjust for forwards DST changeover */ + if (old_time->dst == 0 && t->dst == 1 && !interval->y && !interval->m && !interval->d ) { + t->sse -= old_time->z; + t->sse += t->z; + } + + timelib_update_from_sse(t); + + t->have_relative = 0; + + return t; +} diff --git a/ext/date/lib/parse_iso_intervals.c b/ext/date/lib/parse_iso_intervals.c index fedad043c4254..e669c855a4476 100644 --- a/ext/date/lib/parse_iso_intervals.c +++ b/ext/date/lib/parse_iso_intervals.c @@ -1,4 +1,4 @@ -/* Generated by re2c 0.13.5 on Sun Mar 31 10:48:17 2013 */ +/* Generated by re2c 0.13.5 on Wed Nov 27 11:14:23 2013 */ #line 1 "ext/date/lib/parse_iso_intervals.re" /* +----------------------------------------------------------------------+ @@ -380,7 +380,7 @@ static int scan(Scanner *s) break; } ptr++; - } while (*ptr); + } while (!s->errors->error_count && *ptr); s->have_period = 1; TIMELIB_DEINIT; return TIMELIB_PERIOD; diff --git a/ext/date/lib/parse_iso_intervals.re b/ext/date/lib/parse_iso_intervals.re index e50ab37d3ba7f..cbbf8781bf495 100644 --- a/ext/date/lib/parse_iso_intervals.re +++ b/ext/date/lib/parse_iso_intervals.re @@ -348,7 +348,7 @@ isoweek = year4 "-"? "W" weekofyear; break; } ptr++; - } while (*ptr); + } while (!s->errors->error_count && *ptr); s->have_period = 1; TIMELIB_DEINIT; return TIMELIB_PERIOD; diff --git a/ext/date/lib/timelib.h b/ext/date/lib/timelib.h index dfb7dc0300763..3f8e1254efe9a 100644 --- a/ext/date/lib/timelib.h +++ b/ext/date/lib/timelib.h @@ -138,5 +138,7 @@ int timelib_astro_rise_set_altitude(timelib_time *time, double lon, double lat, /* from interval.c */ timelib_rel_time *timelib_diff(timelib_time *one, timelib_time *two); +timelib_time *timelib_add(timelib_time *t, timelib_rel_time *interval); +timelib_time *timelib_sub(timelib_time *t, timelib_rel_time *interval); #endif diff --git a/ext/date/lib/timezonedb.h b/ext/date/lib/timezonedb.h index 1e5706cdccd3c..4a4b04188248b 100644 --- a/ext/date/lib/timezonedb.h +++ b/ext/date/lib/timezonedb.h @@ -14,573 +14,573 @@ const timelib_tzdb_index_entry timezonedb_idx_builtin[579] = { { "Africa/Bujumbura" , 0x000571 }, { "Africa/Cairo" , 0x0005B5 }, { "Africa/Casablanca" , 0x000878 }, - { "Africa/Ceuta" , 0x000ABC }, - { "Africa/Conakry" , 0x000DC3 }, - { "Africa/Dakar" , 0x000E2E }, - { "Africa/Dar_es_Salaam" , 0x000E94 }, - { "Africa/Djibouti" , 0x000F01 }, - { "Africa/Douala" , 0x000F56 }, - { "Africa/El_Aaiun" , 0x000FAB }, - { "Africa/Freetown" , 0x001011 }, - { "Africa/Gaborone" , 0x001120 }, - { "Africa/Harare" , 0x00118D }, - { "Africa/Johannesburg" , 0x0011E2 }, - { "Africa/Juba" , 0x001250 }, - { "Africa/Kampala" , 0x001363 }, - { "Africa/Khartoum" , 0x0013E2 }, - { "Africa/Kigali" , 0x0014F5 }, - { "Africa/Kinshasa" , 0x00154A }, - { "Africa/Lagos" , 0x0015A5 }, - { "Africa/Libreville" , 0x0015FA }, - { "Africa/Lome" , 0x00164F }, - { "Africa/Luanda" , 0x001693 }, - { "Africa/Lubumbashi" , 0x0016E8 }, - { "Africa/Lusaka" , 0x001743 }, - { "Africa/Malabo" , 0x001798 }, - { "Africa/Maputo" , 0x0017FE }, - { "Africa/Maseru" , 0x001853 }, - { "Africa/Mbabane" , 0x0018BB }, - { "Africa/Mogadishu" , 0x001911 }, - { "Africa/Monrovia" , 0x00196C }, - { "Africa/Nairobi" , 0x0019D2 }, - { "Africa/Ndjamena" , 0x001A51 }, - { "Africa/Niamey" , 0x001ABD }, - { "Africa/Nouakchott" , 0x001B30 }, - { "Africa/Ouagadougou" , 0x001B9B }, - { "Africa/Porto-Novo" , 0x001BF0 }, - { "Africa/Sao_Tome" , 0x001C56 }, - { "Africa/Timbuktu" , 0x001CAB }, - { "Africa/Tripoli" , 0x001D16 }, - { "Africa/Tunis" , 0x001F0F }, - { "Africa/Windhoek" , 0x002021 }, - { "America/Adak" , 0x002268 }, - { "America/Anchorage" , 0x0025DE }, - { "America/Anguilla" , 0x002952 }, - { "America/Antigua" , 0x0029A7 }, - { "America/Araguaina" , 0x002A0D }, - { "America/Argentina/Buenos_Aires" , 0x002C67 }, - { "America/Argentina/Catamarca" , 0x002E15 }, - { "America/Argentina/ComodRivadavia" , 0x002FD6 }, - { "America/Argentina/Cordoba" , 0x00317C }, - { "America/Argentina/Jujuy" , 0x003351 }, - { "America/Argentina/La_Rioja" , 0x003505 }, - { "America/Argentina/Mendoza" , 0x0036BD }, - { "America/Argentina/Rio_Gallegos" , 0x00387D }, - { "America/Argentina/Salta" , 0x003A32 }, - { "America/Argentina/San_Juan" , 0x003BDE }, - { "America/Argentina/San_Luis" , 0x003D96 }, - { "America/Argentina/Tucuman" , 0x003F5C }, - { "America/Argentina/Ushuaia" , 0x004118 }, - { "America/Aruba" , 0x0042D3 }, - { "America/Asuncion" , 0x004339 }, - { "America/Atikokan" , 0x00461E }, - { "America/Atka" , 0x0046F4 }, - { "America/Bahia" , 0x004A5A }, - { "America/Bahia_Banderas" , 0x004BED }, - { "America/Barbados" , 0x004E66 }, - { "America/Belem" , 0x004F00 }, - { "America/Belize" , 0x004FFB }, - { "America/Blanc-Sablon" , 0x005177 }, - { "America/Boa_Vista" , 0x00522B }, - { "America/Bogota" , 0x005334 }, - { "America/Boise" , 0x0053A0 }, - { "America/Buenos_Aires" , 0x005737 }, - { "America/Cambridge_Bay" , 0x0058D0 }, - { "America/Campo_Grande" , 0x005BF8 }, - { "America/Cancun" , 0x005EE7 }, - { "America/Caracas" , 0x006129 }, - { "America/Catamarca" , 0x006190 }, - { "America/Cayenne" , 0x006336 }, - { "America/Cayman" , 0x006398 }, - { "America/Chicago" , 0x0063ED }, - { "America/Chihuahua" , 0x006904 }, - { "America/Coral_Harbour" , 0x006B6F }, - { "America/Cordoba" , 0x006C01 }, - { "America/Costa_Rica" , 0x006DA7 }, - { "America/Creston" , 0x006E31 }, - { "America/Cuiaba" , 0x006EBD }, - { "America/Curacao" , 0x00719B }, - { "America/Danmarkshavn" , 0x007201 }, - { "America/Dawson" , 0x007345 }, - { "America/Dawson_Creek" , 0x007662 }, - { "America/Denver" , 0x00783C }, - { "America/Detroit" , 0x007BC2 }, - { "America/Dominica" , 0x007F21 }, - { "America/Edmonton" , 0x007F76 }, - { "America/Eirunepe" , 0x00832E }, - { "America/El_Salvador" , 0x008441 }, - { "America/Ensenada" , 0x0084B6 }, - { "America/Fort_Wayne" , 0x00895D }, - { "America/Fortaleza" , 0x00881F }, - { "America/Glace_Bay" , 0x008BC7 }, - { "America/Godthab" , 0x008F3E }, - { "America/Goose_Bay" , 0x009202 }, - { "America/Grand_Turk" , 0x0096BF }, - { "America/Grenada" , 0x00996E }, - { "America/Guadeloupe" , 0x0099C3 }, - { "America/Guatemala" , 0x009A18 }, - { "America/Guayaquil" , 0x009AA1 }, - { "America/Guyana" , 0x009AFE }, - { "America/Halifax" , 0x009B7F }, - { "America/Havana" , 0x00A095 }, - { "America/Hermosillo" , 0x00A408 }, - { "America/Indiana/Indianapolis" , 0x00A4E6 }, - { "America/Indiana/Knox" , 0x00A777 }, - { "America/Indiana/Marengo" , 0x00AB0E }, - { "America/Indiana/Petersburg" , 0x00ADB4 }, - { "America/Indiana/Tell_City" , 0x00B301 }, - { "America/Indiana/Vevay" , 0x00B59A }, - { "America/Indiana/Vincennes" , 0x00B7D5 }, - { "America/Indiana/Winamac" , 0x00BA89 }, - { "America/Indianapolis" , 0x00B097 }, - { "America/Inuvik" , 0x00BD42 }, - { "America/Iqaluit" , 0x00C039 }, - { "America/Jamaica" , 0x00C35B }, - { "America/Jujuy" , 0x00C420 }, - { "America/Juneau" , 0x00C5CA }, - { "America/Kentucky/Louisville" , 0x00C948 }, - { "America/Kentucky/Monticello" , 0x00CD66 }, - { "America/Knox_IN" , 0x00D0EB }, - { "America/Kralendijk" , 0x00D45C }, - { "America/La_Paz" , 0x00D4C2 }, - { "America/Lima" , 0x00D529 }, - { "America/Los_Angeles" , 0x00D5D1 }, - { "America/Louisville" , 0x00D9E2 }, - { "America/Lower_Princes" , 0x00DDD7 }, - { "America/Maceio" , 0x00DE3D }, - { "America/Managua" , 0x00DF77 }, - { "America/Manaus" , 0x00E02A }, - { "America/Marigot" , 0x00E12C }, - { "America/Martinique" , 0x00E181 }, - { "America/Matamoros" , 0x00E1ED }, - { "America/Mazatlan" , 0x00E446 }, - { "America/Mendoza" , 0x00E6B3 }, - { "America/Menominee" , 0x00E867 }, - { "America/Merida" , 0x00EBE8 }, - { "America/Metlakatla" , 0x00EE23 }, - { "America/Mexico_City" , 0x00EF5D }, - { "America/Miquelon" , 0x00F1D8 }, - { "America/Moncton" , 0x00F44A }, - { "America/Monterrey" , 0x00F8E1 }, - { "America/Montevideo" , 0x00FB44 }, - { "America/Montreal" , 0x00FE56 }, - { "America/Montserrat" , 0x01036C }, - { "America/Nassau" , 0x0103C1 }, - { "America/New_York" , 0x010706 }, - { "America/Nipigon" , 0x010C11 }, - { "America/Nome" , 0x010F62 }, - { "America/Noronha" , 0x0112E0 }, - { "America/North_Dakota/Beulah" , 0x011410 }, - { "America/North_Dakota/Center" , 0x0117A4 }, - { "America/North_Dakota/New_Salem" , 0x011B38 }, - { "America/Ojinaga" , 0x011EE1 }, - { "America/Panama" , 0x012142 }, - { "America/Pangnirtung" , 0x012197 }, - { "America/Paramaribo" , 0x0124CD }, - { "America/Phoenix" , 0x01255F }, - { "America/Port-au-Prince" , 0x01260D }, - { "America/Port_of_Spain" , 0x01292C }, - { "America/Porto_Acre" , 0x01282D }, - { "America/Porto_Velho" , 0x012981 }, - { "America/Puerto_Rico" , 0x012A77 }, - { "America/Rainy_River" , 0x012AE2 }, - { "America/Rankin_Inlet" , 0x012E1A }, - { "America/Recife" , 0x013100 }, - { "America/Regina" , 0x01322A }, - { "America/Resolute" , 0x0133E8 }, - { "America/Rio_Branco" , 0x0136D9 }, - { "America/Rosario" , 0x0137DC }, - { "America/Santa_Isabel" , 0x013982 }, - { "America/Santarem" , 0x013D25 }, - { "America/Santiago" , 0x013E2A }, - { "America/Santo_Domingo" , 0x0141D3 }, - { "America/Sao_Paulo" , 0x014299 }, - { "America/Scoresbysund" , 0x0145A8 }, - { "America/Shiprock" , 0x014896 }, - { "America/Sitka" , 0x014C25 }, - { "America/St_Barthelemy" , 0x014FAD }, - { "America/St_Johns" , 0x015002 }, - { "America/St_Kitts" , 0x015555 }, - { "America/St_Lucia" , 0x0155AA }, - { "America/St_Thomas" , 0x0155FF }, - { "America/St_Vincent" , 0x015654 }, - { "America/Swift_Current" , 0x0156A9 }, - { "America/Tegucigalpa" , 0x0157CA }, - { "America/Thule" , 0x015849 }, - { "America/Thunder_Bay" , 0x015A90 }, - { "America/Tijuana" , 0x015DD9 }, - { "America/Toronto" , 0x016172 }, - { "America/Tortola" , 0x016689 }, - { "America/Vancouver" , 0x0166DE }, - { "America/Virgin" , 0x016B1B }, - { "America/Whitehorse" , 0x016B70 }, - { "America/Winnipeg" , 0x016E8D }, - { "America/Yakutat" , 0x0172CD }, - { "America/Yellowknife" , 0x017638 }, - { "Antarctica/Casey" , 0x017948 }, - { "Antarctica/Davis" , 0x0179E5 }, - { "Antarctica/DumontDUrville" , 0x017A86 }, - { "Antarctica/Macquarie" , 0x017B18 }, - { "Antarctica/Mawson" , 0x017D5F }, - { "Antarctica/McMurdo" , 0x017DDB }, - { "Antarctica/Palmer" , 0x0180DD }, - { "Antarctica/Rothera" , 0x0183F9 }, - { "Antarctica/South_Pole" , 0x01846F }, - { "Antarctica/Syowa" , 0x018777 }, - { "Antarctica/Vostok" , 0x0187E5 }, - { "Arctic/Longyearbyen" , 0x018856 }, - { "Asia/Aden" , 0x018B88 }, - { "Asia/Almaty" , 0x018BDD }, - { "Asia/Amman" , 0x018D5C }, - { "Asia/Anadyr" , 0x019012 }, - { "Asia/Aqtau" , 0x0191F7 }, - { "Asia/Aqtobe" , 0x0193F6 }, - { "Asia/Ashgabat" , 0x0195AE }, - { "Asia/Ashkhabad" , 0x0196CB }, - { "Asia/Baghdad" , 0x0197E8 }, - { "Asia/Bahrain" , 0x01995D }, - { "Asia/Baku" , 0x0199C3 }, - { "Asia/Bangkok" , 0x019CAB }, - { "Asia/Beirut" , 0x019D00 }, - { "Asia/Bishkek" , 0x01A00D }, - { "Asia/Brunei" , 0x01A1B9 }, - { "Asia/Calcutta" , 0x01A21B }, - { "Asia/Choibalsan" , 0x01A294 }, - { "Asia/Chongqing" , 0x01A40D }, - { "Asia/Chungking" , 0x01A4FC }, - { "Asia/Colombo" , 0x01A5AB }, - { "Asia/Dacca" , 0x01A647 }, - { "Asia/Damascus" , 0x01A6ED }, - { "Asia/Dhaka" , 0x01AA3D }, - { "Asia/Dili" , 0x01AAE3 }, - { "Asia/Dubai" , 0x01AB6C }, - { "Asia/Dushanbe" , 0x01ABC1 }, - { "Asia/Gaza" , 0x01ACC4 }, - { "Asia/Harbin" , 0x01B017 }, - { "Asia/Hebron" , 0x01B0FE }, - { "Asia/Ho_Chi_Minh" , 0x01B45A }, - { "Asia/Hong_Kong" , 0x01B4D2 }, - { "Asia/Hovd" , 0x01B694 }, - { "Asia/Irkutsk" , 0x01B80C }, - { "Asia/Istanbul" , 0x01B9F2 }, - { "Asia/Jakarta" , 0x01BDDF }, - { "Asia/Jayapura" , 0x01BE89 }, - { "Asia/Jerusalem" , 0x01BF25 }, - { "Asia/Kabul" , 0x01C254 }, - { "Asia/Kamchatka" , 0x01C2A5 }, - { "Asia/Karachi" , 0x01C481 }, - { "Asia/Kashgar" , 0x01C536 }, - { "Asia/Kathmandu" , 0x01C607 }, - { "Asia/Katmandu" , 0x01C66D }, - { "Asia/Khandyga" , 0x01C6D3 }, - { "Asia/Kolkata" , 0x01C8F8 }, - { "Asia/Krasnoyarsk" , 0x01C971 }, - { "Asia/Kuala_Lumpur" , 0x01CB59 }, - { "Asia/Kuching" , 0x01CC16 }, - { "Asia/Kuwait" , 0x01CD04 }, - { "Asia/Macao" , 0x01CD59 }, - { "Asia/Macau" , 0x01CE94 }, - { "Asia/Magadan" , 0x01CFCF }, - { "Asia/Makassar" , 0x01D1B1 }, - { "Asia/Manila" , 0x01D275 }, - { "Asia/Muscat" , 0x01D2FA }, - { "Asia/Nicosia" , 0x01D34F }, - { "Asia/Novokuznetsk" , 0x01D637 }, - { "Asia/Novosibirsk" , 0x01D839 }, - { "Asia/Omsk" , 0x01DA24 }, - { "Asia/Oral" , 0x01DC0B }, - { "Asia/Phnom_Penh" , 0x01DDDB }, - { "Asia/Pontianak" , 0x01DE53 }, - { "Asia/Pyongyang" , 0x01DF14 }, - { "Asia/Qatar" , 0x01DF81 }, - { "Asia/Qyzylorda" , 0x01DFE7 }, - { "Asia/Rangoon" , 0x01E1BD }, - { "Asia/Riyadh" , 0x01E235 }, - { "Asia/Saigon" , 0x01E28A }, - { "Asia/Sakhalin" , 0x01E302 }, - { "Asia/Samarkand" , 0x01E4F9 }, - { "Asia/Seoul" , 0x01E62F }, - { "Asia/Shanghai" , 0x01E6D3 }, - { "Asia/Singapore" , 0x01E7B3 }, - { "Asia/Taipei" , 0x01E86A }, - { "Asia/Tashkent" , 0x01E982 }, - { "Asia/Tbilisi" , 0x01EAB3 }, - { "Asia/Tehran" , 0x01EC6D }, - { "Asia/Tel_Aviv" , 0x01EEDB }, - { "Asia/Thimbu" , 0x01F20A }, - { "Asia/Thimphu" , 0x01F270 }, - { "Asia/Tokyo" , 0x01F2D6 }, - { "Asia/Ujung_Pandang" , 0x01F35F }, - { "Asia/Ulaanbaatar" , 0x01F3DB }, - { "Asia/Ulan_Bator" , 0x01F536 }, - { "Asia/Urumqi" , 0x01F683 }, - { "Asia/Ust-Nera" , 0x01F74A }, - { "Asia/Vientiane" , 0x01F94F }, - { "Asia/Vladivostok" , 0x01F9C7 }, - { "Asia/Yakutsk" , 0x01FBB3 }, - { "Asia/Yekaterinburg" , 0x01FD98 }, - { "Asia/Yerevan" , 0x01FFA3 }, - { "Atlantic/Azores" , 0x0201A3 }, - { "Atlantic/Bermuda" , 0x0206A6 }, - { "Atlantic/Canary" , 0x020987 }, - { "Atlantic/Cape_Verde" , 0x020C5D }, - { "Atlantic/Faeroe" , 0x020CD6 }, - { "Atlantic/Faroe" , 0x020F7A }, - { "Atlantic/Jan_Mayen" , 0x02121E }, - { "Atlantic/Madeira" , 0x021550 }, - { "Atlantic/Reykjavik" , 0x021A59 }, - { "Atlantic/South_Georgia" , 0x021C12 }, - { "Atlantic/St_Helena" , 0x021E24 }, - { "Atlantic/Stanley" , 0x021C56 }, - { "Australia/ACT" , 0x021E79 }, - { "Australia/Adelaide" , 0x022196 }, - { "Australia/Brisbane" , 0x0224C2 }, - { "Australia/Broken_Hill" , 0x022589 }, - { "Australia/Canberra" , 0x0228C7 }, - { "Australia/Currie" , 0x022BE4 }, - { "Australia/Darwin" , 0x022F17 }, - { "Australia/Eucla" , 0x022F9D }, - { "Australia/Hobart" , 0x023072 }, - { "Australia/LHI" , 0x0233D0 }, - { "Australia/Lindeman" , 0x02366B }, - { "Australia/Lord_Howe" , 0x02374C }, - { "Australia/Melbourne" , 0x0239F7 }, - { "Australia/North" , 0x023D1C }, - { "Australia/NSW" , 0x023D90 }, - { "Australia/Perth" , 0x0240AD }, - { "Australia/Queensland" , 0x024185 }, - { "Australia/South" , 0x024231 }, - { "Australia/Sydney" , 0x02454E }, - { "Australia/Tasmania" , 0x02488B }, - { "Australia/Victoria" , 0x024BD0 }, - { "Australia/West" , 0x024EED }, - { "Australia/Yancowinna" , 0x024FA3 }, - { "Brazil/Acre" , 0x0252C5 }, - { "Brazil/DeNoronha" , 0x0253C4 }, - { "Brazil/East" , 0x0254E4 }, - { "Brazil/West" , 0x0257C1 }, - { "Canada/Atlantic" , 0x0258B9 }, - { "Canada/Central" , 0x025DA1 }, - { "Canada/East-Saskatchewan" , 0x0266AB }, - { "Canada/Eastern" , 0x0261BB }, - { "Canada/Mountain" , 0x026834 }, - { "Canada/Newfoundland" , 0x026BAA }, - { "Canada/Pacific" , 0x0270D5 }, - { "Canada/Saskatchewan" , 0x0274EE }, - { "Canada/Yukon" , 0x027677 }, - { "CET" , 0x02797A }, - { "Chile/Continental" , 0x027C83 }, - { "Chile/EasterIsland" , 0x02801E }, - { "CST6CDT" , 0x028360 }, - { "Cuba" , 0x0286B1 }, - { "EET" , 0x028A24 }, - { "Egypt" , 0x028CD7 }, - { "Eire" , 0x028F9A }, - { "EST" , 0x0294AB }, - { "EST5EDT" , 0x0294EF }, - { "Etc/GMT" , 0x029840 }, - { "Etc/GMT+0" , 0x02990C }, - { "Etc/GMT+1" , 0x029996 }, - { "Etc/GMT+10" , 0x029A23 }, - { "Etc/GMT+11" , 0x029AB1 }, - { "Etc/GMT+12" , 0x029B3F }, - { "Etc/GMT+2" , 0x029C5A }, - { "Etc/GMT+3" , 0x029CE6 }, - { "Etc/GMT+4" , 0x029D72 }, - { "Etc/GMT+5" , 0x029DFE }, - { "Etc/GMT+6" , 0x029E8A }, - { "Etc/GMT+7" , 0x029F16 }, - { "Etc/GMT+8" , 0x029FA2 }, - { "Etc/GMT+9" , 0x02A02E }, - { "Etc/GMT-0" , 0x0298C8 }, - { "Etc/GMT-1" , 0x029950 }, - { "Etc/GMT-10" , 0x0299DC }, - { "Etc/GMT-11" , 0x029A6A }, - { "Etc/GMT-12" , 0x029AF8 }, - { "Etc/GMT-13" , 0x029B86 }, - { "Etc/GMT-14" , 0x029BCD }, - { "Etc/GMT-2" , 0x029C14 }, - { "Etc/GMT-3" , 0x029CA0 }, - { "Etc/GMT-4" , 0x029D2C }, - { "Etc/GMT-5" , 0x029DB8 }, - { "Etc/GMT-6" , 0x029E44 }, - { "Etc/GMT-7" , 0x029ED0 }, - { "Etc/GMT-8" , 0x029F5C }, - { "Etc/GMT-9" , 0x029FE8 }, - { "Etc/GMT0" , 0x029884 }, - { "Etc/Greenwich" , 0x02A074 }, - { "Etc/UCT" , 0x02A0B8 }, - { "Etc/Universal" , 0x02A0FC }, - { "Etc/UTC" , 0x02A140 }, - { "Etc/Zulu" , 0x02A184 }, - { "Europe/Amsterdam" , 0x02A1C8 }, - { "Europe/Andorra" , 0x02A606 }, - { "Europe/Athens" , 0x02A882 }, - { "Europe/Belfast" , 0x02ABC5 }, - { "Europe/Belgrade" , 0x02B0FC }, - { "Europe/Berlin" , 0x02B3C5 }, - { "Europe/Bratislava" , 0x02B729 }, - { "Europe/Brussels" , 0x02BA5B }, - { "Europe/Bucharest" , 0x02BE92 }, - { "Europe/Budapest" , 0x02C1BC }, - { "Europe/Busingen" , 0x02C52F }, - { "Europe/Chisinau" , 0x02C7E6 }, - { "Europe/Copenhagen" , 0x02CB74 }, - { "Europe/Dublin" , 0x02CE7E }, - { "Europe/Gibraltar" , 0x02D38F }, - { "Europe/Guernsey" , 0x02D7E6 }, - { "Europe/Helsinki" , 0x02DD1D }, - { "Europe/Isle_of_Man" , 0x02DFD3 }, - { "Europe/Istanbul" , 0x02E50A }, - { "Europe/Jersey" , 0x02E8F7 }, - { "Europe/Kaliningrad" , 0x02EE2E }, - { "Europe/Kiev" , 0x02F094 }, - { "Europe/Lisbon" , 0x02F3AB }, - { "Europe/Ljubljana" , 0x02F8AF }, - { "Europe/London" , 0x02FB78 }, - { "Europe/Luxembourg" , 0x0300AF }, - { "Europe/Madrid" , 0x030505 }, - { "Europe/Malta" , 0x0308CB }, - { "Europe/Mariehamn" , 0x030C84 }, - { "Europe/Minsk" , 0x030F3A }, - { "Europe/Monaco" , 0x031148 }, - { "Europe/Moscow" , 0x031583 }, - { "Europe/Nicosia" , 0x0317D4 }, - { "Europe/Oslo" , 0x031ABC }, - { "Europe/Paris" , 0x031DEE }, - { "Europe/Podgorica" , 0x032234 }, - { "Europe/Prague" , 0x0324FD }, - { "Europe/Riga" , 0x03282F }, - { "Europe/Rome" , 0x032B74 }, - { "Europe/Samara" , 0x032F37 }, - { "Europe/San_Marino" , 0x03316A }, - { "Europe/Sarajevo" , 0x03352D }, - { "Europe/Simferopol" , 0x0337F6 }, - { "Europe/Skopje" , 0x033B21 }, - { "Europe/Sofia" , 0x033DEA }, - { "Europe/Stockholm" , 0x0340F2 }, - { "Europe/Tallinn" , 0x0343A1 }, - { "Europe/Tirane" , 0x0346DB }, - { "Europe/Tiraspol" , 0x0349E1 }, - { "Europe/Uzhgorod" , 0x034D6F }, - { "Europe/Vaduz" , 0x035086 }, - { "Europe/Vatican" , 0x035319 }, - { "Europe/Vienna" , 0x0356DC }, - { "Europe/Vilnius" , 0x035A09 }, - { "Europe/Volgograd" , 0x035D48 }, - { "Europe/Warsaw" , 0x035F48 }, - { "Europe/Zagreb" , 0x036329 }, - { "Europe/Zaporozhye" , 0x0365F2 }, - { "Europe/Zurich" , 0x036933 }, - { "Factory" , 0x036BE2 }, - { "GB" , 0x036C53 }, - { "GB-Eire" , 0x03718A }, - { "GMT" , 0x0376C1 }, - { "GMT+0" , 0x03778D }, - { "GMT-0" , 0x037749 }, - { "GMT0" , 0x037705 }, - { "Greenwich" , 0x0377D1 }, - { "Hongkong" , 0x037815 }, - { "HST" , 0x0379D7 }, - { "Iceland" , 0x037A1B }, - { "Indian/Antananarivo" , 0x037BD4 }, - { "Indian/Chagos" , 0x037C48 }, - { "Indian/Christmas" , 0x037CAA }, - { "Indian/Cocos" , 0x037CEE }, - { "Indian/Comoro" , 0x037D32 }, - { "Indian/Kerguelen" , 0x037D87 }, - { "Indian/Mahe" , 0x037DDC }, - { "Indian/Maldives" , 0x037E31 }, - { "Indian/Mauritius" , 0x037E86 }, - { "Indian/Mayotte" , 0x037EFC }, - { "Indian/Reunion" , 0x037F51 }, - { "Iran" , 0x037FA6 }, - { "Israel" , 0x038214 }, - { "Jamaica" , 0x038543 }, - { "Japan" , 0x038608 }, - { "Kwajalein" , 0x038691 }, - { "Libya" , 0x0386F4 }, - { "MET" , 0x0388ED }, - { "Mexico/BajaNorte" , 0x038BF6 }, - { "Mexico/BajaSur" , 0x038F5F }, - { "Mexico/General" , 0x0391A4 }, - { "MST" , 0x039402 }, - { "MST7MDT" , 0x039446 }, - { "Navajo" , 0x039797 }, - { "NZ" , 0x039B10 }, - { "NZ-CHAT" , 0x039E8E }, - { "Pacific/Apia" , 0x03A176 }, - { "Pacific/Auckland" , 0x03A312 }, - { "Pacific/Chatham" , 0x03A69E }, - { "Pacific/Chuuk" , 0x03A995 }, - { "Pacific/Easter" , 0x03A9EE }, - { "Pacific/Efate" , 0x03AD4C }, - { "Pacific/Enderbury" , 0x03AE12 }, - { "Pacific/Fakaofo" , 0x03AE80 }, - { "Pacific/Fiji" , 0x03AED1 }, - { "Pacific/Funafuti" , 0x03B064 }, - { "Pacific/Galapagos" , 0x03B0A8 }, - { "Pacific/Gambier" , 0x03B120 }, - { "Pacific/Guadalcanal" , 0x03B185 }, - { "Pacific/Guam" , 0x03B1DA }, - { "Pacific/Honolulu" , 0x03B230 }, - { "Pacific/Johnston" , 0x03B2A7 }, - { "Pacific/Kiritimati" , 0x03B2F9 }, - { "Pacific/Kosrae" , 0x03B364 }, - { "Pacific/Kwajalein" , 0x03B3C1 }, - { "Pacific/Majuro" , 0x03B42D }, - { "Pacific/Marquesas" , 0x03B48C }, - { "Pacific/Midway" , 0x03B4F3 }, - { "Pacific/Nauru" , 0x03B57D }, - { "Pacific/Niue" , 0x03B5F5 }, - { "Pacific/Norfolk" , 0x03B653 }, - { "Pacific/Noumea" , 0x03B6A8 }, - { "Pacific/Pago_Pago" , 0x03B738 }, - { "Pacific/Palau" , 0x03B7C1 }, - { "Pacific/Pitcairn" , 0x03B805 }, - { "Pacific/Pohnpei" , 0x03B85A }, - { "Pacific/Ponape" , 0x03B8AF }, - { "Pacific/Port_Moresby" , 0x03B8F4 }, - { "Pacific/Rarotonga" , 0x03B938 }, - { "Pacific/Saipan" , 0x03BA14 }, - { "Pacific/Samoa" , 0x03BA77 }, - { "Pacific/Tahiti" , 0x03BB00 }, - { "Pacific/Tarawa" , 0x03BB65 }, - { "Pacific/Tongatapu" , 0x03BBB9 }, - { "Pacific/Truk" , 0x03BC45 }, - { "Pacific/Wake" , 0x03BC8A }, - { "Pacific/Wallis" , 0x03BCDA }, - { "Pacific/Yap" , 0x03BD1E }, - { "Poland" , 0x03BD63 }, - { "Portugal" , 0x03C144 }, - { "PRC" , 0x03C640 }, - { "PST8PDT" , 0x03C6F1 }, - { "ROC" , 0x03CA42 }, - { "ROK" , 0x03CB5A }, - { "Singapore" , 0x03CBFE }, - { "Turkey" , 0x03CCB5 }, - { "UCT" , 0x03D0A2 }, - { "Universal" , 0x03D0E6 }, - { "US/Alaska" , 0x03D12A }, - { "US/Aleutian" , 0x03D493 }, - { "US/Arizona" , 0x03D7F9 }, - { "US/Central" , 0x03D887 }, - { "US/East-Indiana" , 0x03E291 }, - { "US/Eastern" , 0x03DD92 }, - { "US/Hawaii" , 0x03E4FB }, - { "US/Indiana-Starke" , 0x03E56C }, - { "US/Michigan" , 0x03E8DD }, - { "US/Mountain" , 0x03EC14 }, - { "US/Pacific" , 0x03EF8D }, - { "US/Pacific-New" , 0x03F392 }, - { "US/Samoa" , 0x03F797 }, - { "UTC" , 0x03F820 }, - { "W-SU" , 0x03FB17 }, - { "WET" , 0x03F864 }, - { "Zulu" , 0x03FD51 }, + { "Africa/Ceuta" , 0x000ADA }, + { "Africa/Conakry" , 0x000DE1 }, + { "Africa/Dakar" , 0x000E4C }, + { "Africa/Dar_es_Salaam" , 0x000EB2 }, + { "Africa/Djibouti" , 0x000F1F }, + { "Africa/Douala" , 0x000F74 }, + { "Africa/El_Aaiun" , 0x000FC9 }, + { "Africa/Freetown" , 0x0011F4 }, + { "Africa/Gaborone" , 0x001303 }, + { "Africa/Harare" , 0x001370 }, + { "Africa/Johannesburg" , 0x0013C5 }, + { "Africa/Juba" , 0x001433 }, + { "Africa/Kampala" , 0x001546 }, + { "Africa/Khartoum" , 0x0015C5 }, + { "Africa/Kigali" , 0x0016D8 }, + { "Africa/Kinshasa" , 0x00172D }, + { "Africa/Lagos" , 0x001788 }, + { "Africa/Libreville" , 0x0017DD }, + { "Africa/Lome" , 0x001832 }, + { "Africa/Luanda" , 0x001876 }, + { "Africa/Lubumbashi" , 0x0018CB }, + { "Africa/Lusaka" , 0x001926 }, + { "Africa/Malabo" , 0x00197B }, + { "Africa/Maputo" , 0x0019E1 }, + { "Africa/Maseru" , 0x001A36 }, + { "Africa/Mbabane" , 0x001A9E }, + { "Africa/Mogadishu" , 0x001AF4 }, + { "Africa/Monrovia" , 0x001B4F }, + { "Africa/Nairobi" , 0x001BB5 }, + { "Africa/Ndjamena" , 0x001C34 }, + { "Africa/Niamey" , 0x001CA0 }, + { "Africa/Nouakchott" , 0x001D13 }, + { "Africa/Ouagadougou" , 0x001D7E }, + { "Africa/Porto-Novo" , 0x001DD3 }, + { "Africa/Sao_Tome" , 0x001E39 }, + { "Africa/Timbuktu" , 0x001E8E }, + { "Africa/Tripoli" , 0x001EF9 }, + { "Africa/Tunis" , 0x002002 }, + { "Africa/Windhoek" , 0x002114 }, + { "America/Adak" , 0x00235B }, + { "America/Anchorage" , 0x0026D1 }, + { "America/Anguilla" , 0x002A45 }, + { "America/Antigua" , 0x002A9A }, + { "America/Araguaina" , 0x002B00 }, + { "America/Argentina/Buenos_Aires" , 0x002C65 }, + { "America/Argentina/Catamarca" , 0x002E13 }, + { "America/Argentina/ComodRivadavia" , 0x002FD4 }, + { "America/Argentina/Cordoba" , 0x00317A }, + { "America/Argentina/Jujuy" , 0x00334F }, + { "America/Argentina/La_Rioja" , 0x003503 }, + { "America/Argentina/Mendoza" , 0x0036BB }, + { "America/Argentina/Rio_Gallegos" , 0x00387B }, + { "America/Argentina/Salta" , 0x003A30 }, + { "America/Argentina/San_Juan" , 0x003BDC }, + { "America/Argentina/San_Luis" , 0x003D94 }, + { "America/Argentina/Tucuman" , 0x003F5A }, + { "America/Argentina/Ushuaia" , 0x004116 }, + { "America/Aruba" , 0x0042D1 }, + { "America/Asuncion" , 0x004337 }, + { "America/Atikokan" , 0x00461C }, + { "America/Atka" , 0x0046F2 }, + { "America/Bahia" , 0x004A58 }, + { "America/Bahia_Banderas" , 0x004BEB }, + { "America/Barbados" , 0x004E64 }, + { "America/Belem" , 0x004EFE }, + { "America/Belize" , 0x004FF9 }, + { "America/Blanc-Sablon" , 0x005175 }, + { "America/Boa_Vista" , 0x005229 }, + { "America/Bogota" , 0x005332 }, + { "America/Boise" , 0x00539E }, + { "America/Buenos_Aires" , 0x005735 }, + { "America/Cambridge_Bay" , 0x0058CE }, + { "America/Campo_Grande" , 0x005BF6 }, + { "America/Cancun" , 0x005EE5 }, + { "America/Caracas" , 0x006127 }, + { "America/Catamarca" , 0x00618E }, + { "America/Cayenne" , 0x006334 }, + { "America/Cayman" , 0x006396 }, + { "America/Chicago" , 0x0063EB }, + { "America/Chihuahua" , 0x006902 }, + { "America/Coral_Harbour" , 0x006B6D }, + { "America/Cordoba" , 0x006BFF }, + { "America/Costa_Rica" , 0x006DA5 }, + { "America/Creston" , 0x006E2F }, + { "America/Cuiaba" , 0x006EBB }, + { "America/Curacao" , 0x007199 }, + { "America/Danmarkshavn" , 0x0071FF }, + { "America/Dawson" , 0x007343 }, + { "America/Dawson_Creek" , 0x007660 }, + { "America/Denver" , 0x00783A }, + { "America/Detroit" , 0x007BC0 }, + { "America/Dominica" , 0x007F1F }, + { "America/Edmonton" , 0x007F74 }, + { "America/Eirunepe" , 0x00832C }, + { "America/El_Salvador" , 0x008444 }, + { "America/Ensenada" , 0x0084B9 }, + { "America/Fort_Wayne" , 0x008960 }, + { "America/Fortaleza" , 0x008822 }, + { "America/Glace_Bay" , 0x008BCA }, + { "America/Godthab" , 0x008F41 }, + { "America/Goose_Bay" , 0x009205 }, + { "America/Grand_Turk" , 0x0096C2 }, + { "America/Grenada" , 0x009971 }, + { "America/Guadeloupe" , 0x0099C6 }, + { "America/Guatemala" , 0x009A1B }, + { "America/Guayaquil" , 0x009AA4 }, + { "America/Guyana" , 0x009B01 }, + { "America/Halifax" , 0x009B82 }, + { "America/Havana" , 0x00A098 }, + { "America/Hermosillo" , 0x00A40B }, + { "America/Indiana/Indianapolis" , 0x00A4E9 }, + { "America/Indiana/Knox" , 0x00A77A }, + { "America/Indiana/Marengo" , 0x00AB11 }, + { "America/Indiana/Petersburg" , 0x00ADB7 }, + { "America/Indiana/Tell_City" , 0x00B304 }, + { "America/Indiana/Vevay" , 0x00B59D }, + { "America/Indiana/Vincennes" , 0x00B7D8 }, + { "America/Indiana/Winamac" , 0x00BA8C }, + { "America/Indianapolis" , 0x00B09A }, + { "America/Inuvik" , 0x00BD45 }, + { "America/Iqaluit" , 0x00C03C }, + { "America/Jamaica" , 0x00C35E }, + { "America/Jujuy" , 0x00C423 }, + { "America/Juneau" , 0x00C5CD }, + { "America/Kentucky/Louisville" , 0x00C94B }, + { "America/Kentucky/Monticello" , 0x00CD69 }, + { "America/Knox_IN" , 0x00D0EE }, + { "America/Kralendijk" , 0x00D45F }, + { "America/La_Paz" , 0x00D4C5 }, + { "America/Lima" , 0x00D52C }, + { "America/Los_Angeles" , 0x00D5D4 }, + { "America/Louisville" , 0x00D9E5 }, + { "America/Lower_Princes" , 0x00DDDA }, + { "America/Maceio" , 0x00DE40 }, + { "America/Managua" , 0x00DF7A }, + { "America/Manaus" , 0x00E02D }, + { "America/Marigot" , 0x00E12F }, + { "America/Martinique" , 0x00E184 }, + { "America/Matamoros" , 0x00E1F0 }, + { "America/Mazatlan" , 0x00E449 }, + { "America/Mendoza" , 0x00E6B6 }, + { "America/Menominee" , 0x00E86A }, + { "America/Merida" , 0x00EBEB }, + { "America/Metlakatla" , 0x00EE26 }, + { "America/Mexico_City" , 0x00EF60 }, + { "America/Miquelon" , 0x00F1DB }, + { "America/Moncton" , 0x00F44D }, + { "America/Monterrey" , 0x00F8E4 }, + { "America/Montevideo" , 0x00FB47 }, + { "America/Montreal" , 0x00FE59 }, + { "America/Montserrat" , 0x010349 }, + { "America/Nassau" , 0x01039E }, + { "America/New_York" , 0x0106E3 }, + { "America/Nipigon" , 0x010BEE }, + { "America/Nome" , 0x010F3F }, + { "America/Noronha" , 0x0112BD }, + { "America/North_Dakota/Beulah" , 0x0113ED }, + { "America/North_Dakota/Center" , 0x011781 }, + { "America/North_Dakota/New_Salem" , 0x011B15 }, + { "America/Ojinaga" , 0x011EBE }, + { "America/Panama" , 0x01211F }, + { "America/Pangnirtung" , 0x012174 }, + { "America/Paramaribo" , 0x0124AA }, + { "America/Phoenix" , 0x01253C }, + { "America/Port-au-Prince" , 0x0125FA }, + { "America/Port_of_Spain" , 0x01291E }, + { "America/Porto_Acre" , 0x01281A }, + { "America/Porto_Velho" , 0x012973 }, + { "America/Puerto_Rico" , 0x012A69 }, + { "America/Rainy_River" , 0x012AD4 }, + { "America/Rankin_Inlet" , 0x012E0C }, + { "America/Recife" , 0x0130F2 }, + { "America/Regina" , 0x01321C }, + { "America/Resolute" , 0x0133DA }, + { "America/Rio_Branco" , 0x0136CB }, + { "America/Rosario" , 0x0137D3 }, + { "America/Santa_Isabel" , 0x013979 }, + { "America/Santarem" , 0x013D1C }, + { "America/Santiago" , 0x013E21 }, + { "America/Santo_Domingo" , 0x0141CA }, + { "America/Sao_Paulo" , 0x014290 }, + { "America/Scoresbysund" , 0x01459F }, + { "America/Shiprock" , 0x01488D }, + { "America/Sitka" , 0x014C06 }, + { "America/St_Barthelemy" , 0x014F8E }, + { "America/St_Johns" , 0x014FE3 }, + { "America/St_Kitts" , 0x015536 }, + { "America/St_Lucia" , 0x01558B }, + { "America/St_Thomas" , 0x0155E0 }, + { "America/St_Vincent" , 0x015635 }, + { "America/Swift_Current" , 0x01568A }, + { "America/Tegucigalpa" , 0x0157AB }, + { "America/Thule" , 0x01582A }, + { "America/Thunder_Bay" , 0x015A71 }, + { "America/Tijuana" , 0x015DBA }, + { "America/Toronto" , 0x016153 }, + { "America/Tortola" , 0x016673 }, + { "America/Vancouver" , 0x0166C8 }, + { "America/Virgin" , 0x016B05 }, + { "America/Whitehorse" , 0x016B5A }, + { "America/Winnipeg" , 0x016E77 }, + { "America/Yakutat" , 0x0172B7 }, + { "America/Yellowknife" , 0x017622 }, + { "Antarctica/Casey" , 0x017932 }, + { "Antarctica/Davis" , 0x0179CF }, + { "Antarctica/DumontDUrville" , 0x017A70 }, + { "Antarctica/Macquarie" , 0x017B02 }, + { "Antarctica/Mawson" , 0x017D49 }, + { "Antarctica/McMurdo" , 0x017DC5 }, + { "Antarctica/Palmer" , 0x018170 }, + { "Antarctica/Rothera" , 0x01848C }, + { "Antarctica/South_Pole" , 0x018502 }, + { "Antarctica/Syowa" , 0x018880 }, + { "Antarctica/Vostok" , 0x0188EE }, + { "Arctic/Longyearbyen" , 0x01895F }, + { "Asia/Aden" , 0x018C91 }, + { "Asia/Almaty" , 0x018CE6 }, + { "Asia/Amman" , 0x018E65 }, + { "Asia/Anadyr" , 0x01911B }, + { "Asia/Aqtau" , 0x019300 }, + { "Asia/Aqtobe" , 0x0194FF }, + { "Asia/Ashgabat" , 0x0196B7 }, + { "Asia/Ashkhabad" , 0x0197D4 }, + { "Asia/Baghdad" , 0x0198F1 }, + { "Asia/Bahrain" , 0x019A66 }, + { "Asia/Baku" , 0x019ACC }, + { "Asia/Bangkok" , 0x019DB4 }, + { "Asia/Beirut" , 0x019E09 }, + { "Asia/Bishkek" , 0x01A116 }, + { "Asia/Brunei" , 0x01A2C2 }, + { "Asia/Calcutta" , 0x01A324 }, + { "Asia/Choibalsan" , 0x01A39D }, + { "Asia/Chongqing" , 0x01A516 }, + { "Asia/Chungking" , 0x01A605 }, + { "Asia/Colombo" , 0x01A6B4 }, + { "Asia/Dacca" , 0x01A750 }, + { "Asia/Damascus" , 0x01A7F6 }, + { "Asia/Dhaka" , 0x01AB46 }, + { "Asia/Dili" , 0x01ABEC }, + { "Asia/Dubai" , 0x01AC76 }, + { "Asia/Dushanbe" , 0x01ACCB }, + { "Asia/Gaza" , 0x01ADCE }, + { "Asia/Harbin" , 0x01B121 }, + { "Asia/Hebron" , 0x01B208 }, + { "Asia/Ho_Chi_Minh" , 0x01B564 }, + { "Asia/Hong_Kong" , 0x01B5DC }, + { "Asia/Hovd" , 0x01B79E }, + { "Asia/Irkutsk" , 0x01B916 }, + { "Asia/Istanbul" , 0x01BAFC }, + { "Asia/Jakarta" , 0x01BEE9 }, + { "Asia/Jayapura" , 0x01BF93 }, + { "Asia/Jerusalem" , 0x01C02F }, + { "Asia/Kabul" , 0x01C35E }, + { "Asia/Kamchatka" , 0x01C3AF }, + { "Asia/Karachi" , 0x01C58B }, + { "Asia/Kashgar" , 0x01C640 }, + { "Asia/Kathmandu" , 0x01C711 }, + { "Asia/Katmandu" , 0x01C777 }, + { "Asia/Khandyga" , 0x01C7DD }, + { "Asia/Kolkata" , 0x01CA02 }, + { "Asia/Krasnoyarsk" , 0x01CA7B }, + { "Asia/Kuala_Lumpur" , 0x01CC63 }, + { "Asia/Kuching" , 0x01CD20 }, + { "Asia/Kuwait" , 0x01CE0E }, + { "Asia/Macao" , 0x01CE63 }, + { "Asia/Macau" , 0x01CF9E }, + { "Asia/Magadan" , 0x01D0D9 }, + { "Asia/Makassar" , 0x01D2BB }, + { "Asia/Manila" , 0x01D380 }, + { "Asia/Muscat" , 0x01D405 }, + { "Asia/Nicosia" , 0x01D45A }, + { "Asia/Novokuznetsk" , 0x01D742 }, + { "Asia/Novosibirsk" , 0x01D944 }, + { "Asia/Omsk" , 0x01DB2F }, + { "Asia/Oral" , 0x01DD16 }, + { "Asia/Phnom_Penh" , 0x01DEE6 }, + { "Asia/Pontianak" , 0x01DF5E }, + { "Asia/Pyongyang" , 0x01E020 }, + { "Asia/Qatar" , 0x01E08D }, + { "Asia/Qyzylorda" , 0x01E0F3 }, + { "Asia/Rangoon" , 0x01E2C9 }, + { "Asia/Riyadh" , 0x01E341 }, + { "Asia/Saigon" , 0x01E396 }, + { "Asia/Sakhalin" , 0x01E40E }, + { "Asia/Samarkand" , 0x01E605 }, + { "Asia/Seoul" , 0x01E73B }, + { "Asia/Shanghai" , 0x01E7DF }, + { "Asia/Singapore" , 0x01E8BF }, + { "Asia/Taipei" , 0x01E976 }, + { "Asia/Tashkent" , 0x01EA8E }, + { "Asia/Tbilisi" , 0x01EBBF }, + { "Asia/Tehran" , 0x01ED79 }, + { "Asia/Tel_Aviv" , 0x01EFE7 }, + { "Asia/Thimbu" , 0x01F316 }, + { "Asia/Thimphu" , 0x01F37C }, + { "Asia/Tokyo" , 0x01F3E2 }, + { "Asia/Ujung_Pandang" , 0x01F46B }, + { "Asia/Ulaanbaatar" , 0x01F4E8 }, + { "Asia/Ulan_Bator" , 0x01F643 }, + { "Asia/Urumqi" , 0x01F790 }, + { "Asia/Ust-Nera" , 0x01F857 }, + { "Asia/Vientiane" , 0x01FA5C }, + { "Asia/Vladivostok" , 0x01FAD4 }, + { "Asia/Yakutsk" , 0x01FCC0 }, + { "Asia/Yekaterinburg" , 0x01FEA5 }, + { "Asia/Yerevan" , 0x0200B0 }, + { "Atlantic/Azores" , 0x0202B0 }, + { "Atlantic/Bermuda" , 0x0207B3 }, + { "Atlantic/Canary" , 0x020A94 }, + { "Atlantic/Cape_Verde" , 0x020D6A }, + { "Atlantic/Faeroe" , 0x020DE3 }, + { "Atlantic/Faroe" , 0x021087 }, + { "Atlantic/Jan_Mayen" , 0x02132B }, + { "Atlantic/Madeira" , 0x02165D }, + { "Atlantic/Reykjavik" , 0x021B66 }, + { "Atlantic/South_Georgia" , 0x021D1F }, + { "Atlantic/St_Helena" , 0x021F31 }, + { "Atlantic/Stanley" , 0x021D63 }, + { "Australia/ACT" , 0x021F86 }, + { "Australia/Adelaide" , 0x0222A3 }, + { "Australia/Brisbane" , 0x0225CF }, + { "Australia/Broken_Hill" , 0x022696 }, + { "Australia/Canberra" , 0x0229D4 }, + { "Australia/Currie" , 0x022CF1 }, + { "Australia/Darwin" , 0x023024 }, + { "Australia/Eucla" , 0x0230AA }, + { "Australia/Hobart" , 0x02317F }, + { "Australia/LHI" , 0x0234DD }, + { "Australia/Lindeman" , 0x023778 }, + { "Australia/Lord_Howe" , 0x023859 }, + { "Australia/Melbourne" , 0x023B04 }, + { "Australia/North" , 0x023E29 }, + { "Australia/NSW" , 0x023E9D }, + { "Australia/Perth" , 0x0241BA }, + { "Australia/Queensland" , 0x024292 }, + { "Australia/South" , 0x02433E }, + { "Australia/Sydney" , 0x02465B }, + { "Australia/Tasmania" , 0x024998 }, + { "Australia/Victoria" , 0x024CDD }, + { "Australia/West" , 0x024FFA }, + { "Australia/Yancowinna" , 0x0250B0 }, + { "Brazil/Acre" , 0x0253D2 }, + { "Brazil/DeNoronha" , 0x0254D6 }, + { "Brazil/East" , 0x0255F6 }, + { "Brazil/West" , 0x0258D3 }, + { "Canada/Atlantic" , 0x0259CB }, + { "Canada/Central" , 0x025EB3 }, + { "Canada/East-Saskatchewan" , 0x0267BD }, + { "Canada/Eastern" , 0x0262CD }, + { "Canada/Mountain" , 0x026946 }, + { "Canada/Newfoundland" , 0x026CBC }, + { "Canada/Pacific" , 0x0271E7 }, + { "Canada/Saskatchewan" , 0x027600 }, + { "Canada/Yukon" , 0x027789 }, + { "CET" , 0x027A8C }, + { "Chile/Continental" , 0x027D95 }, + { "Chile/EasterIsland" , 0x028130 }, + { "CST6CDT" , 0x028472 }, + { "Cuba" , 0x0287C3 }, + { "EET" , 0x028B36 }, + { "Egypt" , 0x028DE9 }, + { "Eire" , 0x0290AC }, + { "EST" , 0x0295BD }, + { "EST5EDT" , 0x029601 }, + { "Etc/GMT" , 0x029952 }, + { "Etc/GMT+0" , 0x029A1E }, + { "Etc/GMT+1" , 0x029AA8 }, + { "Etc/GMT+10" , 0x029B35 }, + { "Etc/GMT+11" , 0x029BC3 }, + { "Etc/GMT+12" , 0x029C51 }, + { "Etc/GMT+2" , 0x029D6C }, + { "Etc/GMT+3" , 0x029DF8 }, + { "Etc/GMT+4" , 0x029E84 }, + { "Etc/GMT+5" , 0x029F10 }, + { "Etc/GMT+6" , 0x029F9C }, + { "Etc/GMT+7" , 0x02A028 }, + { "Etc/GMT+8" , 0x02A0B4 }, + { "Etc/GMT+9" , 0x02A140 }, + { "Etc/GMT-0" , 0x0299DA }, + { "Etc/GMT-1" , 0x029A62 }, + { "Etc/GMT-10" , 0x029AEE }, + { "Etc/GMT-11" , 0x029B7C }, + { "Etc/GMT-12" , 0x029C0A }, + { "Etc/GMT-13" , 0x029C98 }, + { "Etc/GMT-14" , 0x029CDF }, + { "Etc/GMT-2" , 0x029D26 }, + { "Etc/GMT-3" , 0x029DB2 }, + { "Etc/GMT-4" , 0x029E3E }, + { "Etc/GMT-5" , 0x029ECA }, + { "Etc/GMT-6" , 0x029F56 }, + { "Etc/GMT-7" , 0x029FE2 }, + { "Etc/GMT-8" , 0x02A06E }, + { "Etc/GMT-9" , 0x02A0FA }, + { "Etc/GMT0" , 0x029996 }, + { "Etc/Greenwich" , 0x02A186 }, + { "Etc/UCT" , 0x02A1CA }, + { "Etc/Universal" , 0x02A20E }, + { "Etc/UTC" , 0x02A252 }, + { "Etc/Zulu" , 0x02A296 }, + { "Europe/Amsterdam" , 0x02A2DA }, + { "Europe/Andorra" , 0x02A718 }, + { "Europe/Athens" , 0x02A994 }, + { "Europe/Belfast" , 0x02ACD7 }, + { "Europe/Belgrade" , 0x02B20E }, + { "Europe/Berlin" , 0x02B4D7 }, + { "Europe/Bratislava" , 0x02B83B }, + { "Europe/Brussels" , 0x02BB6D }, + { "Europe/Bucharest" , 0x02BFA4 }, + { "Europe/Budapest" , 0x02C2CE }, + { "Europe/Busingen" , 0x02C641 }, + { "Europe/Chisinau" , 0x02C8F8 }, + { "Europe/Copenhagen" , 0x02CC86 }, + { "Europe/Dublin" , 0x02CF90 }, + { "Europe/Gibraltar" , 0x02D4A1 }, + { "Europe/Guernsey" , 0x02D8F8 }, + { "Europe/Helsinki" , 0x02DE2F }, + { "Europe/Isle_of_Man" , 0x02E0E5 }, + { "Europe/Istanbul" , 0x02E61C }, + { "Europe/Jersey" , 0x02EA09 }, + { "Europe/Kaliningrad" , 0x02EF40 }, + { "Europe/Kiev" , 0x02F1A6 }, + { "Europe/Lisbon" , 0x02F4BD }, + { "Europe/Ljubljana" , 0x02F9C1 }, + { "Europe/London" , 0x02FC8A }, + { "Europe/Luxembourg" , 0x0301C1 }, + { "Europe/Madrid" , 0x030617 }, + { "Europe/Malta" , 0x0309DD }, + { "Europe/Mariehamn" , 0x030D96 }, + { "Europe/Minsk" , 0x03104C }, + { "Europe/Monaco" , 0x03125A }, + { "Europe/Moscow" , 0x031695 }, + { "Europe/Nicosia" , 0x0318E6 }, + { "Europe/Oslo" , 0x031BCE }, + { "Europe/Paris" , 0x031F00 }, + { "Europe/Podgorica" , 0x032346 }, + { "Europe/Prague" , 0x03260F }, + { "Europe/Riga" , 0x032941 }, + { "Europe/Rome" , 0x032C86 }, + { "Europe/Samara" , 0x033049 }, + { "Europe/San_Marino" , 0x03327C }, + { "Europe/Sarajevo" , 0x03363F }, + { "Europe/Simferopol" , 0x033908 }, + { "Europe/Skopje" , 0x033C33 }, + { "Europe/Sofia" , 0x033EFC }, + { "Europe/Stockholm" , 0x034204 }, + { "Europe/Tallinn" , 0x0344B3 }, + { "Europe/Tirane" , 0x0347ED }, + { "Europe/Tiraspol" , 0x034AF3 }, + { "Europe/Uzhgorod" , 0x034E81 }, + { "Europe/Vaduz" , 0x035198 }, + { "Europe/Vatican" , 0x035447 }, + { "Europe/Vienna" , 0x03580A }, + { "Europe/Vilnius" , 0x035B37 }, + { "Europe/Volgograd" , 0x035E76 }, + { "Europe/Warsaw" , 0x036076 }, + { "Europe/Zagreb" , 0x036457 }, + { "Europe/Zaporozhye" , 0x036720 }, + { "Europe/Zurich" , 0x036A61 }, + { "Factory" , 0x036D10 }, + { "GB" , 0x036D81 }, + { "GB-Eire" , 0x0372B8 }, + { "GMT" , 0x0377EF }, + { "GMT+0" , 0x0378BB }, + { "GMT-0" , 0x037877 }, + { "GMT0" , 0x037833 }, + { "Greenwich" , 0x0378FF }, + { "Hongkong" , 0x037943 }, + { "HST" , 0x037B05 }, + { "Iceland" , 0x037B49 }, + { "Indian/Antananarivo" , 0x037D02 }, + { "Indian/Chagos" , 0x037D76 }, + { "Indian/Christmas" , 0x037DD8 }, + { "Indian/Cocos" , 0x037E1C }, + { "Indian/Comoro" , 0x037E60 }, + { "Indian/Kerguelen" , 0x037EB5 }, + { "Indian/Mahe" , 0x037F0A }, + { "Indian/Maldives" , 0x037F5F }, + { "Indian/Mauritius" , 0x037FB4 }, + { "Indian/Mayotte" , 0x03802A }, + { "Indian/Reunion" , 0x03807F }, + { "Iran" , 0x0380D4 }, + { "Israel" , 0x038342 }, + { "Jamaica" , 0x038671 }, + { "Japan" , 0x038736 }, + { "Kwajalein" , 0x0387BF }, + { "Libya" , 0x038822 }, + { "MET" , 0x03892B }, + { "Mexico/BajaNorte" , 0x038C34 }, + { "Mexico/BajaSur" , 0x038F9D }, + { "Mexico/General" , 0x0391E2 }, + { "MST" , 0x039440 }, + { "MST7MDT" , 0x039484 }, + { "Navajo" , 0x0397D5 }, + { "NZ" , 0x039B4E }, + { "NZ-CHAT" , 0x039ECC }, + { "Pacific/Apia" , 0x03A1B4 }, + { "Pacific/Auckland" , 0x03A350 }, + { "Pacific/Chatham" , 0x03A6DC }, + { "Pacific/Chuuk" , 0x03A9D3 }, + { "Pacific/Easter" , 0x03AA2C }, + { "Pacific/Efate" , 0x03AD8A }, + { "Pacific/Enderbury" , 0x03AE50 }, + { "Pacific/Fakaofo" , 0x03AEBE }, + { "Pacific/Fiji" , 0x03AF0F }, + { "Pacific/Funafuti" , 0x03B0A2 }, + { "Pacific/Galapagos" , 0x03B0E6 }, + { "Pacific/Gambier" , 0x03B15E }, + { "Pacific/Guadalcanal" , 0x03B1C3 }, + { "Pacific/Guam" , 0x03B218 }, + { "Pacific/Honolulu" , 0x03B26E }, + { "Pacific/Johnston" , 0x03B2E5 }, + { "Pacific/Kiritimati" , 0x03B364 }, + { "Pacific/Kosrae" , 0x03B3CF }, + { "Pacific/Kwajalein" , 0x03B42C }, + { "Pacific/Majuro" , 0x03B498 }, + { "Pacific/Marquesas" , 0x03B4F7 }, + { "Pacific/Midway" , 0x03B55E }, + { "Pacific/Nauru" , 0x03B5E8 }, + { "Pacific/Niue" , 0x03B660 }, + { "Pacific/Norfolk" , 0x03B6BE }, + { "Pacific/Noumea" , 0x03B713 }, + { "Pacific/Pago_Pago" , 0x03B7A3 }, + { "Pacific/Palau" , 0x03B82C }, + { "Pacific/Pitcairn" , 0x03B870 }, + { "Pacific/Pohnpei" , 0x03B8C5 }, + { "Pacific/Ponape" , 0x03B91A }, + { "Pacific/Port_Moresby" , 0x03B95F }, + { "Pacific/Rarotonga" , 0x03B9A3 }, + { "Pacific/Saipan" , 0x03BA7F }, + { "Pacific/Samoa" , 0x03BAE2 }, + { "Pacific/Tahiti" , 0x03BB6B }, + { "Pacific/Tarawa" , 0x03BBD0 }, + { "Pacific/Tongatapu" , 0x03BC24 }, + { "Pacific/Truk" , 0x03BCB0 }, + { "Pacific/Wake" , 0x03BCF5 }, + { "Pacific/Wallis" , 0x03BD45 }, + { "Pacific/Yap" , 0x03BD89 }, + { "Poland" , 0x03BDCE }, + { "Portugal" , 0x03C1AF }, + { "PRC" , 0x03C6AB }, + { "PST8PDT" , 0x03C75C }, + { "ROC" , 0x03CAAD }, + { "ROK" , 0x03CBC5 }, + { "Singapore" , 0x03CC69 }, + { "Turkey" , 0x03CD20 }, + { "UCT" , 0x03D10D }, + { "Universal" , 0x03D151 }, + { "US/Alaska" , 0x03D195 }, + { "US/Aleutian" , 0x03D4FE }, + { "US/Arizona" , 0x03D864 }, + { "US/Central" , 0x03D8F2 }, + { "US/East-Indiana" , 0x03E2FC }, + { "US/Eastern" , 0x03DDFD }, + { "US/Hawaii" , 0x03E566 }, + { "US/Indiana-Starke" , 0x03E5D7 }, + { "US/Michigan" , 0x03E948 }, + { "US/Mountain" , 0x03EC7F }, + { "US/Pacific" , 0x03EFF8 }, + { "US/Pacific-New" , 0x03F3FD }, + { "US/Samoa" , 0x03F802 }, + { "UTC" , 0x03F88B }, + { "W-SU" , 0x03FB82 }, + { "WET" , 0x03F8CF }, + { "Zulu" , 0x03FDBC }, }; /* This is a generated file, do not modify */ -const unsigned char timelib_timezone_db_data_builtin[261525] = { +const unsigned char timelib_timezone_db_data_builtin[261632] = { /* Africa/Abidjan */ @@ -758,7 +758,7 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { /* Africa/Casablanca */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x4D, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x11, 0x96, 0x51, 0xF9, 0x9C, +0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x11, 0x96, 0x51, 0xF9, 0x9C, 0xC6, 0xFF, 0x14, 0x80, 0xC7, 0x58, 0xAC, 0x70, 0xC7, 0xD9, 0xED, 0x80, 0xD2, 0xA1, 0x32, 0xF0, 0xDB, 0x35, 0xA4, 0x00, 0xDB, 0xEE, 0x27, 0xF0, 0xFB, 0x25, 0x72, 0x40, 0xFB, 0xC2, 0xEF, 0x70, 0x08, 0x6B, 0x84, 0x80, 0x08, 0xC6, 0x6D, 0xF0, 0x0B, 0xE8, 0x0C, 0x00, 0x0C, 0x61, 0x47, 0xF0, @@ -767,32 +767,34 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { 0x4A, 0x23, 0x1A, 0x00, 0x4A, 0x8D, 0xD5, 0x70, 0x4B, 0xDC, 0xC0, 0x80, 0x4C, 0x5D, 0xE5, 0x70, 0x4D, 0x97, 0xB8, 0x80, 0x4E, 0x34, 0x8C, 0xF0, 0x4F, 0x9C, 0xA0, 0xA0, 0x50, 0x08, 0xBB, 0xA0, 0x50, 0x31, 0x9A, 0x20, 0x50, 0x67, 0xA7, 0xA0, 0x51, 0x7C, 0x82, 0xA0, 0x51, 0xD8, 0xCB, 0xA0, -0x52, 0x05, 0x9E, 0xA0, 0x52, 0x47, 0x89, 0xA0, 0x53, 0x5C, 0x64, 0xA0, 0x53, 0xAF, 0x73, 0x20, -0x53, 0xD7, 0x00, 0x20, 0x54, 0x27, 0x6B, 0xA0, 0x55, 0x3C, 0x46, 0xA0, 0x55, 0x82, 0x26, 0x20, -0x55, 0xA9, 0xB3, 0x20, 0x56, 0x07, 0x4D, 0xA0, 0x57, 0x1C, 0x28, 0xA0, 0x57, 0x56, 0x2A, 0xA0, -0x57, 0x7D, 0xB7, 0xA0, 0x57, 0xE7, 0x2F, 0xA0, 0x59, 0x05, 0x45, 0x20, 0x59, 0x28, 0xDD, 0xA0, -0x59, 0x50, 0x6A, 0xA0, 0x59, 0xC7, 0x11, 0xA0, 0x5A, 0xE5, 0x27, 0x20, 0x5A, 0xFB, 0x90, 0xA0, -0x5B, 0x23, 0x1D, 0xA0, 0x5B, 0xB0, 0x2E, 0x20, 0x5C, 0xC5, 0x09, 0x20, 0x5C, 0xCF, 0x95, 0x20, -0x5C, 0xF7, 0x22, 0x20, 0x5D, 0x90, 0x10, 0x20, 0x5E, 0xC9, 0xD5, 0x20, 0x5F, 0x6F, 0xF2, 0x20, -0x60, 0x9C, 0x88, 0x20, 0x61, 0x4F, 0xD4, 0x20, 0x62, 0x70, 0x8C, 0xA0, 0x63, 0x2F, 0xB6, 0x20, -0x64, 0x4D, 0xCB, 0xA0, 0x65, 0x0F, 0x98, 0x20, 0x66, 0x2D, 0xAD, 0xA0, 0x66, 0xF8, 0xB4, 0xA0, -0x68, 0x0D, 0x8F, 0xA0, 0x68, 0xD8, 0x96, 0xA0, 0x69, 0xED, 0x71, 0xA0, 0x6A, 0xB8, 0x78, 0xA0, -0x6B, 0xCD, 0x53, 0xA0, 0x6C, 0x98, 0x5A, 0xA0, 0x6D, 0xB6, 0x70, 0x20, 0x6E, 0x78, 0x3C, 0xA0, -0x6F, 0x96, 0x52, 0x20, 0x70, 0x61, 0x59, 0x20, 0x71, 0x76, 0x34, 0x20, 0x72, 0x41, 0x3B, 0x20, -0x73, 0x56, 0x16, 0x20, 0x74, 0x21, 0x1D, 0x20, 0x75, 0x35, 0xF8, 0x20, 0x76, 0x00, 0xFF, 0x20, -0x77, 0x15, 0xDA, 0x20, 0x77, 0xE0, 0xE1, 0x20, 0x78, 0xFE, 0xF6, 0xA0, 0x79, 0xC0, 0xC3, 0x20, -0x7A, 0xDE, 0xD8, 0xA0, 0x7B, 0xA9, 0xDF, 0xA0, 0x7C, 0xBE, 0xBA, 0xA0, 0x7D, 0x89, 0xC1, 0xA0, -0x7E, 0x9E, 0x9C, 0xA0, 0x7F, 0x69, 0xA3, 0xA0, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, -0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x03, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, +0x52, 0x05, 0x9E, 0xA0, 0x52, 0x6C, 0x73, 0xA0, 0x53, 0x37, 0x7A, 0xA0, 0x53, 0xAF, 0x73, 0x20, +0x53, 0xD7, 0x00, 0x20, 0x54, 0x4C, 0x55, 0xA0, 0x55, 0x17, 0x5C, 0xA0, 0x55, 0x82, 0x26, 0x20, +0x55, 0xA9, 0xB3, 0x20, 0x56, 0x2C, 0x37, 0xA0, 0x56, 0xF7, 0x3E, 0xA0, 0x57, 0x56, 0x2A, 0xA0, +0x57, 0x7D, 0xB7, 0xA0, 0x58, 0x15, 0x54, 0x20, 0x58, 0xD7, 0x20, 0xA0, 0x59, 0x28, 0xDD, 0xA0, +0x59, 0x50, 0x6A, 0xA0, 0x59, 0xF5, 0x36, 0x20, 0x5A, 0xB7, 0x02, 0xA0, 0x5A, 0xFB, 0x90, 0xA0, +0x5B, 0x23, 0x1D, 0xA0, 0x5B, 0xD5, 0x18, 0x20, 0x5C, 0xA0, 0x1F, 0x20, 0x5C, 0xCF, 0x95, 0x20, +0x5C, 0xF7, 0x22, 0x20, 0x5D, 0xB4, 0xFA, 0x20, 0x5E, 0x80, 0x01, 0x20, 0x5E, 0xA2, 0x48, 0x20, +0x5E, 0xC9, 0xD5, 0x20, 0x5F, 0x94, 0xDC, 0x20, 0x60, 0x5F, 0xE3, 0x20, 0x60, 0x74, 0xFB, 0x20, +0x60, 0x9C, 0x88, 0x20, 0x61, 0x7D, 0xF8, 0xA0, 0x62, 0x3F, 0xC5, 0x20, 0x62, 0x48, 0xFF, 0xA0, +0x62, 0x70, 0x8C, 0xA0, 0x63, 0x5D, 0xDA, 0xA0, 0x64, 0x43, 0x3F, 0xA0, 0x65, 0x3D, 0xBC, 0xA0, +0x66, 0x15, 0xF2, 0xA0, 0x67, 0x1D, 0x9E, 0xA0, 0x67, 0xE9, 0xF7, 0x20, 0x68, 0xFD, 0x80, 0xA0, +0x69, 0xC8, 0x87, 0xA0, 0x6A, 0xDD, 0x62, 0xA0, 0x6B, 0xA8, 0x69, 0xA0, 0x6C, 0xC6, 0x7F, 0x20, +0x6D, 0x88, 0x4B, 0xA0, 0x6E, 0xA6, 0x61, 0x20, 0x6F, 0x68, 0x2D, 0xA0, 0x70, 0x86, 0x43, 0x20, +0x71, 0x51, 0x4A, 0x20, 0x72, 0x66, 0x25, 0x20, 0x73, 0x31, 0x2C, 0x20, 0x74, 0x46, 0x07, 0x20, +0x75, 0x11, 0x0E, 0x20, 0x76, 0x2F, 0x23, 0xA0, 0x76, 0xF0, 0xF0, 0x20, 0x78, 0x0F, 0x05, 0xA0, +0x78, 0xD0, 0xD2, 0x20, 0x79, 0xEE, 0xE7, 0xA0, 0x7A, 0xB0, 0xB4, 0x20, 0x7B, 0xCE, 0xC9, 0xA0, +0x7C, 0x99, 0xD0, 0xA0, 0x7D, 0xA8, 0x14, 0x20, 0x7E, 0x79, 0xB2, 0xA0, 0x7F, 0x7C, 0x18, 0xA0, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, +0x02, 0x03, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, -0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0xFF, 0xFF, 0xF8, 0xE4, 0x00, 0x00, 0x00, 0x00, 0x0E, -0x10, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x0E, 0x10, 0x00, 0x0D, 0x4C, -0x4D, 0x54, 0x00, 0x57, 0x45, 0x53, 0x54, 0x00, 0x57, 0x45, 0x54, 0x00, 0x43, 0x45, 0x54, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBC, 0xAC, 0xC8, 0x01, 0x07, 0x16, 0x42, -0x00, 0x00, 0x00, 0x00, +0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, +0x02, 0x01, 0x02, 0x01, 0x02, 0xFF, 0xFF, 0xF8, 0xE4, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x10, 0x01, +0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x0E, 0x10, 0x00, 0x0D, 0x4C, 0x4D, 0x54, +0x00, 0x57, 0x45, 0x53, 0x54, 0x00, 0x57, 0x45, 0x54, 0x00, 0x43, 0x45, 0x54, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBC, 0xAC, 0xC8, 0x01, 0x07, 0x16, 0x42, 0x00, 0x00, +0x00, 0x00, /* Africa/Ceuta */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x45, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -890,12 +892,40 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { /* Africa/El_Aaiun */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x45, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0C, 0xBC, 0x48, 0xF0, 0xE0, -0x0B, 0xD1, 0xB0, 0x90, 0x01, 0x02, 0xFF, 0xFF, 0xF3, 0xA0, 0x00, 0x00, 0xFF, 0xFF, 0xF1, 0xF0, -0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x4C, 0x4D, 0x54, 0x00, 0x57, 0x41, 0x54, 0x00, -0x57, 0x45, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB2, 0xC1, 0xB8, 0x00, 0xFE, -0x84, 0x40, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x5A, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x11, 0xBC, 0x48, 0xF0, 0xE0, +0x0B, 0xD1, 0xB0, 0x90, 0x0B, 0xE8, 0x0C, 0x00, 0x0C, 0x61, 0x47, 0xF0, 0x0D, 0xC9, 0x3F, 0x80, +0x0E, 0x8E, 0xF2, 0x70, 0x0F, 0xD3, 0x51, 0x80, 0x10, 0x27, 0xA3, 0x70, 0x48, 0x41, 0xE6, 0x80, +0x48, 0xBB, 0x22, 0x70, 0x4A, 0x23, 0x1A, 0x00, 0x4A, 0x8D, 0xD5, 0x70, 0x4B, 0xDC, 0xC0, 0x80, +0x4C, 0x5D, 0xE5, 0x70, 0x4D, 0x97, 0xB8, 0x80, 0x4E, 0x34, 0x8C, 0xF0, 0x4F, 0x9C, 0xA0, 0xA0, +0x50, 0x08, 0xBB, 0xA0, 0x50, 0x31, 0x9A, 0x20, 0x50, 0x67, 0xA7, 0xA0, 0x51, 0x7C, 0x82, 0xA0, +0x51, 0xD8, 0xCB, 0xA0, 0x52, 0x05, 0x9E, 0xA0, 0x52, 0x6C, 0x73, 0xA0, 0x53, 0x37, 0x7A, 0xA0, +0x53, 0xAF, 0x73, 0x20, 0x53, 0xD7, 0x00, 0x20, 0x54, 0x4C, 0x55, 0xA0, 0x55, 0x17, 0x5C, 0xA0, +0x55, 0x82, 0x26, 0x20, 0x55, 0xA9, 0xB3, 0x20, 0x56, 0x2C, 0x37, 0xA0, 0x56, 0xF7, 0x3E, 0xA0, +0x57, 0x56, 0x2A, 0xA0, 0x57, 0x7D, 0xB7, 0xA0, 0x58, 0x15, 0x54, 0x20, 0x58, 0xD7, 0x20, 0xA0, +0x59, 0x28, 0xDD, 0xA0, 0x59, 0x50, 0x6A, 0xA0, 0x59, 0xF5, 0x36, 0x20, 0x5A, 0xB7, 0x02, 0xA0, +0x5A, 0xFB, 0x90, 0xA0, 0x5B, 0x23, 0x1D, 0xA0, 0x5B, 0xD5, 0x18, 0x20, 0x5C, 0xA0, 0x1F, 0x20, +0x5C, 0xCF, 0x95, 0x20, 0x5C, 0xF7, 0x22, 0x20, 0x5D, 0xB4, 0xFA, 0x20, 0x5E, 0x80, 0x01, 0x20, +0x5E, 0xA2, 0x48, 0x20, 0x5E, 0xC9, 0xD5, 0x20, 0x5F, 0x94, 0xDC, 0x20, 0x60, 0x5F, 0xE3, 0x20, +0x60, 0x74, 0xFB, 0x20, 0x60, 0x9C, 0x88, 0x20, 0x61, 0x7D, 0xF8, 0xA0, 0x62, 0x3F, 0xC5, 0x20, +0x62, 0x48, 0xFF, 0xA0, 0x62, 0x70, 0x8C, 0xA0, 0x63, 0x5D, 0xDA, 0xA0, 0x64, 0x43, 0x3F, 0xA0, +0x65, 0x3D, 0xBC, 0xA0, 0x66, 0x15, 0xF2, 0xA0, 0x67, 0x1D, 0x9E, 0xA0, 0x67, 0xE9, 0xF7, 0x20, +0x68, 0xFD, 0x80, 0xA0, 0x69, 0xC8, 0x87, 0xA0, 0x6A, 0xDD, 0x62, 0xA0, 0x6B, 0xA8, 0x69, 0xA0, +0x6C, 0xC6, 0x7F, 0x20, 0x6D, 0x88, 0x4B, 0xA0, 0x6E, 0xA6, 0x61, 0x20, 0x6F, 0x68, 0x2D, 0xA0, +0x70, 0x86, 0x43, 0x20, 0x71, 0x51, 0x4A, 0x20, 0x72, 0x66, 0x25, 0x20, 0x73, 0x31, 0x2C, 0x20, +0x74, 0x46, 0x07, 0x20, 0x75, 0x11, 0x0E, 0x20, 0x76, 0x2F, 0x23, 0xA0, 0x76, 0xF0, 0xF0, 0x20, +0x78, 0x0F, 0x05, 0xA0, 0x78, 0xD0, 0xD2, 0x20, 0x79, 0xEE, 0xE7, 0xA0, 0x7A, 0xB0, 0xB4, 0x20, +0x7B, 0xCE, 0xC9, 0xA0, 0x7C, 0x99, 0xD0, 0xA0, 0x7D, 0xA8, 0x14, 0x20, 0x7E, 0x79, 0xB2, 0xA0, +0x7F, 0x7C, 0x18, 0xA0, 0x01, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, +0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, +0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, +0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, +0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, +0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0xFF, 0xFF, +0xF3, 0xA0, 0x00, 0x00, 0xFF, 0xFF, 0xF1, 0xF0, 0x00, 0x04, 0x00, 0x00, 0x0E, 0x10, 0x01, 0x08, +0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x4C, 0x4D, 0x54, 0x00, 0x57, 0x41, 0x54, 0x00, 0x57, 0x45, +0x53, 0x54, 0x00, 0x57, 0x45, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xB2, 0xC1, 0xB8, 0x00, 0xFE, 0x84, 0x40, 0x00, 0x00, 0x00, 0x00, /* Africa/Freetown */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x53, 0x4C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -945,7 +975,7 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { /* Africa/Juba */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x53, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x11, 0xB6, 0xA3, 0xDA, 0xE0, +0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x11, 0xB6, 0xA3, 0xDA, 0x00, 0x00, 0x9E, 0x17, 0xE0, 0x01, 0x7A, 0x34, 0x50, 0x02, 0x7D, 0xF9, 0xE0, 0x03, 0x5B, 0x67, 0xD0, 0x04, 0x60, 0x7E, 0xE0, 0x05, 0x3D, 0xEC, 0xD0, 0x06, 0x40, 0x60, 0xE0, 0x07, 0x1F, 0x20, 0x50, 0x08, 0x20, 0x42, 0xE0, 0x09, 0x00, 0x53, 0xD0, 0x0A, 0x00, 0x24, 0xE0, 0x0A, 0xE1, 0x87, 0x50, @@ -956,7 +986,7 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { 0x1A, 0xF1, 0x8B, 0xE0, 0x1B, 0xD0, 0x4B, 0x50, 0x1C, 0xD1, 0x6D, 0xE0, 0x1D, 0xB1, 0x7E, 0xD0, 0x38, 0x80, 0x45, 0x20, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, -0x02, 0x01, 0x02, 0x01, 0x02, 0x03, 0x00, 0x00, 0x1D, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x30, +0x02, 0x01, 0x02, 0x01, 0x02, 0x03, 0x00, 0x00, 0x1E, 0x80, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x30, 0x01, 0x04, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x09, 0x00, 0x00, 0x2A, 0x30, 0x00, 0x0D, 0x4C, 0x4D, 0x54, 0x00, 0x43, 0x41, 0x53, 0x54, 0x00, 0x43, 0x41, 0x54, 0x00, 0x45, 0x41, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xBA, 0xC8, 0x01, 0x42, 0xE0, 0x40, 0x00, @@ -1181,7 +1211,7 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { /* Africa/Tripoli */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x4C, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x11, 0xA1, 0xF2, 0xC1, 0x24, +0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x11, 0xA1, 0xF2, 0xC1, 0x24, 0xDD, 0xBB, 0xB1, 0x10, 0xDE, 0x23, 0xAD, 0x60, 0xE1, 0x78, 0xD2, 0x10, 0xE1, 0xE7, 0x65, 0xE0, 0xE5, 0x2F, 0x3F, 0x70, 0xE5, 0xA9, 0xCC, 0xE0, 0xEB, 0x4E, 0xC6, 0xF0, 0x16, 0x92, 0x42, 0x60, 0x17, 0x08, 0xF7, 0x70, 0x17, 0xFA, 0x2B, 0xE0, 0x18, 0xEA, 0x2A, 0xF0, 0x19, 0xDB, 0x5F, 0x60, @@ -1189,24 +1219,9 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { 0x1E, 0x93, 0x0B, 0x70, 0x1F, 0x82, 0xEE, 0x60, 0x20, 0x70, 0x4A, 0x70, 0x21, 0x61, 0x7E, 0xE0, 0x22, 0x52, 0xCF, 0x70, 0x23, 0x44, 0x03, 0xE0, 0x24, 0x34, 0x02, 0xF0, 0x25, 0x25, 0x37, 0x60, 0x26, 0x40, 0xB7, 0xF0, 0x32, 0x4E, 0xF1, 0x60, 0x33, 0x44, 0x36, 0x70, 0x34, 0x35, 0x6A, 0xE0, -0x50, 0x9D, 0x99, 0x00, 0x51, 0x54, 0xD9, 0x80, 0x52, 0x69, 0xB4, 0x80, 0x53, 0x34, 0xBB, 0x80, -0x54, 0x52, 0xD1, 0x00, 0x55, 0x14, 0x9D, 0x80, 0x56, 0x32, 0xB3, 0x00, 0x56, 0xF4, 0x7F, 0x80, -0x58, 0x12, 0x95, 0x00, 0x58, 0xDD, 0x9C, 0x00, 0x59, 0xF2, 0x77, 0x00, 0x5A, 0xBD, 0x7E, 0x00, -0x5B, 0xD2, 0x59, 0x00, 0x5C, 0x9D, 0x60, 0x00, 0x5D, 0xB2, 0x3B, 0x00, 0x5E, 0x7D, 0x42, 0x00, -0x5F, 0x9B, 0x57, 0x80, 0x60, 0x5D, 0x24, 0x00, 0x61, 0x7B, 0x39, 0x80, 0x62, 0x3D, 0x06, 0x00, -0x63, 0x5B, 0x1B, 0x80, 0x64, 0x26, 0x22, 0x80, 0x65, 0x3A, 0xFD, 0x80, 0x66, 0x06, 0x04, 0x80, -0x67, 0x1A, 0xDF, 0x80, 0x67, 0xE5, 0xE6, 0x80, 0x69, 0x03, 0xFC, 0x00, 0x69, 0xC5, 0xC8, 0x80, -0x6A, 0xE3, 0xDE, 0x00, 0x6B, 0xA5, 0xAA, 0x80, 0x6C, 0xC3, 0xC0, 0x00, 0x6D, 0x8E, 0xC7, 0x00, -0x6E, 0xA3, 0xA2, 0x00, 0x6F, 0x6E, 0xA9, 0x00, 0x70, 0x83, 0x84, 0x00, 0x71, 0x4E, 0x8B, 0x00, -0x72, 0x63, 0x66, 0x00, 0x73, 0x2E, 0x6D, 0x00, 0x74, 0x4C, 0x82, 0x80, 0x75, 0x0E, 0x4F, 0x00, -0x76, 0x2C, 0x64, 0x80, 0x76, 0xEE, 0x31, 0x00, 0x78, 0x0C, 0x46, 0x80, 0x78, 0xD7, 0x4D, 0x80, -0x79, 0xEC, 0x28, 0x80, 0x7A, 0xB7, 0x2F, 0x80, 0x7B, 0xCC, 0x0A, 0x80, 0x7C, 0x97, 0x11, 0x80, -0x7D, 0xB5, 0x27, 0x00, 0x7E, 0x76, 0xF3, 0x80, 0x7F, 0x95, 0x09, 0x00, 0x02, 0x01, 0x02, 0x01, +0x50, 0x9D, 0x99, 0x00, 0x51, 0x54, 0xD9, 0x80, 0x52, 0x69, 0xB4, 0x80, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x03, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, -0x02, 0x01, 0x02, 0x01, 0x02, 0x03, 0x02, 0x01, 0x03, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, -0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, -0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, -0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x00, 0x00, 0x0C, 0x5C, +0x02, 0x01, 0x02, 0x01, 0x02, 0x03, 0x02, 0x01, 0x03, 0x02, 0x01, 0x03, 0x00, 0x00, 0x0C, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x20, 0x01, 0x04, 0x00, 0x00, 0x0E, 0x10, 0x00, 0x09, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x0D, 0x4C, 0x4D, 0x54, 0x00, 0x43, 0x45, 0x53, 0x54, 0x00, 0x43, 0x45, 0x54, 0x00, 0x45, 0x45, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBB, 0x87, @@ -1390,8 +1405,8 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { /* America/Anguilla */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x41, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x93, 0x37, 0x35, 0x20, -0x01, 0xFF, 0xFF, 0xC4, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0x4C, 0x4D, 0x54, +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x93, 0x37, 0x33, 0xAC, +0x01, 0xFF, 0xFF, 0xC6, 0x54, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0x4C, 0x4D, 0x54, 0x00, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA5, 0x19, 0xA0, 0x00, 0xB2, 0x6D, 0x15, 0x00, 0x00, 0x00, 0x00, @@ -1407,7 +1422,7 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { /* America/Araguaina */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x42, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0D, 0x96, 0xAA, 0x74, 0x30, +0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0D, 0x96, 0xAA, 0x74, 0x30, 0xB8, 0x0F, 0x49, 0xE0, 0xB8, 0xFD, 0x40, 0xA0, 0xB9, 0xF1, 0x34, 0x30, 0xBA, 0xDE, 0x74, 0x20, 0xDA, 0x38, 0xAE, 0x30, 0xDA, 0xEB, 0xFA, 0x30, 0xDC, 0x19, 0xE1, 0xB0, 0xDC, 0xB9, 0x59, 0x20, 0xDD, 0xFB, 0x15, 0x30, 0xDE, 0x9B, 0xDE, 0x20, 0xDF, 0xDD, 0x9A, 0x30, 0xE0, 0x54, 0x33, 0x20, @@ -1420,29 +1435,14 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { 0x34, 0x38, 0x54, 0x30, 0x34, 0xF8, 0xC1, 0x20, 0x36, 0x20, 0x1F, 0x30, 0x36, 0xCF, 0x68, 0xA0, 0x37, 0xF6, 0xC6, 0xB0, 0x38, 0xB8, 0x85, 0x20, 0x39, 0xDF, 0xE3, 0x30, 0x3A, 0x8F, 0x2C, 0xA0, 0x3B, 0xC8, 0xFF, 0xB0, 0x3C, 0x6F, 0x0E, 0xA0, 0x3D, 0xC4, 0x91, 0x30, 0x3E, 0x4E, 0xF0, 0xA0, -0x50, 0x83, 0x65, 0x30, 0x51, 0x20, 0x39, 0xA0, 0x52, 0x63, 0x47, 0x30, 0x53, 0x00, 0x1B, 0xA0, -0x54, 0x43, 0x29, 0x30, 0x54, 0xE9, 0x38, 0x20, 0x56, 0x23, 0x0B, 0x30, 0x56, 0xC9, 0x1A, 0x20, -0x58, 0x02, 0xED, 0x30, 0x58, 0xA8, 0xFC, 0x20, 0x59, 0xE2, 0xCF, 0x30, 0x5A, 0x88, 0xDE, 0x20, -0x5B, 0xCB, 0xEB, 0xB0, 0x5C, 0x68, 0xC0, 0x20, 0x5D, 0xAB, 0xCD, 0xB0, 0x5E, 0x48, 0xA2, 0x20, -0x5F, 0x8B, 0xAF, 0xB0, 0x60, 0x31, 0xBE, 0xA0, 0x61, 0x6B, 0x91, 0xB0, 0x62, 0x11, 0xA0, 0xA0, -0x63, 0x4B, 0x73, 0xB0, 0x63, 0xFA, 0xBD, 0x20, 0x65, 0x2B, 0x55, 0xB0, 0x65, 0xD1, 0x64, 0xA0, -0x67, 0x14, 0x72, 0x30, 0x67, 0xB1, 0x46, 0xA0, 0x68, 0xF4, 0x54, 0x30, 0x69, 0x9A, 0x63, 0x20, -0x6A, 0xD4, 0x36, 0x30, 0x6B, 0x7A, 0x45, 0x20, 0x6C, 0xB4, 0x18, 0x30, 0x6D, 0x5A, 0x27, 0x20, -0x6E, 0x93, 0xFA, 0x30, 0x6F, 0x3A, 0x09, 0x20, 0x70, 0x7D, 0x16, 0xB0, 0x71, 0x19, 0xEB, 0x20, -0x72, 0x5C, 0xF8, 0xB0, 0x72, 0xF9, 0xCD, 0x20, 0x74, 0x3C, 0xDA, 0xB0, 0x74, 0xD9, 0xAF, 0x20, -0x76, 0x1C, 0xBC, 0xB0, 0x76, 0xC2, 0xCB, 0xA0, 0x77, 0xFC, 0x9E, 0xB0, 0x78, 0xAB, 0xE8, 0x20, -0x79, 0xDC, 0x80, 0xB0, 0x7A, 0x82, 0x8F, 0xA0, 0x7B, 0xC5, 0x9D, 0x30, 0x7C, 0x62, 0x71, 0xA0, -0x7D, 0xA5, 0x7F, 0x30, 0x7E, 0x4B, 0x8E, 0x20, 0x7F, 0x85, 0x61, 0x30, 0x02, 0x01, 0x02, 0x01, +0x50, 0x83, 0x65, 0x30, 0x51, 0x20, 0x39, 0xA0, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, -0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, -0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, -0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, -0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, -0xFF, 0xFF, 0xD2, 0xD0, 0x00, 0x00, 0xFF, 0xFF, 0xE3, 0xE0, 0x01, 0x04, 0xFF, 0xFF, 0xD5, 0xD0, -0x00, 0x09, 0x4C, 0x4D, 0x54, 0x00, 0x42, 0x52, 0x53, 0x54, 0x00, 0x42, 0x52, 0x54, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x57, 0xC0, 0x00, 0xC9, 0x1C, 0x60, 0x00, 0x00, 0x00, -0x09, 0x54, 0x6F, 0x63, 0x61, 0x6E, 0x74, 0x69, 0x6E, 0x73, +0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0xFF, 0xFF, 0xD2, 0xD0, 0x00, +0x00, 0xFF, 0xFF, 0xE3, 0xE0, 0x01, 0x04, 0xFF, 0xFF, 0xD5, 0xD0, 0x00, 0x09, 0x4C, 0x4D, 0x54, +0x00, 0x42, 0x52, 0x53, 0x54, 0x00, 0x42, 0x52, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x7E, 0x57, 0xC0, 0x00, 0xC9, 0x1C, 0x60, 0x00, 0x00, 0x00, 0x09, 0x54, 0x6F, 0x63, 0x61, +0x6E, 0x74, 0x69, 0x6E, 0x73, /* America/Argentina/Buenos_Aires */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x41, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -1767,7 +1767,7 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x05, -0x06, 0x05, 0x04, 0x06, 0x04, 0x05, 0x04, 0x03, 0x06, 0x05, 0x06, 0x05, 0x06, 0xFF, 0xFF, 0xC3, +0x06, 0x05, 0x04, 0x06, 0x04, 0x05, 0x04, 0x03, 0x06, 0x05, 0x06, 0x05, 0x04, 0xFF, 0xFF, 0xC3, 0xD0, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x08, 0xFF, 0xFF, 0xE3, 0xE0, 0x01, 0x08, 0xFF, 0xFF, 0xD5, 0xD0, 0x00, 0x04, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x0D, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x12, 0x43, 0x4D, 0x54, 0x00, 0x41, 0x52, 0x54, 0x00, 0x41, @@ -1839,8 +1839,8 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { /* America/Aruba */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x41, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x93, 0x1E, 0x2F, 0x38, -0xF6, 0x98, 0xEC, 0x48, 0x01, 0x02, 0xFF, 0xFF, 0xBE, 0x48, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0xB8, +0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x93, 0x1E, 0x2E, 0x23, +0xF6, 0x98, 0xEC, 0x48, 0x01, 0x02, 0xFF, 0xFF, 0xBF, 0x5D, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0xB8, 0x00, 0x04, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x08, 0x4C, 0x4D, 0x54, 0x00, 0x41, 0x4E, 0x54, 0x00, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x67, 0x10, 0x00, 0xA7, 0xE5, 0xC5, 0x00, 0x00, 0x00, 0x00, @@ -2414,8 +2414,8 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { /* America/Cayman */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x4B, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x93, 0x0F, 0xB5, 0x00, -0x01, 0xFF, 0xFF, 0xB8, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x04, 0x4B, 0x4D, 0x54, +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x93, 0x0F, 0xB4, 0xFF, +0x01, 0xFF, 0xFF, 0xB8, 0x01, 0x00, 0x00, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x04, 0x4B, 0x4D, 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0xC7, 0x50, 0x00, 0x96, 0x7A, 0x22, 0x00, 0x00, 0x00, 0x00, @@ -2889,8 +2889,8 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { /* America/Dominica */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x44, 0x4D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x91, 0xF4, 0x34, 0x4C, -0x01, 0xFF, 0xFF, 0xC6, 0x70, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0x4C, 0x4D, 0x54, +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x93, 0x37, 0x33, 0xAC, +0x01, 0xFF, 0xFF, 0xC6, 0x54, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0x4C, 0x4D, 0x54, 0x00, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0xAC, 0xD0, 0x00, 0xB4, 0xF8, 0x20, 0x00, 0x00, 0x00, 0x00, @@ -2959,7 +2959,7 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { /* America/Eirunepe */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x42, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x11, 0x96, 0xAA, 0x88, 0x80, +0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x11, 0x96, 0xAA, 0x88, 0x80, 0xB8, 0x0F, 0x66, 0x00, 0xB8, 0xFD, 0x5C, 0xC0, 0xB9, 0xF1, 0x50, 0x50, 0xBA, 0xDE, 0x90, 0x40, 0xDA, 0x38, 0xCA, 0x50, 0xDA, 0xEC, 0x16, 0x50, 0xDC, 0x19, 0xFD, 0xD0, 0xDC, 0xB9, 0x75, 0x40, 0xDD, 0xFB, 0x31, 0x50, 0xDE, 0x9B, 0xFA, 0x40, 0xDF, 0xDD, 0xB6, 0x50, 0xE0, 0x54, 0x4F, 0x40, @@ -2967,14 +2967,14 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { 0xF8, 0x51, 0x48, 0x50, 0xF8, 0xC7, 0xE1, 0x40, 0xFA, 0x0A, 0xEE, 0xD0, 0xFA, 0xA9, 0x14, 0xC0, 0xFB, 0xEC, 0x22, 0x50, 0xFC, 0x8B, 0x99, 0xC0, 0x1D, 0xC9, 0xAA, 0x50, 0x1E, 0x78, 0xF3, 0xC0, 0x1F, 0xA0, 0x51, 0xD0, 0x20, 0x33, 0xEB, 0xC0, 0x21, 0x81, 0x85, 0x50, 0x22, 0x0B, 0xE4, 0xC0, -0x2C, 0xC0, 0xD1, 0x50, 0x2D, 0x66, 0xE0, 0x40, 0x48, 0x60, 0x7F, 0x50, 0x02, 0x01, 0x02, 0x01, +0x2C, 0xC0, 0xD1, 0x50, 0x2D, 0x66, 0xE0, 0x40, 0x48, 0x60, 0x7F, 0x50, 0x52, 0x7F, 0x04, 0xC0, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, -0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x03, 0xFF, 0xFF, 0xBE, 0x80, -0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x04, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x09, 0xFF, 0xFF, -0xC7, 0xC0, 0x00, 0x0D, 0x4C, 0x4D, 0x54, 0x00, 0x41, 0x43, 0x53, 0x54, 0x00, 0x41, 0x43, 0x54, -0x00, 0x41, 0x4D, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x28, -0x15, 0x00, 0xA8, 0x0C, 0xD5, 0x00, 0x00, 0x00, 0x0A, 0x57, 0x20, 0x41, 0x6D, 0x61, 0x7A, 0x6F, -0x6E, 0x61, 0x73, +0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x03, +0x02, 0xFF, 0xFF, 0xBE, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x04, 0xFF, 0xFF, 0xB9, +0xB0, 0x00, 0x09, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x0D, 0x4C, 0x4D, 0x54, 0x00, 0x41, 0x43, 0x53, +0x54, 0x00, 0x41, 0x43, 0x54, 0x00, 0x41, 0x4D, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x7F, 0x28, 0x15, 0x00, 0xA8, 0x0C, 0xD5, 0x00, 0x00, 0x00, 0x0A, 0x57, 0x20, +0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x61, 0x73, /* America/El_Salvador */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x53, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -3292,7 +3292,7 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { /* America/Grand_Turk */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x54, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x93, 0x0F, 0xB5, 0x00, +0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x93, 0x0F, 0xB4, 0xFF, 0x11, 0x89, 0x65, 0xF0, 0x12, 0x79, 0x48, 0xE0, 0x13, 0x69, 0x47, 0xF0, 0x14, 0x59, 0x2A, 0xE0, 0x15, 0x49, 0x29, 0xF0, 0x16, 0x39, 0x0C, 0xE0, 0x17, 0x29, 0x0B, 0xF0, 0x18, 0x22, 0x29, 0x60, 0x19, 0x08, 0xED, 0xF0, 0x1A, 0x02, 0x0B, 0x60, 0x1A, 0xF2, 0x0A, 0x70, 0x1B, 0xE1, 0xED, 0x60, @@ -3330,23 +3330,23 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0xFF, -0xFF, 0xB8, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x04, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, +0xFF, 0xB8, 0x01, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x04, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x08, 0x4B, 0x4D, 0x54, 0x00, 0x45, 0x44, 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x15, 0xAA, 0x00, 0xA6, 0x1E, 0x0A, 0x00, 0x00, 0x00, 0x00, /* America/Grenada */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x47, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x91, 0xF4, 0x34, 0x64, -0x01, 0xFF, 0xFF, 0xC6, 0x1C, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0x4C, 0x4D, 0x54, +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x93, 0x37, 0x33, 0xAC, +0x01, 0xFF, 0xFF, 0xC6, 0x54, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0x4C, 0x4D, 0x54, 0x00, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9B, 0xB7, 0x48, 0x00, 0xB4, 0x6F, 0x68, 0x00, 0x00, 0x00, 0x00, /* America/Guadeloupe */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x47, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x91, 0xD5, 0xE1, 0xB0, -0x01, 0xFF, 0xFF, 0xC6, 0x50, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0x4C, 0x4D, 0x54, +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x93, 0x37, 0x33, 0xAC, +0x01, 0xFF, 0xFF, 0xC6, 0x54, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0x4C, 0x4D, 0x54, 0x00, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x19, 0x65, 0x00, 0xB4, 0xC4, 0x0A, 0x00, 0x00, 0x00, 0x00, @@ -3490,7 +3490,7 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { 0x33, 0x47, 0x2D, 0xD0, 0x34, 0x40, 0x59, 0x50, 0x35, 0x1D, 0xD5, 0x50, 0x36, 0x32, 0xB0, 0x50, 0x36, 0xFD, 0xB7, 0x50, 0x38, 0x1B, 0xCC, 0xD0, 0x38, 0xE6, 0xD3, 0xD0, 0x39, 0xFB, 0xAE, 0xD0, 0x3A, 0xC6, 0xB5, 0xD0, 0x3B, 0xDB, 0x90, 0xD0, 0x3C, 0xAF, 0xD2, 0x50, 0x3D, 0xBB, 0x72, 0xD0, -0x3E, 0x8F, 0xB4, 0x50, 0x3F, 0x9B, 0x54, 0xD0, 0x40, 0x6F, 0x96, 0x50, 0x45, 0x44, 0x35, 0x50, +0x3E, 0x8F, 0xB4, 0x50, 0x3F, 0x9B, 0x54, 0xD0, 0x40, 0x66, 0x5B, 0xD0, 0x45, 0x44, 0x35, 0x50, 0x45, 0xF3, 0x8C, 0xD0, 0x47, 0x24, 0x17, 0x50, 0x47, 0xDC, 0xA9, 0x50, 0x49, 0x03, 0xF9, 0x50, 0x49, 0xB3, 0x50, 0xD0, 0x4A, 0xE3, 0xDB, 0x50, 0x4B, 0x9C, 0x6D, 0x50, 0x4C, 0xCC, 0xF7, 0xD0, 0x4D, 0x85, 0x89, 0xD0, 0x4E, 0xBF, 0x4E, 0xD0, 0x4F, 0x77, 0xE0, 0xD0, 0x50, 0x95, 0xF6, 0x50, @@ -4057,17 +4057,17 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { /* America/Jamaica */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x4A, 0x4D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x93, 0x0F, 0xB5, 0x00, +0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x93, 0x0F, 0xB4, 0xFF, 0x08, 0x20, 0xC1, 0x70, 0x09, 0x10, 0xA4, 0x60, 0x09, 0xAD, 0x94, 0xF0, 0x0A, 0xF0, 0x86, 0x60, 0x0B, 0xE0, 0x85, 0x70, 0x0C, 0xD9, 0xA2, 0xE0, 0x0D, 0xC0, 0x67, 0x70, 0x0E, 0xB9, 0x84, 0xE0, 0x0F, 0xA9, 0x83, 0xF0, 0x10, 0x99, 0x66, 0xE0, 0x11, 0x89, 0x65, 0xF0, 0x12, 0x79, 0x48, 0xE0, 0x13, 0x69, 0x47, 0xF0, 0x14, 0x59, 0x2A, 0xE0, 0x15, 0x49, 0x29, 0xF0, 0x16, 0x39, 0x0C, 0xE0, 0x17, 0x29, 0x0B, 0xF0, 0x18, 0x22, 0x29, 0x60, 0x19, 0x08, 0xED, 0xF0, 0x1A, 0x02, 0x0B, 0x60, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, -0x01, 0x02, 0x01, 0x02, 0x01, 0xFF, 0xFF, 0xB8, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, +0x01, 0x02, 0x01, 0x02, 0x01, 0xFF, 0xFF, 0xB8, 0x01, 0x00, 0x00, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x04, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x08, 0x4B, 0x4D, 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x45, -0x44, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA4, 0xCB, 0x80, 0x00, 0x9D, 0x78, -0x80, 0x00, 0x00, 0x00, 0x00, +0x44, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA4, 0xBF, 0x05, 0x00, 0x9D, 0x7B, +0x1A, 0x00, 0x00, 0x00, 0x00, /* America/Jujuy */ 0x50, 0x48, 0x50, 0x31, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -4573,8 +4573,8 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { /* America/Marigot */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x4D, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x91, 0xD5, 0xE1, 0xB0, -0x01, 0xFF, 0xFF, 0xC6, 0x50, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0x4C, 0x4D, 0x54, +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x93, 0x37, 0x33, 0xAC, +0x01, 0xFF, 0xFF, 0xC6, 0x54, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0x4C, 0x4D, 0x54, 0x00, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA4, 0xE5, 0x8A, 0x00, 0xB2, 0x66, 0x92, 0x00, 0x00, 0x00, 0x00, @@ -5071,7 +5071,7 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { 0x00, 0x00, /* America/Montreal */ -0x50, 0x48, 0x50, 0x31, 0x01, 0x43, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x50, 0x48, 0x50, 0x31, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE8, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x10, 0x9C, 0xBD, 0x01, 0xF0, 0x9C, 0xE4, 0x64, 0xC0, 0x9E, 0xB8, 0x93, 0x70, 0x9F, 0xBA, 0xEB, 0x60, 0xA0, 0x87, 0x58, 0xF8, @@ -5149,16 +5149,14 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { 0x00, 0x01, 0x00, 0x01, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x00, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x04, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x08, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x0C, 0x45, 0x44, 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x45, 0x57, 0x54, 0x00, 0x45, 0x50, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, -0x00, 0x00, 0x00, 0x01, 0x00, 0xCE, 0xC8, 0x32, 0x00, 0xA2, 0x67, 0x85, 0x00, 0x00, 0x00, 0x26, -0x45, 0x61, 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x51, -0x75, 0x65, 0x62, 0x65, 0x63, 0x20, 0x2D, 0x20, 0x6D, 0x6F, 0x73, 0x74, 0x20, 0x6C, 0x6F, 0x63, -0x61, 0x74, 0x69, 0x6F, 0x6E, 0x73, +0x00, 0x00, 0x00, 0x01, 0x00, 0x89, 0x54, 0x40, 0x01, 0x12, 0xA8, 0x80, 0x00, 0x00, 0x00, 0x00, + /* America/Montserrat */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x4D, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x91, 0xF4, 0x35, 0x10, -0x01, 0xFF, 0xFF, 0xC5, 0xAC, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0x4C, 0x4D, 0x54, +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x93, 0x37, 0x33, 0xAC, +0x01, 0xFF, 0xFF, 0xC6, 0x54, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0x4C, 0x4D, 0x54, 0x00, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0xD6, 0x32, 0x00, 0xB3, 0xB9, 0x1D, 0x00, 0x00, 0x00, 0x00, @@ -5741,9 +5739,10 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { 0xFB, 0xE8, 0x58, 0x00, 0x00, 0x01, 0x00, 0x01, 0x02, 0x01, 0x02, 0x01, 0x00, 0x01, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x00, 0xFF, 0xFF, 0x9D, 0x90, 0x00, 0x04, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x08, 0x4D, 0x44, 0x54, 0x00, 0x4D, 0x53, 0x54, 0x00, 0x4D, 0x57, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0xBC, 0x5E, 0x01, 0x00, 0x67, 0xA5, 0xDA, 0x00, 0x00, 0x00, 0x20, 0x4D, 0x6F, +0x00, 0x00, 0x00, 0xBC, 0x5E, 0x01, 0x00, 0x67, 0xA5, 0xDA, 0x00, 0x00, 0x00, 0x30, 0x4D, 0x6F, 0x75, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, -0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x41, 0x72, 0x69, 0x7A, 0x6F, 0x6E, 0x61, +0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x41, 0x72, 0x69, 0x7A, 0x6F, 0x6E, 0x61, 0x20, 0x28, +0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x20, 0x4E, 0x61, 0x76, 0x61, 0x6A, 0x6F, 0x29, /* America/Port-au-Prince */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x48, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -5785,7 +5784,7 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { /* America/Porto_Acre */ 0x50, 0x48, 0x50, 0x31, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x11, 0x96, 0xAA, 0x86, 0x90, +0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x11, 0x96, 0xAA, 0x86, 0x90, 0xB8, 0x0F, 0x66, 0x00, 0xB8, 0xFD, 0x5C, 0xC0, 0xB9, 0xF1, 0x50, 0x50, 0xBA, 0xDE, 0x90, 0x40, 0xDA, 0x38, 0xCA, 0x50, 0xDA, 0xEC, 0x16, 0x50, 0xDC, 0x19, 0xFD, 0xD0, 0xDC, 0xB9, 0x75, 0x40, 0xDD, 0xFB, 0x31, 0x50, 0xDE, 0x9B, 0xFA, 0x40, 0xDF, 0xDD, 0xB6, 0x50, 0xE0, 0x54, 0x4F, 0x40, @@ -5793,12 +5792,13 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { 0xF8, 0x51, 0x48, 0x50, 0xF8, 0xC7, 0xE1, 0x40, 0xFA, 0x0A, 0xEE, 0xD0, 0xFA, 0xA9, 0x14, 0xC0, 0xFB, 0xEC, 0x22, 0x50, 0xFC, 0x8B, 0x99, 0xC0, 0x1D, 0xC9, 0xAA, 0x50, 0x1E, 0x78, 0xF3, 0xC0, 0x1F, 0xA0, 0x51, 0xD0, 0x20, 0x33, 0xEB, 0xC0, 0x21, 0x81, 0x85, 0x50, 0x22, 0x0B, 0xE4, 0xC0, -0x48, 0x60, 0x7F, 0x50, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, +0x48, 0x60, 0x7F, 0x50, 0x52, 0x7F, 0x04, 0xC0, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, -0x02, 0x03, 0xFF, 0xFF, 0xC0, 0x70, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x04, 0xFF, 0xFF, -0xB9, 0xB0, 0x00, 0x09, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x0D, 0x4C, 0x4D, 0x54, 0x00, 0x41, 0x43, -0x53, 0x54, 0x00, 0x41, 0x43, 0x54, 0x00, 0x41, 0x4D, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x89, 0x54, 0x40, 0x01, 0x12, 0xA8, 0x80, 0x00, 0x00, 0x00, 0x00, +0x02, 0x01, 0x02, 0x01, 0x02, 0x03, 0x02, 0xFF, 0xFF, 0xC0, 0x70, 0x00, 0x00, 0xFF, 0xFF, 0xC7, +0xC0, 0x01, 0x04, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x09, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x0D, 0x4C, +0x4D, 0x54, 0x00, 0x41, 0x43, 0x53, 0x54, 0x00, 0x41, 0x43, 0x54, 0x00, 0x41, 0x4D, 0x54, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x54, 0x40, 0x01, 0x12, 0xA8, 0x80, +0x00, 0x00, 0x00, 0x00, /* America/Port_of_Spain */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x54, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -6042,7 +6042,7 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { /* America/Rio_Branco */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x42, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x11, 0x96, 0xAA, 0x86, 0x90, +0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x11, 0x96, 0xAA, 0x86, 0x90, 0xB8, 0x0F, 0x66, 0x00, 0xB8, 0xFD, 0x5C, 0xC0, 0xB9, 0xF1, 0x50, 0x50, 0xBA, 0xDE, 0x90, 0x40, 0xDA, 0x38, 0xCA, 0x50, 0xDA, 0xEC, 0x16, 0x50, 0xDC, 0x19, 0xFD, 0xD0, 0xDC, 0xB9, 0x75, 0x40, 0xDD, 0xFB, 0x31, 0x50, 0xDE, 0x9B, 0xFA, 0x40, 0xDF, 0xDD, 0xB6, 0x50, 0xE0, 0x54, 0x4F, 0x40, @@ -6050,13 +6050,13 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { 0xF8, 0x51, 0x48, 0x50, 0xF8, 0xC7, 0xE1, 0x40, 0xFA, 0x0A, 0xEE, 0xD0, 0xFA, 0xA9, 0x14, 0xC0, 0xFB, 0xEC, 0x22, 0x50, 0xFC, 0x8B, 0x99, 0xC0, 0x1D, 0xC9, 0xAA, 0x50, 0x1E, 0x78, 0xF3, 0xC0, 0x1F, 0xA0, 0x51, 0xD0, 0x20, 0x33, 0xEB, 0xC0, 0x21, 0x81, 0x85, 0x50, 0x22, 0x0B, 0xE4, 0xC0, -0x48, 0x60, 0x7F, 0x50, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, +0x48, 0x60, 0x7F, 0x50, 0x52, 0x7F, 0x04, 0xC0, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, -0x02, 0x03, 0xFF, 0xFF, 0xC0, 0x70, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x04, 0xFF, 0xFF, -0xB9, 0xB0, 0x00, 0x09, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x0D, 0x4C, 0x4D, 0x54, 0x00, 0x41, 0x43, -0x53, 0x54, 0x00, 0x41, 0x43, 0x54, 0x00, 0x41, 0x4D, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x7A, 0x1F, 0x05, 0x00, 0xAB, 0x34, 0x20, 0x00, 0x00, 0x00, 0x04, 0x41, -0x63, 0x72, 0x65, +0x02, 0x01, 0x02, 0x01, 0x02, 0x03, 0x02, 0xFF, 0xFF, 0xC0, 0x70, 0x00, 0x00, 0xFF, 0xFF, 0xC7, +0xC0, 0x01, 0x04, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x09, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x0D, 0x4C, +0x4D, 0x54, 0x00, 0x41, 0x43, 0x53, 0x54, 0x00, 0x41, 0x43, 0x54, 0x00, 0x41, 0x4D, 0x54, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7A, 0x1F, 0x05, 0x00, 0xAB, 0x34, 0x20, +0x00, 0x00, 0x00, 0x04, 0x41, 0x63, 0x72, 0x65, /* America/Rosario */ 0x50, 0x48, 0x50, 0x31, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -6344,7 +6344,7 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { 0x74, 0x6F, 0x71, 0x71, 0x6F, 0x72, 0x74, 0x6F, 0x6F, 0x72, 0x6D, 0x69, 0x69, 0x74, /* America/Shiprock */ -0x50, 0x48, 0x50, 0x31, 0x01, 0x55, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x50, 0x48, 0x50, 0x31, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9D, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x10, 0x9E, 0xA6, 0x3A, 0x90, 0x9F, 0xBB, 0x07, 0x80, 0xA0, 0x86, 0x1C, 0x90, 0xA1, 0x9A, 0xE9, 0x80, 0xA2, 0x65, 0xFE, 0x90, @@ -6398,9 +6398,8 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x00, 0xFF, 0xFF, 0x9D, 0x90, 0x00, 0x04, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x08, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x0C, 0x4D, 0x44, 0x54, 0x00, 0x4D, 0x53, 0x54, 0x00, 0x4D, 0x57, 0x54, -0x00, 0x4D, 0x50, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xC1, 0x75, -0x9B, 0x00, 0x6C, 0xD0, 0xE1, 0x00, 0x00, 0x00, 0x16, 0x4D, 0x6F, 0x75, 0x6E, 0x74, 0x61, 0x69, -0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x4E, 0x61, 0x76, 0x61, 0x6A, 0x6F, +0x00, 0x4D, 0x50, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x89, 0x54, +0x40, 0x01, 0x12, 0xA8, 0x80, 0x00, 0x00, 0x00, 0x00, /* America/Sitka */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x55, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -6464,8 +6463,8 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { /* America/St_Barthelemy */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x42, 0x4C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x91, 0xD5, 0xE1, 0xB0, -0x01, 0xFF, 0xFF, 0xC6, 0x50, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0x4C, 0x4D, 0x54, +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x93, 0x37, 0x33, 0xAC, +0x01, 0xFF, 0xFF, 0xC6, 0x54, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0x4C, 0x4D, 0x54, 0x00, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA4, 0x9D, 0xED, 0x00, 0xB2, 0xC1, 0xB8, 0x00, 0x00, 0x00, 0x00, @@ -6560,32 +6559,32 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { /* America/St_Kitts */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x4B, 0x4E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x93, 0x37, 0x34, 0xCC, -0x01, 0xFF, 0xFF, 0xC5, 0x34, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0x4C, 0x4D, 0x54, +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x93, 0x37, 0x33, 0xAC, +0x01, 0xFF, 0xFF, 0xC6, 0x54, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0x4C, 0x4D, 0x54, 0x00, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0xBA, 0x10, 0x00, 0xB2, 0xF5, 0xCD, 0x00, 0x00, 0x00, 0x00, /* America/St_Lucia */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x4C, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x92, 0xE6, 0xC7, 0xB0, -0x01, 0xFF, 0xFF, 0xC6, 0xD0, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0x43, 0x4D, 0x54, +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x93, 0x37, 0x33, 0xAC, +0x01, 0xFF, 0xFF, 0xC6, 0x54, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0x4C, 0x4D, 0x54, 0x00, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9E, 0xB7, 0x82, 0x00, 0xB5, 0x94, 0x60, 0x00, 0x00, 0x00, 0x00, /* America/St_Thomas */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x56, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x91, 0xF4, 0x37, 0x60, -0x01, 0xFF, 0xFF, 0xC3, 0x20, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0x4C, 0x4D, 0x54, +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x93, 0x37, 0x33, 0xAC, +0x01, 0xFF, 0xFF, 0xC6, 0x54, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0x4C, 0x4D, 0x54, 0x00, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA5, 0x54, 0x38, 0x00, 0xAF, 0x93, 0xEA, 0x00, 0x00, 0x00, 0x00, /* America/St_Vincent */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x56, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x92, 0xE6, 0xC7, 0xE8, -0x01, 0xFF, 0xFF, 0xC6, 0x98, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0x4B, 0x4D, 0x54, +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x93, 0x37, 0x33, 0xAC, +0x01, 0xFF, 0xFF, 0xC6, 0x54, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0x4C, 0x4D, 0x54, 0x00, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9D, 0x64, 0xF8, 0x00, 0xB5, 0x39, 0x3A, 0x00, 0x00, 0x00, 0x00, @@ -6853,16 +6852,17 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { 0x00, 0x01, 0x00, 0x01, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x00, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x04, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x08, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x0C, 0x45, 0x44, 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x45, 0x57, 0x54, 0x00, 0x45, 0x50, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, -0x00, 0x00, 0x00, 0x01, 0x00, 0xCB, 0xEF, 0x08, 0x00, 0x99, 0x87, 0x62, 0x00, 0x00, 0x00, 0x27, +0x00, 0x00, 0x00, 0x01, 0x00, 0xCB, 0xEF, 0x08, 0x00, 0x99, 0x87, 0x62, 0x00, 0x00, 0x00, 0x30, 0x45, 0x61, 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x4F, -0x6E, 0x74, 0x61, 0x72, 0x69, 0x6F, 0x20, 0x2D, 0x20, 0x6D, 0x6F, 0x73, 0x74, 0x20, 0x6C, 0x6F, -0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x73, +0x6E, 0x74, 0x61, 0x72, 0x69, 0x6F, 0x20, 0x26, 0x20, 0x51, 0x75, 0x65, 0x62, 0x65, 0x63, 0x20, +0x2D, 0x20, 0x6D, 0x6F, 0x73, 0x74, 0x20, 0x6C, 0x6F, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x73, + /* America/Tortola */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x56, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x91, 0xF4, 0x37, 0x14, -0x01, 0xFF, 0xFF, 0xC3, 0x6C, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0x4C, 0x4D, 0x54, +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x93, 0x37, 0x33, 0xAC, +0x01, 0xFF, 0xFF, 0xC6, 0x54, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0x4C, 0x4D, 0x54, 0x00, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA5, 0x7B, 0x48, 0x00, 0xB0, 0x0F, 0x9D, 0x00, 0x00, 0x00, 0x00, @@ -6939,8 +6939,8 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { /* America/Virgin */ 0x50, 0x48, 0x50, 0x31, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x91, 0xF4, 0x37, 0x60, -0x01, 0xFF, 0xFF, 0xC3, 0x20, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0x4C, 0x4D, 0x54, +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x93, 0x37, 0x33, 0xAC, +0x01, 0xFF, 0xFF, 0xC6, 0x54, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0x4C, 0x4D, 0x54, 0x00, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x54, 0x40, 0x01, 0x12, 0xA8, 0x80, 0x00, 0x00, 0x00, 0x00, @@ -7264,54 +7264,64 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { /* Antarctica/McMurdo */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x41, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0E, 0xE5, 0xA9, 0xE9, 0x00, -0x09, 0x18, 0xFD, 0xE0, 0x09, 0xAC, 0xA5, 0xE0, 0x0A, 0xEF, 0xA5, 0x60, 0x0B, 0x9E, 0xFC, 0xE0, -0x0C, 0xD8, 0xC1, 0xE0, 0x0D, 0x7E, 0xDE, 0xE0, 0x0E, 0xB8, 0xA3, 0xE0, 0x0F, 0x5E, 0xC0, 0xE0, -0x10, 0x98, 0x85, 0xE0, 0x11, 0x3E, 0xA2, 0xE0, 0x12, 0x78, 0x67, 0xE0, 0x13, 0x1E, 0x84, 0xE0, -0x14, 0x58, 0x49, 0xE0, 0x14, 0xFE, 0x66, 0xE0, 0x16, 0x38, 0x2B, 0xE0, 0x16, 0xE7, 0x83, 0x60, -0x18, 0x21, 0x48, 0x60, 0x18, 0xC7, 0x65, 0x60, 0x1A, 0x01, 0x2A, 0x60, 0x1A, 0xA7, 0x47, 0x60, -0x1B, 0xE1, 0x0C, 0x60, 0x1C, 0x87, 0x29, 0x60, 0x1D, 0xC0, 0xEE, 0x60, 0x1E, 0x67, 0x0B, 0x60, -0x1F, 0xA0, 0xD0, 0x60, 0x20, 0x46, 0xED, 0x60, 0x21, 0x80, 0xB2, 0x60, 0x22, 0x30, 0x09, 0xE0, -0x23, 0x69, 0xCE, 0xE0, 0x24, 0x0F, 0xEB, 0xE0, 0x25, 0x2E, 0x01, 0x60, 0x26, 0x02, 0x42, 0xE0, -0x27, 0x0D, 0xE3, 0x60, 0x27, 0xE2, 0x24, 0xE0, 0x28, 0xED, 0xC5, 0x60, 0x29, 0xC2, 0x06, 0xE0, -0x2A, 0xCD, 0xA7, 0x60, 0x2B, 0xAB, 0x23, 0x60, 0x2C, 0xAD, 0x89, 0x60, 0x2D, 0x8B, 0x05, 0x60, -0x2E, 0x8D, 0x6B, 0x60, 0x2F, 0x6A, 0xE7, 0x60, 0x30, 0x6D, 0x4D, 0x60, 0x31, 0x4A, 0xC9, 0x60, -0x32, 0x56, 0x69, 0xE0, 0x33, 0x2A, 0xAB, 0x60, 0x34, 0x36, 0x4B, 0xE0, 0x35, 0x0A, 0x8D, 0x60, -0x36, 0x16, 0x2D, 0xE0, 0x36, 0xF3, 0xA9, 0xE0, 0x37, 0xF6, 0x0F, 0xE0, 0x38, 0xD3, 0x8B, 0xE0, -0x39, 0xD5, 0xF1, 0xE0, 0x3A, 0xB3, 0x6D, 0xE0, 0x3B, 0xBF, 0x0E, 0x60, 0x3C, 0x93, 0x4F, 0xE0, -0x3D, 0x9E, 0xF0, 0x60, 0x3E, 0x73, 0x31, 0xE0, 0x3F, 0x7E, 0xD2, 0x60, 0x40, 0x5C, 0x4E, 0x60, -0x41, 0x5E, 0xB4, 0x60, 0x42, 0x3C, 0x30, 0x60, 0x43, 0x3E, 0x96, 0x60, 0x44, 0x1C, 0x12, 0x60, -0x45, 0x1E, 0x78, 0x60, 0x45, 0xFB, 0xF4, 0x60, 0x46, 0xFE, 0x5A, 0x60, 0x47, 0xF7, 0x85, 0xE0, -0x48, 0xDE, 0x3C, 0x60, 0x49, 0xD7, 0x67, 0xE0, 0x4A, 0xBE, 0x1E, 0x60, 0x4B, 0xB7, 0x49, 0xE0, -0x4C, 0x9E, 0x00, 0x60, 0x4D, 0x97, 0x2B, 0xE0, 0x4E, 0x7D, 0xE2, 0x60, 0x4F, 0x77, 0x0D, 0xE0, -0x50, 0x66, 0xFE, 0xE0, 0x51, 0x60, 0x2A, 0x60, 0x52, 0x46, 0xE0, 0xE0, 0x53, 0x40, 0x0C, 0x60, -0x54, 0x26, 0xC2, 0xE0, 0x55, 0x1F, 0xEE, 0x60, 0x56, 0x06, 0xA4, 0xE0, 0x56, 0xFF, 0xD0, 0x60, -0x57, 0xE6, 0x86, 0xE0, 0x58, 0xDF, 0xB2, 0x60, 0x59, 0xC6, 0x68, 0xE0, 0x5A, 0xBF, 0x94, 0x60, -0x5B, 0xAF, 0x85, 0x60, 0x5C, 0xA8, 0xB0, 0xE0, 0x5D, 0x8F, 0x67, 0x60, 0x5E, 0x88, 0x92, 0xE0, -0x5F, 0x6F, 0x49, 0x60, 0x60, 0x68, 0x74, 0xE0, 0x61, 0x4F, 0x2B, 0x60, 0x62, 0x48, 0x56, 0xE0, -0x63, 0x2F, 0x0D, 0x60, 0x64, 0x28, 0x38, 0xE0, 0x65, 0x0E, 0xEF, 0x60, 0x66, 0x11, 0x55, 0x60, -0x66, 0xF8, 0x0B, 0xE0, 0x67, 0xF1, 0x37, 0x60, 0x68, 0xD7, 0xED, 0xE0, 0x69, 0xD1, 0x19, 0x60, -0x6A, 0xB7, 0xCF, 0xE0, 0x6B, 0xB0, 0xFB, 0x60, 0x6C, 0x97, 0xB1, 0xE0, 0x6D, 0x90, 0xDD, 0x60, -0x6E, 0x77, 0x93, 0xE0, 0x6F, 0x70, 0xBF, 0x60, 0x70, 0x60, 0xB0, 0x60, 0x71, 0x59, 0xDB, 0xE0, -0x72, 0x40, 0x92, 0x60, 0x73, 0x39, 0xBD, 0xE0, 0x74, 0x20, 0x74, 0x60, 0x75, 0x19, 0x9F, 0xE0, -0x76, 0x00, 0x56, 0x60, 0x76, 0xF9, 0x81, 0xE0, 0x77, 0xE0, 0x38, 0x60, 0x78, 0xD9, 0x63, 0xE0, -0x79, 0xC0, 0x1A, 0x60, 0x7A, 0xB9, 0x45, 0xE0, 0x7B, 0xA9, 0x36, 0xE0, 0x7C, 0xA2, 0x62, 0x60, -0x7D, 0x89, 0x18, 0xE0, 0x7E, 0x82, 0x44, 0x60, 0x7F, 0x68, 0xFA, 0xE0, 0x03, 0x01, 0x02, 0x01, -0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, -0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, -0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, -0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, -0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, -0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x9B, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0F, 0xB0, 0xB4, 0xB2, 0xE8, +0xB1, 0x51, 0x87, 0x58, 0xB2, 0x78, 0xE5, 0x68, 0xB3, 0x43, 0xE5, 0x60, 0xB4, 0x58, 0xC7, 0x68, +0xB5, 0x23, 0xC7, 0x60, 0xB6, 0x38, 0xA9, 0x68, 0xB7, 0x03, 0xA9, 0x60, 0xB8, 0x18, 0x8B, 0x68, +0xB8, 0xEC, 0xC5, 0xE0, 0xB9, 0xF8, 0x6D, 0x68, 0xBA, 0xCC, 0xA7, 0xE0, 0xBB, 0xD8, 0x4F, 0x68, +0xBC, 0xE3, 0xE8, 0xE0, 0xBD, 0xAE, 0xF6, 0xE8, 0xBE, 0xC3, 0xCA, 0xE0, 0xBF, 0x8E, 0xD8, 0xE8, +0xC0, 0xA3, 0xAC, 0xE0, 0xC1, 0x6E, 0xBA, 0xE8, 0xC2, 0x83, 0x8E, 0xE0, 0xC3, 0x4E, 0x9C, 0xE8, +0xC4, 0x63, 0x70, 0xE0, 0xC5, 0x2E, 0x7E, 0xE8, 0xC6, 0x4C, 0x8D, 0x60, 0xC7, 0x0E, 0x60, 0xE8, +0xC8, 0x2C, 0x6F, 0x60, 0xC8, 0xF7, 0x7D, 0x68, 0xD2, 0xDA, 0x9A, 0x40, 0x09, 0x18, 0xFD, 0xE0, +0x09, 0xAC, 0xA5, 0xE0, 0x0A, 0xEF, 0xA5, 0x60, 0x0B, 0x9E, 0xFC, 0xE0, 0x0C, 0xD8, 0xC1, 0xE0, +0x0D, 0x7E, 0xDE, 0xE0, 0x0E, 0xB8, 0xA3, 0xE0, 0x0F, 0x5E, 0xC0, 0xE0, 0x10, 0x98, 0x85, 0xE0, +0x11, 0x3E, 0xA2, 0xE0, 0x12, 0x78, 0x67, 0xE0, 0x13, 0x1E, 0x84, 0xE0, 0x14, 0x58, 0x49, 0xE0, +0x14, 0xFE, 0x66, 0xE0, 0x16, 0x38, 0x2B, 0xE0, 0x16, 0xE7, 0x83, 0x60, 0x18, 0x21, 0x48, 0x60, +0x18, 0xC7, 0x65, 0x60, 0x1A, 0x01, 0x2A, 0x60, 0x1A, 0xA7, 0x47, 0x60, 0x1B, 0xE1, 0x0C, 0x60, +0x1C, 0x87, 0x29, 0x60, 0x1D, 0xC0, 0xEE, 0x60, 0x1E, 0x67, 0x0B, 0x60, 0x1F, 0xA0, 0xD0, 0x60, +0x20, 0x46, 0xED, 0x60, 0x21, 0x80, 0xB2, 0x60, 0x22, 0x30, 0x09, 0xE0, 0x23, 0x69, 0xCE, 0xE0, +0x24, 0x0F, 0xEB, 0xE0, 0x25, 0x2E, 0x01, 0x60, 0x26, 0x02, 0x42, 0xE0, 0x27, 0x0D, 0xE3, 0x60, +0x27, 0xE2, 0x24, 0xE0, 0x28, 0xED, 0xC5, 0x60, 0x29, 0xC2, 0x06, 0xE0, 0x2A, 0xCD, 0xA7, 0x60, +0x2B, 0xAB, 0x23, 0x60, 0x2C, 0xAD, 0x89, 0x60, 0x2D, 0x8B, 0x05, 0x60, 0x2E, 0x8D, 0x6B, 0x60, +0x2F, 0x6A, 0xE7, 0x60, 0x30, 0x6D, 0x4D, 0x60, 0x31, 0x4A, 0xC9, 0x60, 0x32, 0x56, 0x69, 0xE0, +0x33, 0x2A, 0xAB, 0x60, 0x34, 0x36, 0x4B, 0xE0, 0x35, 0x0A, 0x8D, 0x60, 0x36, 0x16, 0x2D, 0xE0, +0x36, 0xF3, 0xA9, 0xE0, 0x37, 0xF6, 0x0F, 0xE0, 0x38, 0xD3, 0x8B, 0xE0, 0x39, 0xD5, 0xF1, 0xE0, +0x3A, 0xB3, 0x6D, 0xE0, 0x3B, 0xBF, 0x0E, 0x60, 0x3C, 0x93, 0x4F, 0xE0, 0x3D, 0x9E, 0xF0, 0x60, +0x3E, 0x73, 0x31, 0xE0, 0x3F, 0x7E, 0xD2, 0x60, 0x40, 0x5C, 0x4E, 0x60, 0x41, 0x5E, 0xB4, 0x60, +0x42, 0x3C, 0x30, 0x60, 0x43, 0x3E, 0x96, 0x60, 0x44, 0x1C, 0x12, 0x60, 0x45, 0x1E, 0x78, 0x60, +0x45, 0xFB, 0xF4, 0x60, 0x46, 0xFE, 0x5A, 0x60, 0x47, 0xF7, 0x85, 0xE0, 0x48, 0xDE, 0x3C, 0x60, +0x49, 0xD7, 0x67, 0xE0, 0x4A, 0xBE, 0x1E, 0x60, 0x4B, 0xB7, 0x49, 0xE0, 0x4C, 0x9E, 0x00, 0x60, +0x4D, 0x97, 0x2B, 0xE0, 0x4E, 0x7D, 0xE2, 0x60, 0x4F, 0x77, 0x0D, 0xE0, 0x50, 0x66, 0xFE, 0xE0, +0x51, 0x60, 0x2A, 0x60, 0x52, 0x46, 0xE0, 0xE0, 0x53, 0x40, 0x0C, 0x60, 0x54, 0x26, 0xC2, 0xE0, +0x55, 0x1F, 0xEE, 0x60, 0x56, 0x06, 0xA4, 0xE0, 0x56, 0xFF, 0xD0, 0x60, 0x57, 0xE6, 0x86, 0xE0, +0x58, 0xDF, 0xB2, 0x60, 0x59, 0xC6, 0x68, 0xE0, 0x5A, 0xBF, 0x94, 0x60, 0x5B, 0xAF, 0x85, 0x60, +0x5C, 0xA8, 0xB0, 0xE0, 0x5D, 0x8F, 0x67, 0x60, 0x5E, 0x88, 0x92, 0xE0, 0x5F, 0x6F, 0x49, 0x60, +0x60, 0x68, 0x74, 0xE0, 0x61, 0x4F, 0x2B, 0x60, 0x62, 0x48, 0x56, 0xE0, 0x63, 0x2F, 0x0D, 0x60, +0x64, 0x28, 0x38, 0xE0, 0x65, 0x0E, 0xEF, 0x60, 0x66, 0x11, 0x55, 0x60, 0x66, 0xF8, 0x0B, 0xE0, +0x67, 0xF1, 0x37, 0x60, 0x68, 0xD7, 0xED, 0xE0, 0x69, 0xD1, 0x19, 0x60, 0x6A, 0xB7, 0xCF, 0xE0, +0x6B, 0xB0, 0xFB, 0x60, 0x6C, 0x97, 0xB1, 0xE0, 0x6D, 0x90, 0xDD, 0x60, 0x6E, 0x77, 0x93, 0xE0, +0x6F, 0x70, 0xBF, 0x60, 0x70, 0x60, 0xB0, 0x60, 0x71, 0x59, 0xDB, 0xE0, 0x72, 0x40, 0x92, 0x60, +0x73, 0x39, 0xBD, 0xE0, 0x74, 0x20, 0x74, 0x60, 0x75, 0x19, 0x9F, 0xE0, 0x76, 0x00, 0x56, 0x60, +0x76, 0xF9, 0x81, 0xE0, 0x77, 0xE0, 0x38, 0x60, 0x78, 0xD9, 0x63, 0xE0, 0x79, 0xC0, 0x1A, 0x60, +0x7A, 0xB9, 0x45, 0xE0, 0x7B, 0xA9, 0x36, 0xE0, 0x7C, 0xA2, 0x62, 0x60, 0x7D, 0x89, 0x18, 0xE0, +0x7E, 0x82, 0x44, 0x60, 0x7F, 0x68, 0xFA, 0xE0, 0x00, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, -0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xB6, 0xD0, 0x01, 0x04, 0x00, 0x00, 0xA8, 0xC0, 0x00, 0x09, 0x00, 0x00, -0xA8, 0xC0, 0x00, 0x09, 0x7A, 0x7A, 0x7A, 0x00, 0x4E, 0x5A, 0x44, 0x54, 0x00, 0x4E, 0x5A, 0x53, -0x54, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x90, 0x9A, 0x02, 0x10, -0xDE, 0xA0, 0x00, 0x00, 0x00, 0x1C, 0x4D, 0x63, 0x4D, 0x75, 0x72, 0x64, 0x6F, 0x20, 0x53, 0x74, -0x61, 0x74, 0x69, 0x6F, 0x6E, 0x2C, 0x20, 0x52, 0x6F, 0x73, 0x73, 0x20, 0x49, 0x73, 0x6C, 0x61, -0x6E, 0x64, +0x02, 0x01, 0x02, 0x05, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, +0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, +0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, +0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, +0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, +0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, +0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, +0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, +0x03, 0x04, 0x03, 0x00, 0x00, 0xAF, 0xC8, 0x01, 0x00, 0x00, 0x00, 0xA1, 0xB8, 0x00, 0x05, 0x00, +0x00, 0xA8, 0xC0, 0x01, 0x00, 0x00, 0x00, 0xB6, 0xD0, 0x01, 0x0A, 0x00, 0x00, 0xA8, 0xC0, 0x00, +0x00, 0x00, 0x00, 0xA8, 0xC0, 0x00, 0x00, 0x4E, 0x5A, 0x53, 0x54, 0x00, 0x4E, 0x5A, 0x4D, 0x54, +0x00, 0x4E, 0x5A, 0x44, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x12, 0x90, 0x9A, 0x02, 0x10, 0xDE, 0xA0, 0x00, 0x00, 0x00, 0x2D, 0x4D, 0x63, +0x4D, 0x75, 0x72, 0x64, 0x6F, 0x2C, 0x20, 0x53, 0x6F, 0x75, 0x74, 0x68, 0x20, 0x50, 0x6F, 0x6C, +0x65, 0x2C, 0x20, 0x53, 0x63, 0x6F, 0x74, 0x74, 0x20, 0x28, 0x4E, 0x65, 0x77, 0x20, 0x5A, 0x65, +0x61, 0x6C, 0x61, 0x6E, 0x64, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x29, /* Antarctica/Palmer */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x41, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -7376,55 +7386,62 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { 0x49, 0x73, 0x6C, 0x61, 0x6E, 0x64, /* Antarctica/South_Pole */ -0x50, 0x48, 0x50, 0x31, 0x01, 0x41, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0E, 0xE5, 0xA9, 0xE9, 0x00, -0x09, 0x18, 0xFD, 0xE0, 0x09, 0xAC, 0xA5, 0xE0, 0x0A, 0xEF, 0xA5, 0x60, 0x0B, 0x9E, 0xFC, 0xE0, -0x0C, 0xD8, 0xC1, 0xE0, 0x0D, 0x7E, 0xDE, 0xE0, 0x0E, 0xB8, 0xA3, 0xE0, 0x0F, 0x5E, 0xC0, 0xE0, -0x10, 0x98, 0x85, 0xE0, 0x11, 0x3E, 0xA2, 0xE0, 0x12, 0x78, 0x67, 0xE0, 0x13, 0x1E, 0x84, 0xE0, -0x14, 0x58, 0x49, 0xE0, 0x14, 0xFE, 0x66, 0xE0, 0x16, 0x38, 0x2B, 0xE0, 0x16, 0xE7, 0x83, 0x60, -0x18, 0x21, 0x48, 0x60, 0x18, 0xC7, 0x65, 0x60, 0x1A, 0x01, 0x2A, 0x60, 0x1A, 0xA7, 0x47, 0x60, -0x1B, 0xE1, 0x0C, 0x60, 0x1C, 0x87, 0x29, 0x60, 0x1D, 0xC0, 0xEE, 0x60, 0x1E, 0x67, 0x0B, 0x60, -0x1F, 0xA0, 0xD0, 0x60, 0x20, 0x46, 0xED, 0x60, 0x21, 0x80, 0xB2, 0x60, 0x22, 0x30, 0x09, 0xE0, -0x23, 0x69, 0xCE, 0xE0, 0x24, 0x0F, 0xEB, 0xE0, 0x25, 0x2E, 0x01, 0x60, 0x26, 0x02, 0x42, 0xE0, -0x27, 0x0D, 0xE3, 0x60, 0x27, 0xE2, 0x24, 0xE0, 0x28, 0xED, 0xC5, 0x60, 0x29, 0xC2, 0x06, 0xE0, -0x2A, 0xCD, 0xA7, 0x60, 0x2B, 0xAB, 0x23, 0x60, 0x2C, 0xAD, 0x89, 0x60, 0x2D, 0x8B, 0x05, 0x60, -0x2E, 0x8D, 0x6B, 0x60, 0x2F, 0x6A, 0xE7, 0x60, 0x30, 0x6D, 0x4D, 0x60, 0x31, 0x4A, 0xC9, 0x60, -0x32, 0x56, 0x69, 0xE0, 0x33, 0x2A, 0xAB, 0x60, 0x34, 0x36, 0x4B, 0xE0, 0x35, 0x0A, 0x8D, 0x60, -0x36, 0x16, 0x2D, 0xE0, 0x36, 0xF3, 0xA9, 0xE0, 0x37, 0xF6, 0x0F, 0xE0, 0x38, 0xD3, 0x8B, 0xE0, -0x39, 0xD5, 0xF1, 0xE0, 0x3A, 0xB3, 0x6D, 0xE0, 0x3B, 0xBF, 0x0E, 0x60, 0x3C, 0x93, 0x4F, 0xE0, -0x3D, 0x9E, 0xF0, 0x60, 0x3E, 0x73, 0x31, 0xE0, 0x3F, 0x7E, 0xD2, 0x60, 0x40, 0x5C, 0x4E, 0x60, -0x41, 0x5E, 0xB4, 0x60, 0x42, 0x3C, 0x30, 0x60, 0x43, 0x3E, 0x96, 0x60, 0x44, 0x1C, 0x12, 0x60, -0x45, 0x1E, 0x78, 0x60, 0x45, 0xFB, 0xF4, 0x60, 0x46, 0xFE, 0x5A, 0x60, 0x47, 0xF7, 0x85, 0xE0, -0x48, 0xDE, 0x3C, 0x60, 0x49, 0xD7, 0x67, 0xE0, 0x4A, 0xBE, 0x1E, 0x60, 0x4B, 0xB7, 0x49, 0xE0, -0x4C, 0x9E, 0x00, 0x60, 0x4D, 0x97, 0x2B, 0xE0, 0x4E, 0x7D, 0xE2, 0x60, 0x4F, 0x77, 0x0D, 0xE0, -0x50, 0x66, 0xFE, 0xE0, 0x51, 0x60, 0x2A, 0x60, 0x52, 0x46, 0xE0, 0xE0, 0x53, 0x40, 0x0C, 0x60, -0x54, 0x26, 0xC2, 0xE0, 0x55, 0x1F, 0xEE, 0x60, 0x56, 0x06, 0xA4, 0xE0, 0x56, 0xFF, 0xD0, 0x60, -0x57, 0xE6, 0x86, 0xE0, 0x58, 0xDF, 0xB2, 0x60, 0x59, 0xC6, 0x68, 0xE0, 0x5A, 0xBF, 0x94, 0x60, -0x5B, 0xAF, 0x85, 0x60, 0x5C, 0xA8, 0xB0, 0xE0, 0x5D, 0x8F, 0x67, 0x60, 0x5E, 0x88, 0x92, 0xE0, -0x5F, 0x6F, 0x49, 0x60, 0x60, 0x68, 0x74, 0xE0, 0x61, 0x4F, 0x2B, 0x60, 0x62, 0x48, 0x56, 0xE0, -0x63, 0x2F, 0x0D, 0x60, 0x64, 0x28, 0x38, 0xE0, 0x65, 0x0E, 0xEF, 0x60, 0x66, 0x11, 0x55, 0x60, -0x66, 0xF8, 0x0B, 0xE0, 0x67, 0xF1, 0x37, 0x60, 0x68, 0xD7, 0xED, 0xE0, 0x69, 0xD1, 0x19, 0x60, -0x6A, 0xB7, 0xCF, 0xE0, 0x6B, 0xB0, 0xFB, 0x60, 0x6C, 0x97, 0xB1, 0xE0, 0x6D, 0x90, 0xDD, 0x60, -0x6E, 0x77, 0x93, 0xE0, 0x6F, 0x70, 0xBF, 0x60, 0x70, 0x60, 0xB0, 0x60, 0x71, 0x59, 0xDB, 0xE0, -0x72, 0x40, 0x92, 0x60, 0x73, 0x39, 0xBD, 0xE0, 0x74, 0x20, 0x74, 0x60, 0x75, 0x19, 0x9F, 0xE0, -0x76, 0x00, 0x56, 0x60, 0x76, 0xF9, 0x81, 0xE0, 0x77, 0xE0, 0x38, 0x60, 0x78, 0xD9, 0x63, 0xE0, -0x79, 0xC0, 0x1A, 0x60, 0x7A, 0xB9, 0x45, 0xE0, 0x7B, 0xA9, 0x36, 0xE0, 0x7C, 0xA2, 0x62, 0x60, -0x7D, 0x89, 0x18, 0xE0, 0x7E, 0x82, 0x44, 0x60, 0x7F, 0x68, 0xFA, 0xE0, 0x03, 0x01, 0x02, 0x01, -0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, -0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, -0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, -0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, -0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, -0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, +0x50, 0x48, 0x50, 0x31, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x9B, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0F, 0xB0, 0xB4, 0xB2, 0xE8, +0xB1, 0x51, 0x87, 0x58, 0xB2, 0x78, 0xE5, 0x68, 0xB3, 0x43, 0xE5, 0x60, 0xB4, 0x58, 0xC7, 0x68, +0xB5, 0x23, 0xC7, 0x60, 0xB6, 0x38, 0xA9, 0x68, 0xB7, 0x03, 0xA9, 0x60, 0xB8, 0x18, 0x8B, 0x68, +0xB8, 0xEC, 0xC5, 0xE0, 0xB9, 0xF8, 0x6D, 0x68, 0xBA, 0xCC, 0xA7, 0xE0, 0xBB, 0xD8, 0x4F, 0x68, +0xBC, 0xE3, 0xE8, 0xE0, 0xBD, 0xAE, 0xF6, 0xE8, 0xBE, 0xC3, 0xCA, 0xE0, 0xBF, 0x8E, 0xD8, 0xE8, +0xC0, 0xA3, 0xAC, 0xE0, 0xC1, 0x6E, 0xBA, 0xE8, 0xC2, 0x83, 0x8E, 0xE0, 0xC3, 0x4E, 0x9C, 0xE8, +0xC4, 0x63, 0x70, 0xE0, 0xC5, 0x2E, 0x7E, 0xE8, 0xC6, 0x4C, 0x8D, 0x60, 0xC7, 0x0E, 0x60, 0xE8, +0xC8, 0x2C, 0x6F, 0x60, 0xC8, 0xF7, 0x7D, 0x68, 0xD2, 0xDA, 0x9A, 0x40, 0x09, 0x18, 0xFD, 0xE0, +0x09, 0xAC, 0xA5, 0xE0, 0x0A, 0xEF, 0xA5, 0x60, 0x0B, 0x9E, 0xFC, 0xE0, 0x0C, 0xD8, 0xC1, 0xE0, +0x0D, 0x7E, 0xDE, 0xE0, 0x0E, 0xB8, 0xA3, 0xE0, 0x0F, 0x5E, 0xC0, 0xE0, 0x10, 0x98, 0x85, 0xE0, +0x11, 0x3E, 0xA2, 0xE0, 0x12, 0x78, 0x67, 0xE0, 0x13, 0x1E, 0x84, 0xE0, 0x14, 0x58, 0x49, 0xE0, +0x14, 0xFE, 0x66, 0xE0, 0x16, 0x38, 0x2B, 0xE0, 0x16, 0xE7, 0x83, 0x60, 0x18, 0x21, 0x48, 0x60, +0x18, 0xC7, 0x65, 0x60, 0x1A, 0x01, 0x2A, 0x60, 0x1A, 0xA7, 0x47, 0x60, 0x1B, 0xE1, 0x0C, 0x60, +0x1C, 0x87, 0x29, 0x60, 0x1D, 0xC0, 0xEE, 0x60, 0x1E, 0x67, 0x0B, 0x60, 0x1F, 0xA0, 0xD0, 0x60, +0x20, 0x46, 0xED, 0x60, 0x21, 0x80, 0xB2, 0x60, 0x22, 0x30, 0x09, 0xE0, 0x23, 0x69, 0xCE, 0xE0, +0x24, 0x0F, 0xEB, 0xE0, 0x25, 0x2E, 0x01, 0x60, 0x26, 0x02, 0x42, 0xE0, 0x27, 0x0D, 0xE3, 0x60, +0x27, 0xE2, 0x24, 0xE0, 0x28, 0xED, 0xC5, 0x60, 0x29, 0xC2, 0x06, 0xE0, 0x2A, 0xCD, 0xA7, 0x60, +0x2B, 0xAB, 0x23, 0x60, 0x2C, 0xAD, 0x89, 0x60, 0x2D, 0x8B, 0x05, 0x60, 0x2E, 0x8D, 0x6B, 0x60, +0x2F, 0x6A, 0xE7, 0x60, 0x30, 0x6D, 0x4D, 0x60, 0x31, 0x4A, 0xC9, 0x60, 0x32, 0x56, 0x69, 0xE0, +0x33, 0x2A, 0xAB, 0x60, 0x34, 0x36, 0x4B, 0xE0, 0x35, 0x0A, 0x8D, 0x60, 0x36, 0x16, 0x2D, 0xE0, +0x36, 0xF3, 0xA9, 0xE0, 0x37, 0xF6, 0x0F, 0xE0, 0x38, 0xD3, 0x8B, 0xE0, 0x39, 0xD5, 0xF1, 0xE0, +0x3A, 0xB3, 0x6D, 0xE0, 0x3B, 0xBF, 0x0E, 0x60, 0x3C, 0x93, 0x4F, 0xE0, 0x3D, 0x9E, 0xF0, 0x60, +0x3E, 0x73, 0x31, 0xE0, 0x3F, 0x7E, 0xD2, 0x60, 0x40, 0x5C, 0x4E, 0x60, 0x41, 0x5E, 0xB4, 0x60, +0x42, 0x3C, 0x30, 0x60, 0x43, 0x3E, 0x96, 0x60, 0x44, 0x1C, 0x12, 0x60, 0x45, 0x1E, 0x78, 0x60, +0x45, 0xFB, 0xF4, 0x60, 0x46, 0xFE, 0x5A, 0x60, 0x47, 0xF7, 0x85, 0xE0, 0x48, 0xDE, 0x3C, 0x60, +0x49, 0xD7, 0x67, 0xE0, 0x4A, 0xBE, 0x1E, 0x60, 0x4B, 0xB7, 0x49, 0xE0, 0x4C, 0x9E, 0x00, 0x60, +0x4D, 0x97, 0x2B, 0xE0, 0x4E, 0x7D, 0xE2, 0x60, 0x4F, 0x77, 0x0D, 0xE0, 0x50, 0x66, 0xFE, 0xE0, +0x51, 0x60, 0x2A, 0x60, 0x52, 0x46, 0xE0, 0xE0, 0x53, 0x40, 0x0C, 0x60, 0x54, 0x26, 0xC2, 0xE0, +0x55, 0x1F, 0xEE, 0x60, 0x56, 0x06, 0xA4, 0xE0, 0x56, 0xFF, 0xD0, 0x60, 0x57, 0xE6, 0x86, 0xE0, +0x58, 0xDF, 0xB2, 0x60, 0x59, 0xC6, 0x68, 0xE0, 0x5A, 0xBF, 0x94, 0x60, 0x5B, 0xAF, 0x85, 0x60, +0x5C, 0xA8, 0xB0, 0xE0, 0x5D, 0x8F, 0x67, 0x60, 0x5E, 0x88, 0x92, 0xE0, 0x5F, 0x6F, 0x49, 0x60, +0x60, 0x68, 0x74, 0xE0, 0x61, 0x4F, 0x2B, 0x60, 0x62, 0x48, 0x56, 0xE0, 0x63, 0x2F, 0x0D, 0x60, +0x64, 0x28, 0x38, 0xE0, 0x65, 0x0E, 0xEF, 0x60, 0x66, 0x11, 0x55, 0x60, 0x66, 0xF8, 0x0B, 0xE0, +0x67, 0xF1, 0x37, 0x60, 0x68, 0xD7, 0xED, 0xE0, 0x69, 0xD1, 0x19, 0x60, 0x6A, 0xB7, 0xCF, 0xE0, +0x6B, 0xB0, 0xFB, 0x60, 0x6C, 0x97, 0xB1, 0xE0, 0x6D, 0x90, 0xDD, 0x60, 0x6E, 0x77, 0x93, 0xE0, +0x6F, 0x70, 0xBF, 0x60, 0x70, 0x60, 0xB0, 0x60, 0x71, 0x59, 0xDB, 0xE0, 0x72, 0x40, 0x92, 0x60, +0x73, 0x39, 0xBD, 0xE0, 0x74, 0x20, 0x74, 0x60, 0x75, 0x19, 0x9F, 0xE0, 0x76, 0x00, 0x56, 0x60, +0x76, 0xF9, 0x81, 0xE0, 0x77, 0xE0, 0x38, 0x60, 0x78, 0xD9, 0x63, 0xE0, 0x79, 0xC0, 0x1A, 0x60, +0x7A, 0xB9, 0x45, 0xE0, 0x7B, 0xA9, 0x36, 0xE0, 0x7C, 0xA2, 0x62, 0x60, 0x7D, 0x89, 0x18, 0xE0, +0x7E, 0x82, 0x44, 0x60, 0x7F, 0x68, 0xFA, 0xE0, 0x00, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, -0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xB6, 0xD0, 0x01, 0x04, 0x00, 0x00, 0xA8, 0xC0, 0x00, 0x09, 0x00, 0x00, -0xA8, 0xC0, 0x00, 0x09, 0x7A, 0x7A, 0x7A, 0x00, 0x4E, 0x5A, 0x44, 0x54, 0x00, 0x4E, 0x5A, 0x53, -0x54, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x12, -0xA8, 0x80, 0x00, 0x00, 0x00, 0x22, 0x41, 0x6D, 0x75, 0x6E, 0x64, 0x73, 0x65, 0x6E, 0x2D, 0x53, -0x63, 0x6F, 0x74, 0x74, 0x20, 0x53, 0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x2C, 0x20, 0x53, 0x6F, -0x75, 0x74, 0x68, 0x20, 0x50, 0x6F, 0x6C, 0x65, +0x02, 0x01, 0x02, 0x05, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, +0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, +0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, +0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, +0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, +0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, +0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, +0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, +0x03, 0x04, 0x03, 0x00, 0x00, 0xAF, 0xC8, 0x01, 0x00, 0x00, 0x00, 0xA1, 0xB8, 0x00, 0x05, 0x00, +0x00, 0xA8, 0xC0, 0x01, 0x00, 0x00, 0x00, 0xB6, 0xD0, 0x01, 0x0A, 0x00, 0x00, 0xA8, 0xC0, 0x00, +0x00, 0x00, 0x00, 0xA8, 0xC0, 0x00, 0x00, 0x4E, 0x5A, 0x53, 0x54, 0x00, 0x4E, 0x5A, 0x4D, 0x54, +0x00, 0x4E, 0x5A, 0x44, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x89, 0x54, 0x40, 0x01, 0x12, 0xA8, 0x80, 0x00, 0x00, 0x00, 0x00, /* Antarctica/Syowa */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x41, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -7553,7 +7570,7 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { 0x42, 0x4C, 0x72, 0xE0, 0x43, 0x3C, 0x63, 0xE0, 0x44, 0x2C, 0x54, 0xE0, 0x45, 0x41, 0x2F, 0xE0, 0x46, 0x0C, 0x36, 0xE0, 0x47, 0x21, 0x11, 0xE0, 0x47, 0xEC, 0x18, 0xE0, 0x49, 0x0A, 0x2E, 0x60, 0x49, 0xCB, 0xFA, 0xE0, 0x4A, 0xEA, 0x10, 0x60, 0x4B, 0xAB, 0xDC, 0xE0, 0x4C, 0xC9, 0xF2, 0x60, -0x4D, 0x94, 0xF9, 0x60, 0x4E, 0xA9, 0xD4, 0x60, 0x4F, 0x74, 0xDB, 0x60, 0x52, 0x69, 0x98, 0x60, +0x4D, 0x94, 0xF9, 0x60, 0x4E, 0xA9, 0xD4, 0x60, 0x4F, 0x74, 0xDB, 0x60, 0x52, 0xB3, 0x5E, 0x50, 0x53, 0x34, 0x9F, 0x60, 0x54, 0x52, 0xB4, 0xE0, 0x55, 0x14, 0x81, 0x60, 0x56, 0x32, 0x96, 0xE0, 0x56, 0xFD, 0x9D, 0xE0, 0x58, 0x12, 0x78, 0xE0, 0x58, 0xDD, 0x7F, 0xE0, 0x59, 0xF2, 0x5A, 0xE0, 0x5A, 0xBD, 0x61, 0xE0, 0x5B, 0xD2, 0x3C, 0xE0, 0x5C, 0x9D, 0x43, 0xE0, 0x5D, 0xB2, 0x1E, 0xE0, @@ -7570,7 +7587,7 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x03, 0x01, 0x03, 0x01, 0x03, 0x01, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x01, 0x03, 0x01, 0x03, 0x01, 0x03, 0x01, 0x03, 0x01, 0x03, 0x01, 0x03, 0x01, 0x03, 0x01, 0x03, 0x01, -0x03, 0x01, 0x03, 0x01, 0x03, 0x01, 0x03, 0x01, 0x03, 0x01, 0x03, 0x01, 0x03, 0x01, 0x03, 0x01, +0x03, 0x01, 0x03, 0x01, 0x02, 0x01, 0x03, 0x01, 0x03, 0x01, 0x03, 0x01, 0x03, 0x01, 0x03, 0x01, 0x03, 0x01, 0x03, 0x01, 0x03, 0x01, 0x03, 0x01, 0x03, 0x01, 0x03, 0x01, 0x03, 0x01, 0x03, 0x01, 0x03, 0x01, 0x03, 0x01, 0x03, 0x01, 0x03, 0x01, 0x03, 0x01, 0x03, 0x01, 0x03, 0x01, 0x03, 0x01, 0x03, 0x01, 0x03, 0x01, 0x03, 0x00, 0x00, 0x21, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x30, 0x01, @@ -8060,13 +8077,13 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { /* Asia/Dili */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x54, 0x4C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x10, 0x92, 0xE6, 0x18, 0xC4, +0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x11, 0x92, 0xE6, 0x18, 0xC4, 0xCB, 0x99, 0x32, 0xF0, 0xD2, 0x56, 0xEE, 0x70, 0x0B, 0xEA, 0x30, 0x70, 0x39, 0xC3, 0x99, 0x00, 0x01, 0x02, 0x03, 0x04, 0x03, 0x00, 0x00, 0x75, 0xBC, 0x00, 0x00, 0x00, 0x00, 0x70, 0x80, 0x00, 0x04, 0x00, 0x00, 0x7E, 0x90, 0x00, 0x08, 0x00, 0x00, 0x7E, 0x90, 0x00, 0x04, 0x00, 0x00, 0x70, -0x80, 0x00, 0x0C, 0x4C, 0x4D, 0x54, 0x00, 0x54, 0x4C, 0x54, 0x00, 0x4A, 0x53, 0x54, 0x00, 0x43, -0x49, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x48, -0x68, 0x01, 0xD2, 0x48, 0x7D, 0x00, 0x00, 0x00, 0x00, +0x80, 0x00, 0x0C, 0x4C, 0x4D, 0x54, 0x00, 0x54, 0x4C, 0x54, 0x00, 0x4A, 0x53, 0x54, 0x00, 0x57, +0x49, 0x54, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, +0x48, 0x68, 0x01, 0xD2, 0x48, 0x7D, 0x00, 0x00, 0x00, 0x00, /* Asia/Dubai */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x41, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -8122,19 +8139,19 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { 0x45, 0x12, 0xFD, 0x50, 0x46, 0x0E, 0xD9, 0xE0, 0x46, 0xE8, 0x6F, 0x70, 0x47, 0xEC, 0x18, 0xE0, 0x48, 0xB7, 0x11, 0xD0, 0x49, 0xCB, 0xFA, 0xE0, 0x4A, 0xA0, 0x3C, 0x60, 0x4B, 0xAD, 0x2E, 0x9C, 0x4C, 0x61, 0xBD, 0xD0, 0x4D, 0x94, 0xF9, 0x9C, 0x4E, 0x35, 0xC2, 0x50, 0x4F, 0x74, 0xDB, 0x60, -0x50, 0x5B, 0x91, 0xE0, 0x51, 0x54, 0xBD, 0x60, 0x52, 0x44, 0xAE, 0x60, 0x53, 0x34, 0x9F, 0x60, -0x54, 0x24, 0x90, 0x60, 0x55, 0x14, 0x81, 0x60, 0x56, 0x04, 0x72, 0x60, 0x56, 0xFD, 0x9D, 0xE0, -0x57, 0xE4, 0x54, 0x60, 0x58, 0xDD, 0x7F, 0xE0, 0x59, 0xC4, 0x36, 0x60, 0x5A, 0xBD, 0x61, 0xE0, -0x5B, 0xA4, 0x18, 0x60, 0x5C, 0x9D, 0x43, 0xE0, 0x5D, 0x8D, 0x34, 0xE0, 0x5E, 0x7D, 0x25, 0xE0, -0x5F, 0x6D, 0x16, 0xE0, 0x60, 0x5D, 0x07, 0xE0, 0x61, 0x4C, 0xF8, 0xE0, 0x62, 0x46, 0x24, 0x60, -0x63, 0x2C, 0xDA, 0xE0, 0x64, 0x26, 0x06, 0x60, 0x65, 0x0C, 0xBC, 0xE0, 0x66, 0x05, 0xE8, 0x60, -0x66, 0xF5, 0xD9, 0x60, 0x67, 0xE5, 0xCA, 0x60, 0x68, 0xD5, 0xBB, 0x60, 0x69, 0xC5, 0xAC, 0x60, -0x6A, 0xB5, 0x9D, 0x60, 0x6B, 0xA5, 0x8E, 0x60, 0x6C, 0x95, 0x7F, 0x60, 0x6D, 0x8E, 0xAA, 0xE0, -0x6E, 0x75, 0x61, 0x60, 0x6F, 0x6E, 0x8C, 0xE0, 0x70, 0x55, 0x43, 0x60, 0x71, 0x4E, 0x6E, 0xE0, -0x72, 0x3E, 0x5F, 0xE0, 0x73, 0x2E, 0x50, 0xE0, 0x74, 0x1E, 0x41, 0xE0, 0x75, 0x0E, 0x32, 0xE0, -0x75, 0xFE, 0x23, 0xE0, 0x76, 0xF7, 0x4F, 0x60, 0x77, 0xDE, 0x05, 0xE0, 0x78, 0xD7, 0x31, 0x60, -0x79, 0xBD, 0xE7, 0xE0, 0x7A, 0xB7, 0x13, 0x60, 0x7B, 0x9D, 0xC9, 0xE0, 0x7C, 0x96, 0xF5, 0x60, -0x7D, 0x86, 0xE6, 0x60, 0x7E, 0x76, 0xD7, 0x60, 0x7F, 0x66, 0xC8, 0x60, 0x00, 0x01, 0x00, 0x01, +0x50, 0x5B, 0x91, 0xE0, 0x51, 0x54, 0xBD, 0x60, 0x52, 0x44, 0xA0, 0x50, 0x53, 0x34, 0x9F, 0x60, +0x54, 0x24, 0x82, 0x50, 0x55, 0x14, 0x81, 0x60, 0x56, 0x04, 0x64, 0x50, 0x56, 0xFD, 0x9D, 0xE0, +0x57, 0xE4, 0x46, 0x50, 0x58, 0xDD, 0x7F, 0xE0, 0x59, 0xC4, 0x28, 0x50, 0x5A, 0xBD, 0x61, 0xE0, +0x5B, 0xA4, 0x0A, 0x50, 0x5C, 0x9D, 0x43, 0xE0, 0x5D, 0x8D, 0x26, 0xD0, 0x5E, 0x7D, 0x25, 0xE0, +0x5F, 0x6D, 0x08, 0xD0, 0x60, 0x5D, 0x07, 0xE0, 0x61, 0x4C, 0xEA, 0xD0, 0x62, 0x46, 0x24, 0x60, +0x63, 0x2C, 0xCC, 0xD0, 0x64, 0x26, 0x06, 0x60, 0x65, 0x0C, 0xAE, 0xD0, 0x66, 0x05, 0xE8, 0x60, +0x66, 0xF5, 0xCB, 0x50, 0x67, 0xE5, 0xCA, 0x60, 0x68, 0xD5, 0xAD, 0x50, 0x69, 0xC5, 0xAC, 0x60, +0x6A, 0xB5, 0x8F, 0x50, 0x6B, 0xA5, 0x8E, 0x60, 0x6C, 0x95, 0x71, 0x50, 0x6D, 0x8E, 0xAA, 0xE0, +0x6E, 0x75, 0x53, 0x50, 0x6F, 0x6E, 0x8C, 0xE0, 0x70, 0x55, 0x35, 0x50, 0x71, 0x4E, 0x6E, 0xE0, +0x72, 0x3E, 0x51, 0xD0, 0x73, 0x2E, 0x50, 0xE0, 0x74, 0x1E, 0x33, 0xD0, 0x75, 0x0E, 0x32, 0xE0, +0x75, 0xFE, 0x15, 0xD0, 0x76, 0xF7, 0x4F, 0x60, 0x77, 0xDD, 0xF7, 0xD0, 0x78, 0xD7, 0x31, 0x60, +0x79, 0xBD, 0xD9, 0xD0, 0x7A, 0xB7, 0x13, 0x60, 0x7B, 0x9D, 0xBB, 0xD0, 0x7C, 0x96, 0xF5, 0x60, +0x7D, 0x86, 0xD8, 0x50, 0x7E, 0x76, 0xD7, 0x60, 0x7F, 0x66, 0xBA, 0x50, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, @@ -8196,19 +8213,19 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { 0x48, 0xBB, 0x06, 0x50, 0x49, 0xCB, 0xFA, 0xE0, 0x4A, 0xA0, 0x3C, 0x60, 0x4B, 0xAB, 0xDC, 0xE0, 0x4C, 0x61, 0xBD, 0xD0, 0x4D, 0x94, 0xF9, 0x9C, 0x4E, 0x35, 0xC2, 0x50, 0x4E, 0x5C, 0x0B, 0xE0, 0x4E, 0x84, 0xDC, 0x50, 0x4F, 0x74, 0xDB, 0x60, 0x50, 0x5B, 0x91, 0xE0, 0x51, 0x54, 0xBD, 0x60, -0x52, 0x44, 0xAE, 0x60, 0x53, 0x34, 0x9F, 0x60, 0x54, 0x24, 0x90, 0x60, 0x55, 0x14, 0x81, 0x60, -0x56, 0x04, 0x72, 0x60, 0x56, 0xFD, 0x9D, 0xE0, 0x57, 0xE4, 0x54, 0x60, 0x58, 0xDD, 0x7F, 0xE0, -0x59, 0xC4, 0x36, 0x60, 0x5A, 0xBD, 0x61, 0xE0, 0x5B, 0xA4, 0x18, 0x60, 0x5C, 0x9D, 0x43, 0xE0, -0x5D, 0x8D, 0x34, 0xE0, 0x5E, 0x7D, 0x25, 0xE0, 0x5F, 0x6D, 0x16, 0xE0, 0x60, 0x5D, 0x07, 0xE0, -0x61, 0x4C, 0xF8, 0xE0, 0x62, 0x46, 0x24, 0x60, 0x63, 0x2C, 0xDA, 0xE0, 0x64, 0x26, 0x06, 0x60, -0x65, 0x0C, 0xBC, 0xE0, 0x66, 0x05, 0xE8, 0x60, 0x66, 0xF5, 0xD9, 0x60, 0x67, 0xE5, 0xCA, 0x60, -0x68, 0xD5, 0xBB, 0x60, 0x69, 0xC5, 0xAC, 0x60, 0x6A, 0xB5, 0x9D, 0x60, 0x6B, 0xA5, 0x8E, 0x60, -0x6C, 0x95, 0x7F, 0x60, 0x6D, 0x8E, 0xAA, 0xE0, 0x6E, 0x75, 0x61, 0x60, 0x6F, 0x6E, 0x8C, 0xE0, -0x70, 0x55, 0x43, 0x60, 0x71, 0x4E, 0x6E, 0xE0, 0x72, 0x3E, 0x5F, 0xE0, 0x73, 0x2E, 0x50, 0xE0, -0x74, 0x1E, 0x41, 0xE0, 0x75, 0x0E, 0x32, 0xE0, 0x75, 0xFE, 0x23, 0xE0, 0x76, 0xF7, 0x4F, 0x60, -0x77, 0xDE, 0x05, 0xE0, 0x78, 0xD7, 0x31, 0x60, 0x79, 0xBD, 0xE7, 0xE0, 0x7A, 0xB7, 0x13, 0x60, -0x7B, 0x9D, 0xC9, 0xE0, 0x7C, 0x96, 0xF5, 0x60, 0x7D, 0x86, 0xE6, 0x60, 0x7E, 0x76, 0xD7, 0x60, -0x7F, 0x66, 0xC8, 0x60, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x02, 0x01, +0x52, 0x44, 0xA0, 0x50, 0x53, 0x34, 0x9F, 0x60, 0x54, 0x24, 0x82, 0x50, 0x55, 0x14, 0x81, 0x60, +0x56, 0x04, 0x64, 0x50, 0x56, 0xFD, 0x9D, 0xE0, 0x57, 0xE4, 0x46, 0x50, 0x58, 0xDD, 0x7F, 0xE0, +0x59, 0xC4, 0x28, 0x50, 0x5A, 0xBD, 0x61, 0xE0, 0x5B, 0xA4, 0x0A, 0x50, 0x5C, 0x9D, 0x43, 0xE0, +0x5D, 0x8D, 0x26, 0xD0, 0x5E, 0x7D, 0x25, 0xE0, 0x5F, 0x6D, 0x08, 0xD0, 0x60, 0x5D, 0x07, 0xE0, +0x61, 0x4C, 0xEA, 0xD0, 0x62, 0x46, 0x24, 0x60, 0x63, 0x2C, 0xCC, 0xD0, 0x64, 0x26, 0x06, 0x60, +0x65, 0x0C, 0xAE, 0xD0, 0x66, 0x05, 0xE8, 0x60, 0x66, 0xF5, 0xCB, 0x50, 0x67, 0xE5, 0xCA, 0x60, +0x68, 0xD5, 0xAD, 0x50, 0x69, 0xC5, 0xAC, 0x60, 0x6A, 0xB5, 0x8F, 0x50, 0x6B, 0xA5, 0x8E, 0x60, +0x6C, 0x95, 0x71, 0x50, 0x6D, 0x8E, 0xAA, 0xE0, 0x6E, 0x75, 0x53, 0x50, 0x6F, 0x6E, 0x8C, 0xE0, +0x70, 0x55, 0x35, 0x50, 0x71, 0x4E, 0x6E, 0xE0, 0x72, 0x3E, 0x51, 0xD0, 0x73, 0x2E, 0x50, 0xE0, +0x74, 0x1E, 0x33, 0xD0, 0x75, 0x0E, 0x32, 0xE0, 0x75, 0xFE, 0x15, 0xD0, 0x76, 0xF7, 0x4F, 0x60, +0x77, 0xDD, 0xF7, 0xD0, 0x78, 0xD7, 0x31, 0x60, 0x79, 0xBD, 0xD9, 0xD0, 0x7A, 0xB7, 0x13, 0x60, +0x7B, 0x9D, 0xBB, 0xD0, 0x7C, 0x96, 0xF5, 0x60, 0x7D, 0x86, 0xD8, 0x50, 0x7E, 0x76, 0xD7, 0x60, +0x7F, 0x66, 0xBA, 0x50, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x01, 0x02, @@ -8397,7 +8414,7 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { 0xDA, 0xFF, 0x26, 0x00, 0xF4, 0xB5, 0xBE, 0x88, 0x01, 0x02, 0x03, 0x02, 0x04, 0x02, 0x05, 0x00, 0x00, 0x64, 0x20, 0x00, 0x00, 0x00, 0x00, 0x67, 0x20, 0x00, 0x04, 0x00, 0x00, 0x69, 0x78, 0x00, 0x09, 0x00, 0x00, 0x7E, 0x90, 0x00, 0x0D, 0x00, 0x00, 0x70, 0x80, 0x00, 0x09, 0x00, 0x00, 0x62, -0x70, 0x00, 0x09, 0x4A, 0x4D, 0x54, 0x00, 0x4A, 0x41, 0x56, 0x54, 0x00, 0x57, 0x49, 0x54, 0x00, +0x70, 0x00, 0x09, 0x42, 0x4D, 0x54, 0x00, 0x4A, 0x41, 0x56, 0x54, 0x00, 0x57, 0x49, 0x42, 0x00, 0x4A, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xEB, 0x65, 0x01, 0xB5, 0x9F, 0x40, 0x00, 0x00, 0x00, 0x0E, 0x4A, 0x61, 0x76, 0x61, 0x20, 0x26, 0x20, 0x53, 0x75, 0x6D, 0x61, 0x74, 0x72, 0x61, @@ -8408,7 +8425,7 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0C, 0xBA, 0x16, 0xC1, 0x98, 0xD0, 0x58, 0xB9, 0xF0, 0xF4, 0xB5, 0xA2, 0x68, 0x01, 0x02, 0x01, 0x00, 0x00, 0x83, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x90, 0x00, 0x04, 0x00, 0x00, 0x85, 0x98, 0x00, 0x08, 0x4C, 0x4D, 0x54, -0x00, 0x45, 0x49, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x57, 0x49, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x76, 0xAA, 0x01, 0xE9, 0x59, 0x70, 0x00, 0x00, 0x00, 0x31, 0x77, 0x65, 0x73, 0x74, 0x20, 0x4E, 0x65, 0x77, 0x20, 0x47, 0x75, 0x69, 0x6E, 0x65, 0x61, 0x20, 0x28, 0x49, 0x72, 0x69, 0x61, 0x6E, 0x20, 0x4A, 0x61, 0x79, 0x61, 0x29, 0x20, 0x26, 0x20, 0x4D, 0x61, 0x6C, 0x75, 0x6B, 0x75, @@ -8754,17 +8771,17 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { /* Asia/Makassar */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x49, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x10, 0xA1, 0xF2, 0x5D, 0x90, +0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x11, 0xA1, 0xF2, 0x5D, 0x90, 0xBA, 0x16, 0xD5, 0x90, 0xCB, 0x88, 0x1D, 0x80, 0xD2, 0x56, 0xEE, 0x70, 0x01, 0x02, 0x03, 0x02, 0x00, 0x00, 0x6F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x6F, 0xF0, 0x00, 0x04, 0x00, 0x00, 0x70, 0x80, -0x00, 0x08, 0x00, 0x00, 0x7E, 0x90, 0x00, 0x0C, 0x4C, 0x4D, 0x54, 0x00, 0x4D, 0x4D, 0x54, 0x00, -0x43, 0x49, 0x54, 0x00, 0x4A, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x81, 0x85, 0x8D, 0x01, 0xC8, 0xD9, 0x1F, 0x00, 0x00, 0x00, 0x48, 0x65, 0x61, 0x73, 0x74, -0x20, 0x26, 0x20, 0x73, 0x6F, 0x75, 0x74, 0x68, 0x20, 0x42, 0x6F, 0x72, 0x6E, 0x65, 0x6F, 0x2C, -0x20, 0x53, 0x75, 0x6C, 0x61, 0x77, 0x65, 0x73, 0x69, 0x20, 0x28, 0x43, 0x65, 0x6C, 0x65, 0x62, -0x65, 0x73, 0x29, 0x2C, 0x20, 0x42, 0x61, 0x6C, 0x69, 0x2C, 0x20, 0x4E, 0x75, 0x73, 0x61, 0x20, -0x54, 0x65, 0x6E, 0x67, 0x61, 0x72, 0x72, 0x61, 0x2C, 0x20, 0x77, 0x65, 0x73, 0x74, 0x20, 0x54, -0x69, 0x6D, 0x6F, 0x72, +0x00, 0x08, 0x00, 0x00, 0x7E, 0x90, 0x00, 0x0D, 0x4C, 0x4D, 0x54, 0x00, 0x4D, 0x4D, 0x54, 0x00, +0x57, 0x49, 0x54, 0x41, 0x00, 0x4A, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x81, 0x85, 0x8D, 0x01, 0xC8, 0xD9, 0x1F, 0x00, 0x00, 0x00, 0x48, 0x65, 0x61, 0x73, +0x74, 0x20, 0x26, 0x20, 0x73, 0x6F, 0x75, 0x74, 0x68, 0x20, 0x42, 0x6F, 0x72, 0x6E, 0x65, 0x6F, +0x2C, 0x20, 0x53, 0x75, 0x6C, 0x61, 0x77, 0x65, 0x73, 0x69, 0x20, 0x28, 0x43, 0x65, 0x6C, 0x65, +0x62, 0x65, 0x73, 0x29, 0x2C, 0x20, 0x42, 0x61, 0x6C, 0x69, 0x2C, 0x20, 0x4E, 0x75, 0x73, 0x61, +0x20, 0x54, 0x65, 0x6E, 0x67, 0x61, 0x72, 0x72, 0x61, 0x2C, 0x20, 0x77, 0x65, 0x73, 0x74, 0x20, +0x54, 0x69, 0x6D, 0x6F, 0x72, /* Asia/Manila */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x50, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -8980,17 +8997,17 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { /* Asia/Pontianak */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x49, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x14, 0x8B, 0xFF, 0x8E, 0x00, +0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x15, 0x8B, 0xFF, 0x8E, 0x00, 0xBA, 0x16, 0xDF, 0x00, 0xCB, 0x79, 0xA4, 0x08, 0xD2, 0x56, 0xEE, 0x70, 0xD7, 0x3C, 0xC6, 0x08, 0xDA, 0xFF, 0x26, 0x00, 0xF4, 0xB5, 0xBE, 0x88, 0x21, 0xDA, 0x74, 0x80, 0x01, 0x02, 0x03, 0x02, 0x04, 0x02, 0x05, 0x06, 0x00, 0x00, 0x66, 0x80, 0x00, 0x00, 0x00, 0x00, 0x66, 0x80, 0x00, 0x04, 0x00, 0x00, 0x69, 0x78, 0x00, 0x08, 0x00, 0x00, 0x7E, 0x90, 0x00, 0x0C, 0x00, 0x00, 0x70, 0x80, 0x00, 0x08, 0x00, 0x00, 0x70, 0x80, 0x00, 0x10, 0x00, 0x00, 0x62, 0x70, 0x00, 0x08, 0x4C, 0x4D, -0x54, 0x00, 0x50, 0x4D, 0x54, 0x00, 0x57, 0x49, 0x54, 0x00, 0x4A, 0x53, 0x54, 0x00, 0x43, 0x49, -0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x89, 0x47, 0x3A, 0x01, 0xB9, 0x7C, 0xD5, 0x00, 0x00, 0x00, 0x15, 0x77, 0x65, 0x73, 0x74, -0x20, 0x26, 0x20, 0x63, 0x65, 0x6E, 0x74, 0x72, 0x61, 0x6C, 0x20, 0x42, 0x6F, 0x72, 0x6E, 0x65, -0x6F, +0x54, 0x00, 0x50, 0x4D, 0x54, 0x00, 0x57, 0x49, 0x42, 0x00, 0x4A, 0x53, 0x54, 0x00, 0x57, 0x49, +0x54, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x89, 0x47, 0x3A, 0x01, 0xB9, 0x7C, 0xD5, 0x00, 0x00, 0x00, 0x15, 0x77, 0x65, 0x73, +0x74, 0x20, 0x26, 0x20, 0x63, 0x65, 0x6E, 0x74, 0x72, 0x61, 0x6C, 0x20, 0x42, 0x6F, 0x72, 0x6E, +0x65, 0x6F, /* Asia/Pyongyang */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x4B, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -9368,12 +9385,12 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { /* Asia/Ujung_Pandang */ 0x50, 0x48, 0x50, 0x31, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x10, 0xA1, 0xF2, 0x5D, 0x90, +0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x11, 0xA1, 0xF2, 0x5D, 0x90, 0xBA, 0x16, 0xD5, 0x90, 0xCB, 0x88, 0x1D, 0x80, 0xD2, 0x56, 0xEE, 0x70, 0x01, 0x02, 0x03, 0x02, 0x00, 0x00, 0x6F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x6F, 0xF0, 0x00, 0x04, 0x00, 0x00, 0x70, 0x80, -0x00, 0x08, 0x00, 0x00, 0x7E, 0x90, 0x00, 0x0C, 0x4C, 0x4D, 0x54, 0x00, 0x4D, 0x4D, 0x54, 0x00, -0x43, 0x49, 0x54, 0x00, 0x4A, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x89, 0x54, 0x40, 0x01, 0x12, 0xA8, 0x80, 0x00, 0x00, 0x00, 0x00, +0x00, 0x08, 0x00, 0x00, 0x7E, 0x90, 0x00, 0x0D, 0x4C, 0x4D, 0x54, 0x00, 0x4D, 0x4D, 0x54, 0x00, +0x57, 0x49, 0x54, 0x41, 0x00, 0x4A, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x89, 0x54, 0x40, 0x01, 0x12, 0xA8, 0x80, 0x00, 0x00, 0x00, 0x00, /* Asia/Ulaanbaatar */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x4D, 0x4E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -11007,7 +11024,7 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { /* Brazil/Acre */ 0x50, 0x48, 0x50, 0x31, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x11, 0x96, 0xAA, 0x86, 0x90, +0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x11, 0x96, 0xAA, 0x86, 0x90, 0xB8, 0x0F, 0x66, 0x00, 0xB8, 0xFD, 0x5C, 0xC0, 0xB9, 0xF1, 0x50, 0x50, 0xBA, 0xDE, 0x90, 0x40, 0xDA, 0x38, 0xCA, 0x50, 0xDA, 0xEC, 0x16, 0x50, 0xDC, 0x19, 0xFD, 0xD0, 0xDC, 0xB9, 0x75, 0x40, 0xDD, 0xFB, 0x31, 0x50, 0xDE, 0x9B, 0xFA, 0x40, 0xDF, 0xDD, 0xB6, 0x50, 0xE0, 0x54, 0x4F, 0x40, @@ -11015,12 +11032,13 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { 0xF8, 0x51, 0x48, 0x50, 0xF8, 0xC7, 0xE1, 0x40, 0xFA, 0x0A, 0xEE, 0xD0, 0xFA, 0xA9, 0x14, 0xC0, 0xFB, 0xEC, 0x22, 0x50, 0xFC, 0x8B, 0x99, 0xC0, 0x1D, 0xC9, 0xAA, 0x50, 0x1E, 0x78, 0xF3, 0xC0, 0x1F, 0xA0, 0x51, 0xD0, 0x20, 0x33, 0xEB, 0xC0, 0x21, 0x81, 0x85, 0x50, 0x22, 0x0B, 0xE4, 0xC0, -0x48, 0x60, 0x7F, 0x50, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, +0x48, 0x60, 0x7F, 0x50, 0x52, 0x7F, 0x04, 0xC0, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, -0x02, 0x03, 0xFF, 0xFF, 0xC0, 0x70, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x04, 0xFF, 0xFF, -0xB9, 0xB0, 0x00, 0x09, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x0D, 0x4C, 0x4D, 0x54, 0x00, 0x41, 0x43, -0x53, 0x54, 0x00, 0x41, 0x43, 0x54, 0x00, 0x41, 0x4D, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x89, 0x54, 0x40, 0x01, 0x12, 0xA8, 0x80, 0x00, 0x00, 0x00, 0x00, +0x02, 0x01, 0x02, 0x01, 0x02, 0x03, 0x02, 0xFF, 0xFF, 0xC0, 0x70, 0x00, 0x00, 0xFF, 0xFF, 0xC7, +0xC0, 0x01, 0x04, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x09, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x0D, 0x4C, +0x4D, 0x54, 0x00, 0x41, 0x43, 0x53, 0x54, 0x00, 0x41, 0x43, 0x54, 0x00, 0x41, 0x4D, 0x54, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x54, 0x40, 0x01, 0x12, 0xA8, 0x80, +0x00, 0x00, 0x00, 0x00, /* Brazil/DeNoronha */ 0x50, 0x48, 0x50, 0x31, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -11904,7 +11922,7 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { 0x33, 0x47, 0x2D, 0xD0, 0x34, 0x40, 0x59, 0x50, 0x35, 0x1D, 0xD5, 0x50, 0x36, 0x32, 0xB0, 0x50, 0x36, 0xFD, 0xB7, 0x50, 0x38, 0x1B, 0xCC, 0xD0, 0x38, 0xE6, 0xD3, 0xD0, 0x39, 0xFB, 0xAE, 0xD0, 0x3A, 0xC6, 0xB5, 0xD0, 0x3B, 0xDB, 0x90, 0xD0, 0x3C, 0xAF, 0xD2, 0x50, 0x3D, 0xBB, 0x72, 0xD0, -0x3E, 0x8F, 0xB4, 0x50, 0x3F, 0x9B, 0x54, 0xD0, 0x40, 0x6F, 0x96, 0x50, 0x45, 0x44, 0x35, 0x50, +0x3E, 0x8F, 0xB4, 0x50, 0x3F, 0x9B, 0x54, 0xD0, 0x40, 0x66, 0x5B, 0xD0, 0x45, 0x44, 0x35, 0x50, 0x45, 0xF3, 0x8C, 0xD0, 0x47, 0x24, 0x17, 0x50, 0x47, 0xDC, 0xA9, 0x50, 0x49, 0x03, 0xF9, 0x50, 0x49, 0xB3, 0x50, 0xD0, 0x4A, 0xE3, 0xDB, 0x50, 0x4B, 0x9C, 0x6D, 0x50, 0x4C, 0xCC, 0xF7, 0xD0, 0x4D, 0x85, 0x89, 0xD0, 0x4E, 0xBF, 0x4E, 0xD0, 0x4F, 0x77, 0xE0, 0xD0, 0x50, 0x95, 0xF6, 0x50, @@ -15346,8 +15364,9 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { /* Europe/Vaduz */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x4C, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x72, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x09, 0x15, 0x23, 0xEB, 0x90, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0xCA, 0x17, 0x6A, 0x00, +0xCA, 0xE2, 0x71, 0x00, 0xCB, 0xF7, 0x4C, 0x00, 0xCC, 0xC2, 0x53, 0x00, 0x15, 0x23, 0xEB, 0x90, 0x16, 0x13, 0xDC, 0x90, 0x17, 0x03, 0xCD, 0x90, 0x17, 0xF3, 0xBE, 0x90, 0x18, 0xE3, 0xAF, 0x90, 0x19, 0xD3, 0xA0, 0x90, 0x1A, 0xC3, 0x91, 0x90, 0x1B, 0xBC, 0xBD, 0x10, 0x1C, 0xAC, 0xAE, 0x10, 0x1D, 0x9C, 0x9F, 0x10, 0x1E, 0x8C, 0x90, 0x10, 0x1F, 0x7C, 0x81, 0x10, 0x20, 0x6C, 0x72, 0x10, @@ -15376,17 +15395,17 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { 0x74, 0x45, 0xF9, 0x10, 0x75, 0x11, 0x00, 0x10, 0x76, 0x2F, 0x15, 0x90, 0x76, 0xF0, 0xE2, 0x10, 0x78, 0x0E, 0xF7, 0x90, 0x78, 0xD0, 0xC4, 0x10, 0x79, 0xEE, 0xD9, 0x90, 0x7A, 0xB0, 0xA6, 0x10, 0x7B, 0xCE, 0xBB, 0x90, 0x7C, 0x99, 0xC2, 0x90, 0x7D, 0xAE, 0x9D, 0x90, 0x7E, 0x79, 0xA4, 0x90, -0x7F, 0x8E, 0x7F, 0x90, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, -0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, -0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, -0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, -0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, -0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, -0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, -0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x00, 0x00, 0x0E, 0x10, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x20, -0x01, 0x04, 0x00, 0x00, 0x0E, 0x10, 0x00, 0x00, 0x43, 0x45, 0x54, 0x00, 0x43, 0x45, 0x53, 0x54, -0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0xD1, 0x46, 0x38, 0x01, 0x21, 0x2D, 0xF2, 0x00, -0x00, 0x00, 0x00, +0x7F, 0x8E, 0x7F, 0x90, 0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, +0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, +0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, +0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, +0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, +0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, +0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, +0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x00, 0x00, 0x1C, 0x20, 0x01, 0x00, +0x00, 0x00, 0x0E, 0x10, 0x00, 0x05, 0x00, 0x00, 0x1C, 0x20, 0x01, 0x00, 0x00, 0x00, 0x0E, 0x10, +0x00, 0x05, 0x43, 0x45, 0x53, 0x54, 0x00, 0x43, 0x45, 0x54, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, +0x00, 0x01, 0x01, 0x00, 0xD1, 0x46, 0x38, 0x01, 0x21, 0x2D, 0xF2, 0x00, 0x00, 0x00, 0x00, /* Europe/Vatican */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x56, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -16278,14 +16297,14 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { /* Jamaica */ 0x50, 0x48, 0x50, 0x31, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x93, 0x0F, 0xB5, 0x00, +0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x93, 0x0F, 0xB4, 0xFF, 0x08, 0x20, 0xC1, 0x70, 0x09, 0x10, 0xA4, 0x60, 0x09, 0xAD, 0x94, 0xF0, 0x0A, 0xF0, 0x86, 0x60, 0x0B, 0xE0, 0x85, 0x70, 0x0C, 0xD9, 0xA2, 0xE0, 0x0D, 0xC0, 0x67, 0x70, 0x0E, 0xB9, 0x84, 0xE0, 0x0F, 0xA9, 0x83, 0xF0, 0x10, 0x99, 0x66, 0xE0, 0x11, 0x89, 0x65, 0xF0, 0x12, 0x79, 0x48, 0xE0, 0x13, 0x69, 0x47, 0xF0, 0x14, 0x59, 0x2A, 0xE0, 0x15, 0x49, 0x29, 0xF0, 0x16, 0x39, 0x0C, 0xE0, 0x17, 0x29, 0x0B, 0xF0, 0x18, 0x22, 0x29, 0x60, 0x19, 0x08, 0xED, 0xF0, 0x1A, 0x02, 0x0B, 0x60, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, -0x01, 0x02, 0x01, 0x02, 0x01, 0xFF, 0xFF, 0xB8, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, +0x01, 0x02, 0x01, 0x02, 0x01, 0xFF, 0xFF, 0xB8, 0x01, 0x00, 0x00, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x04, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x08, 0x4B, 0x4D, 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x45, 0x44, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x54, 0x40, 0x01, 0x12, 0xA8, 0x80, 0x00, 0x00, 0x00, 0x00, @@ -16313,7 +16332,7 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { /* Libya */ 0x50, 0x48, 0x50, 0x31, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x11, 0xA1, 0xF2, 0xC1, 0x24, +0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x11, 0xA1, 0xF2, 0xC1, 0x24, 0xDD, 0xBB, 0xB1, 0x10, 0xDE, 0x23, 0xAD, 0x60, 0xE1, 0x78, 0xD2, 0x10, 0xE1, 0xE7, 0x65, 0xE0, 0xE5, 0x2F, 0x3F, 0x70, 0xE5, 0xA9, 0xCC, 0xE0, 0xEB, 0x4E, 0xC6, 0xF0, 0x16, 0x92, 0x42, 0x60, 0x17, 0x08, 0xF7, 0x70, 0x17, 0xFA, 0x2B, 0xE0, 0x18, 0xEA, 0x2A, 0xF0, 0x19, 0xDB, 0x5F, 0x60, @@ -16321,24 +16340,9 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { 0x1E, 0x93, 0x0B, 0x70, 0x1F, 0x82, 0xEE, 0x60, 0x20, 0x70, 0x4A, 0x70, 0x21, 0x61, 0x7E, 0xE0, 0x22, 0x52, 0xCF, 0x70, 0x23, 0x44, 0x03, 0xE0, 0x24, 0x34, 0x02, 0xF0, 0x25, 0x25, 0x37, 0x60, 0x26, 0x40, 0xB7, 0xF0, 0x32, 0x4E, 0xF1, 0x60, 0x33, 0x44, 0x36, 0x70, 0x34, 0x35, 0x6A, 0xE0, -0x50, 0x9D, 0x99, 0x00, 0x51, 0x54, 0xD9, 0x80, 0x52, 0x69, 0xB4, 0x80, 0x53, 0x34, 0xBB, 0x80, -0x54, 0x52, 0xD1, 0x00, 0x55, 0x14, 0x9D, 0x80, 0x56, 0x32, 0xB3, 0x00, 0x56, 0xF4, 0x7F, 0x80, -0x58, 0x12, 0x95, 0x00, 0x58, 0xDD, 0x9C, 0x00, 0x59, 0xF2, 0x77, 0x00, 0x5A, 0xBD, 0x7E, 0x00, -0x5B, 0xD2, 0x59, 0x00, 0x5C, 0x9D, 0x60, 0x00, 0x5D, 0xB2, 0x3B, 0x00, 0x5E, 0x7D, 0x42, 0x00, -0x5F, 0x9B, 0x57, 0x80, 0x60, 0x5D, 0x24, 0x00, 0x61, 0x7B, 0x39, 0x80, 0x62, 0x3D, 0x06, 0x00, -0x63, 0x5B, 0x1B, 0x80, 0x64, 0x26, 0x22, 0x80, 0x65, 0x3A, 0xFD, 0x80, 0x66, 0x06, 0x04, 0x80, -0x67, 0x1A, 0xDF, 0x80, 0x67, 0xE5, 0xE6, 0x80, 0x69, 0x03, 0xFC, 0x00, 0x69, 0xC5, 0xC8, 0x80, -0x6A, 0xE3, 0xDE, 0x00, 0x6B, 0xA5, 0xAA, 0x80, 0x6C, 0xC3, 0xC0, 0x00, 0x6D, 0x8E, 0xC7, 0x00, -0x6E, 0xA3, 0xA2, 0x00, 0x6F, 0x6E, 0xA9, 0x00, 0x70, 0x83, 0x84, 0x00, 0x71, 0x4E, 0x8B, 0x00, -0x72, 0x63, 0x66, 0x00, 0x73, 0x2E, 0x6D, 0x00, 0x74, 0x4C, 0x82, 0x80, 0x75, 0x0E, 0x4F, 0x00, -0x76, 0x2C, 0x64, 0x80, 0x76, 0xEE, 0x31, 0x00, 0x78, 0x0C, 0x46, 0x80, 0x78, 0xD7, 0x4D, 0x80, -0x79, 0xEC, 0x28, 0x80, 0x7A, 0xB7, 0x2F, 0x80, 0x7B, 0xCC, 0x0A, 0x80, 0x7C, 0x97, 0x11, 0x80, -0x7D, 0xB5, 0x27, 0x00, 0x7E, 0x76, 0xF3, 0x80, 0x7F, 0x95, 0x09, 0x00, 0x02, 0x01, 0x02, 0x01, +0x50, 0x9D, 0x99, 0x00, 0x51, 0x54, 0xD9, 0x80, 0x52, 0x69, 0xB4, 0x80, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x03, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, -0x02, 0x01, 0x02, 0x01, 0x02, 0x03, 0x02, 0x01, 0x03, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, -0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, -0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, -0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x00, 0x00, 0x0C, 0x5C, +0x02, 0x01, 0x02, 0x01, 0x02, 0x03, 0x02, 0x01, 0x03, 0x02, 0x01, 0x03, 0x00, 0x00, 0x0C, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x20, 0x01, 0x04, 0x00, 0x00, 0x0E, 0x10, 0x00, 0x09, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x0D, 0x4C, 0x4D, 0x54, 0x00, 0x43, 0x45, 0x53, 0x54, 0x00, 0x43, 0x45, 0x54, 0x00, 0x45, 0x45, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x54, @@ -16999,19 +17003,19 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { 0x36, 0x3B, 0x17, 0xE0, 0x36, 0xD7, 0xFA, 0x60, 0x38, 0x24, 0x34, 0x60, 0x38, 0xB7, 0xDC, 0x60, 0x4B, 0x11, 0x2C, 0xE0, 0x4B, 0xAE, 0x0F, 0x60, 0x4C, 0xC2, 0xEA, 0x60, 0x4D, 0x72, 0x41, 0xE0, 0x4E, 0xA2, 0xCC, 0x60, 0x4F, 0x1A, 0xC4, 0xE0, 0x50, 0x82, 0xAE, 0x60, 0x50, 0xFA, 0xA6, 0xE0, -0x52, 0x62, 0x90, 0x60, 0x52, 0xDA, 0x88, 0xE0, 0x54, 0x42, 0x72, 0x60, 0x54, 0xBA, 0x6A, 0xE0, -0x56, 0x22, 0x54, 0x60, 0x56, 0xA3, 0x87, 0x60, 0x58, 0x0B, 0x70, 0xE0, 0x58, 0x83, 0x69, 0x60, +0x52, 0x6B, 0xCA, 0xE0, 0x52, 0xDA, 0x88, 0xE0, 0x54, 0x4B, 0xAC, 0xE0, 0x54, 0xBA, 0x6A, 0xE0, +0x56, 0x2B, 0x8E, 0xE0, 0x56, 0xA3, 0x87, 0x60, 0x58, 0x0B, 0x70, 0xE0, 0x58, 0x83, 0x69, 0x60, 0x59, 0xEB, 0x52, 0xE0, 0x5A, 0x63, 0x4B, 0x60, 0x5B, 0xCB, 0x34, 0xE0, 0x5C, 0x43, 0x2D, 0x60, -0x5D, 0xAB, 0x16, 0xE0, 0x5E, 0x23, 0x0F, 0x60, 0x5F, 0x8A, 0xF8, 0xE0, 0x60, 0x0C, 0x2B, 0xE0, +0x5D, 0xB4, 0x51, 0x60, 0x5E, 0x23, 0x0F, 0x60, 0x5F, 0x94, 0x33, 0x60, 0x60, 0x0C, 0x2B, 0xE0, 0x61, 0x74, 0x15, 0x60, 0x61, 0xEC, 0x0D, 0xE0, 0x63, 0x53, 0xF7, 0x60, 0x63, 0xCB, 0xEF, 0xE0, -0x65, 0x33, 0xD9, 0x60, 0x65, 0xAB, 0xD1, 0xE0, 0x67, 0x13, 0xBB, 0x60, 0x67, 0x8B, 0xB3, 0xE0, -0x68, 0xF3, 0x9D, 0x60, 0x69, 0x6B, 0x95, 0xE0, 0x6A, 0xD3, 0x7F, 0x60, 0x6B, 0x54, 0xB2, 0x60, +0x65, 0x33, 0xD9, 0x60, 0x65, 0xAB, 0xD1, 0xE0, 0x67, 0x1C, 0xF5, 0xE0, 0x67, 0x8B, 0xB3, 0xE0, +0x68, 0xFC, 0xD7, 0xE0, 0x69, 0x6B, 0x95, 0xE0, 0x6A, 0xDC, 0xB9, 0xE0, 0x6B, 0x54, 0xB2, 0x60, 0x6C, 0xBC, 0x9B, 0xE0, 0x6D, 0x34, 0x94, 0x60, 0x6E, 0x9C, 0x7D, 0xE0, 0x6F, 0x14, 0x76, 0x60, -0x70, 0x7C, 0x5F, 0xE0, 0x70, 0xF4, 0x58, 0x60, 0x72, 0x5C, 0x41, 0xE0, 0x72, 0xD4, 0x3A, 0x60, -0x74, 0x3C, 0x23, 0xE0, 0x74, 0xB4, 0x1C, 0x60, 0x76, 0x25, 0x40, 0x60, 0x76, 0x9D, 0x38, 0xE0, +0x70, 0x7C, 0x5F, 0xE0, 0x70, 0xF4, 0x58, 0x60, 0x72, 0x65, 0x7C, 0x60, 0x72, 0xD4, 0x3A, 0x60, +0x74, 0x45, 0x5E, 0x60, 0x74, 0xB4, 0x1C, 0x60, 0x76, 0x25, 0x40, 0x60, 0x76, 0x9D, 0x38, 0xE0, 0x78, 0x05, 0x22, 0x60, 0x78, 0x7D, 0x1A, 0xE0, 0x79, 0xE5, 0x04, 0x60, 0x7A, 0x5C, 0xFC, 0xE0, -0x7B, 0xC4, 0xE6, 0x60, 0x7C, 0x3C, 0xDE, 0xE0, 0x7D, 0xA4, 0xC8, 0x60, 0x7E, 0x1C, 0xC0, 0xE0, -0x7F, 0x84, 0xAA, 0x60, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, +0x7B, 0xC4, 0xE6, 0x60, 0x7C, 0x3C, 0xDE, 0xE0, 0x7D, 0xAE, 0x02, 0xE0, 0x7E, 0x1C, 0xC0, 0xE0, +0x7F, 0x8D, 0xE4, 0xE0, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, @@ -17074,11 +17078,13 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { /* Pacific/Johnston */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x55, 0x4D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0xFF, 0xFF, 0x73, 0x60, -0x00, 0x00, 0x48, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0xA2, 0xE3, 0x38, 0x00, 0x0F, 0xFF, 0x0D, -0x00, 0x00, 0x00, 0x0E, 0x4A, 0x6F, 0x68, 0x6E, 0x73, 0x74, 0x6F, 0x6E, 0x20, 0x41, 0x74, 0x6F, -0x6C, 0x6C, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0xBB, 0x05, 0x43, 0x48, +0xBB, 0x21, 0x71, 0x58, 0xCB, 0x89, 0x3D, 0xC8, 0xD2, 0x61, 0x49, 0x38, 0xD5, 0x8D, 0x73, 0x48, +0x01, 0x00, 0x01, 0x00, 0x02, 0xFF, 0xFF, 0x6C, 0x58, 0x00, 0x00, 0xFF, 0xFF, 0x7A, 0x68, 0x01, +0x04, 0xFF, 0xFF, 0x73, 0x60, 0x00, 0x00, 0x48, 0x53, 0x54, 0x00, 0x48, 0x44, 0x54, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0xE3, 0x38, 0x00, 0x0F, 0xFF, 0x0D, 0x00, 0x00, 0x00, +0x0E, 0x4A, 0x6F, 0x68, 0x6E, 0x73, 0x74, 0x6F, 0x6E, 0x20, 0x41, 0x74, 0x6F, 0x6C, 0x6C, /* Pacific/Kiritimati */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x4B, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -18410,4 +18416,4 @@ const unsigned char timelib_timezone_db_data_builtin[261525] = { 0x00, 0x00, 0x55, 0x54, 0x43, 0x00, 0x00, 0x00, 0x00, 0x89, 0x54, 0x40, 0x01, 0x12, 0xA8, 0x80, 0x00, 0x00, 0x00, 0x00, }; -const timelib_tzdb timezonedb_builtin = { "2013.4", 579, timezonedb_idx_builtin, timelib_timezone_db_data_builtin }; +const timelib_tzdb timezonedb_builtin = { "2013.9", 579, timezonedb_idx_builtin, timelib_timezone_db_data_builtin }; diff --git a/ext/date/lib/unixtime2tm.c b/ext/date/lib/unixtime2tm.c index c177feebb188a..194b3b2116a8c 100644 --- a/ext/date/lib/unixtime2tm.c +++ b/ext/date/lib/unixtime2tm.c @@ -137,19 +137,16 @@ void timelib_unixtime2gmt(timelib_time* tm, timelib_sll ts) void timelib_update_from_sse(timelib_time *tm) { timelib_sll sse; + int z = tm->z; + signed int dst = tm->dst; sse = tm->sse; switch (tm->zone_type) { case TIMELIB_ZONETYPE_ABBR: case TIMELIB_ZONETYPE_OFFSET: { - int z = tm->z; - signed int dst = tm->dst; - timelib_unixtime2gmt(tm, tm->sse - (tm->z * 60) + (tm->dst * 3600)); - tm->z = z; - tm->dst = dst; goto cleanup; } @@ -171,6 +168,8 @@ void timelib_update_from_sse(timelib_time *tm) tm->sse = sse; tm->is_localtime = 1; tm->have_zone = 1; + tm->z = z; + tm->dst = dst; } void timelib_unixtime2local(timelib_time *tm, timelib_sll ts) diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 7d3d1d739e113..cd3bf745dcbc4 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -797,6 +797,14 @@ PHP_RSHUTDOWN_FUNCTION(date) #define DATE_FORMAT_ISO8601 "Y-m-d\\TH:i:sO" +/* + * This comes from various sources that like to contradict. I'm going with the + * format here because of: + * http://msdn.microsoft.com/en-us/library/windows/desktop/aa384321%28v=vs.85%29.aspx + * and http://curl.haxx.se/rfc/cookie_spec.html + */ +#define DATE_FORMAT_COOKIE "l, d-M-Y H:i:s T" + #define DATE_TZ_ERRMSG \ "It is not safe to rely on the system's timezone settings. You are " \ "*required* to use the date.timezone setting or the " \ @@ -827,7 +835,7 @@ PHP_MINIT_FUNCTION(date) * with the variations that the only legal time zone is GMT * and the separators between the elements of the date must be dashes." */ - REGISTER_STRING_CONSTANT("DATE_COOKIE", DATE_FORMAT_RFC850, CONST_CS | CONST_PERSISTENT); + REGISTER_STRING_CONSTANT("DATE_COOKIE", DATE_FORMAT_COOKIE, CONST_CS | CONST_PERSISTENT); REGISTER_STRING_CONSTANT("DATE_ISO8601", DATE_FORMAT_ISO8601, CONST_CS | CONST_PERSISTENT); REGISTER_STRING_CONSTANT("DATE_RFC822", DATE_FORMAT_RFC822, CONST_CS | CONST_PERSISTENT); REGISTER_STRING_CONSTANT("DATE_RFC850", DATE_FORMAT_RFC850, CONST_CS | CONST_PERSISTENT); @@ -1406,6 +1414,7 @@ PHPAPI signed long php_parse_date(char *string, signed long *now) parsed_time = timelib_strtotime(string, strlen(string), &error, DATE_TIMEZONEDB, php_date_parse_tzfile_wrapper); if (error->error_count) { + timelib_time_dtor(parsed_time); timelib_error_container_dtor(error); return -1; } @@ -1980,12 +1989,25 @@ zend_object_iterator *date_object_period_get_iterator(zend_class_entry *ce, zval return (zend_object_iterator*)iterator; } +static int implement_date_interface_handler(zend_class_entry *interface, zend_class_entry *implementor TSRMLS_DC) +{ + if (implementor->type == ZEND_USER_CLASS && + !instanceof_function(implementor, date_ce_date TSRMLS_CC) && + !instanceof_function(implementor, date_ce_immutable TSRMLS_CC) + ) { + zend_error(E_ERROR, "DateTimeInterface can't be implemented by user classes"); + } + + return SUCCESS; +} + static void date_register_classes(TSRMLS_D) { zend_class_entry ce_date, ce_immutable, ce_timezone, ce_interval, ce_period, ce_interface; INIT_CLASS_ENTRY(ce_interface, "DateTimeInterface", date_funcs_interface); date_ce_interface = zend_register_internal_interface(&ce_interface TSRMLS_CC); + date_ce_interface->interface_gets_implemented = implement_date_interface_handler; INIT_CLASS_ENTRY(ce_date, "DateTime", date_funcs_date); ce_date.create_object = date_object_new_date; @@ -2001,7 +2023,7 @@ static void date_register_classes(TSRMLS_D) zend_declare_class_constant_stringl(date_ce_date, const_name, sizeof(const_name)-1, value, sizeof(value)-1 TSRMLS_CC); REGISTER_DATE_CLASS_CONST_STRING("ATOM", DATE_FORMAT_RFC3339); - REGISTER_DATE_CLASS_CONST_STRING("COOKIE", DATE_FORMAT_RFC850); + REGISTER_DATE_CLASS_CONST_STRING("COOKIE", DATE_FORMAT_COOKIE); REGISTER_DATE_CLASS_CONST_STRING("ISO8601", DATE_FORMAT_ISO8601); REGISTER_DATE_CLASS_CONST_STRING("RFC822", DATE_FORMAT_RFC822); REGISTER_DATE_CLASS_CONST_STRING("RFC850", DATE_FORMAT_RFC850); @@ -2601,6 +2623,7 @@ PHPAPI int php_date_initialize(php_date_obj *dateobj, /*const*/ char *time_str, timelib_fill_holes(dateobj->time, now, TIMELIB_NO_CLONE); timelib_update_ts(dateobj->time, tzi); + timelib_update_from_sse(dateobj->time); dateobj->time->have_relative = 0; @@ -3602,13 +3625,13 @@ PHP_FUNCTION(date_diff) php_interval_obj *interval; long absolute = 0; - if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO|l", &object1, date_ce_date, &object2, date_ce_date, &absolute) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO|l", &object1, date_ce_interface, &object2, date_ce_interface, &absolute) == FAILURE) { RETURN_FALSE; } dateobj1 = (php_date_obj *) zend_object_store_get_object(object1 TSRMLS_CC); dateobj2 = (php_date_obj *) zend_object_store_get_object(object2 TSRMLS_CC); - DATE_CHECK_INITIALIZED(dateobj1->time, DateTime); - DATE_CHECK_INITIALIZED(dateobj2->time, DateTime); + DATE_CHECK_INITIALIZED(dateobj1->time, DateTimeInterface); + DATE_CHECK_INITIALIZED(dateobj2->time, DateTimeInterface); timelib_update_ts(dateobj1->time, NULL); timelib_update_ts(dateobj2->time, NULL); @@ -4386,7 +4409,7 @@ PHP_METHOD(DatePeriod, __construct) zend_replace_error_handling(EH_THROW, NULL, &error_handling TSRMLS_CC); if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "OOl|l", &start, date_ce_interface, &interval, date_ce_interval, &recurrences, &options) == FAILURE) { - if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "OOO|l", &start, date_ce_interface, &interval, date_ce_interval, &end, date_ce_date, &options) == FAILURE) { + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "OOO|l", &start, date_ce_interface, &interval, date_ce_interval, &end, date_ce_interface, &options) == FAILURE) { if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &isostr, &isostr_len, &options) == FAILURE) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "This constructor accepts either (DateTimeInterface, DateInterval, int) OR (DateTimeInterface, DateInterval, DateTime) OR (string) as arguments."); zend_restore_error_handling(&error_handling TSRMLS_CC); diff --git a/ext/date/tests/DateTime_format_basic2.phpt b/ext/date/tests/DateTime_format_basic2.phpt index d7adaa5df8871..016fa7b6b2815 100644 --- a/ext/date/tests/DateTime_format_basic2.phpt +++ b/ext/date/tests/DateTime_format_basic2.phpt @@ -31,7 +31,7 @@ var_dump( $date->format( DateTime::W3C) ) ; --EXPECT-- *** Testing date_format() : basic functionality - formatting coinstants *** string(25) "2005-07-14T22:30:41+01:00" -string(32) "Thursday, 14-Jul-05 22:30:41 BST" +string(34) "Thursday, 14-Jul-2005 22:30:41 BST" string(24) "2005-07-14T22:30:41+0100" string(29) "Thu, 14 Jul 05 22:30:41 +0100" string(32) "Thursday, 14-Jul-05 22:30:41 BST" diff --git a/ext/date/tests/DateTime_verify.phpt b/ext/date/tests/DateTime_verify.phpt index a03911f5c8298..c7909747292ac 100644 --- a/ext/date/tests/DateTime_verify.phpt +++ b/ext/date/tests/DateTime_verify.phpt @@ -160,7 +160,7 @@ array(11) { ["ATOM"]=> string(13) "Y-m-d\TH:i:sP" ["COOKIE"]=> - string(16) "l, d-M-y H:i:s T" + string(16) "l, d-M-Y H:i:s T" ["ISO8601"]=> string(13) "Y-m-d\TH:i:sO" ["RFC822"]=> @@ -180,4 +180,4 @@ array(11) { ["W3C"]=> string(13) "Y-m-d\TH:i:sP" } -===DONE=== \ No newline at end of file +===DONE=== diff --git a/ext/date/tests/bug52063.phpt b/ext/date/tests/bug52063.phpt index af9da9e429d4f..7364a8061225c 100644 --- a/ext/date/tests/bug52063.phpt +++ b/ext/date/tests/bug52063.phpt @@ -11,5 +11,5 @@ echo $a->format(DateTime::COOKIE); echo "\n"; ?> --EXPECTF-- -Thursday, 01-Jan-09 00:00:00 WET -Thursday, 01-Jan-09 00:00:00 WET +Thursday, 01-Jan-2009 00:00:00 WET +Thursday, 01-Jan-2009 00:00:00 WET diff --git a/ext/date/tests/bug53879.phpt b/ext/date/tests/bug53879.phpt new file mode 100644 index 0000000000000..3d16c97209743 --- /dev/null +++ b/ext/date/tests/bug53879.phpt @@ -0,0 +1,16 @@ +--TEST-- +Bug #53879 (DateTime::createFromFormat() fails to parse cookie expiration date) +--INI-- +date.timezone=UTC +--FILE-- + +--EXPECTF-- +DateTime Object +( + [date] => 2041-01-21 15:24:52 + [timezone_type] => 2 + [timezone] => GMT +) diff --git a/ext/date/tests/bug63391.phpt b/ext/date/tests/bug63391.phpt new file mode 100644 index 0000000000000..a29d25e730656 --- /dev/null +++ b/ext/date/tests/bug63391.phpt @@ -0,0 +1,20 @@ +--TEST-- +Test for #63391 (Incorrect/inconsistent day of week prior to the year 1600) +--FILE-- +format('Y-m-d D'), "\n"; +} +?> +--EXPECT-- +Date PHP +---------- --- +1599-12-30 Thu +1599-12-31 Fri +1600-01-01 Sat +1600-01-02 Sun diff --git a/ext/date/tests/date_constants.phpt b/ext/date/tests/date_constants.phpt index 132e24159bf84..b9fce8c78bd0a 100644 --- a/ext/date/tests/date_constants.phpt +++ b/ext/date/tests/date_constants.phpt @@ -41,8 +41,8 @@ Date constants --EXPECT-- string(25) "2006-07-01T14:27:30+02:00" string(25) "2006-05-30T14:32:13+02:00" -string(33) "Saturday, 01-Jul-06 14:27:30 CEST" -string(32) "Tuesday, 30-May-06 14:32:13 CEST" +string(35) "Saturday, 01-Jul-2006 14:27:30 CEST" +string(34) "Tuesday, 30-May-2006 14:32:13 CEST" string(24) "2006-07-01T14:27:30+0200" string(24) "2006-05-30T14:32:13+0200" string(29) "Sat, 01 Jul 06 14:27:30 +0200" diff --git a/ext/date/tests/forward-transition-construction.phpt b/ext/date/tests/forward-transition-construction.phpt new file mode 100644 index 0000000000000..8f195a51bdec5 --- /dev/null +++ b/ext/date/tests/forward-transition-construction.phpt @@ -0,0 +1,27 @@ +--TEST-- +Test for Date/Time construction during a forward DST transition +--FILE-- +format('Y-m-d H:i:s T/e - U') . "\n"; + +$date = new DateTime('2010-03-14 02:00:00'); +echo $date->format('Y-m-d H:i:s T/e - U') . "\n"; + +$date = new DateTime('2010-03-14 02:30:00'); +echo $date->format('Y-m-d H:i:s T/e - U') . "\n"; + +$date = new DateTime('2010-03-14 03:00:00'); +echo $date->format('Y-m-d H:i:s T/e - U') . "\n"; + +$date = new DateTime('2010-03-14 03:30:00'); +echo $date->format('Y-m-d H:i:s T/e - U') . "\n"; +?> +--EXPECT-- +2010-03-14 01:30:00 EST/America/New_York - 1268548200 +2010-03-14 03:00:00 EDT/America/New_York - 1268550000 +2010-03-14 03:30:00 EDT/America/New_York - 1268551800 +2010-03-14 03:00:00 EDT/America/New_York - 1268550000 +2010-03-14 03:30:00 EDT/America/New_York - 1268551800 diff --git a/ext/date/tests/gmdate_variation13.phpt b/ext/date/tests/gmdate_variation13.phpt index 5a19ae268e012..1d1f434ecee0e 100644 --- a/ext/date/tests/gmdate_variation13.phpt +++ b/ext/date/tests/gmdate_variation13.phpt @@ -45,7 +45,7 @@ string(25) "2008-08-08T08:08:08+00:00" string(%d) "%s" --DATE_COOKIE Constant-- -string(30) "Friday, 08-Aug-08 08:08:08 GMT" +string(32) "Friday, 08-Aug-2008 08:08:08 GMT" string(%d) "%s" --DATE_RFC822 Constant-- @@ -79,4 +79,4 @@ string(%d) "%s" --DATE_W3C Constant-- string(25) "2008-08-08T08:08:08+00:00" string(%d) "%s" -===DONE=== \ No newline at end of file +===DONE=== diff --git a/ext/date/tests/rfc-datetime_and_daylight_saving_time-type3-ba.phpt b/ext/date/tests/rfc-datetime_and_daylight_saving_time-type3-ba.phpt new file mode 100644 index 0000000000000..fdbe96d7d08cd --- /dev/null +++ b/ext/date/tests/rfc-datetime_and_daylight_saving_time-type3-ba.phpt @@ -0,0 +1,96 @@ +--TEST-- +RFC: DateTime and Daylight Saving Time Transitions (zone type 3, ba) +--CREDITS-- +Daniel Convissor +--FILE-- +format($date_format) . " + $interval_spec = " + . $start->add($interval)->format($date_format) . "\n"; + +$start = new DateTime('2010-11-06 04:30:00'); +$interval_spec = 'P1D'; +$interval = new DateInterval($interval_spec); +echo 'ba2 ' . $start->format($date_format) . " + $interval_spec = " + . $start->add($interval)->format($date_format) . "\n"; + +$start = new DateTime('2010-11-06 04:30:00'); +$interval_spec = 'PT24H'; +$interval = new DateInterval($interval_spec); +echo 'ba3 ' . $start->format($date_format) . " + $interval_spec = " + . $start->add($interval)->format($date_format) . "\n"; + +$start = new DateTime('2010-11-06 04:30:00'); +$interval_spec = 'PT23H'; +$interval = new DateInterval($interval_spec); +echo 'ba4 ' . $start->format($date_format) . " + $interval_spec = " + . $start->add($interval)->format($date_format) . "\n"; + +$start = new DateTime('2010-11-06 04:30:00'); +$interval_spec = 'PT22H'; +$interval = new DateInterval($interval_spec); +echo 'ba5 ' . $start->format($date_format) . " + $interval_spec = " + . $start->add($interval)->format($date_format) . "\n"; + +$start = new DateTime('2010-11-06 04:30:00'); +$interval_spec = 'PT21H'; +$interval = new DateInterval($interval_spec); +echo 'ba6 ' . $start->format($date_format) . " + $interval_spec = " + . $start->add($interval)->format($date_format) . "\n"; + +$start = new DateTime('2010-11-06 01:30:00'); +$interval_spec = 'P1D'; +$interval = new DateInterval($interval_spec); +echo 'ba7 ' . $start->format($date_format) . " + $interval_spec = " + . $start->add($interval)->format($date_format) . "\n"; + +$start = new DateTime('2010-11-06 01:30:00'); +$interval_spec = 'P1DT1H'; +$interval = new DateInterval($interval_spec); +echo 'ba8 ' . $start->format($date_format) . " + $interval_spec = " + . $start->add($interval)->format($date_format) . "\n"; + +$start = new DateTime('2010-11-06 04:30:00'); +$interval_spec = 'PT25H'; +$interval = new DateInterval($interval_spec); +echo 'ba9 ' . $start->format($date_format) . " + $interval_spec = " + . $start->add($interval)->format($date_format) . "\n"; + +$start = new DateTime('2010-11-06 03:30:00'); +$interval_spec = 'P1D'; +$interval = new DateInterval($interval_spec); +echo 'ba10 ' . $start->format($date_format) . " + $interval_spec = " + . $start->add($interval)->format($date_format) . "\n"; + +$start = new DateTime('2010-11-06 02:30:00'); +$interval_spec = 'P1D'; +$interval = new DateInterval($interval_spec); +echo 'ba11 ' . $start->format($date_format) . " + $interval_spec = " + . $start->add($interval)->format($date_format) . "\n"; + +echo "\n"; + +?> +--EXPECT-- +ba1 2010-11-07 01:59:59 EDT America/New_York + PT1S = 2010-11-07 01:00:00 EST America/New_York +ba2 2010-11-06 04:30:00 EDT America/New_York + P1D = 2010-11-07 04:30:00 EST America/New_York +ba3 2010-11-06 04:30:00 EDT America/New_York + PT24H = 2010-11-07 03:30:00 EST America/New_York +ba4 2010-11-06 04:30:00 EDT America/New_York + PT23H = 2010-11-07 02:30:00 EST America/New_York +ba5 2010-11-06 04:30:00 EDT America/New_York + PT22H = 2010-11-07 01:30:00 EST America/New_York +ba6 2010-11-06 04:30:00 EDT America/New_York + PT21H = 2010-11-07 01:30:00 EDT America/New_York +ba7 2010-11-06 01:30:00 EDT America/New_York + P1D = 2010-11-07 01:30:00 EDT America/New_York +ba8 2010-11-06 01:30:00 EDT America/New_York + P1DT1H = 2010-11-07 02:30:00 EST America/New_York +ba9 2010-11-06 04:30:00 EDT America/New_York + PT25H = 2010-11-07 04:30:00 EST America/New_York +ba10 2010-11-06 03:30:00 EDT America/New_York + P1D = 2010-11-07 03:30:00 EST America/New_York +ba11 2010-11-06 02:30:00 EDT America/New_York + P1D = 2010-11-07 02:30:00 EST America/New_York diff --git a/ext/date/tests/rfc-datetime_and_daylight_saving_time-type3-bd1.phpt b/ext/date/tests/rfc-datetime_and_daylight_saving_time-type3-bd1.phpt new file mode 100644 index 0000000000000..8249599931978 --- /dev/null +++ b/ext/date/tests/rfc-datetime_and_daylight_saving_time-type3-bd1.phpt @@ -0,0 +1,48 @@ +--TEST-- +RFC: DateTime and Daylight Saving Time Transitions (zone type 3, bd1) +--CREDITS-- +Daniel Convissor +--FILE-- +format($date_format) . ' - ' . $start->format($date_format) + . ' = ' . $start->diff($end)->format($interval_format) . "\n"; + +$end = new DateTime('2010-11-07 04:30:00'); +$start = new DateTime('2010-11-06 04:30:00'); +echo 'bd2 ' . $end->format($date_format) . ' - ' . $start->format($date_format) + . ' = ' . $start->diff($end)->format($interval_format) . "\n"; + +$end = new DateTime('2010-11-07 03:30:00'); +$start = new DateTime('2010-11-06 04:30:00'); +echo 'bd3 ' . $end->format($date_format) . ' - ' . $start->format($date_format) + . ' = ' . $start->diff($end)->format($interval_format) . "\n"; + +$end = new DateTime('2010-11-07 02:30:00'); +$start = new DateTime('2010-11-06 04:30:00'); +echo 'bd4 ' . $end->format($date_format) . ' - ' . $start->format($date_format) + . ' = ' . $start->diff($end)->format($interval_format) . "\n"; + +$end = new DateTime('2010-11-07 01:30:00'); +$start = new DateTime('2010-11-06 01:30:00'); +echo 'bd7 ' . $end->format($date_format) . ' - ' . $start->format($date_format) + . ' = ' . $start->diff($end)->format($interval_format) . "\n"; + +echo "\n"; +?> +--EXPECT-- +bd1 2010-11-07 05:30:00 EST America/New_York - 2010-11-06 04:30:00 EDT America/New_York = P1DT1H +bd2 2010-11-07 04:30:00 EST America/New_York - 2010-11-06 04:30:00 EDT America/New_York = P1DT0H +bd3 2010-11-07 03:30:00 EST America/New_York - 2010-11-06 04:30:00 EDT America/New_York = P0DT24H +bd4 2010-11-07 02:30:00 EST America/New_York - 2010-11-06 04:30:00 EDT America/New_York = P0DT23H +bd7 2010-11-07 01:30:00 EDT America/New_York - 2010-11-06 01:30:00 EDT America/New_York = P1DT0H diff --git a/ext/date/tests/rfc-datetime_and_daylight_saving_time-type3-bd2.phpt b/ext/date/tests/rfc-datetime_and_daylight_saving_time-type3-bd2.phpt new file mode 100644 index 0000000000000..fe2e79b3b9d6b --- /dev/null +++ b/ext/date/tests/rfc-datetime_and_daylight_saving_time-type3-bd2.phpt @@ -0,0 +1,56 @@ +--TEST-- +RFC: DateTime and Daylight Saving Time Transitions (zone type 3, bd2) +--CREDITS-- +Daniel Convissor +--XFAIL-- +Still not quite right +--FILE-- +setTimeZone($tz); +$start = new DateTime('2010-11-06 04:30:59'); +echo 'bd0 ' . $end->format($date_format) . ' - ' . $start->format($date_format) + . ' = ' . $start->diff($end)->format('P%dDT%hH%iM%sS') . "\n"; + +$end = new DateTime('2010-11-07 01:30:00 EST'); +$end->setTimeZone($tz); +$start = new DateTime('2010-11-06 04:30:00'); +echo 'bd5 ' . $end->format($date_format) . ' - ' . $start->format($date_format) + . ' = ' . $start->diff($end)->format($interval_format) . "\n"; + +$end = new DateTime('2010-11-07 01:30:00 EDT'); +$end->setTimeZone($tz); +$start = new DateTime('2010-11-06 04:30:00'); +echo 'bd6 ' . $end->format($date_format) . ' - ' . $start->format($date_format) + . ' = ' . $start->diff($end)->format($interval_format) . "\n"; + +$end = new DateTime('2010-11-07 01:30:00 EST'); +$end->setTimeZone($tz); +$start = new DateTime('2010-11-06 01:30:00'); +echo 'bd8 ' . $end->format($date_format) . ' - ' . $start->format($date_format) + . ' = ' . $start->diff($end)->format($interval_format) . "\n"; + +echo "\n"; +?> +--EXPECT-- +bd0 2010-11-07 01:00:00 EST America/New_York - 2010-11-07 01:59:59 EDT America/New_York = PT0H0M1S +bd5 2010-11-07 01:30:00 EST America/New_York - 2010-11-06 04:30:00 EDT America/New_York = P0DT22H +bd6 2010-11-07 01:30:00 EDT America/New_York - 2010-11-06 04:30:00 EDT America/New_York = P0DT21H +bd8 2010-11-07 01:30:00 EST America/New_York - 2010-11-06 01:30:00 EDT America/New_York = P1DT1H diff --git a/ext/date/tests/rfc-datetime_and_daylight_saving_time-type3-bs.phpt b/ext/date/tests/rfc-datetime_and_daylight_saving_time-type3-bs.phpt new file mode 100644 index 0000000000000..138c68f3a9b4a --- /dev/null +++ b/ext/date/tests/rfc-datetime_and_daylight_saving_time-type3-bs.phpt @@ -0,0 +1,92 @@ +--TEST-- +RFC: DateTime and Daylight Saving Time Transitions (zone type 3, bs) +--CREDITS-- +Daniel Convissor +--FILE-- +setTimeZone($tz); +$interval_spec = 'PT1S'; +$interval = new DateInterval($interval_spec); +echo 'bs1 ' . $end->format($date_format) . " - $interval_spec = " + . $end->sub($interval)->format($date_format) . "\n"; + +$end = new DateTime('2010-11-07 04:30:00'); +$interval_spec = 'P1D'; +$interval = new DateInterval($interval_spec); +echo 'bs2 ' . $end->format($date_format) . " - $interval_spec = " + . $end->sub($interval)->format($date_format) . "\n"; + +$end = new DateTime('2010-11-07 03:30:00'); +$interval_spec = 'PT24H'; +$interval = new DateInterval($interval_spec); +echo 'bs3 ' . $end->format($date_format) . " - $interval_spec = " + . $end->sub($interval)->format($date_format) . "\n"; + +$end = new DateTime('2010-11-07 02:30:00'); +$interval_spec = 'PT23H'; +$interval = new DateInterval($interval_spec); +echo 'bs4 ' . $end->format($date_format) . " - $interval_spec = " + . $end->sub($interval)->format($date_format) . "\n"; + +$end = new DateTime('2010-11-07 01:30:00 EST'); +$end->setTimeZone($tz); +$interval_spec = 'PT22H'; +$interval = new DateInterval($interval_spec); +echo 'bs5 ' . $end->format($date_format) . " - $interval_spec = " + . $end->sub($interval)->format($date_format) . "\n"; + +$end = new DateTime('2010-11-07 01:30:00 EDT'); +$end->setTimeZone($tz); +$interval_spec = 'PT21H'; +$interval = new DateInterval($interval_spec); +echo 'bs6 ' . $end->format($date_format) . " - $interval_spec = " + . $end->sub($interval)->format($date_format) . "\n"; + +$end = new DateTime('2010-11-07 01:30:00'); +$interval_spec = 'P1D'; +$interval = new DateInterval($interval_spec); +echo 'bs7 ' . $end->format($date_format) . " - $interval_spec = " + . $end->sub($interval)->format($date_format) . "\n"; + +$end = new DateTime('2010-11-07 01:30:00 EST'); +$end->setTimeZone($tz); +$interval_spec = 'P1DT1H'; +$interval = new DateInterval($interval_spec); +echo 'bs8 ' . $end->format($date_format) . " - $interval_spec = " + . $end->sub($interval)->format($date_format) . "\n"; + +$end = new DateTime('2010-11-07 03:30:00'); +$interval_spec = 'P1D'; +$interval = new DateInterval($interval_spec); +echo 'bs9 ' . $end->format($date_format) . " - $interval_spec = " + . $end->sub($interval)->format($date_format) . "\n"; + +$end = new DateTime('2010-11-07 02:30:00'); +$interval_spec = 'P1D'; +$interval = new DateInterval($interval_spec); +echo 'bs10 ' . $end->format($date_format) . " - $interval_spec = " + . $end->sub($interval)->format($date_format) . "\n"; + +?> +--EXPECT-- +bs1 2010-11-07 01:00:00 EST America/New_York - PT1S = 2010-11-07 01:59:59 EDT America/New_York +bs2 2010-11-07 04:30:00 EST America/New_York - P1D = 2010-11-06 04:30:00 EDT America/New_York +bs3 2010-11-07 03:30:00 EST America/New_York - PT24H = 2010-11-06 04:30:00 EDT America/New_York +bs4 2010-11-07 02:30:00 EST America/New_York - PT23H = 2010-11-06 04:30:00 EDT America/New_York +bs5 2010-11-07 01:30:00 EST America/New_York - PT22H = 2010-11-06 04:30:00 EDT America/New_York +bs6 2010-11-07 01:30:00 EDT America/New_York - PT21H = 2010-11-06 04:30:00 EDT America/New_York +bs7 2010-11-07 01:30:00 EDT America/New_York - P1D = 2010-11-06 01:30:00 EDT America/New_York +bs8 2010-11-07 01:30:00 EST America/New_York - P1DT1H = 2010-11-06 00:30:00 EDT America/New_York +bs9 2010-11-07 03:30:00 EST America/New_York - P1D = 2010-11-06 03:30:00 EDT America/New_York +bs10 2010-11-07 02:30:00 EST America/New_York - P1D = 2010-11-06 02:30:00 EDT America/New_York diff --git a/ext/date/tests/rfc-datetime_and_daylight_saving_time-type3-fa.phpt b/ext/date/tests/rfc-datetime_and_daylight_saving_time-type3-fa.phpt new file mode 100644 index 0000000000000..9fa493f578c80 --- /dev/null +++ b/ext/date/tests/rfc-datetime_and_daylight_saving_time-type3-fa.phpt @@ -0,0 +1,58 @@ +--TEST-- +RFC: DateTime and Daylight Saving Time Transitions (zone type 3, fa) +--CREDITS-- +Daniel Convissor +--FILE-- +format($date_format) . " + $interval_spec = " + . $start->add($interval)->format($date_format) . "\n"; + +$start = new DateTime('2010-03-13 04:30:00'); +$interval_spec = 'P1D'; +$interval = new DateInterval($interval_spec); +echo 'fa2 ' . $start->format($date_format) . " + $interval_spec = " + . $start->add($interval)->format($date_format) . "\n"; + +$start = new DateTime('2010-03-13 04:30:00'); +$interval_spec = 'PT22H'; +$interval = new DateInterval($interval_spec); +echo 'fa3 ' . $start->format($date_format) . " + $interval_spec = " + . $start->add($interval)->format($date_format) . "\n"; + +$start = new DateTime('2010-03-13 04:30:00'); +$interval_spec = 'PT21H'; +$interval = new DateInterval($interval_spec); +echo 'fa4 ' . $start->format($date_format) . " + $interval_spec = " + . $start->add($interval)->format($date_format) . "\n"; + +$start = new DateTime('2010-03-13 01:30:00'); +$interval_spec = 'P1D'; +$interval = new DateInterval($interval_spec); +echo 'fa5 ' . $start->format($date_format) . " + $interval_spec = " + . $start->add($interval)->format($date_format) . "\n"; + +$start = new DateTime('2010-03-13 02:30:00'); +$interval_spec = 'P1D'; +$interval = new DateInterval($interval_spec); +echo 'fa6 ' . $start->format($date_format) . " + $interval_spec = " + . $start->add($interval)->format($date_format) . "\n"; +?> +--EXPECT-- +fa1 2010-03-14 01:59:59 EST America/New_York + PT1S = 2010-03-14 03:00:00 EDT America/New_York +fa2 2010-03-13 04:30:00 EST America/New_York + P1D = 2010-03-14 04:30:00 EDT America/New_York +fa3 2010-03-13 04:30:00 EST America/New_York + PT22H = 2010-03-14 03:30:00 EDT America/New_York +fa4 2010-03-13 04:30:00 EST America/New_York + PT21H = 2010-03-14 01:30:00 EST America/New_York +fa5 2010-03-13 01:30:00 EST America/New_York + P1D = 2010-03-14 01:30:00 EST America/New_York +fa6 2010-03-13 02:30:00 EST America/New_York + P1D = 2010-03-14 03:30:00 EDT America/New_York diff --git a/ext/date/tests/rfc-datetime_and_daylight_saving_time-type3-fd.phpt b/ext/date/tests/rfc-datetime_and_daylight_saving_time-type3-fd.phpt new file mode 100644 index 0000000000000..ae7060be0b3a5 --- /dev/null +++ b/ext/date/tests/rfc-datetime_and_daylight_saving_time-type3-fd.phpt @@ -0,0 +1,58 @@ +--TEST-- +RFC: DateTime and Daylight Saving Time Transitions (zone type 3, fd) +--CREDITS-- +Daniel Convissor +--FILE-- +format($date_format) . ' - ' . $start->format($date_format) + . ' = ' . $start->diff($end)->format('PT%hH%iM%sS') . "\n"; + +$end = new DateTime('2010-03-14 04:30:00'); +$start = new DateTime('2010-03-13 04:30:00'); +echo 'fd2 ' . $end->format($date_format) . ' - ' . $start->format($date_format) + . ' = ' . $start->diff($end)->format($interval_format) . "\n"; + +$end = new DateTime('2010-03-14 03:30:00'); +$start = new DateTime('2010-03-13 04:30:00'); +echo 'fd3 ' . $end->format($date_format) . ' - ' . $start->format($date_format) + . ' = ' . $start->diff($end)->format($interval_format) . "\n"; + +$end = new DateTime('2010-03-14 01:30:00'); +$start = new DateTime('2010-03-13 04:30:00'); +echo 'fd4 ' . $end->format($date_format) . ' - ' . $start->format($date_format) + . ' = ' . $start->diff($end)->format($interval_format) . "\n"; + +$end = new DateTime('2010-03-14 01:30:00'); +$start = new DateTime('2010-03-13 01:30:00'); +echo 'fd5 ' . $end->format($date_format) . ' - ' . $start->format($date_format) + . ' = ' . $start->diff($end)->format($interval_format) . "\n"; + +$end = new DateTime('2010-03-14 03:30:00'); +$start = new DateTime('2010-03-13 03:30:00'); +echo 'fd6 ' . $end->format($date_format) . ' - ' . $start->format($date_format) + . ' = ' . $start->diff($end)->format($interval_format) . "\n"; + +$end = new DateTime('2010-03-14 03:30:00'); +$start = new DateTime('2010-03-13 02:30:00'); +echo 'fd7 ' . $end->format($date_format) . ' - ' . $start->format($date_format) + . ' = ' . $start->diff($end)->format($interval_format) . "\n"; +?> +--EXPECT-- +fd1 2010-03-14 03:00:00 EDT America/New_York - 2010-03-14 01:59:59 EST America/New_York = PT0H0M1S +fd2 2010-03-14 04:30:00 EDT America/New_York - 2010-03-13 04:30:00 EST America/New_York = P1DT0H +fd3 2010-03-14 03:30:00 EDT America/New_York - 2010-03-13 04:30:00 EST America/New_York = P0DT22H +fd4 2010-03-14 01:30:00 EST America/New_York - 2010-03-13 04:30:00 EST America/New_York = P0DT21H +fd5 2010-03-14 01:30:00 EST America/New_York - 2010-03-13 01:30:00 EST America/New_York = P1DT0H +fd6 2010-03-14 03:30:00 EDT America/New_York - 2010-03-13 03:30:00 EST America/New_York = P1DT0H +fd7 2010-03-14 03:30:00 EDT America/New_York - 2010-03-13 02:30:00 EST America/New_York = P1DT1H diff --git a/ext/date/tests/rfc-datetime_and_daylight_saving_time-type3-fs.phpt b/ext/date/tests/rfc-datetime_and_daylight_saving_time-type3-fs.phpt new file mode 100644 index 0000000000000..72351d37e158d --- /dev/null +++ b/ext/date/tests/rfc-datetime_and_daylight_saving_time-type3-fs.phpt @@ -0,0 +1,67 @@ +--TEST-- +RFC: DateTime and Daylight Saving Time Transitions (zone type 3, fs) +--CREDITS-- +Daniel Convissor +--XFAIL-- +Still not quite right +--FILE-- +format($date_format) . " - $interval_spec = " + . $end->sub($interval)->format($date_format) . "\n"; + +$end = new DateTime('2010-03-14 04:30:00'); +$interval_spec = 'P1D'; +$interval = new DateInterval($interval_spec); +echo 'fs2 ' . $end->format($date_format) . " - $interval_spec = " + . $end->sub($interval)->format($date_format) . "\n"; + +$end = new DateTime('2010-03-14 03:30:00'); +$interval_spec = 'PT22H'; +$interval = new DateInterval($interval_spec); +echo 'fs3 ' . $end->format($date_format) . " - $interval_spec = " + . $end->sub($interval)->format($date_format) . "\n"; + +$end = new DateTime('2010-03-14 01:30:00'); +$interval_spec = 'PT21H'; +$interval = new DateInterval($interval_spec); +echo 'fs4 ' . $end->format($date_format) . " - $interval_spec = " + . $end->sub($interval)->format($date_format) . "\n"; + +$end = new DateTime('2010-03-14 01:30:00'); +$interval_spec = 'P1D'; +$interval = new DateInterval($interval_spec); +echo 'fs5 ' . $end->format($date_format) . " - $interval_spec = " + . $end->sub($interval)->format($date_format) . "\n"; + +$end = new DateTime('2010-03-15 03:30:00'); +$interval_spec = 'P1D'; +$interval = new DateInterval($interval_spec); +echo 'fs6 ' . $end->format($date_format) . " - $interval_spec = " + . $end->sub($interval)->format($date_format) . "\n"; + +$end = new DateTime('2010-03-15 02:30:00'); +$interval_spec = 'P1D'; +$interval = new DateInterval($interval_spec); +echo 'fs7 ' . $end->format($date_format) . " - $interval_spec = " + . $end->sub($interval)->format($date_format) . "\n"; +?> +--EXPECT-- +fs1 2010-03-14 03:00:00 EDT America/New_York - PT1S = 2010-03-14 01:59:59 EST America/New_York +fs2 2010-03-14 04:30:00 EDT America/New_York - P1D = 2010-03-13 04:30:00 EST America/New_York +fs3 2010-03-14 03:30:00 EDT America/New_York - PT22H = 2010-03-13 04:30:00 EST America/New_York +fs4 2010-03-14 01:30:00 EST America/New_York - PT21H = 2010-03-13 04:30:00 EST America/New_York +fs5 2010-03-14 01:30:00 EST America/New_York - P1D = 2010-03-13 01:30:00 EST America/New_York +fs6 2010-03-15 03:30:00 EDT America/New_York - P1D = 2010-03-14 03:30:00 EDT America/New_York +fs7 2010-03-15 02:30:00 EDT America/New_York - P1D = 2010-03-14 03:30:00 EDT America/New_York diff --git a/ext/date/tests/rfc-datetime_and_daylight_saving_time-type3.phpt b/ext/date/tests/rfc-datetime_and_daylight_saving_time-type3.phpt deleted file mode 100644 index 855fe4ef650c8..0000000000000 --- a/ext/date/tests/rfc-datetime_and_daylight_saving_time-type3.phpt +++ /dev/null @@ -1,399 +0,0 @@ ---TEST-- -RFC: DateTime and Daylight Saving Time Transitions (zone type 3) ---CREDITS-- -Daniel Convissor ---XFAIL-- -RFC not implemented yet ---FILE-- -format($date_format) . ' - ' . $start->format($date_format) - . ' = ' . $start->diff($end)->format('PT%hH%iM%sS') . "\n"; - -$end = new DateTime('2010-03-14 04:30:00'); -$start = new DateTime('2010-03-13 04:30:00'); -echo 'fd2 ' . $end->format($date_format) . ' - ' . $start->format($date_format) - . ' = ' . $start->diff($end)->format($interval_format) . "\n"; - -$end = new DateTime('2010-03-14 03:30:00'); -$start = new DateTime('2010-03-13 04:30:00'); -echo 'fd3 ' . $end->format($date_format) . ' - ' . $start->format($date_format) - . ' = ' . $start->diff($end)->format($interval_format) . "\n"; - -$end = new DateTime('2010-03-14 01:30:00'); -$start = new DateTime('2010-03-13 04:30:00'); -echo 'fd4 ' . $end->format($date_format) . ' - ' . $start->format($date_format) - . ' = ' . $start->diff($end)->format($interval_format) . "\n"; - -$end = new DateTime('2010-03-14 01:30:00'); -$start = new DateTime('2010-03-13 01:30:00'); -echo 'fd5 ' . $end->format($date_format) . ' - ' . $start->format($date_format) - . ' = ' . $start->diff($end)->format($interval_format) . "\n"; - -$end = new DateTime('2010-03-14 03:30:00'); -$start = new DateTime('2010-03-13 03:30:00'); -echo 'fd6 ' . $end->format($date_format) . ' - ' . $start->format($date_format) - . ' = ' . $start->diff($end)->format($interval_format) . "\n"; - -$end = new DateTime('2010-03-14 03:30:00'); -$start = new DateTime('2010-03-13 02:30:00'); -echo 'fd7 ' . $end->format($date_format) . ' - ' . $start->format($date_format) - . ' = ' . $start->diff($end)->format($interval_format) . "\n"; - -echo "\n"; - -/* - * Forward Transitions, add(). - */ - -$start = new DateTime('2010-03-14 01:59:59'); -$interval_spec = 'PT1S'; -$interval = new DateInterval($interval_spec); -echo 'fa1 ' . $start->format($date_format) . " + $interval_spec = " - . $start->add($interval)->format($date_format) . "\n"; - -$start = new DateTime('2010-03-13 04:30:00'); -$interval_spec = 'P1D'; -$interval = new DateInterval($interval_spec); -echo 'fa2 ' . $start->format($date_format) . " + $interval_spec = " - . $start->add($interval)->format($date_format) . "\n"; - -$start = new DateTime('2010-03-13 04:30:00'); -$interval_spec = 'PT22H'; -$interval = new DateInterval($interval_spec); -echo 'fa3 ' . $start->format($date_format) . " + $interval_spec = " - . $start->add($interval)->format($date_format) . "\n"; - -$start = new DateTime('2010-03-13 04:30:00'); -$interval_spec = 'PT21H'; -$interval = new DateInterval($interval_spec); -echo 'fa4 ' . $start->format($date_format) . " + $interval_spec = " - . $start->add($interval)->format($date_format) . "\n"; - -$start = new DateTime('2010-03-13 01:30:00'); -$interval_spec = 'P1D'; -$interval = new DateInterval($interval_spec); -echo 'fa5 ' . $start->format($date_format) . " + $interval_spec = " - . $start->add($interval)->format($date_format) . "\n"; - -$start = new DateTime('2010-03-13 02:30:00'); -$interval_spec = 'P1D'; -$interval = new DateInterval($interval_spec); -echo 'fa6 ' . $start->format($date_format) . " + $interval_spec = " - . $start->add($interval)->format($date_format) . "\n"; - -echo "\n"; - -/* - * Forward Transitions, sub(). - */ - -$end = new DateTime('2010-03-14 03:00:00'); -$interval_spec = 'PT1S'; -$interval = new DateInterval($interval_spec); -echo 'fs1 ' . $end->format($date_format) . " - $interval_spec = " - . $end->sub($interval)->format($date_format) . "\n"; - -$end = new DateTime('2010-03-14 04:30:00'); -$interval_spec = 'P1D'; -$interval = new DateInterval($interval_spec); -echo 'fs2 ' . $end->format($date_format) . " - $interval_spec = " - . $end->sub($interval)->format($date_format) . "\n"; - -$end = new DateTime('2010-03-14 03:30:00'); -$interval_spec = 'PT22H'; -$interval = new DateInterval($interval_spec); -echo 'fs3 ' . $end->format($date_format) . " - $interval_spec = " - . $end->sub($interval)->format($date_format) . "\n"; - -$end = new DateTime('2010-03-14 01:30:00'); -$interval_spec = 'PT21H'; -$interval = new DateInterval($interval_spec); -echo 'fs4 ' . $end->format($date_format) . " - $interval_spec = " - . $end->sub($interval)->format($date_format) . "\n"; - -$end = new DateTime('2010-03-14 01:30:00'); -$interval_spec = 'P1D'; -$interval = new DateInterval($interval_spec); -echo 'fs5 ' . $end->format($date_format) . " - $interval_spec = " - . $end->sub($interval)->format($date_format) . "\n"; - -$end = new DateTime('2010-03-15 03:30:00'); -$interval_spec = 'P1D'; -$interval = new DateInterval($interval_spec); -echo 'fs6 ' . $end->format($date_format) . " - $interval_spec = " - . $end->sub($interval)->format($date_format) . "\n"; - -$end = new DateTime('2010-03-15 02:30:00'); -$interval_spec = 'P1D'; -$interval = new DateInterval($interval_spec); -echo 'fs7 ' . $end->format($date_format) . " - $interval_spec = " - . $end->sub($interval)->format($date_format) . "\n"; - -echo "\n"; - - -/* - * For backward transitions, must create objects with zone type 2 - * where specifying Daylight or Standard time is required - * then converting them to zone type 3. - */ - -$tz = new DateTimeZone('America/New_York'); - -/* - * Backward Transitions, diff(). - */ - -$end = new DateTime('2010-11-07 01:00:00 EST'); -$end->setTimeZone($tz); -$start = new DateTime('2010-11-07 01:59:59'); -echo 'bd1 ' . $end->format($date_format) . ' - ' . $start->format($date_format) - . ' = ' . $start->diff($end)->format('PT%hH%iM%sS') . "\n"; - -$end = new DateTime('2010-11-07 04:30:00'); -$start = new DateTime('2010-11-06 04:30:00'); -echo 'bd2 ' . $end->format($date_format) . ' - ' . $start->format($date_format) - . ' = ' . $start->diff($end)->format($interval_format) . "\n"; - -$end = new DateTime('2010-11-07 03:30:00'); -$start = new DateTime('2010-11-06 04:30:00'); -echo 'bd3 ' . $end->format($date_format) . ' - ' . $start->format($date_format) - . ' = ' . $start->diff($end)->format($interval_format) . "\n"; - -$end = new DateTime('2010-11-07 02:30:00'); -$start = new DateTime('2010-11-06 04:30:00'); -echo 'bd4 ' . $end->format($date_format) . ' - ' . $start->format($date_format) - . ' = ' . $start->diff($end)->format($interval_format) . "\n"; - -$end = new DateTime('2010-11-07 01:30:00 EST'); -$end->setTimeZone($tz); -$start = new DateTime('2010-11-06 04:30:00'); -echo 'bd5 ' . $end->format($date_format) . ' - ' . $start->format($date_format) - . ' = ' . $start->diff($end)->format($interval_format) . "\n"; - -$end = new DateTime('2010-11-07 01:30:00 EDT'); -$end->setTimeZone($tz); -$start = new DateTime('2010-11-06 04:30:00'); -echo 'bd6 ' . $end->format($date_format) . ' - ' . $start->format($date_format) - . ' = ' . $start->diff($end)->format($interval_format) . "\n"; - -$end = new DateTime('2010-11-07 01:30:00'); -$start = new DateTime('2010-11-06 01:30:00'); -echo 'bd7 ' . $end->format($date_format) . ' - ' . $start->format($date_format) - . ' = ' . $start->diff($end)->format($interval_format) . "\n"; - -$end = new DateTime('2010-11-07 01:30:00 EST'); -$end->setTimeZone($tz); -$start = new DateTime('2010-11-06 01:30:00'); -echo 'bd8 ' . $end->format($date_format) . ' - ' . $start->format($date_format) - . ' = ' . $start->diff($end)->format($interval_format) . "\n"; - -echo "\n"; - -/* - * Backward Transitions, add(). - */ - -$start = new DateTime('2010-11-07 01:59:59'); -$interval_spec = 'PT1S'; -$interval = new DateInterval($interval_spec); -echo 'ba1 ' . $start->format($date_format) . " + $interval_spec = " - . $start->add($interval)->format($date_format) . "\n"; - -$start = new DateTime('2010-11-06 04:30:00'); -$interval_spec = 'P1D'; -$interval = new DateInterval($interval_spec); -echo 'ba2 ' . $start->format($date_format) . " + $interval_spec = " - . $start->add($interval)->format($date_format) . "\n"; - -$start = new DateTime('2010-11-06 04:30:00'); -$interval_spec = 'PT24H'; -$interval = new DateInterval($interval_spec); -echo 'ba3 ' . $start->format($date_format) . " + $interval_spec = " - . $start->add($interval)->format($date_format) . "\n"; - -$start = new DateTime('2010-11-06 04:30:00'); -$interval_spec = 'PT23H'; -$interval = new DateInterval($interval_spec); -echo 'ba4 ' . $start->format($date_format) . " + $interval_spec = " - . $start->add($interval)->format($date_format) . "\n"; - -$start = new DateTime('2010-11-06 04:30:00'); -$interval_spec = 'PT22H'; -$interval = new DateInterval($interval_spec); -echo 'ba5 ' . $start->format($date_format) . " + $interval_spec = " - . $start->add($interval)->format($date_format) . "\n"; - -$start = new DateTime('2010-11-06 04:30:00'); -$interval_spec = 'PT21H'; -$interval = new DateInterval($interval_spec); -echo 'ba6 ' . $start->format($date_format) . " + $interval_spec = " - . $start->add($interval)->format($date_format) . "\n"; - -$start = new DateTime('2010-11-06 01:30:00'); -$interval_spec = 'P1D'; -$interval = new DateInterval($interval_spec); -echo 'ba7 ' . $start->format($date_format) . " + $interval_spec = " - . $start->add($interval)->format($date_format) . "\n"; - -$start = new DateTime('2010-11-06 01:30:00'); -$interval_spec = 'P1DT1H'; -$interval = new DateInterval($interval_spec); -echo 'ba8 ' . $start->format($date_format) . " + $interval_spec = " - . $start->add($interval)->format($date_format) . "\n"; - -$start = new DateTime('2010-11-06 04:30:00'); -$interval_spec = 'PT25H'; -$interval = new DateInterval($interval_spec); -echo 'ba9 ' . $start->format($date_format) . " + $interval_spec = " - . $start->add($interval)->format($date_format) . "\n"; - -$start = new DateTime('2010-11-06 03:30:00'); -$interval_spec = 'P1D'; -$interval = new DateInterval($interval_spec); -echo 'ba10 ' . $start->format($date_format) . " + $interval_spec = " - . $start->add($interval)->format($date_format) . "\n"; - -$start = new DateTime('2010-11-06 02:30:00'); -$interval_spec = 'P1D'; -$interval = new DateInterval($interval_spec); -echo 'ba11 ' . $start->format($date_format) . " + $interval_spec = " - . $start->add($interval)->format($date_format) . "\n"; - -echo "\n"; - -/* - * Backward Transitions, sub(). - */ - -$end = new DateTime('2010-11-07 01:00:00 EST'); -$end->setTimeZone($tz); -$interval_spec = 'PT1S'; -$interval = new DateInterval($interval_spec); -echo 'bs1 ' . $end->format($date_format) . " - $interval_spec = " - . $end->sub($interval)->format($date_format) . "\n"; - -$end = new DateTime('2010-11-07 04:30:00'); -$interval_spec = 'P1D'; -$interval = new DateInterval($interval_spec); -echo 'bs2 ' . $end->format($date_format) . " - $interval_spec = " - . $end->sub($interval)->format($date_format) . "\n"; - -$end = new DateTime('2010-11-07 03:30:00'); -$interval_spec = 'PT24H'; -$interval = new DateInterval($interval_spec); -echo 'bs3 ' . $end->format($date_format) . " - $interval_spec = " - . $end->sub($interval)->format($date_format) . "\n"; - -$end = new DateTime('2010-11-07 02:30:00'); -$interval_spec = 'PT23H'; -$interval = new DateInterval($interval_spec); -echo 'bs4 ' . $end->format($date_format) . " - $interval_spec = " - . $end->sub($interval)->format($date_format) . "\n"; - -$end = new DateTime('2010-11-07 01:30:00 EST'); -$end->setTimeZone($tz); -$interval_spec = 'PT22H'; -$interval = new DateInterval($interval_spec); -echo 'bs5 ' . $end->format($date_format) . " - $interval_spec = " - . $end->sub($interval)->format($date_format) . "\n"; - -$end = new DateTime('2010-11-07 01:30:00 EDT'); -$end->setTimeZone($tz); -$interval_spec = 'PT21H'; -$interval = new DateInterval($interval_spec); -echo 'bs6 ' . $end->format($date_format) . " - $interval_spec = " - . $end->sub($interval)->format($date_format) . "\n"; - -$end = new DateTime('2010-11-07 01:30:00'); -$interval_spec = 'P1D'; -$interval = new DateInterval($interval_spec); -echo 'bs7 ' . $end->format($date_format) . " - $interval_spec = " - . $end->sub($interval)->format($date_format) . "\n"; - -$end = new DateTime('2010-11-07 01:30:00 EST'); -$end->setTimeZone($tz); -$interval_spec = 'P1DT1H'; -$interval = new DateInterval($interval_spec); -echo 'bs8 ' . $end->format($date_format) . " - $interval_spec = " - . $end->sub($interval)->format($date_format) . "\n"; - -$end = new DateTime('2010-11-07 03:30:00'); -$interval_spec = 'P1D'; -$interval = new DateInterval($interval_spec); -echo 'bs9 ' . $end->format($date_format) . " - $interval_spec = " - . $end->sub($interval)->format($date_format) . "\n"; - -$end = new DateTime('2010-11-07 02:30:00'); -$interval_spec = 'P1D'; -$interval = new DateInterval($interval_spec); -echo 'bs10 ' . $end->format($date_format) . " - $interval_spec = " - . $end->sub($interval)->format($date_format) . "\n"; - -?> ---EXPECT-- -fd1 2010-03-14 03:00:00 EDT America/New_York - 2010-03-14 01:59:59 EST America/New_York = PT0H0M1S -fd2 2010-03-14 04:30:00 EDT America/New_York - 2010-03-13 04:30:00 EST America/New_York = P1DT0H -fd3 2010-03-14 03:30:00 EDT America/New_York - 2010-03-13 04:30:00 EST America/New_York = P0DT22H -fd4 2010-03-14 01:30:00 EST America/New_York - 2010-03-13 04:30:00 EST America/New_York = P0DT21H -fd5 2010-03-14 01:30:00 EST America/New_York - 2010-03-13 01:30:00 EST America/New_York = P1DT0H -fd6 2010-03-14 03:30:00 EDT America/New_York - 2010-03-13 03:30:00 EST America/New_York = P1DT0H -fd7 2010-03-14 03:30:00 EDT America/New_York - 2010-03-13 02:30:00 EST America/New_York = P1DT1H - -fa1 2010-03-14 01:59:59 EST America/New_York + PT1S = 2010-03-14 03:00:00 EDT America/New_York -fa2 2010-03-13 04:30:00 EST America/New_York + P1D = 2010-03-14 04:30:00 EDT America/New_York -fa3 2010-03-13 04:30:00 EST America/New_York + PT22H = 2010-03-14 03:30:00 EDT America/New_York -fa4 2010-03-13 04:30:00 EST America/New_York + PT21H = 2010-03-14 01:30:00 EST America/New_York -fa5 2010-03-13 01:30:00 EST America/New_York + P1D = 2010-03-14 01:30:00 EST America/New_York -fa6 2010-03-13 02:30:00 EST America/New_York + P1D = 2010-03-14 03:30:00 EDT America/New_York - -fs1 2010-03-14 03:00:00 EDT America/New_York - PT1S = 2010-03-14 01:59:59 EST America/New_York -fs2 2010-03-14 04:30:00 EDT America/New_York - P1D = 2010-03-13 04:30:00 EST America/New_York -fs3 2010-03-14 03:30:00 EDT America/New_York - PT22H = 2010-03-13 04:30:00 EST America/New_York -fs4 2010-03-14 01:30:00 EST America/New_York - PT21H = 2010-03-13 04:30:00 EST America/New_York -fs5 2010-03-14 01:30:00 EST America/New_York - P1D = 2010-03-13 01:30:00 EST America/New_York -fs6 2010-03-15 03:30:00 EDT America/New_York - P1D = 2010-03-14 03:30:00 EDT America/New_York -fs7 2010-03-15 03:30:00 EDT America/New_York - P1D = 2010-03-14 03:30:00 EDT America/New_York - -bd1 2010-11-07 01:00:00 EST America/New_York - 2010-11-07 01:59:59 EDT America/New_York = PT0H0M1S -bd2 2010-11-07 04:30:00 EST America/New_York - 2010-11-06 04:30:00 EDT America/New_York = P1DT0H -bd3 2010-11-07 03:30:00 EST America/New_York - 2010-11-06 04:30:00 EDT America/New_York = P0DT24H -bd4 2010-11-07 02:30:00 EST America/New_York - 2010-11-06 04:30:00 EDT America/New_York = P0DT23H -bd5 2010-11-07 01:30:00 EST America/New_York - 2010-11-06 04:30:00 EDT America/New_York = P0DT22H -bd6 2010-11-07 01:30:00 EDT America/New_York - 2010-11-06 04:30:00 EDT America/New_York = P0DT21H -bd7 2010-11-07 01:30:00 EDT America/New_York - 2010-11-06 01:30:00 EDT America/New_York = P1DT0H -bd8 2010-11-07 01:30:00 EST America/New_York - 2010-11-06 01:30:00 EDT America/New_York = P1DT1H - -ba1 2010-11-07 01:59:59 EDT America/New_York + PT1S = 2010-11-07 01:00:00 EST America/New_York -ba2 2010-11-06 04:30:00 EDT America/New_York + P1D = 2010-11-07 04:30:00 EST America/New_York -ba3 2010-11-06 04:30:00 EDT America/New_York + PT24H = 2010-11-07 03:30:00 EST America/New_York -ba4 2010-11-06 04:30:00 EDT America/New_York + PT23H = 2010-11-07 02:30:00 EST America/New_York -ba5 2010-11-06 04:30:00 EDT America/New_York + PT22H = 2010-11-07 01:30:00 EST America/New_York -ba6 2010-11-06 04:30:00 EDT America/New_York + PT21H = 2010-11-07 01:30:00 EDT America/New_York -ba7 2010-11-06 01:30:00 EDT America/New_York + P1D = 2010-11-07 01:30:00 EDT America/New_York -ba8 2010-11-06 01:30:00 EDT America/New_York + P1DT1H = 2010-11-07 01:30:00 EST America/New_York -ba9 2010-11-06 04:30:00 EDT America/New_York + PT25H = 2010-11-07 04:30:00 EST America/New_York -ba10 2010-11-06 03:30:00 EDT America/New_York + P1D = 2010-11-07 03:30:00 EST America/New_York -ba11 2010-11-06 02:30:00 EDT America/New_York + P1D = 2010-11-07 02:30:00 EST America/New_York - -bs1 2010-11-07 01:00:00 EST America/New_York - PT1S = 2010-11-07 01:59:59 EDT America/New_York -bs2 2010-11-07 04:30:00 EST America/New_York - P1D = 2010-11-06 04:30:00 EDT America/New_York -bs3 2010-11-07 03:30:00 EST America/New_York - PT24H = 2010-11-06 04:30:00 EDT America/New_York -bs4 2010-11-07 02:30:00 EST America/New_York - PT23H = 2010-11-06 04:30:00 EDT America/New_York -bs5 2010-11-07 01:30:00 EST America/New_York - PT22H = 2010-11-06 04:30:00 EDT America/New_York -bs6 2010-11-07 01:30:00 EDT America/New_York - PT21H = 2010-11-06 04:30:00 EDT America/New_York -bs7 2010-11-07 01:30:00 EDT America/New_York - P1D = 2010-11-06 01:30:00 EDT America/New_York -bs8 2010-11-07 01:30:00 EST America/New_York - P1DT1H = 2010-11-06 00:30:00 EDT America/New_York -bs9 2010-11-07 03:30:00 EST America/New_York - P1D = 2010-11-06 03:30:00 EDT America/New_York -bs10 2010-11-07 02:30:00 EST America/New_York - P1D = 2010-11-06 02:30:00 EDT America/New_York diff --git a/ext/date/tests/strtotime3-64bit.phpt b/ext/date/tests/strtotime3-64bit.phpt index 7dc0816359da8..3a47659f868aa 100644 --- a/ext/date/tests/strtotime3-64bit.phpt +++ b/ext/date/tests/strtotime3-64bit.phpt @@ -53,7 +53,7 @@ bool(false) string(31) "Fri, 16 Jun 2006 23:49:12 +0100" bool(false) string(31) "Fri, 16 Jun 2006 02:22:00 +0100" -string(31) "Mon, 16 Jun 0222 02:22:00 -0036" +string(31) "Sun, 16 Jun 0222 02:22:00 -0036" string(31) "Fri, 16 Jun 2006 02:22:33 +0100" bool(false) string(31) "Tue, 02 Mar 2004 00:00:00 +0000" diff --git a/ext/date/tests/test-parse-from-format.phpt b/ext/date/tests/test-parse-from-format.phpt index 2bf9c4e1b8262..5bb5fe5325641 100644 --- a/ext/date/tests/test-parse-from-format.phpt +++ b/ext/date/tests/test-parse-from-format.phpt @@ -32,8 +32,8 @@ object(DateTime)#2 (3) { string(6) "+02:00" } -string(16) "l, d-M-y H:i:s T" -string(36) "Tuesday, 08-Jul-08 22:14:12 GMT+0200" +string(16) "l, d-M-Y H:i:s T" +string(38) "Tuesday, 08-Jul-2008 22:14:12 GMT+0200" object(DateTime)#1 (3) { ["date"]=> string(19) "2008-07-08 22:14:12" diff --git a/ext/dba/dba.c b/ext/dba/dba.c index 50a94dd2adca3..ced90f0c62299 100644 --- a/ext/dba/dba.c +++ b/ext/dba/dba.c @@ -625,7 +625,8 @@ static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, int persistent) char *file_mode; char mode[4], *pmode, *lock_file_mode = NULL; int persistent_flag = persistent ? STREAM_OPEN_PERSISTENT : 0; - char *opened_path, *lock_name; + char *opened_path = NULL; + char *lock_name; if(ac < 2) { WRONG_PARAM_COUNT; @@ -848,8 +849,10 @@ static void php_dba_open(INTERNAL_FUNCTION_PARAMETERS, int persistent) if (!persistent) { info->lock.name = opened_path; } else { - info->lock.name = pestrdup(opened_path, persistent); - efree(opened_path); + if (opened_path) { + info->lock.name = pestrdup(opened_path, persistent); + efree(opened_path); + } } } } diff --git a/ext/dba/dba_inifile.c b/ext/dba/dba_inifile.c index 05ee95c0ecbce..9461259f82bc1 100644 --- a/ext/dba/dba_inifile.c +++ b/ext/dba/dba_inifile.c @@ -124,14 +124,15 @@ DBA_EXISTS_FUNC(inifile) DBA_DELETE_FUNC(inifile) { int res; + zend_bool found = 0; INIFILE_DATA; INIFILE_GKEY; - res = inifile_delete(dba, &ini_key TSRMLS_CC); + res = inifile_delete_ex(dba, &ini_key, &found TSRMLS_CC); INIFILE_DONE; - return (res == -1 ? FAILURE : SUCCESS); + return (res == -1 || !found ? FAILURE : SUCCESS); } DBA_FIRSTKEY_FUNC(inifile) diff --git a/ext/dba/libinifile/inifile.c b/ext/dba/libinifile/inifile.c index cc09b3dd80cbc..5e4b22a732106 100644 --- a/ext/dba/libinifile/inifile.c +++ b/ext/dba/libinifile/inifile.c @@ -402,7 +402,7 @@ static int inifile_copy_to(inifile *dba, size_t pos_start, size_t pos_end, inifi return FAILURE; } php_stream_seek(dba->fp, pos_start, SEEK_SET); - if (!php_stream_copy_to_stream_ex(dba->fp, fp, pos_end - pos_start, NULL)) { + if (SUCCESS != php_stream_copy_to_stream_ex(dba->fp, fp, pos_end - pos_start, NULL)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not copy group [%zu - %zu] to temporary stream", pos_start, pos_end); return FAILURE; } @@ -413,7 +413,7 @@ static int inifile_copy_to(inifile *dba, size_t pos_start, size_t pos_end, inifi /* {{{ inifile_filter * copy from to dba while ignoring key name (group must equal) */ -static int inifile_filter(inifile *dba, inifile *from, const key_type *key TSRMLS_DC) +static int inifile_filter(inifile *dba, inifile *from, const key_type *key, zend_bool *found TSRMLS_DC) { size_t pos_start = 0, pos_next = 0, pos_curr; int ret = SUCCESS; @@ -424,10 +424,13 @@ static int inifile_filter(inifile *dba, inifile *from, const key_type *key TSRML while(inifile_read(from, &ln TSRMLS_CC)) { switch(inifile_key_cmp(&ln.key, key TSRMLS_CC)) { case 0: + if (found) { + *found = (zend_bool) 1; + } pos_curr = php_stream_tell(from->fp); if (pos_start != pos_next) { php_stream_seek(from->fp, pos_start, SEEK_SET); - if (!php_stream_copy_to_stream_ex(from->fp, dba->fp, pos_next - pos_start, NULL)) { + if (SUCCESS != php_stream_copy_to_stream_ex(from->fp, dba->fp, pos_next - pos_start, NULL)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not copy [%zu - %zu] from temporary stream", pos_next, pos_start); ret = FAILURE; } @@ -446,7 +449,7 @@ static int inifile_filter(inifile *dba, inifile *from, const key_type *key TSRML } if (pos_start != pos_next) { php_stream_seek(from->fp, pos_start, SEEK_SET); - if (!php_stream_copy_to_stream_ex(from->fp, dba->fp, pos_next - pos_start, NULL)) { + if (SUCCESS != php_stream_copy_to_stream_ex(from->fp, dba->fp, pos_next - pos_start, NULL)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not copy [%zu - %zu] from temporary stream", pos_next, pos_start); ret = FAILURE; } @@ -458,7 +461,7 @@ static int inifile_filter(inifile *dba, inifile *from, const key_type *key TSRML /* {{{ inifile_delete_replace_append */ -static int inifile_delete_replace_append(inifile *dba, const key_type *key, const val_type *value, int append TSRMLS_DC) +static int inifile_delete_replace_append(inifile *dba, const key_type *key, const val_type *value, int append, zend_bool *found TSRMLS_DC) { size_t pos_grp_start=0, pos_grp_next; inifile *ini_tmp = NULL; @@ -497,7 +500,7 @@ static int inifile_delete_replace_append(inifile *dba, const key_type *key, cons php_stream_seek(dba->fp, 0, SEEK_END); if (pos_grp_next != (size_t)php_stream_tell(dba->fp)) { php_stream_seek(dba->fp, pos_grp_next, SEEK_SET); - if (!php_stream_copy_to_stream_ex(dba->fp, fp_tmp, PHP_STREAM_COPY_ALL, NULL)) { + if (SUCCESS != php_stream_copy_to_stream_ex(dba->fp, fp_tmp, PHP_STREAM_COPY_ALL, NULL)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not copy remainder to temporary stream"); ret = FAILURE; } @@ -516,7 +519,7 @@ static int inifile_delete_replace_append(inifile *dba, const key_type *key, cons if (key->name && strlen(key->name)) { /* 6 */ if (!append && ini_tmp) { - ret = inifile_filter(dba, ini_tmp, key TSRMLS_CC); + ret = inifile_filter(dba, ini_tmp, key, found TSRMLS_CC); } /* 7 */ @@ -538,7 +541,7 @@ static int inifile_delete_replace_append(inifile *dba, const key_type *key, cons if (fp_tmp && php_stream_tell(fp_tmp)) { php_stream_seek(fp_tmp, 0, SEEK_SET); php_stream_seek(dba->fp, 0, SEEK_END); - if (!php_stream_copy_to_stream_ex(fp_tmp, dba->fp, PHP_STREAM_COPY_ALL, NULL)) { + if (SUCCESS != php_stream_copy_to_stream_ex(fp_tmp, dba->fp, PHP_STREAM_COPY_ALL, NULL)) { php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "Could not copy from temporary stream - ini file truncated"); ret = FAILURE; } @@ -563,7 +566,15 @@ static int inifile_delete_replace_append(inifile *dba, const key_type *key, cons */ int inifile_delete(inifile *dba, const key_type *key TSRMLS_DC) { - return inifile_delete_replace_append(dba, key, NULL, 0 TSRMLS_CC); + return inifile_delete_replace_append(dba, key, NULL, 0, NULL TSRMLS_CC); +} +/* }}} */ + +/* {{{ inifile_delete_ex + */ +int inifile_delete_ex(inifile *dba, const key_type *key, zend_bool *found TSRMLS_DC) +{ + return inifile_delete_replace_append(dba, key, NULL, 0, found TSRMLS_CC); } /* }}} */ @@ -571,7 +582,15 @@ int inifile_delete(inifile *dba, const key_type *key TSRMLS_DC) */ int inifile_replace(inifile *dba, const key_type *key, const val_type *value TSRMLS_DC) { - return inifile_delete_replace_append(dba, key, value, 0 TSRMLS_CC); + return inifile_delete_replace_append(dba, key, value, 0, NULL TSRMLS_CC); +} +/* }}} */ + +/* {{{ inifile_replace_ex + */ +int inifile_replace_ex(inifile *dba, const key_type *key, const val_type *value, zend_bool *found TSRMLS_DC) +{ + return inifile_delete_replace_append(dba, key, value, 0, found TSRMLS_CC); } /* }}} */ @@ -579,7 +598,7 @@ int inifile_replace(inifile *dba, const key_type *key, const val_type *value TSR */ int inifile_append(inifile *dba, const key_type *key, const val_type *value TSRMLS_DC) { - return inifile_delete_replace_append(dba, key, value, 1 TSRMLS_CC); + return inifile_delete_replace_append(dba, key, value, 1, NULL TSRMLS_CC); } /* }}} */ diff --git a/ext/dba/libinifile/inifile.h b/ext/dba/libinifile/inifile.h index 5a255738925da..8556b8d2e59a0 100644 --- a/ext/dba/libinifile/inifile.h +++ b/ext/dba/libinifile/inifile.h @@ -49,7 +49,9 @@ val_type inifile_fetch(inifile *dba, const key_type *key, int skip TSRMLS_DC); int inifile_firstkey(inifile *dba TSRMLS_DC); int inifile_nextkey(inifile *dba TSRMLS_DC); int inifile_delete(inifile *dba, const key_type *key TSRMLS_DC); +int inifile_delete_ex(inifile *dba, const key_type *key, zend_bool *found TSRMLS_DC); int inifile_replace(inifile *dba, const key_type *key, const val_type *val TSRMLS_DC); +int inifile_replace_ex(inifile *dba, const key_type *key, const val_type *val, zend_bool *found TSRMLS_DC); int inifile_append(inifile *dba, const key_type *key, const val_type *val TSRMLS_DC); char *inifile_version(); diff --git a/ext/dba/tests/bug62490.phpt b/ext/dba/tests/bug62490.phpt new file mode 100644 index 0000000000000..325dd34554170 --- /dev/null +++ b/ext/dba/tests/bug62490.phpt @@ -0,0 +1,43 @@ +--TEST-- +Bug #62490 (dba_delete returns true on missing item (inifile)) +--SKIPIF-- + +--FILE-- + +===DONE=== +--CLEAN-- + +--EXPECT-- +insert 0:bool(true) +insert 1:bool(true) +insert 2:bool(true) +exists:bool(true) +delete:bool(true) +exists:bool(false) +delete:bool(false) +===DONE=== diff --git a/ext/dba/tests/dba_db4_003.phpt b/ext/dba/tests/dba_db4_003.phpt index 7e8568c0855f3..8708170fc1bcd 100644 --- a/ext/dba/tests/dba_db4_003.phpt +++ b/ext/dba/tests/dba_db4_003.phpt @@ -39,8 +39,6 @@ require(dirname(__FILE__) .'/clean.inc'); database handler: db4 int(14) -Notice: dba_open(): %stest0.dbm: unexpected file type or format in %sdba_db4_003.php on line %d - Warning: dba_open(%stest0.dbm,c): Driver initialization failed for handler: db4: Invalid argument in %sdba_db4_003.php on line %d Error creating %stest0.dbm Dummy contents diff --git a/ext/dba/tests/dba_db4_007.phpt b/ext/dba/tests/dba_db4_007.phpt index bd95e0bec74dd..027d0af032911 100644 --- a/ext/dba/tests/dba_db4_007.phpt +++ b/ext/dba/tests/dba_db4_007.phpt @@ -35,7 +35,5 @@ require(dirname(__FILE__) .'/clean.inc'); database handler: db4 int(14) -Notice: dba_popen(): %stest0.dbm: unexpected file type or format in %sdba_db4_007.php on line %d - Warning: dba_popen(%stest0.dbm,c): Driver initialization failed for handler: db4: Invalid argument in %sdba_db4_007.php on line %d Error creating %stest0.dbm diff --git a/ext/dba/tests/dba_db4_010.phpt b/ext/dba/tests/dba_db4_010.phpt deleted file mode 100644 index fb31f0583501c..0000000000000 --- a/ext/dba/tests/dba_db4_010.phpt +++ /dev/null @@ -1,38 +0,0 @@ ---TEST-- -DBA DB4 magic_quotes_runtime Test ---SKIPIF-- - ---FILE-- - ---CLEAN-- - ---EXPECTF-- -database handler: db4 -string(1) """ -string(2) "\"" -string(2) "\"" -string(1) """ diff --git a/ext/dba/tests/dba_handler.inc b/ext/dba/tests/dba_handler.inc index a950e903af426..ed2a52400aceb 100644 --- a/ext/dba/tests/dba_handler.inc +++ b/ext/dba/tests/dba_handler.inc @@ -82,7 +82,7 @@ do { dba_close($dba_reader); } if (($db_file = dba_popen($db_filename, 'r'.($lock_flag==''?'':'-'), $handler))!==FALSE) { - if ($handler == 'dbm') { + if ($handler == 'dbm' || $handler == "tcadb") { dba_close($db_file); } } diff --git a/ext/dba/tests/dba_inifile.phpt b/ext/dba/tests/dba_inifile.phpt index 5975d25f4dc54..ae06aee09f4bf 100644 --- a/ext/dba/tests/dba_inifile.phpt +++ b/ext/dba/tests/dba_inifile.phpt @@ -12,6 +12,10 @@ DBA INIFILE handler test require_once dirname(__FILE__) .'/dba_handler.inc'; ?> ===DONE=== +--CLEAN-- + --EXPECT-- database handler: inifile 3NYNYY @@ -19,7 +23,7 @@ Content String 2 Content 2 replaced Read during write: not allowed "key number 6" written -Failed to write "key number 6" 2nd time +"key number 6" written 2nd time Content 2 replaced 2nd time The 6th value array(3) { @@ -36,7 +40,7 @@ Content String 2 Content 2 replaced Read during write: not allowed "key number 6" written -Failed to write "key number 6" 2nd time +"key number 6" written 2nd time Content 2 replaced 2nd time The 6th value array(3) { diff --git a/ext/dba/tests/dba_tcadb.phpt b/ext/dba/tests/dba_tcadb.phpt index 28b6dd8f0b5a0..f75aa813d4838 100644 --- a/ext/dba/tests/dba_tcadb.phpt +++ b/ext/dba/tests/dba_tcadb.phpt @@ -16,6 +16,12 @@ DBA TCADB handler test require_once dirname(__FILE__) .'/dba_handler.inc'; ?> ===DONE=== +--CLEAN-- + --EXPECT-- database handler: tcadb 3NYNYY diff --git a/ext/dom/document.c b/ext/dom/document.c index efe6d9070fb7c..cca77ff9df9cb 100644 --- a/ext/dom/document.c +++ b/ext/dom/document.c @@ -2304,7 +2304,7 @@ PHP_FUNCTION(dom_document_save_html) xmlBufferPtr buf; dom_object *intern, *nodeobj; xmlChar *mem = NULL; - int size, format; + int size = 0, format; dom_doc_propsptr doc_props; if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), @@ -2332,7 +2332,22 @@ PHP_FUNCTION(dom_document_save_html) RETURN_FALSE; } - size = htmlNodeDump(buf, docp, node); + if (node->type == XML_DOCUMENT_FRAG_NODE) { + int one_size; + + for (node = node->children; node; node = node->next) { + one_size = htmlNodeDump(buf, docp, node); + + if (one_size >= 0) { + size += one_size; + } else { + size = -1; + break; + } + } + } else { + size = htmlNodeDump(buf, docp, node); + } if (size >= 0) { mem = (xmlChar*) xmlBufferContent(buf); if (!mem) { diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c index db8ec83a44391..529fe8dfa26d5 100644 --- a/ext/dom/php_dom.c +++ b/ext/dom/php_dom.c @@ -448,7 +448,7 @@ static int dom_property_exists(zval *object, zval *member, int check_empty, cons Z_SET_REFCOUNT_P(tmp, 1); Z_UNSET_ISREF_P(tmp); if (check_empty == 1) { - retval = zend_is_true(tmp); + retval = zend_is_true(tmp TSRMLS_CC); } else if (check_empty == 0) { retval = (Z_TYPE_P(tmp) != IS_NULL); } diff --git a/ext/dom/tests/bug65196.phpt b/ext/dom/tests/bug65196.phpt new file mode 100644 index 0000000000000..c77f97222f18d --- /dev/null +++ b/ext/dom/tests/bug65196.phpt @@ -0,0 +1,26 @@ +--TEST-- +bug #65196 (Passing DOMDocumentFragment to DOMDocument::saveHTML() Produces invalid Markup) +--SKIPIF-- + +--FILE-- +createDocumentFragment(); +var_dump($dom->saveHTML($frag1)); + +$frag2 = $dom->createDocumentFragment(); +$div = $dom->createElement('div'); +$div->appendChild($dom->createElement('span')); +$frag2->appendChild($div); +$frag2->appendChild($dom->createElement('div')); +$frag2->appendChild($dom->createElement('div')); +var_dump($dom->saveHTML($frag2)); +?> +===DONE=== +--EXPECT-- +string(0) "" +string(46) "
" +===DONE=== diff --git a/ext/exif/exif.c b/ext/exif/exif.c index ec121a6c326bc..eb00f04327e6f 100644 --- a/ext/exif/exif.c +++ b/ext/exif/exif.c @@ -2633,6 +2633,7 @@ static int exif_process_user_comment(image_info_type *ImageInfo, char **pszInfoP } else { decode = ImageInfo->decode_unicode_le; } + /* XXX this will fail again if encoding_converter returns on error something different than SIZE_MAX */ if (zend_multibyte_encoding_converter( (unsigned char**)pszInfoPtr, &len, @@ -2640,7 +2641,7 @@ static int exif_process_user_comment(image_info_type *ImageInfo, char **pszInfoP ByteCount, zend_multibyte_fetch_encoding(ImageInfo->encode_unicode TSRMLS_CC), zend_multibyte_fetch_encoding(decode TSRMLS_CC) - TSRMLS_CC) < 0) { + TSRMLS_CC) == (size_t)-1) { len = exif_process_string_raw(pszInfoPtr, szValuePtr, ByteCount); } return len; @@ -2653,6 +2654,7 @@ static int exif_process_user_comment(image_info_type *ImageInfo, char **pszInfoP *pszEncoding = estrdup((const char*)szValuePtr); szValuePtr = szValuePtr+8; ByteCount -= 8; + /* XXX this will fail again if encoding_converter returns on error something different than SIZE_MAX */ if (zend_multibyte_encoding_converter( (unsigned char**)pszInfoPtr, &len, @@ -2660,7 +2662,7 @@ static int exif_process_user_comment(image_info_type *ImageInfo, char **pszInfoP ByteCount, zend_multibyte_fetch_encoding(ImageInfo->encode_jis TSRMLS_CC), zend_multibyte_fetch_encoding(ImageInfo->motorola_intel ? ImageInfo->decode_jis_be : ImageInfo->decode_jis_le TSRMLS_CC) - TSRMLS_CC) < 0) { + TSRMLS_CC) == (size_t)-1) { len = exif_process_string_raw(pszInfoPtr, szValuePtr, ByteCount); } return len; @@ -2690,8 +2692,8 @@ static int exif_process_user_comment(image_info_type *ImageInfo, char **pszInfoP static int exif_process_unicode(image_info_type *ImageInfo, xp_field_type *xp_field, int tag, char *szValuePtr, int ByteCount TSRMLS_DC) { xp_field->tag = tag; - - /* Copy the comment */ + + /* XXX this will fail again if encoding_converter returns on error something different than SIZE_MAX */ if (zend_multibyte_encoding_converter( (unsigned char**)&xp_field->value, &xp_field->size, @@ -2699,7 +2701,7 @@ static int exif_process_unicode(image_info_type *ImageInfo, xp_field_type *xp_fi ByteCount, zend_multibyte_fetch_encoding(ImageInfo->encode_unicode TSRMLS_CC), zend_multibyte_fetch_encoding(ImageInfo->motorola_intel ? ImageInfo->decode_unicode_be : ImageInfo->decode_unicode_le TSRMLS_CC) - TSRMLS_CC) < 0) { + TSRMLS_CC) == (size_t)-1) { xp_field->size = exif_process_string_raw(&xp_field->value, szValuePtr, ByteCount); } return xp_field->size; @@ -2840,7 +2842,12 @@ static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, cha offset_val = php_ifd_get32u(dir_entry+8, ImageInfo->motorola_intel); /* If its bigger than 4 bytes, the dir entry contains an offset. */ value_ptr = offset_base+offset_val; - if (byte_count > IFDlength || offset_val > IFDlength-byte_count || value_ptr < dir_entry) { + /* + dir_entry is ImageInfo->file.list[sn].data+2+i*12 + offset_base is ImageInfo->file.list[sn].data-dir_offset + dir_entry - offset_base is dir_offset+2+i*12 + */ + if (byte_count > IFDlength || offset_val > IFDlength-byte_count || value_ptr < dir_entry || offset_val < (size_t)(dir_entry-offset_base)) { /* It is important to check for IMAGE_FILETYPE_TIFF * JPEG does not use absolute pointers instead its pointers are * relative to the start of the TIFF header in APP1 section. */ diff --git a/ext/exif/tests/bug62523_1.jpg b/ext/exif/tests/bug62523_1.jpg new file mode 100644 index 0000000000000..9a63d1e84d90b --- /dev/null +++ b/ext/exif/tests/bug62523_1.jpg @@ -0,0 +1,9 @@ + + +301 Moved Permanently + +

Moved Permanently

+

The document has moved here.

+
+
Apache Server at getid3.org Port 80
+ diff --git a/ext/exif/tests/bug62523_1.phpt b/ext/exif/tests/bug62523_1.phpt new file mode 100644 index 0000000000000..28d42f021d073 --- /dev/null +++ b/ext/exif/tests/bug62523_1.phpt @@ -0,0 +1,18 @@ +--TEST-- +Bug 62523 (php crashes with segfault when exif_read_data called) +--SKIPIF-- + +--FILE-- + +Done +--EXPECTF-- +Test + +Warning: exif_read_data(bug62523_1.jpg): File not supported in %sbug62523_1.php on line %d +int(1) +Done diff --git a/ext/exif/tests/bug62523_2.jpg b/ext/exif/tests/bug62523_2.jpg new file mode 100644 index 0000000000000..8d7fc6c5f41ba Binary files /dev/null and b/ext/exif/tests/bug62523_2.jpg differ diff --git a/ext/exif/tests/bug62523_2.phpt b/ext/exif/tests/bug62523_2.phpt new file mode 100644 index 0000000000000..ddc8ae824e82e --- /dev/null +++ b/ext/exif/tests/bug62523_2.phpt @@ -0,0 +1,16 @@ +--TEST-- +Bug 62523 (php crashes with segfault when exif_read_data called) +--SKIPIF-- + +--FILE-- + +Done +--EXPECT-- +Test +int(76) +Done diff --git a/ext/exif/tests/bug62523_3.jpg b/ext/exif/tests/bug62523_3.jpg new file mode 100644 index 0000000000000..3ee91368ceb86 --- /dev/null +++ b/ext/exif/tests/bug62523_3.jpg @@ -0,0 +1,12 @@ + + Found + +

Found

+

The resource was found at http://dl.dropboxusercontent.com/u/7562584/Bugs/Php/bad_exif.jpeg; +you should be redirected automatically. + +

+
+
WSGI Server
+ + diff --git a/ext/exif/tests/bug62523_3.phpt b/ext/exif/tests/bug62523_3.phpt new file mode 100644 index 0000000000000..6e11354c5a725 --- /dev/null +++ b/ext/exif/tests/bug62523_3.phpt @@ -0,0 +1,18 @@ +--TEST-- +Bug 62523 (php crashes with segfault when exif_read_data called) +--SKIPIF-- + +--FILE-- + +Done +--EXPECTF-- +Test + +Warning: exif_read_data(bug62523_3.jpg): File not supported in %sbug62523_3.php on line %d +int(1) +Done diff --git a/ext/exif/tests/exif_encoding_crash.jpg b/ext/exif/tests/exif_encoding_crash.jpg new file mode 100644 index 0000000000000..55138abe55210 Binary files /dev/null and b/ext/exif/tests/exif_encoding_crash.jpg differ diff --git a/ext/exif/tests/exif_encoding_crash.phpt b/ext/exif/tests/exif_encoding_crash.phpt new file mode 100644 index 0000000000000..1c4ad63860346 --- /dev/null +++ b/ext/exif/tests/exif_encoding_crash.phpt @@ -0,0 +1,14 @@ +--TEST-- +PHP crash when zend_multibyte_encoding_converter returns (size_t)-1) +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECT-- +*** no core dump *** +===DONE=== diff --git a/ext/filter/logical_filters.c b/ext/filter/logical_filters.c index 653cce23e6b26..a6c8056acb313 100644 --- a/ext/filter/logical_filters.c +++ b/ext/filter/logical_filters.c @@ -714,9 +714,7 @@ void php_filter_validate_ip(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ if (flags & FILTER_FLAG_NO_RES_RANGE) { if ( (ip[0] == 0) || - (ip[0] == 100 && (ip[1] >= 64 || ip[1] <= 127)) || - (ip[0] == 128 && ip[1] == 0) || - (ip[0] == 191 && ip[1] == 255) || + (ip[0] == 100 && (ip[1] >= 64 && ip[1] <= 127)) || (ip[0] == 169 && ip[1] == 254) || (ip[0] == 192 && ip[1] == 0 && ip[2] == 2) || (ip[0] == 127 && ip[1] == 0 && ip[2] == 0 && ip[3] == 1) || diff --git a/ext/filter/tests/018.phpt b/ext/filter/tests/018.phpt index 9c73fc3cfc4e6..75bbd13427994 100644 --- a/ext/filter/tests/018.phpt +++ b/ext/filter/tests/018.phpt @@ -15,7 +15,7 @@ var_dump(filter_var("192.168.0.1", FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE var_dump(filter_var("192.0.34.166", FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE)); var_dump(filter_var("127.0.0.1", FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE)); var_dump(filter_var("192.0.0.1", FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE)); -var_dump(filter_var("100.0.0.0", FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE)); +var_dump(filter_var("100.64.0.0", FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE)); var_dump(filter_var("100.127.255.255", FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE)); var_dump(filter_var("192.0.34.166", FILTER_VALIDATE_IP)); var_dump(filter_var("256.1237.123.1", FILTER_VALIDATE_IP)); diff --git a/ext/filter/tests/bug53150.phpt b/ext/filter/tests/bug53150.phpt index 4baa4db772ae7..4906888bdf779 100644 --- a/ext/filter/tests/bug53150.phpt +++ b/ext/filter/tests/bug53150.phpt @@ -23,6 +23,6 @@ string(3) "::1" bool(false) bool(false) string(9) "128.0.0.1" -bool(false) +string(9) "128.0.0.1" +string(11) "191.255.0.0" string(11) "191.255.0.0" -bool(false) diff --git a/ext/ftp/ftp.c b/ext/ftp/ftp.c index 2c5bc5d7e39e0..30b3ba6285042 100644 --- a/ext/ftp/ftp.c +++ b/ext/ftp/ftp.c @@ -630,7 +630,7 @@ ftp_alloc(ftpbuf_t *ftp, const long size, char **response) return 0; } - if (response && ftp->inbuf) { + if (response) { *response = estrdup(ftp->inbuf); } @@ -1638,7 +1638,7 @@ ftp_genlist(ftpbuf_t *ftp, const char *cmd, const char *path TSRMLS_DC) if (ftp->resp == 226) { ftp->data = data_close(ftp, data); php_stream_close(tmpstream); - return ecalloc(1, sizeof(char**)); + return ecalloc(1, sizeof(char*)); } /* pull data buffer into tmpfile */ @@ -1666,11 +1666,11 @@ ftp_genlist(ftpbuf_t *ftp, const char *cmd, const char *path TSRMLS_DC) } } - ftp->data = data = data_close(ftp, data); + ftp->data = data_close(ftp, data); php_stream_rewind(tmpstream); - ret = safe_emalloc((lines + 1), sizeof(char**), size * sizeof(char*)); + ret = safe_emalloc((lines + 1), sizeof(char*), size); entry = ret; text = (char*) (ret + lines + 1); diff --git a/ext/ftp/php_ftp.c b/ext/ftp/php_ftp.c index da22e0b63eb3a..21e13ea460563 100644 --- a/ext/ftp/php_ftp.c +++ b/ext/ftp/php_ftp.c @@ -968,7 +968,9 @@ PHP_FUNCTION(ftp_nb_get) RETURN_LONG(PHP_FTP_FAILED); } - php_stream_close(outstream); + if (ret == PHP_FTP_FINISHED){ + php_stream_close(outstream); + } RETURN_LONG(ret); } diff --git a/ext/ftp/tests/ftp_fget_basic1.phpt b/ext/ftp/tests/ftp_fget_basic1.phpt index 475f7183d2532..5909d35cef608 100644 --- a/ext/ftp/tests/ftp_fget_basic1.phpt +++ b/ext/ftp/tests/ftp_fget_basic1.phpt @@ -16,7 +16,7 @@ ftp_login($ftp, 'user', 'pass'); if (!$ftp) die("Couldn't connect to the server"); ftp_set_option($ftp, FTP_AUTOSEEK, false); -$local_file = dirname(__FILE__) . DIRECTORY_SEPARATOR . "localfile.txt"; +$local_file = dirname(__FILE__) . DIRECTORY_SEPARATOR . "ftp_fget_basic1.txt"; $handle = fopen($local_file, 'w'); var_dump(ftp_fget($ftp, $handle, 'fget.txt', FTP_ASCII, FTP_AUTORESUME)); @@ -24,7 +24,7 @@ var_dump(file_get_contents($local_file)); ?> --CLEAN-- --EXPECT-- bool(true) diff --git a/ext/ftp/tests/ftp_fget_basic2.phpt b/ext/ftp/tests/ftp_fget_basic2.phpt index 00a26752d9150..622cea3683b0d 100644 --- a/ext/ftp/tests/ftp_fget_basic2.phpt +++ b/ext/ftp/tests/ftp_fget_basic2.phpt @@ -15,7 +15,7 @@ $ftp = ftp_connect('127.0.0.1', $port); ftp_login($ftp, 'user', 'pass'); if (!$ftp) die("Couldn't connect to the server"); -$local_file = dirname(__FILE__) . DIRECTORY_SEPARATOR . "localfile.txt"; +$local_file = dirname(__FILE__) . DIRECTORY_SEPARATOR . "ftp_fget_basic2.txt"; file_put_contents($local_file, 'ASCIIFoo'); $handle = fopen($local_file, 'a'); @@ -24,7 +24,7 @@ var_dump(file_get_contents($local_file)); ?> --CLEAN-- --EXPECT-- bool(true) diff --git a/ext/ftp/tests/ftp_fget_basic3.phpt b/ext/ftp/tests/ftp_fget_basic3.phpt index b7098701ab12e..9485473b1c6a3 100644 --- a/ext/ftp/tests/ftp_fget_basic3.phpt +++ b/ext/ftp/tests/ftp_fget_basic3.phpt @@ -15,7 +15,7 @@ $ftp = ftp_connect('127.0.0.1', $port); ftp_login($ftp, 'user', 'pass'); if (!$ftp) die("Couldn't connect to the server"); -$local_file = dirname(__FILE__) . DIRECTORY_SEPARATOR . "localfile.txt"; +$local_file = dirname(__FILE__) . DIRECTORY_SEPARATOR . "ftp_fget_basic3.txt"; file_put_contents($local_file, 'ASCIIFoo'); $handle = fopen($local_file, 'a'); @@ -24,7 +24,7 @@ var_dump(file_get_contents($local_file)); ?> --CLEAN-- --EXPECT-- bool(true) diff --git a/ext/ftp/tests/ftp_nb_continue.phpt b/ext/ftp/tests/ftp_nb_continue.phpt new file mode 100644 index 0000000000000..1f703399139bf --- /dev/null +++ b/ext/ftp/tests/ftp_nb_continue.phpt @@ -0,0 +1,182 @@ +--TEST-- +Testing whether ftp_nb_continue() fetches more data +--SKIPIF-- + +--FILE-- + +--CLEAN-- + +--EXPECT-- +This is line 0 of the test data. +This is line 1 of the test data. +This is line 2 of the test data. +This is line 3 of the test data. +This is line 4 of the test data. +This is line 5 of the test data. +This is line 6 of the test data. +This is line 7 of the test data. +This is line 8 of the test data. +This is line 9 of the test data. +This is line 10 of the test data. +This is line 11 of the test data. +This is line 12 of the test data. +This is line 13 of the test data. +This is line 14 of the test data. +This is line 15 of the test data. +This is line 16 of the test data. +This is line 17 of the test data. +This is line 18 of the test data. +This is line 19 of the test data. +This is line 20 of the test data. +This is line 21 of the test data. +This is line 22 of the test data. +This is line 23 of the test data. +This is line 24 of the test data. +This is line 25 of the test data. +This is line 26 of the test data. +This is line 27 of the test data. +This is line 28 of the test data. +This is line 29 of the test data. +This is line 30 of the test data. +This is line 31 of the test data. +This is line 32 of the test data. +This is line 33 of the test data. +This is line 34 of the test data. +This is line 35 of the test data. +This is line 36 of the test data. +This is line 37 of the test data. +This is line 38 of the test data. +This is line 39 of the test data. +This is line 40 of the test data. +This is line 41 of the test data. +This is line 42 of the test data. +This is line 43 of the test data. +This is line 44 of the test data. +This is line 45 of the test data. +This is line 46 of the test data. +This is line 47 of the test data. +This is line 48 of the test data. +This is line 49 of the test data. +This is line 50 of the test data. +This is line 51 of the test data. +This is line 52 of the test data. +This is line 53 of the test data. +This is line 54 of the test data. +This is line 55 of the test data. +This is line 56 of the test data. +This is line 57 of the test data. +This is line 58 of the test data. +This is line 59 of the test data. +This is line 60 of the test data. +This is line 61 of the test data. +This is line 62 of the test data. +This is line 63 of the test data. +This is line 64 of the test data. +This is line 65 of the test data. +This is line 66 of the test data. +This is line 67 of the test data. +This is line 68 of the test data. +This is line 69 of the test data. +This is line 70 of the test data. +This is line 71 of the test data. +This is line 72 of the test data. +This is line 73 of the test data. +This is line 74 of the test data. +This is line 75 of the test data. +This is line 76 of the test data. +This is line 77 of the test data. +This is line 78 of the test data. +This is line 79 of the test data. +This is line 80 of the test data. +This is line 81 of the test data. +This is line 82 of the test data. +This is line 83 of the test data. +This is line 84 of the test data. +This is line 85 of the test data. +This is line 86 of the test data. +This is line 87 of the test data. +This is line 88 of the test data. +This is line 89 of the test data. +This is line 90 of the test data. +This is line 91 of the test data. +This is line 92 of the test data. +This is line 93 of the test data. +This is line 94 of the test data. +This is line 95 of the test data. +This is line 96 of the test data. +This is line 97 of the test data. +This is line 98 of the test data. +This is line 99 of the test data. +This is line 100 of the test data. +This is line 101 of the test data. +This is line 102 of the test data. +This is line 103 of the test data. +This is line 104 of the test data. +This is line 105 of the test data. +This is line 106 of the test data. +This is line 107 of the test data. +This is line 108 of the test data. +This is line 109 of the test data. +This is line 110 of the test data. +This is line 111 of the test data. +This is line 112 of the test data. +This is line 113 of the test data. +This is line 114 of the test data. +This is line 115 of the test data. +This is line 116 of the test data. +This is line 117 of the test data. +This is line 118 of the test data. +This is line 119 of the test data. +This is line 120 of the test data. +This is line 121 of the test data. +This is line 122 of the test data. +This is line 123 of the test data. +This is line 124 of the test data. +This is line 125 of the test data. +This is line 126 of the test data. +This is line 127 of the test data. +This is line 128 of the test data. +This is line 129 of the test data. +This is line 130 of the test data. +This is line 131 of the test data. +This is line 132 of the test data. +This is line 133 of the test data. +This is line 134 of the test data. +This is line 135 of the test data. +This is line 136 of the test data. +This is line 137 of the test data. +This is line 138 of the test data. +This is line 139 of the test data. +This is line 140 of the test data. +This is line 141 of the test data. +This is line 142 of the test data. +This is line 143 of the test data. +This is line 144 of the test data. +This is line 145 of the test data. +This is line 146 of the test data. +This is line 147 of the test data. +This is line 148 of the test data. +This is line 149 of the test data. diff --git a/ext/ftp/tests/ftp_nb_fget_basic1.phpt b/ext/ftp/tests/ftp_nb_fget_basic1.phpt index cac4eec56bc99..5e6389ff1336a 100644 --- a/ext/ftp/tests/ftp_nb_fget_basic1.phpt +++ b/ext/ftp/tests/ftp_nb_fget_basic1.phpt @@ -16,7 +16,7 @@ ftp_login($ftp, 'user', 'pass'); if (!$ftp) die("Couldn't connect to the server"); ftp_set_option($ftp, FTP_AUTOSEEK, false); -$local_file = dirname(__FILE__) . DIRECTORY_SEPARATOR . "localfile.txt"; +$local_file = dirname(__FILE__) . DIRECTORY_SEPARATOR . "ftp_nb_fget_basic1.txt"; $handle = fopen($local_file, 'w'); var_dump(ftp_nb_fget($ftp, $handle, 'fget.txt', FTP_ASCII, FTP_AUTORESUME)); @@ -24,7 +24,7 @@ var_dump(file_get_contents($local_file)); ?> --CLEAN-- --EXPECT-- int(2) diff --git a/ext/ftp/tests/ftp_nb_fget_basic2.phpt b/ext/ftp/tests/ftp_nb_fget_basic2.phpt index dc92f4e23bc99..215b79ac4a986 100644 --- a/ext/ftp/tests/ftp_nb_fget_basic2.phpt +++ b/ext/ftp/tests/ftp_nb_fget_basic2.phpt @@ -15,7 +15,7 @@ $ftp = ftp_connect('127.0.0.1', $port); ftp_login($ftp, 'user', 'pass'); if (!$ftp) die("Couldn't connect to the server"); -$local_file = dirname(__FILE__) . DIRECTORY_SEPARATOR . "localfile.txt"; +$local_file = dirname(__FILE__) . DIRECTORY_SEPARATOR . "ftp_nb_fget_basic2.txt"; file_put_contents($local_file, 'ASCIIFoo'); $handle = fopen($local_file, 'a'); @@ -24,7 +24,7 @@ var_dump(file_get_contents($local_file)); ?> --CLEAN-- --EXPECT-- int(2) diff --git a/ext/ftp/tests/ftp_nb_fget_basic3.phpt b/ext/ftp/tests/ftp_nb_fget_basic3.phpt index d1a87c4f3dfe3..66daf2ba0a030 100644 --- a/ext/ftp/tests/ftp_nb_fget_basic3.phpt +++ b/ext/ftp/tests/ftp_nb_fget_basic3.phpt @@ -15,7 +15,7 @@ $ftp = ftp_connect('127.0.0.1', $port); ftp_login($ftp, 'user', 'pass'); if (!$ftp) die("Couldn't connect to the server"); -$local_file = dirname(__FILE__) . DIRECTORY_SEPARATOR . "localfile.txt"; +$local_file = dirname(__FILE__) . DIRECTORY_SEPARATOR . "ftp_nb_fget_basic3.txt"; file_put_contents($local_file, 'ASCIIFoo'); $handle = fopen($local_file, 'a'); @@ -24,7 +24,7 @@ var_dump(file_get_contents($local_file)); ?> --CLEAN-- --EXPECT-- int(2) diff --git a/ext/ftp/tests/ftp_nb_get_large.phpt b/ext/ftp/tests/ftp_nb_get_large.phpt index 3fbf2a4831d14..0c354d7c1978f 100644 --- a/ext/ftp/tests/ftp_nb_get_large.phpt +++ b/ext/ftp/tests/ftp_nb_get_large.phpt @@ -18,7 +18,7 @@ $ftp = ftp_connect('127.0.0.1', $port); ftp_login($ftp, 'user', 'pass'); if (!$ftp) die("Couldn't connect to the server"); -$local_file = dirname(__FILE__) . DIRECTORY_SEPARATOR . "localfile.txt"; +$local_file = dirname(__FILE__) . DIRECTORY_SEPARATOR . "ftp_nb_get_large.txt"; touch($local_file); ftp_nb_get($ftp, $local_file, 'fget_large.txt', FTP_BINARY, 5368709119); $fp = fopen($local_file, 'r'); @@ -29,7 +29,7 @@ fclose($fp); ?> --CLEAN-- --EXPECT-- string(1) "X" diff --git a/ext/ftp/tests/server.inc b/ext/ftp/tests/server.inc index 7dc8fa08d99ff..bb0c1ff10bec9 100644 --- a/ext/ftp/tests/server.inc +++ b/ext/ftp/tests/server.inc @@ -368,6 +368,13 @@ if ($pid) { } fputs($s, "226 Closing data Connection.\r\n"); break; + case "mediumfile": + fputs($s, "150 File status okay; about to open data connection.\r\n"); + for($i = 0; $i < 150; $i++){ + fputs($fs, "This is line $i of the test data.\n"); + } + fputs($s, "226 Closing data Connection.\r\n"); + default: fputs($s, "550 {$matches[1]}: No such file or directory \r\n"); break; diff --git a/ext/gd/config.m4 b/ext/gd/config.m4 index c9e080faab7cd..446c2425ae791 100644 --- a/ext/gd/config.m4 +++ b/ext/gd/config.m4 @@ -185,30 +185,25 @@ AC_DEFUN([PHP_GD_FREETYPE2],[ if test "$PHP_FREETYPE_DIR" != "no"; then for i in $PHP_FREETYPE_DIR /usr/local /usr; do - if test -f "$i/include/freetype2/freetype/freetype.h"; then + if test -f "$i/bin/freetype-config"; then FREETYPE2_DIR=$i - FREETYPE2_INC_DIR=$i/include/freetype2 + FREETYPE2_CONFIG="$i/bin/freetype-config" break fi done if test -z "$FREETYPE2_DIR"; then - AC_MSG_ERROR([freetype.h not found.]) + AC_MSG_ERROR([freetype-config not found.]) fi - PHP_CHECK_LIBRARY(freetype, FT_New_Face, - [ - PHP_ADD_LIBRARY_WITH_PATH(freetype, $FREETYPE2_DIR/$PHP_LIBDIR, GD_SHARED_LIBADD) - PHP_ADD_INCLUDE($FREETYPE2_DIR/include) - PHP_ADD_INCLUDE($FREETYPE2_INC_DIR) - AC_DEFINE(USE_GD_IMGSTRTTF, 1, [ ]) - AC_DEFINE(HAVE_LIBFREETYPE,1,[ ]) - AC_DEFINE(ENABLE_GD_TTF,1,[ ]) - ],[ - AC_MSG_ERROR([Problem with freetype.(a|so). Please check config.log for more information.]) - ],[ - -L$FREETYPE2_DIR/$PHP_LIBDIR - ]) + FREETYPE2_CFLAGS=`$FREETYPE2_CONFIG --cflags` + FREETYPE2_LIBS=`$FREETYPE2_CONFIG --libs` + + PHP_EVAL_INCLINE($FREETYPE2_CFLAGS) + PHP_EVAL_LIBLINE($FREETYPE2_LIBS, GD_SHARED_LIBADD) + AC_DEFINE(USE_GD_IMGSTRTTF, 1, [ ]) + AC_DEFINE(HAVE_LIBFREETYPE,1,[ ]) + AC_DEFINE(ENABLE_GD_TTF,1,[ ]) else AC_MSG_RESULT([If configure fails try --with-freetype-dir=]) fi diff --git a/ext/gd/php_gd.h b/ext/gd/php_gd.h index 269c315e88be5..22fac40dd0ea3 100644 --- a/ext/gd/php_gd.h +++ b/ext/gd/php_gd.h @@ -59,7 +59,7 @@ PHPAPI extern const char php_sig_gif[3]; PHPAPI extern const char php_sig_jpg[3]; -PHPAPI extern const char php_sig_png[3]; +PHPAPI extern const char php_sig_png[8]; extern zend_module_entry gd_module_entry; #define phpext_gd_ptr &gd_module_entry diff --git a/ext/gmp/gmp.c b/ext/gmp/gmp.c index 8b5c131e76060..8835f05246809 100644 --- a/ext/gmp/gmp.c +++ b/ext/gmp/gmp.c @@ -24,6 +24,8 @@ #include "php_ini.h" #include "php_gmp.h" #include "ext/standard/info.h" +#include "ext/standard/php_var.h" +#include "ext/standard/php_smart_str_public.h" #include "zend_exceptions.h" #if HAVE_GMP @@ -41,7 +43,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_gmp_init, 0, 0, 1) ZEND_ARG_INFO(0, base) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO(arginfo_gmp_intval, 0) +ZEND_BEGIN_ARG_INFO_EX(arginfo_gmp_intval, 0, 0, 1) ZEND_ARG_INFO(0, gmpnumber) ZEND_END_ARG_INFO() @@ -50,82 +52,35 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_gmp_strval, 0, 0, 1) ZEND_ARG_INFO(0, base) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO(arginfo_gmp_add, 0) +ZEND_BEGIN_ARG_INFO_EX(arginfo_gmp_unary, 0, 0, 1) ZEND_ARG_INFO(0, a) - ZEND_ARG_INFO(0, b) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_gmp_sub, 0) - ZEND_ARG_INFO(0, a) - ZEND_ARG_INFO(0, b) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_gmp_mul, 0) - ZEND_ARG_INFO(0, a) - ZEND_ARG_INFO(0, b) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_gmp_div_qr, 0, 0, 2) - ZEND_ARG_INFO(0, a) - ZEND_ARG_INFO(0, b) - ZEND_ARG_INFO(0, round) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_gmp_div_r, 0, 0, 2) +ZEND_BEGIN_ARG_INFO_EX(arginfo_gmp_binary, 0, 0, 2) ZEND_ARG_INFO(0, a) ZEND_ARG_INFO(0, b) - ZEND_ARG_INFO(0, round) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_gmp_div_q, 0, 0, 2) +ZEND_BEGIN_ARG_INFO_EX(arginfo_gmp_div, 0, 0, 2) ZEND_ARG_INFO(0, a) ZEND_ARG_INFO(0, b) ZEND_ARG_INFO(0, round) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO(arginfo_gmp_mod, 0) - ZEND_ARG_INFO(0, a) - ZEND_ARG_INFO(0, b) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_gmp_divexact, 0) - ZEND_ARG_INFO(0, a) - ZEND_ARG_INFO(0, b) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_gmp_neg, 0) - ZEND_ARG_INFO(0, a) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_gmp_abs, 0) - ZEND_ARG_INFO(0, a) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_gmp_fact, 0) - ZEND_ARG_INFO(0, a) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_gmp_pow, 0) +ZEND_BEGIN_ARG_INFO_EX(arginfo_gmp_pow, 0, 0, 2) ZEND_ARG_INFO(0, base) ZEND_ARG_INFO(0, exp) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO(arginfo_gmp_powm, 0) +ZEND_BEGIN_ARG_INFO_EX(arginfo_gmp_powm, 0, 0, 3) ZEND_ARG_INFO(0, base) ZEND_ARG_INFO(0, exp) ZEND_ARG_INFO(0, mod) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO(arginfo_gmp_sqrt, 0) - ZEND_ARG_INFO(0, a) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_gmp_sqrtrem, 0) - ZEND_ARG_INFO(0, a) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_gmp_perfect_square, 0) +ZEND_BEGIN_ARG_INFO_EX(arginfo_gmp_root, 0, 0, 2) ZEND_ARG_INFO(0, a) + ZEND_ARG_INFO(0, nth) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_gmp_prob_prime, 0, 0, 1) @@ -133,102 +88,26 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_gmp_prob_prime, 0, 0, 1) ZEND_ARG_INFO(0, reps) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO(arginfo_gmp_gcd, 0) - ZEND_ARG_INFO(0, a) - ZEND_ARG_INFO(0, b) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_gmp_gcdext, 0) - ZEND_ARG_INFO(0, a) - ZEND_ARG_INFO(0, b) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_gmp_invert, 0) - ZEND_ARG_INFO(0, a) - ZEND_ARG_INFO(0, b) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_gmp_jacobi, 0) - ZEND_ARG_INFO(0, a) - ZEND_ARG_INFO(0, b) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_gmp_legendre, 0) - ZEND_ARG_INFO(0, a) - ZEND_ARG_INFO(0, b) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_gmp_cmp, 0) - ZEND_ARG_INFO(0, a) - ZEND_ARG_INFO(0, b) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_gmp_sign, 0) - ZEND_ARG_INFO(0, a) -ZEND_END_ARG_INFO() - ZEND_BEGIN_ARG_INFO_EX(arginfo_gmp_random, 0, 0, 0) ZEND_ARG_INFO(0, limiter) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO(arginfo_gmp_and, 0) - ZEND_ARG_INFO(0, a) - ZEND_ARG_INFO(0, b) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_gmp_or, 0) - ZEND_ARG_INFO(0, a) - ZEND_ARG_INFO(0, b) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_gmp_com, 0) - ZEND_ARG_INFO(0, a) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_gmp_xor, 0) - ZEND_ARG_INFO(0, a) - ZEND_ARG_INFO(0, b) -ZEND_END_ARG_INFO() - ZEND_BEGIN_ARG_INFO_EX(arginfo_gmp_setbit, 0, 0, 2) - ZEND_ARG_INFO(1, a) + ZEND_ARG_INFO(0, a) ZEND_ARG_INFO(0, index) ZEND_ARG_INFO(0, set_clear) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO(arginfo_gmp_clrbit, 0) - ZEND_ARG_INFO(1, a) - ZEND_ARG_INFO(0, index) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_gmp_testbit, 0) +ZEND_BEGIN_ARG_INFO_EX(arginfo_gmp_bit, 0, 0, 2) ZEND_ARG_INFO(0, a) ZEND_ARG_INFO(0, index) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO(arginfo_gmp_popcount, 0) - ZEND_ARG_INFO(0, a) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_gmp_hamdist, 0) - ZEND_ARG_INFO(0, a) - ZEND_ARG_INFO(0, b) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_gmp_scan0, 0) +ZEND_BEGIN_ARG_INFO_EX(arginfo_gmp_scan, 0, 0, 2) ZEND_ARG_INFO(0, a) ZEND_ARG_INFO(0, start) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO(arginfo_gmp_scan1, 0) - ZEND_ARG_INFO(0, a) - ZEND_ARG_INFO(0, start) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_gmp_nextprime, 0) - ZEND_ARG_INFO(0, a) -ZEND_END_ARG_INFO() - /* }}} */ ZEND_DECLARE_MODULE_GLOBALS(gmp) @@ -237,47 +116,49 @@ static ZEND_GINIT_FUNCTION(gmp); /* {{{ gmp_functions[] */ const zend_function_entry gmp_functions[] = { - ZEND_FE(gmp_init, arginfo_gmp_init) - ZEND_FE(gmp_intval, arginfo_gmp_intval) - ZEND_FE(gmp_strval, arginfo_gmp_strval) - ZEND_FE(gmp_add, arginfo_gmp_add) - ZEND_FE(gmp_sub, arginfo_gmp_sub) - ZEND_FE(gmp_mul, arginfo_gmp_mul) - ZEND_FE(gmp_div_qr, arginfo_gmp_div_qr) - ZEND_FE(gmp_div_q, arginfo_gmp_div_q) - ZEND_FE(gmp_div_r, arginfo_gmp_div_r) - ZEND_FALIAS(gmp_div, gmp_div_q, arginfo_gmp_div_q) - ZEND_FE(gmp_mod, arginfo_gmp_mod) - ZEND_FE(gmp_divexact, arginfo_gmp_divexact) - ZEND_FE(gmp_neg, arginfo_gmp_neg) - ZEND_FE(gmp_abs, arginfo_gmp_abs) - ZEND_FE(gmp_fact, arginfo_gmp_fact) - ZEND_FE(gmp_sqrt, arginfo_gmp_sqrt) - ZEND_FE(gmp_sqrtrem, arginfo_gmp_sqrtrem) - ZEND_FE(gmp_pow, arginfo_gmp_pow) - ZEND_FE(gmp_powm, arginfo_gmp_powm) - ZEND_FE(gmp_perfect_square, arginfo_gmp_perfect_square) - ZEND_FE(gmp_prob_prime, arginfo_gmp_prob_prime) - ZEND_FE(gmp_gcd, arginfo_gmp_gcd) - ZEND_FE(gmp_gcdext, arginfo_gmp_gcdext) - ZEND_FE(gmp_invert, arginfo_gmp_invert) - ZEND_FE(gmp_jacobi, arginfo_gmp_jacobi) - ZEND_FE(gmp_legendre, arginfo_gmp_legendre) - ZEND_FE(gmp_cmp, arginfo_gmp_cmp) - ZEND_FE(gmp_sign, arginfo_gmp_sign) - ZEND_FE(gmp_random, arginfo_gmp_random) - ZEND_FE(gmp_and, arginfo_gmp_and) - ZEND_FE(gmp_or, arginfo_gmp_or) - ZEND_FE(gmp_com, arginfo_gmp_com) - ZEND_FE(gmp_xor, arginfo_gmp_xor) - ZEND_FE(gmp_setbit, arginfo_gmp_setbit) - ZEND_FE(gmp_clrbit, arginfo_gmp_clrbit) - ZEND_FE(gmp_scan0, arginfo_gmp_scan0) - ZEND_FE(gmp_scan1, arginfo_gmp_scan1) - ZEND_FE(gmp_testbit,arginfo_gmp_testbit) - ZEND_FE(gmp_popcount, arginfo_gmp_popcount) - ZEND_FE(gmp_hamdist, arginfo_gmp_hamdist) - ZEND_FE(gmp_nextprime, arginfo_gmp_nextprime) + ZEND_FE(gmp_init, arginfo_gmp_init) + ZEND_FE(gmp_intval, arginfo_gmp_intval) + ZEND_FE(gmp_strval, arginfo_gmp_strval) + ZEND_FE(gmp_add, arginfo_gmp_binary) + ZEND_FE(gmp_sub, arginfo_gmp_binary) + ZEND_FE(gmp_mul, arginfo_gmp_binary) + ZEND_FE(gmp_div_qr, arginfo_gmp_div) + ZEND_FE(gmp_div_q, arginfo_gmp_div) + ZEND_FE(gmp_div_r, arginfo_gmp_div) + ZEND_FALIAS(gmp_div, gmp_div_q, arginfo_gmp_div) + ZEND_FE(gmp_mod, arginfo_gmp_binary) + ZEND_FE(gmp_divexact, arginfo_gmp_binary) + ZEND_FE(gmp_neg, arginfo_gmp_unary) + ZEND_FE(gmp_abs, arginfo_gmp_unary) + ZEND_FE(gmp_fact, arginfo_gmp_unary) + ZEND_FE(gmp_sqrt, arginfo_gmp_unary) + ZEND_FE(gmp_sqrtrem, arginfo_gmp_unary) + ZEND_FE(gmp_root, arginfo_gmp_root) + ZEND_FE(gmp_rootrem, arginfo_gmp_root) + ZEND_FE(gmp_pow, arginfo_gmp_pow) + ZEND_FE(gmp_powm, arginfo_gmp_powm) + ZEND_FE(gmp_perfect_square, arginfo_gmp_unary) + ZEND_FE(gmp_prob_prime, arginfo_gmp_prob_prime) + ZEND_FE(gmp_gcd, arginfo_gmp_binary) + ZEND_FE(gmp_gcdext, arginfo_gmp_binary) + ZEND_FE(gmp_invert, arginfo_gmp_binary) + ZEND_FE(gmp_jacobi, arginfo_gmp_binary) + ZEND_FE(gmp_legendre, arginfo_gmp_binary) + ZEND_FE(gmp_cmp, arginfo_gmp_binary) + ZEND_FE(gmp_sign, arginfo_gmp_unary) + ZEND_FE(gmp_random, arginfo_gmp_random) + ZEND_FE(gmp_and, arginfo_gmp_binary) + ZEND_FE(gmp_or, arginfo_gmp_binary) + ZEND_FE(gmp_com, arginfo_gmp_unary) + ZEND_FE(gmp_xor, arginfo_gmp_binary) + ZEND_FE(gmp_setbit, arginfo_gmp_setbit) + ZEND_FE(gmp_clrbit, arginfo_gmp_bit) + ZEND_FE(gmp_testbit, arginfo_gmp_bit) + ZEND_FE(gmp_scan0, arginfo_gmp_scan) + ZEND_FE(gmp_scan1, arginfo_gmp_scan) + ZEND_FE(gmp_popcount, arginfo_gmp_unary) + ZEND_FE(gmp_hamdist, arginfo_gmp_binary) + ZEND_FE(gmp_nextprime, arginfo_gmp_unary) PHP_FE_END }; /* }}} */ @@ -323,9 +204,12 @@ typedef struct _gmp_temp { #define GMP_ROUND_PLUSINF 1 #define GMP_ROUND_MINUSINF 2 +#define GMP_42_OR_NEWER \ + ((__GNU_MP_VERSION >= 5) || (__GNU_MP_VERSION >= 4 && __GNU_MP_VERSION_MINOR >= 2)) + /* The maximum base for input and output conversions is 62 from GMP 4.2 * onwards. */ -#if (__GNU_MP_VERSION >= 5) || (__GNU_MP_VERSION >= 4 && __GNU_MP_VERSION_MINOR >= 2) +#if GMP_42_OR_NEWER # define MAX_BASE 62 #else # define MAX_BASE 36 @@ -564,12 +448,17 @@ static int gmp_cast_object(zval *readobj, zval *writeobj, int type TSRMLS_DC) /* } /* }}} */ -static HashTable *gmp_get_properties(zval *obj TSRMLS_DC) /* {{{ */ +static HashTable *gmp_get_debug_info(zval *obj, int *is_temp TSRMLS_DC) /* {{{ */ { - HashTable *ht = zend_std_get_properties(obj TSRMLS_CC); + HashTable *ht, *props = zend_std_get_properties(obj TSRMLS_CC); mpz_ptr gmpnum = GET_GMP_FROM_ZVAL(obj); zval *zv; + *is_temp = 1; + ALLOC_HASHTABLE(ht); + ZEND_INIT_SYMTABLE_EX(ht, zend_hash_num_elements(props) + 1, 0); + zend_hash_copy(ht, props, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *)); + MAKE_STD_ZVAL(zv); gmp_strval(zv, gmpnum, 10); zend_hash_update(ht, "num", sizeof("num"), &zv, sizeof(zval *), NULL); @@ -678,39 +567,82 @@ static int gmp_compare(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */ } /* }}} */ -PHP_METHOD(GMP, __wakeup) /* {{{ */ +static int gmp_serialize(zval *object, unsigned char **buffer, zend_uint *buf_len, zend_serialize_data *data TSRMLS_DC) /* {{{ */ { - HashTable *props; - zval **num_zv; + mpz_ptr gmpnum = GET_GMP_FROM_ZVAL(object); + smart_str buf = {0}; + zval zv, *zv_ptr = &zv; + php_serialize_data_t *serialize_data = (php_serialize_data_t *) data; - if (zend_parse_parameters_none() == FAILURE) { - return; + PHP_VAR_SERIALIZE_INIT(*serialize_data); + + INIT_PZVAL(zv_ptr); + + gmp_strval(zv_ptr, gmpnum, 10); + php_var_serialize(&buf, &zv_ptr, serialize_data TSRMLS_CC); + zval_dtor(zv_ptr); + + Z_ARRVAL_P(zv_ptr) = zend_std_get_properties(object TSRMLS_CC); + Z_TYPE_P(zv_ptr) = IS_ARRAY; + php_var_serialize(&buf, &zv_ptr, serialize_data TSRMLS_CC); + + PHP_VAR_SERIALIZE_DESTROY(*serialize_data); + + *buffer = (unsigned char *) buf.c; + *buf_len = buf.len; + + return SUCCESS; +} +/* }}} */ + +static int gmp_unserialize(zval **object, zend_class_entry *ce, const unsigned char *buf, zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC) /* {{{ */ +{ + mpz_ptr gmpnum; + const unsigned char *p, *max; + zval zv, *zv_ptr = &zv; + int retval = FAILURE; + php_unserialize_data_t *unserialize_data = (php_unserialize_data_t *) data; + + PHP_VAR_UNSERIALIZE_INIT(*unserialize_data); + + gmp_create_ex(*object, &gmpnum TSRMLS_CC); + + p = buf; + max = buf + buf_len; + + INIT_ZVAL(zv); + if (!php_var_unserialize(&zv_ptr, &p, max, unserialize_data TSRMLS_CC) + || Z_TYPE_P(zv_ptr) != IS_STRING + || convert_to_gmp(gmpnum, zv_ptr, 10 TSRMLS_CC) == FAILURE + ) { + zend_throw_exception(NULL, "Could not unserialize number", 0 TSRMLS_CC); + goto exit; } + zval_dtor(&zv); - props = zend_std_get_properties(getThis() TSRMLS_CC); - if (zend_hash_find(props, "num", sizeof("num"), (void **) &num_zv) == SUCCESS - && Z_TYPE_PP(num_zv) == IS_STRING && Z_STRLEN_PP(num_zv) > 0 + INIT_ZVAL(zv); + if (!php_var_unserialize(&zv_ptr, &p, max, unserialize_data TSRMLS_CC) + || Z_TYPE_P(zv_ptr) != IS_ARRAY ) { - mpz_ptr gmpnumber = GET_GMP_FROM_ZVAL(getThis()); - if (convert_to_gmp(gmpnumber, *num_zv, 10 TSRMLS_CC) == SUCCESS) { - return; - } + zend_throw_exception(NULL, "Could not unserialize properties", 0 TSRMLS_CC); + goto exit; } - zend_throw_exception( - NULL, "Invalid serialization data", 0 TSRMLS_CC - ); + if (zend_hash_num_elements(Z_ARRVAL_P(zv_ptr)) != 0) { + zend_hash_copy( + zend_std_get_properties(*object TSRMLS_CC), Z_ARRVAL_P(zv_ptr), + (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *) + ); + } + + retval = SUCCESS; +exit: + zval_dtor(&zv); + PHP_VAR_UNSERIALIZE_DESTROY(*unserialize_data); + return retval; } /* }}} */ -ZEND_BEGIN_ARG_INFO_EX(arginfo_wakeup, 0, 0, 0) -ZEND_END_ARG_INFO() - -const zend_function_entry gmp_methods[] = { - PHP_ME(GMP, __wakeup, arginfo_wakeup, ZEND_ACC_PUBLIC) - PHP_FE_END -}; - /* {{{ ZEND_GINIT_FUNCTION */ static ZEND_GINIT_FUNCTION(gmp) @@ -724,13 +656,15 @@ static ZEND_GINIT_FUNCTION(gmp) ZEND_MINIT_FUNCTION(gmp) { zend_class_entry tmp_ce; - INIT_CLASS_ENTRY(tmp_ce, "GMP", gmp_methods); /* No methods on the class for now */ + INIT_CLASS_ENTRY(tmp_ce, "GMP", NULL); gmp_ce = zend_register_internal_class(&tmp_ce TSRMLS_CC); gmp_ce->create_object = gmp_create_object; + gmp_ce->serialize = gmp_serialize; + gmp_ce->unserialize = gmp_unserialize; memcpy(&gmp_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); gmp_object_handlers.cast_object = gmp_cast_object; - gmp_object_handlers.get_properties = gmp_get_properties; + gmp_object_handlers.get_debug_info = gmp_get_debug_info; gmp_object_handlers.clone_obj = gmp_clone_obj; gmp_object_handlers.do_operation = gmp_do_operation; gmp_object_handlers.compare = gmp_compare; @@ -1363,7 +1297,7 @@ ZEND_FUNCTION(gmp_powm) zval *base_arg, *exp_arg, *mod_arg; mpz_ptr gmpnum_base, gmpnum_exp, gmpnum_mod, gmpnum_result; int use_ui = 0; - gmp_temp_t temp_base = {0}, temp_exp = {0}, temp_mod; + gmp_temp_t temp_base, temp_exp, temp_mod; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zzz", &base_arg, &exp_arg, &mod_arg) == FAILURE){ return; @@ -1462,6 +1396,81 @@ ZEND_FUNCTION(gmp_sqrtrem) } /* }}} */ +/* {{{ proto GMP gmp_root(mixed a, int nth) + Takes integer part of nth root */ +ZEND_FUNCTION(gmp_root) +{ + zval *a_arg; + long nth; + mpz_ptr gmpnum_a, gmpnum_result; + gmp_temp_t temp_a; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zl", &a_arg, &nth) == FAILURE) { + return; + } + + if (nth <= 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The root must be positive"); + RETURN_FALSE; + } + + FETCH_GMP_ZVAL(gmpnum_a, a_arg, temp_a); + + if (nth % 2 == 0 && mpz_sgn(gmpnum_a) < 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't take even root of negative number"); + FREE_GMP_TEMP(temp_a); + RETURN_FALSE; + } + + INIT_GMP_RETVAL(gmpnum_result); + mpz_root(gmpnum_result, gmpnum_a, (unsigned long) nth); + FREE_GMP_TEMP(temp_a); +} +/* }}} */ + +/* {{{ proto GMP gmp_rootrem(mixed a, int nth) + Calculates integer part of nth root and remainder */ +ZEND_FUNCTION(gmp_rootrem) +{ + zval *a_arg; + long nth; + mpz_ptr gmpnum_a, gmpnum_result1, gmpnum_result2; + gmp_temp_t temp_a; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zl", &a_arg, &nth) == FAILURE) { + return; + } + + if (nth <= 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The root must be positive"); + RETURN_FALSE; + } + + FETCH_GMP_ZVAL(gmpnum_a, a_arg, temp_a); + + if (nth % 2 == 0 && mpz_sgn(gmpnum_a) < 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't take even root of negative number"); + FREE_GMP_TEMP(temp_a); + RETURN_FALSE; + } + + array_init(return_value); + add_index_zval(return_value, 0, gmp_create(&gmpnum_result1 TSRMLS_CC)); + add_index_zval(return_value, 1, gmp_create(&gmpnum_result2 TSRMLS_CC)); + +#if GMP_42_OR_NEWER + mpz_rootrem(gmpnum_result1, gmpnum_result2, gmpnum_a, (unsigned long) nth); +#else + mpz_root(gmpnum_result1, gmpnum_a, (unsigned long) nth); + mpz_pow_ui(gmpnum_result2, gmpnum_result1, (unsigned long) nth); + mpz_sub(gmpnum_result2, gmpnum_a, gmpnum_result2); + mpz_abs(gmpnum_result2, gmpnum_result2); +#endif + + FREE_GMP_TEMP(temp_a); +} +/* }}} */ + /* {{{ proto bool gmp_perfect_square(mixed a) Checks if a is an exact square */ ZEND_FUNCTION(gmp_perfect_square) @@ -1596,6 +1605,7 @@ ZEND_FUNCTION(gmp_cmp) Gets the sign of the number */ ZEND_FUNCTION(gmp_sign) { + /* Can't use gmp_unary_opl here, because mpz_sgn is a macro */ zval *a_arg; mpz_ptr gmpnum_a; gmp_temp_t temp_a; @@ -1603,7 +1613,7 @@ ZEND_FUNCTION(gmp_sign) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &a_arg) == FAILURE){ return; } - + FETCH_GMP_ZVAL(gmpnum_a, a_arg, temp_a); RETVAL_LONG(mpz_sgn(gmpnum_a)); @@ -1678,36 +1688,10 @@ ZEND_FUNCTION(gmp_nextprime) ZEND_FUNCTION(gmp_xor) { gmp_binary_op(mpz_xor); - /* use formula: a^b = (a|b)&~(a&b) */ - /*zval **a_arg, **b_arg; - mpz_t *gmpnum_a, *gmpnum_b, *gmpnum_result, *gmpnum_t; - gmp_temp_t temp_a, temp_b; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ", &a_arg, &b_arg) == FAILURE){ - return; - } - - FETCH_GMP_ZVAL(gmpnum_a, a_arg, temp_a); - FETCH_GMP_ZVAL_DEP(gmpnum_b, b_arg, temp_b, temp_a); - - INIT_GMP_NUM(gmpnum_result); - INIT_GMP_NUM(gmpnum_t); - - mpz_and(*gmpnum_t, *gmpnum_a, *gmpnum_b); - mpz_com(*gmpnum_t, *gmpnum_t); - - mpz_ior(*gmpnum_result, *gmpnum_a, *gmpnum_b); - mpz_and(*gmpnum_result, *gmpnum_result, *gmpnum_t); - - FREE_GMP_NUM(gmpnum_t); - - FREE_GMP_TEMP(temp_a); - FREE_GMP_TEMP(temp_b); - RETVAL_GMP(gmpnum_result);*/ } /* }}} */ -/* {{{ proto void gmp_setbit(GMP &a, int index[, bool set_clear]) +/* {{{ proto void gmp_setbit(GMP a, int index[, bool set_clear]) Sets or clear bit in a */ ZEND_FUNCTION(gmp_setbit) { @@ -1735,7 +1719,7 @@ ZEND_FUNCTION(gmp_setbit) } /* }}} */ -/* {{{ proto void gmp_clrbit(GMP &a, int index) +/* {{{ proto void gmp_clrbit(GMP a, int index) Clears bit in a */ ZEND_FUNCTION(gmp_clrbit) { @@ -1783,18 +1767,7 @@ ZEND_FUNCTION(gmp_testbit) Calculates the population count of a */ ZEND_FUNCTION(gmp_popcount) { - zval *a_arg; - mpz_ptr gmpnum_a; - gmp_temp_t temp_a; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &a_arg) == FAILURE){ - return; - } - - FETCH_GMP_ZVAL(gmpnum_a, a_arg, temp_a); - - RETVAL_LONG(mpz_popcount(gmpnum_a)); - FREE_GMP_TEMP(temp_a); + gmp_unary_opl((gmp_unary_opl_t) mpz_popcount); } /* }}} */ @@ -1802,20 +1775,7 @@ ZEND_FUNCTION(gmp_popcount) Calculates hamming distance between a and b */ ZEND_FUNCTION(gmp_hamdist) { - zval *a_arg, *b_arg; - mpz_ptr gmpnum_a, gmpnum_b; - gmp_temp_t temp_a, temp_b; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &a_arg, &b_arg) == FAILURE){ - return; - } - - FETCH_GMP_ZVAL(gmpnum_a, a_arg, temp_a); - FETCH_GMP_ZVAL_DEP(gmpnum_b, b_arg, temp_b, temp_a); - - RETVAL_LONG(mpz_hamdist(gmpnum_a, gmpnum_b)); - FREE_GMP_TEMP(temp_a); - FREE_GMP_TEMP(temp_b); + gmp_binary_opl((gmp_binary_opl_t) mpz_hamdist); } /* }}} */ diff --git a/ext/gmp/php_gmp.h b/ext/gmp/php_gmp.h index e1aaef886d277..902c3ac0bbd6f 100644 --- a/ext/gmp/php_gmp.h +++ b/ext/gmp/php_gmp.h @@ -45,9 +45,11 @@ ZEND_FUNCTION(gmp_neg); ZEND_FUNCTION(gmp_abs); ZEND_FUNCTION(gmp_fact); ZEND_FUNCTION(gmp_sqrt); +ZEND_FUNCTION(gmp_sqrtrem); +ZEND_FUNCTION(gmp_root); +ZEND_FUNCTION(gmp_rootrem); ZEND_FUNCTION(gmp_pow); ZEND_FUNCTION(gmp_powm); -ZEND_FUNCTION(gmp_sqrtrem); ZEND_FUNCTION(gmp_perfect_square); ZEND_FUNCTION(gmp_prob_prime); ZEND_FUNCTION(gmp_gcd); diff --git a/ext/gmp/tests/bug659967.phpt b/ext/gmp/tests/bug659967.phpt new file mode 100644 index 0000000000000..6ba220274c4f7 --- /dev/null +++ b/ext/gmp/tests/bug659967.phpt @@ -0,0 +1,15 @@ +--TEST-- +Bug #65997: Leak when using gc_collect_cycles with new GMP implementation +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECT-- +===DONE=== diff --git a/ext/gmp/tests/serialize.phpt b/ext/gmp/tests/serialize.phpt index 26716b659c368..208e0e98001e7 100644 --- a/ext/gmp/tests/serialize.phpt +++ b/ext/gmp/tests/serialize.phpt @@ -9,14 +9,34 @@ var_dump($n = gmp_init(42)); var_dump($s = serialize($n)); var_dump(unserialize($s)); +$n = gmp_init(13); +$n->foo = "bar"; +var_dump(unserialize(serialize($n))); + +try { + unserialize('C:3:"GMP":0:{}'); +} catch (Exception $e) { var_dump($e->getMessage()); } + +try { + unserialize('C:3:"GMP":8:{s:2:"42"}'); +} catch (Exception $e) { var_dump($e->getMessage()); } + ?> --EXPECTF-- object(GMP)#%d (1) { ["num"]=> string(2) "42" } -string(33) "O:3:"GMP":1:{s:3:"num";s:2:"42";}" +string(30) "C:3:"GMP":15:{s:2:"42";a:0:{}}" object(GMP)#%d (1) { ["num"]=> string(2) "42" } +object(GMP)#%d (2) { + ["foo"]=> + string(3) "bar" + ["num"]=> + string(2) "13" +} +string(28) "Could not unserialize number" +string(32) "Could not unserialize properties" diff --git a/ext/hash/hash.c b/ext/hash/hash.c index 117221484e363..87f19c5cacb1e 100644 --- a/ext/hash/hash.c +++ b/ext/hash/hash.c @@ -986,6 +986,7 @@ PHP_MINIT_FUNCTION(hash) php_hash_register_algo("snefru", &php_hash_snefru_ops); php_hash_register_algo("snefru256", &php_hash_snefru_ops); php_hash_register_algo("gost", &php_hash_gost_ops); + php_hash_register_algo("gost-crypto", &php_hash_gost_crypto_ops); php_hash_register_algo("adler32", &php_hash_adler32_ops); php_hash_register_algo("crc32", &php_hash_crc32_ops); php_hash_register_algo("crc32b", &php_hash_crc32b_ops); diff --git a/ext/hash/hash_gost.c b/ext/hash/hash_gost.c index 3961c4f2d5c36..da65bb5903e62 100644 --- a/ext/hash/hash_gost.c +++ b/ext/hash/hash_gost.c @@ -27,7 +27,7 @@ * derived from gost_compress() by Markku-Juhani Saarinen */ -#define round(k1, k2) \ +#define round(tables, k1, k2) \ t = (k1) + r; \ l ^= tables[0][t & 0xff] ^ tables[1][(t >> 8) & 0xff] ^ \ tables[2][(t >> 16) & 0xff] ^ tables[3][t >> 24]; \ @@ -35,25 +35,25 @@ r ^= tables[0][t & 0xff] ^ tables[1][(t >> 8) & 0xff] ^ \ tables[2][(t >> 16) & 0xff] ^ tables[3][t >> 24]; -#define R(key, h, i, t, l, r) \ +#define R(tables, key, h, i, t, l, r) \ r = h[i]; \ l = h[i + 1]; \ - round(key[0], key[1]) \ - round(key[2], key[3]) \ - round(key[4], key[5]) \ - round(key[6], key[7]) \ - round(key[0], key[1]) \ - round(key[2], key[3]) \ - round(key[4], key[5]) \ - round(key[6], key[7]) \ - round(key[0], key[1]) \ - round(key[2], key[3]) \ - round(key[4], key[5]) \ - round(key[6], key[7]) \ - round(key[7], key[6]) \ - round(key[5], key[4]) \ - round(key[3], key[2]) \ - round(key[1], key[0]) \ + round(tables, key[0], key[1]) \ + round(tables, key[2], key[3]) \ + round(tables, key[4], key[5]) \ + round(tables, key[6], key[7]) \ + round(tables, key[0], key[1]) \ + round(tables, key[2], key[3]) \ + round(tables, key[4], key[5]) \ + round(tables, key[6], key[7]) \ + round(tables, key[0], key[1]) \ + round(tables, key[2], key[3]) \ + round(tables, key[4], key[5]) \ + round(tables, key[6], key[7]) \ + round(tables, key[7], key[6]) \ + round(tables, key[5], key[4]) \ + round(tables, key[3], key[2]) \ + round(tables, key[1], key[0]) \ t = r; \ r = l; \ l = t; \ @@ -194,10 +194,10 @@ (v[3] >> 16) ^ v[3] ^ (v[4] << 16) ^ v[4] ^ (v[5] >> 16) ^ v[5] ^ \ (v[6] << 16) ^ (v[6] >> 16) ^ (v[7] << 16) ^ v[7]; -#define PASS \ +#define PASS(tables) \ X(w, u, v); \ P(key, w); \ - R(key, h, i, t, l, r); \ + R((tables), key, h, i, t, l, r); \ S(s, l, r); \ if (i != 6) { \ A(u, l, r); \ @@ -207,16 +207,16 @@ AA(v, l, r); \ } -static inline void Gost(php_hash_uint32 state[8], php_hash_uint32 data[8]) +static inline void Gost(PHP_GOST_CTX *context, php_hash_uint32 data[8]) { int i; - php_hash_uint32 l, r, t, key[8], u[8], v[8], w[8], s[8], *h = state, *m = data; + php_hash_uint32 l, r, t, key[8], u[8], v[8], w[8], s[8], *h = context->state, *m = data; - memcpy(u, state, sizeof(u)); + memcpy(u, context->state, sizeof(u)); memcpy(v, data, sizeof(v)); for (i = 0; i < 8; i += 2) { - PASS; + PASS(*context->tables); } SHIFT12(u, m, s); SHIFT16(h, v, u); @@ -237,12 +237,19 @@ static inline void GostTransform(PHP_GOST_CTX *context, const unsigned char inpu temp = ((context->state[i + 8] < data[i]) || (context->state[i + 8] < save)) ? 1 : 0; } - Gost(context->state, data); + Gost(context, data); } PHP_HASH_API void PHP_GOSTInit(PHP_GOST_CTX *context) { memset(context, 0, sizeof(*context)); + context->tables = &tables_test; +} + +PHP_HASH_API void PHP_GOSTInitCrypto(PHP_GOST_CTX *context) +{ + PHP_GOSTInit(context); + context->tables = &tables_crypto; } static const php_hash_uint32 MAX32 = 0xffffffffLU; @@ -288,9 +295,9 @@ PHP_HASH_API void PHP_GOSTFinal(unsigned char digest[32], PHP_GOST_CTX *context) } memcpy(l, context->count, sizeof(context->count)); - Gost(context->state, l); + Gost(context, l); memcpy(l, &context->state[8], sizeof(l)); - Gost(context->state, l); + Gost(context, l); for (i = 0, j = 0; j < 32; i++, j += 4) { digest[j] = (unsigned char) (context->state[i] & 0xff); @@ -312,6 +319,16 @@ const php_hash_ops php_hash_gost_ops = { sizeof(PHP_GOST_CTX) }; +const php_hash_ops php_hash_gost_crypto_ops = { + (php_hash_init_func_t) PHP_GOSTInitCrypto, + (php_hash_update_func_t) PHP_GOSTUpdate, + (php_hash_final_func_t) PHP_GOSTFinal, + (php_hash_copy_func_t) php_hash_copy, + 32, + 32, + sizeof(PHP_GOST_CTX) +}; + /* * Local variables: * tab-width: 4 diff --git a/ext/hash/php_hash.h b/ext/hash/php_hash.h index 3f5e7ced3a19b..e92572216aea4 100644 --- a/ext/hash/php_hash.h +++ b/ext/hash/php_hash.h @@ -80,6 +80,7 @@ extern const php_hash_ops php_hash_4tiger160_ops; extern const php_hash_ops php_hash_4tiger192_ops; extern const php_hash_ops php_hash_snefru_ops; extern const php_hash_ops php_hash_gost_ops; +extern const php_hash_ops php_hash_gost_crypto_ops; extern const php_hash_ops php_hash_adler32_ops; extern const php_hash_ops php_hash_crc32_ops; extern const php_hash_ops php_hash_crc32b_ops; diff --git a/ext/hash/php_hash_gost.h b/ext/hash/php_hash_gost.h index 6a4af310dc64c..a9c137530c4ae 100644 --- a/ext/hash/php_hash_gost.h +++ b/ext/hash/php_hash_gost.h @@ -29,6 +29,7 @@ typedef struct { php_hash_uint32 count[2]; unsigned char length; unsigned char buffer[32]; + const php_hash_uint32 (*tables)[4][256]; } PHP_GOST_CTX; PHP_HASH_API void PHP_GOSTInit(PHP_GOST_CTX *); diff --git a/ext/hash/php_hash_gost_tables.h b/ext/hash/php_hash_gost_tables.h index 5d05e593cb13a..a00d8b74907d2 100644 --- a/ext/hash/php_hash_gost_tables.h +++ b/ext/hash/php_hash_gost_tables.h @@ -1,4 +1,4 @@ -static const php_hash_uint32 tables[4][256] = { +static const php_hash_uint32 tables_test[4][256] = { { /* table 1 */ 0x00072000LU, 0x00075000LU, 0x00074800LU, 0x00071000LU, 0x00076800LU, 0x00074000LU, 0x00070000LU, 0x00077000LU, 0x00073000LU, 0x00075800LU, 0x00070800LU, 0x00076000LU, 0x00073800LU, 0x00077800LU, 0x00072800LU, 0x00071800LU, @@ -136,3 +136,142 @@ static const php_hash_uint32 tables[4][256] = { 0x00000600LU, 0x00000650LU, 0x00000670LU, 0x00000638LU, 0x00000630LU, 0x00000640LU, 0x00000610LU, 0x00000660LU, }, }; + +static const php_hash_uint32 tables_crypto[4][256] = { + { /* table 1 */ + 0x0002d000LU, 0x0002a000LU, 0x0002a800LU, 0x0002b000LU, 0x0002c000LU, 0x00028800LU, 0x00029800LU, 0x0002b800LU, + 0x0002e800LU, 0x0002e000LU, 0x0002f000LU, 0x00028000LU, 0x0002c800LU, 0x00029000LU, 0x0002d800LU, 0x0002f800LU, + 0x0007d000LU, 0x0007a000LU, 0x0007a800LU, 0x0007b000LU, 0x0007c000LU, 0x00078800LU, 0x00079800LU, 0x0007b800LU, + 0x0007e800LU, 0x0007e000LU, 0x0007f000LU, 0x00078000LU, 0x0007c800LU, 0x00079000LU, 0x0007d800LU, 0x0007f800LU, + 0x00025000LU, 0x00022000LU, 0x00022800LU, 0x00023000LU, 0x00024000LU, 0x00020800LU, 0x00021800LU, 0x00023800LU, + 0x00026800LU, 0x00026000LU, 0x00027000LU, 0x00020000LU, 0x00024800LU, 0x00021000LU, 0x00025800LU, 0x00027800LU, + 0x00005000LU, 0x00002000LU, 0x00002800LU, 0x00003000LU, 0x00004000LU, 0x00000800LU, 0x00001800LU, 0x00003800LU, + 0x00006800LU, 0x00006000LU, 0x00007000LU, 0x00000000LU, 0x00004800LU, 0x00001000LU, 0x00005800LU, 0x00007800LU, + 0x00015000LU, 0x00012000LU, 0x00012800LU, 0x00013000LU, 0x00014000LU, 0x00010800LU, 0x00011800LU, 0x00013800LU, + 0x00016800LU, 0x00016000LU, 0x00017000LU, 0x00010000LU, 0x00014800LU, 0x00011000LU, 0x00015800LU, 0x00017800LU, + 0x0006d000LU, 0x0006a000LU, 0x0006a800LU, 0x0006b000LU, 0x0006c000LU, 0x00068800LU, 0x00069800LU, 0x0006b800LU, + 0x0006e800LU, 0x0006e000LU, 0x0006f000LU, 0x00068000LU, 0x0006c800LU, 0x00069000LU, 0x0006d800LU, 0x0006f800LU, + 0x0005d000LU, 0x0005a000LU, 0x0005a800LU, 0x0005b000LU, 0x0005c000LU, 0x00058800LU, 0x00059800LU, 0x0005b800LU, + 0x0005e800LU, 0x0005e000LU, 0x0005f000LU, 0x00058000LU, 0x0005c800LU, 0x00059000LU, 0x0005d800LU, 0x0005f800LU, + 0x0004d000LU, 0x0004a000LU, 0x0004a800LU, 0x0004b000LU, 0x0004c000LU, 0x00048800LU, 0x00049800LU, 0x0004b800LU, + 0x0004e800LU, 0x0004e000LU, 0x0004f000LU, 0x00048000LU, 0x0004c800LU, 0x00049000LU, 0x0004d800LU, 0x0004f800LU, + 0x0000d000LU, 0x0000a000LU, 0x0000a800LU, 0x0000b000LU, 0x0000c000LU, 0x00008800LU, 0x00009800LU, 0x0000b800LU, + 0x0000e800LU, 0x0000e000LU, 0x0000f000LU, 0x00008000LU, 0x0000c800LU, 0x00009000LU, 0x0000d800LU, 0x0000f800LU, + 0x0003d000LU, 0x0003a000LU, 0x0003a800LU, 0x0003b000LU, 0x0003c000LU, 0x00038800LU, 0x00039800LU, 0x0003b800LU, + 0x0003e800LU, 0x0003e000LU, 0x0003f000LU, 0x00038000LU, 0x0003c800LU, 0x00039000LU, 0x0003d800LU, 0x0003f800LU, + 0x00035000LU, 0x00032000LU, 0x00032800LU, 0x00033000LU, 0x00034000LU, 0x00030800LU, 0x00031800LU, 0x00033800LU, + 0x00036800LU, 0x00036000LU, 0x00037000LU, 0x00030000LU, 0x00034800LU, 0x00031000LU, 0x00035800LU, 0x00037800LU, + 0x0001d000LU, 0x0001a000LU, 0x0001a800LU, 0x0001b000LU, 0x0001c000LU, 0x00018800LU, 0x00019800LU, 0x0001b800LU, + 0x0001e800LU, 0x0001e000LU, 0x0001f000LU, 0x00018000LU, 0x0001c800LU, 0x00019000LU, 0x0001d800LU, 0x0001f800LU, + 0x00065000LU, 0x00062000LU, 0x00062800LU, 0x00063000LU, 0x00064000LU, 0x00060800LU, 0x00061800LU, 0x00063800LU, + 0x00066800LU, 0x00066000LU, 0x00067000LU, 0x00060000LU, 0x00064800LU, 0x00061000LU, 0x00065800LU, 0x00067800LU, + 0x00075000LU, 0x00072000LU, 0x00072800LU, 0x00073000LU, 0x00074000LU, 0x00070800LU, 0x00071800LU, 0x00073800LU, + 0x00076800LU, 0x00076000LU, 0x00077000LU, 0x00070000LU, 0x00074800LU, 0x00071000LU, 0x00075800LU, 0x00077800LU, + 0x00055000LU, 0x00052000LU, 0x00052800LU, 0x00053000LU, 0x00054000LU, 0x00050800LU, 0x00051800LU, 0x00053800LU, + 0x00056800LU, 0x00056000LU, 0x00057000LU, 0x00050000LU, 0x00054800LU, 0x00051000LU, 0x00055800LU, 0x00057800LU, + 0x00045000LU, 0x00042000LU, 0x00042800LU, 0x00043000LU, 0x00044000LU, 0x00040800LU, 0x00041800LU, 0x00043800LU, + 0x00046800LU, 0x00046000LU, 0x00047000LU, 0x00040000LU, 0x00044800LU, 0x00041000LU, 0x00045800LU, 0x00047800LU, + }, + { /* table 2 */ + 0x02380000LU, 0x02780000LU, 0x02600000LU, 0x02700000LU, 0x02480000LU, 0x02200000LU, 0x02080000LU, 0x02000000LU, + 0x02180000LU, 0x02580000LU, 0x02280000LU, 0x02100000LU, 0x02300000LU, 0x02500000LU, 0x02400000LU, 0x02680000LU, + 0x05380000LU, 0x05780000LU, 0x05600000LU, 0x05700000LU, 0x05480000LU, 0x05200000LU, 0x05080000LU, 0x05000000LU, + 0x05180000LU, 0x05580000LU, 0x05280000LU, 0x05100000LU, 0x05300000LU, 0x05500000LU, 0x05400000LU, 0x05680000LU, + 0x03b80000LU, 0x03f80000LU, 0x03e00000LU, 0x03f00000LU, 0x03c80000LU, 0x03a00000LU, 0x03880000LU, 0x03800000LU, + 0x03980000LU, 0x03d80000LU, 0x03a80000LU, 0x03900000LU, 0x03b00000LU, 0x03d00000LU, 0x03c00000LU, 0x03e80000LU, + 0x06380000LU, 0x06780000LU, 0x06600000LU, 0x06700000LU, 0x06480000LU, 0x06200000LU, 0x06080000LU, 0x06000000LU, + 0x06180000LU, 0x06580000LU, 0x06280000LU, 0x06100000LU, 0x06300000LU, 0x06500000LU, 0x06400000LU, 0x06680000LU, + 0x00380000LU, 0x00780000LU, 0x00600000LU, 0x00700000LU, 0x00480000LU, 0x00200000LU, 0x00080000LU, 0x00000000LU, + 0x00180000LU, 0x00580000LU, 0x00280000LU, 0x00100000LU, 0x00300000LU, 0x00500000LU, 0x00400000LU, 0x00680000LU, + 0x07b80000LU, 0x07f80000LU, 0x07e00000LU, 0x07f00000LU, 0x07c80000LU, 0x07a00000LU, 0x07880000LU, 0x07800000LU, + 0x07980000LU, 0x07d80000LU, 0x07a80000LU, 0x07900000LU, 0x07b00000LU, 0x07d00000LU, 0x07c00000LU, 0x07e80000LU, + 0x01380000LU, 0x01780000LU, 0x01600000LU, 0x01700000LU, 0x01480000LU, 0x01200000LU, 0x01080000LU, 0x01000000LU, + 0x01180000LU, 0x01580000LU, 0x01280000LU, 0x01100000LU, 0x01300000LU, 0x01500000LU, 0x01400000LU, 0x01680000LU, + 0x04380000LU, 0x04780000LU, 0x04600000LU, 0x04700000LU, 0x04480000LU, 0x04200000LU, 0x04080000LU, 0x04000000LU, + 0x04180000LU, 0x04580000LU, 0x04280000LU, 0x04100000LU, 0x04300000LU, 0x04500000LU, 0x04400000LU, 0x04680000LU, + 0x07380000LU, 0x07780000LU, 0x07600000LU, 0x07700000LU, 0x07480000LU, 0x07200000LU, 0x07080000LU, 0x07000000LU, + 0x07180000LU, 0x07580000LU, 0x07280000LU, 0x07100000LU, 0x07300000LU, 0x07500000LU, 0x07400000LU, 0x07680000LU, + 0x00b80000LU, 0x00f80000LU, 0x00e00000LU, 0x00f00000LU, 0x00c80000LU, 0x00a00000LU, 0x00880000LU, 0x00800000LU, + 0x00980000LU, 0x00d80000LU, 0x00a80000LU, 0x00900000LU, 0x00b00000LU, 0x00d00000LU, 0x00c00000LU, 0x00e80000LU, + 0x03380000LU, 0x03780000LU, 0x03600000LU, 0x03700000LU, 0x03480000LU, 0x03200000LU, 0x03080000LU, 0x03000000LU, + 0x03180000LU, 0x03580000LU, 0x03280000LU, 0x03100000LU, 0x03300000LU, 0x03500000LU, 0x03400000LU, 0x03680000LU, + 0x02b80000LU, 0x02f80000LU, 0x02e00000LU, 0x02f00000LU, 0x02c80000LU, 0x02a00000LU, 0x02880000LU, 0x02800000LU, + 0x02980000LU, 0x02d80000LU, 0x02a80000LU, 0x02900000LU, 0x02b00000LU, 0x02d00000LU, 0x02c00000LU, 0x02e80000LU, + 0x06b80000LU, 0x06f80000LU, 0x06e00000LU, 0x06f00000LU, 0x06c80000LU, 0x06a00000LU, 0x06880000LU, 0x06800000LU, + 0x06980000LU, 0x06d80000LU, 0x06a80000LU, 0x06900000LU, 0x06b00000LU, 0x06d00000LU, 0x06c00000LU, 0x06e80000LU, + 0x05b80000LU, 0x05f80000LU, 0x05e00000LU, 0x05f00000LU, 0x05c80000LU, 0x05a00000LU, 0x05880000LU, 0x05800000LU, + 0x05980000LU, 0x05d80000LU, 0x05a80000LU, 0x05900000LU, 0x05b00000LU, 0x05d00000LU, 0x05c00000LU, 0x05e80000LU, + 0x04b80000LU, 0x04f80000LU, 0x04e00000LU, 0x04f00000LU, 0x04c80000LU, 0x04a00000LU, 0x04880000LU, 0x04800000LU, + 0x04980000LU, 0x04d80000LU, 0x04a80000LU, 0x04900000LU, 0x04b00000LU, 0x04d00000LU, 0x04c00000LU, 0x04e80000LU, + 0x01b80000LU, 0x01f80000LU, 0x01e00000LU, 0x01f00000LU, 0x01c80000LU, 0x01a00000LU, 0x01880000LU, 0x01800000LU, + 0x01980000LU, 0x01d80000LU, 0x01a80000LU, 0x01900000LU, 0x01b00000LU, 0x01d00000LU, 0x01c00000LU, 0x01e80000LU, + }, + { /* table 3 */ + 0xb8000003LU, 0xb0000003LU, 0xa0000003LU, 0xd8000003LU, 0xc8000003LU, 0xe0000003LU, 0x90000003LU, 0xd0000003LU, + 0x88000003LU, 0xc0000003LU, 0x80000003LU, 0xf0000003LU, 0xf8000003LU, 0xe8000003LU, 0x98000003LU, 0xa8000003LU, + 0x38000003LU, 0x30000003LU, 0x20000003LU, 0x58000003LU, 0x48000003LU, 0x60000003LU, 0x10000003LU, 0x50000003LU, + 0x08000003LU, 0x40000003LU, 0x00000003LU, 0x70000003LU, 0x78000003LU, 0x68000003LU, 0x18000003LU, 0x28000003LU, + 0x38000001LU, 0x30000001LU, 0x20000001LU, 0x58000001LU, 0x48000001LU, 0x60000001LU, 0x10000001LU, 0x50000001LU, + 0x08000001LU, 0x40000001LU, 0x00000001LU, 0x70000001LU, 0x78000001LU, 0x68000001LU, 0x18000001LU, 0x28000001LU, + 0x38000002LU, 0x30000002LU, 0x20000002LU, 0x58000002LU, 0x48000002LU, 0x60000002LU, 0x10000002LU, 0x50000002LU, + 0x08000002LU, 0x40000002LU, 0x00000002LU, 0x70000002LU, 0x78000002LU, 0x68000002LU, 0x18000002LU, 0x28000002LU, + 0xb8000006LU, 0xb0000006LU, 0xa0000006LU, 0xd8000006LU, 0xc8000006LU, 0xe0000006LU, 0x90000006LU, 0xd0000006LU, + 0x88000006LU, 0xc0000006LU, 0x80000006LU, 0xf0000006LU, 0xf8000006LU, 0xe8000006LU, 0x98000006LU, 0xa8000006LU, + 0xb8000004LU, 0xb0000004LU, 0xa0000004LU, 0xd8000004LU, 0xc8000004LU, 0xe0000004LU, 0x90000004LU, 0xd0000004LU, + 0x88000004LU, 0xc0000004LU, 0x80000004LU, 0xf0000004LU, 0xf8000004LU, 0xe8000004LU, 0x98000004LU, 0xa8000004LU, + 0xb8000007LU, 0xb0000007LU, 0xa0000007LU, 0xd8000007LU, 0xc8000007LU, 0xe0000007LU, 0x90000007LU, 0xd0000007LU, + 0x88000007LU, 0xc0000007LU, 0x80000007LU, 0xf0000007LU, 0xf8000007LU, 0xe8000007LU, 0x98000007LU, 0xa8000007LU, + 0x38000000LU, 0x30000000LU, 0x20000000LU, 0x58000000LU, 0x48000000LU, 0x60000000LU, 0x10000000LU, 0x50000000LU, + 0x08000000LU, 0x40000000LU, 0x00000000LU, 0x70000000LU, 0x78000000LU, 0x68000000LU, 0x18000000LU, 0x28000000LU, + 0x38000005LU, 0x30000005LU, 0x20000005LU, 0x58000005LU, 0x48000005LU, 0x60000005LU, 0x10000005LU, 0x50000005LU, + 0x08000005LU, 0x40000005LU, 0x00000005LU, 0x70000005LU, 0x78000005LU, 0x68000005LU, 0x18000005LU, 0x28000005LU, + 0xb8000000LU, 0xb0000000LU, 0xa0000000LU, 0xd8000000LU, 0xc8000000LU, 0xe0000000LU, 0x90000000LU, 0xd0000000LU, + 0x88000000LU, 0xc0000000LU, 0x80000000LU, 0xf0000000LU, 0xf8000000LU, 0xe8000000LU, 0x98000000LU, 0xa8000000LU, + 0xb8000002LU, 0xb0000002LU, 0xa0000002LU, 0xd8000002LU, 0xc8000002LU, 0xe0000002LU, 0x90000002LU, 0xd0000002LU, + 0x88000002LU, 0xc0000002LU, 0x80000002LU, 0xf0000002LU, 0xf8000002LU, 0xe8000002LU, 0x98000002LU, 0xa8000002LU, + 0xb8000005LU, 0xb0000005LU, 0xa0000005LU, 0xd8000005LU, 0xc8000005LU, 0xe0000005LU, 0x90000005LU, 0xd0000005LU, + 0x88000005LU, 0xc0000005LU, 0x80000005LU, 0xf0000005LU, 0xf8000005LU, 0xe8000005LU, 0x98000005LU, 0xa8000005LU, + 0x38000004LU, 0x30000004LU, 0x20000004LU, 0x58000004LU, 0x48000004LU, 0x60000004LU, 0x10000004LU, 0x50000004LU, + 0x08000004LU, 0x40000004LU, 0x00000004LU, 0x70000004LU, 0x78000004LU, 0x68000004LU, 0x18000004LU, 0x28000004LU, + 0x38000007LU, 0x30000007LU, 0x20000007LU, 0x58000007LU, 0x48000007LU, 0x60000007LU, 0x10000007LU, 0x50000007LU, + 0x08000007LU, 0x40000007LU, 0x00000007LU, 0x70000007LU, 0x78000007LU, 0x68000007LU, 0x18000007LU, 0x28000007LU, + 0x38000006LU, 0x30000006LU, 0x20000006LU, 0x58000006LU, 0x48000006LU, 0x60000006LU, 0x10000006LU, 0x50000006LU, + 0x08000006LU, 0x40000006LU, 0x00000006LU, 0x70000006LU, 0x78000006LU, 0x68000006LU, 0x18000006LU, 0x28000006LU, + 0xb8000001LU, 0xb0000001LU, 0xa0000001LU, 0xd8000001LU, 0xc8000001LU, 0xe0000001LU, 0x90000001LU, 0xd0000001LU, + 0x88000001LU, 0xc0000001LU, 0x80000001LU, 0xf0000001LU, 0xf8000001LU, 0xe8000001LU, 0x98000001LU, 0xa8000001LU, + }, + { /* table 4 */ + 0x000000e8LU, 0x000000f0LU, 0x000000a0LU, 0x00000088LU, 0x000000b8LU, 0x00000080LU, 0x000000a8LU, 0x000000d0LU, + 0x00000098LU, 0x000000e0LU, 0x000000c0LU, 0x000000f8LU, 0x000000b0LU, 0x00000090LU, 0x000000c8LU, 0x000000d8LU, + 0x000001e8LU, 0x000001f0LU, 0x000001a0LU, 0x00000188LU, 0x000001b8LU, 0x00000180LU, 0x000001a8LU, 0x000001d0LU, + 0x00000198LU, 0x000001e0LU, 0x000001c0LU, 0x000001f8LU, 0x000001b0LU, 0x00000190LU, 0x000001c8LU, 0x000001d8LU, + 0x00000568LU, 0x00000570LU, 0x00000520LU, 0x00000508LU, 0x00000538LU, 0x00000500LU, 0x00000528LU, 0x00000550LU, + 0x00000518LU, 0x00000560LU, 0x00000540LU, 0x00000578LU, 0x00000530LU, 0x00000510LU, 0x00000548LU, 0x00000558LU, + 0x000004e8LU, 0x000004f0LU, 0x000004a0LU, 0x00000488LU, 0x000004b8LU, 0x00000480LU, 0x000004a8LU, 0x000004d0LU, + 0x00000498LU, 0x000004e0LU, 0x000004c0LU, 0x000004f8LU, 0x000004b0LU, 0x00000490LU, 0x000004c8LU, 0x000004d8LU, + 0x000002e8LU, 0x000002f0LU, 0x000002a0LU, 0x00000288LU, 0x000002b8LU, 0x00000280LU, 0x000002a8LU, 0x000002d0LU, + 0x00000298LU, 0x000002e0LU, 0x000002c0LU, 0x000002f8LU, 0x000002b0LU, 0x00000290LU, 0x000002c8LU, 0x000002d8LU, + 0x000005e8LU, 0x000005f0LU, 0x000005a0LU, 0x00000588LU, 0x000005b8LU, 0x00000580LU, 0x000005a8LU, 0x000005d0LU, + 0x00000598LU, 0x000005e0LU, 0x000005c0LU, 0x000005f8LU, 0x000005b0LU, 0x00000590LU, 0x000005c8LU, 0x000005d8LU, + 0x00000268LU, 0x00000270LU, 0x00000220LU, 0x00000208LU, 0x00000238LU, 0x00000200LU, 0x00000228LU, 0x00000250LU, + 0x00000218LU, 0x00000260LU, 0x00000240LU, 0x00000278LU, 0x00000230LU, 0x00000210LU, 0x00000248LU, 0x00000258LU, + 0x000007e8LU, 0x000007f0LU, 0x000007a0LU, 0x00000788LU, 0x000007b8LU, 0x00000780LU, 0x000007a8LU, 0x000007d0LU, + 0x00000798LU, 0x000007e0LU, 0x000007c0LU, 0x000007f8LU, 0x000007b0LU, 0x00000790LU, 0x000007c8LU, 0x000007d8LU, + 0x00000468LU, 0x00000470LU, 0x00000420LU, 0x00000408LU, 0x00000438LU, 0x00000400LU, 0x00000428LU, 0x00000450LU, + 0x00000418LU, 0x00000460LU, 0x00000440LU, 0x00000478LU, 0x00000430LU, 0x00000410LU, 0x00000448LU, 0x00000458LU, + 0x00000368LU, 0x00000370LU, 0x00000320LU, 0x00000308LU, 0x00000338LU, 0x00000300LU, 0x00000328LU, 0x00000350LU, + 0x00000318LU, 0x00000360LU, 0x00000340LU, 0x00000378LU, 0x00000330LU, 0x00000310LU, 0x00000348LU, 0x00000358LU, + 0x000003e8LU, 0x000003f0LU, 0x000003a0LU, 0x00000388LU, 0x000003b8LU, 0x00000380LU, 0x000003a8LU, 0x000003d0LU, + 0x00000398LU, 0x000003e0LU, 0x000003c0LU, 0x000003f8LU, 0x000003b0LU, 0x00000390LU, 0x000003c8LU, 0x000003d8LU, + 0x00000768LU, 0x00000770LU, 0x00000720LU, 0x00000708LU, 0x00000738LU, 0x00000700LU, 0x00000728LU, 0x00000750LU, + 0x00000718LU, 0x00000760LU, 0x00000740LU, 0x00000778LU, 0x00000730LU, 0x00000710LU, 0x00000748LU, 0x00000758LU, + 0x000006e8LU, 0x000006f0LU, 0x000006a0LU, 0x00000688LU, 0x000006b8LU, 0x00000680LU, 0x000006a8LU, 0x000006d0LU, + 0x00000698LU, 0x000006e0LU, 0x000006c0LU, 0x000006f8LU, 0x000006b0LU, 0x00000690LU, 0x000006c8LU, 0x000006d8LU, + 0x00000068LU, 0x00000070LU, 0x00000020LU, 0x00000008LU, 0x00000038LU, 0x00000000LU, 0x00000028LU, 0x00000050LU, + 0x00000018LU, 0x00000060LU, 0x00000040LU, 0x00000078LU, 0x00000030LU, 0x00000010LU, 0x00000048LU, 0x00000058LU, + 0x00000168LU, 0x00000170LU, 0x00000120LU, 0x00000108LU, 0x00000138LU, 0x00000100LU, 0x00000128LU, 0x00000150LU, + 0x00000118LU, 0x00000160LU, 0x00000140LU, 0x00000178LU, 0x00000130LU, 0x00000110LU, 0x00000148LU, 0x00000158LU, + 0x00000668LU, 0x00000670LU, 0x00000620LU, 0x00000608LU, 0x00000638LU, 0x00000600LU, 0x00000628LU, 0x00000650LU, + 0x00000618LU, 0x00000660LU, 0x00000640LU, 0x00000678LU, 0x00000630LU, 0x00000610LU, 0x00000648LU, 0x00000658LU, + }, +}; diff --git a/ext/hash/tests/gost.phpt b/ext/hash/tests/gost.phpt index b800e112e85c3..6ce00242b1a40 100644 --- a/ext/hash/tests/gost.phpt +++ b/ext/hash/tests/gost.phpt @@ -10,6 +10,13 @@ echo hash('gost', 'The quick brown fox jumps over the lazy cog'), "\n"; echo hash('gost', str_repeat('a', 31)), "\n"; echo hash('gost', str_repeat('a', 32)), "\n"; echo hash('gost', str_repeat('a', 33)), "\n"; + +echo hash('gost-crypto', ''), "\n"; +echo hash('gost-crypto', 'The quick brown fox jumps over the lazy dog'), "\n"; +echo hash('gost-crypto', 'The quick brown fox jumps over the lazy cog'), "\n"; +echo hash('gost-crypto', str_repeat('a', 31)), "\n"; +echo hash('gost-crypto', str_repeat('a', 32)), "\n"; +echo hash('gost-crypto', str_repeat('a', 33)), "\n"; ?> --EXPECT-- ce85b99cc46752fffee35cab9a7b0278abb4c2d2055cff685af4912c49490f8d @@ -18,3 +25,9 @@ a3ebc4daaab78b0be131dab5737a7f67e602670d543521319150d2e14eeec445 03840d6348763f11e28e7b1ecc4da0cdf7f898fa555b928ef684c6c5b8f46d9f fd1b746d9397e78edd311baef391450434271e02816caa37680d6d7381c79d4e 715e59cdc8ebde9fdf0fe2a2e811b3bf7f48209a01505e467d2cd2aa2bbb5ecf +981e5f3ca30c841487830f84fb433e13ac1101569b9c13584ac483234cd656c0 +9004294a361a508c586fe53d1f1b02746765e71b765472786e4770d565830a76 +a93124f5bf2c6d83c3bbf722bc55569310245ca5957541f4dbd7dfaf8137e6f2 +8978e06b0ecf54ea81ec51ca4e02bcb4eb390b3f04cb5f65ee8de195ffae591b +e121e3740ae94ca6d289e6d653ff31695783efff3dd960417a1098a0130fa720 +d3e8f22d9762a148ddfc84a6043d97a608604dae7c05baee72b55f559d03dd74 diff --git a/ext/hash/tests/hash_algos.phpt b/ext/hash/tests/hash_algos.phpt index 55796ecbce9aa..7773fe979a72d 100644 --- a/ext/hash/tests/hash_algos.phpt +++ b/ext/hash/tests/hash_algos.phpt @@ -18,7 +18,7 @@ var_dump(hash_algos()); ===Done=== --EXPECTF-- *** Testing hash_algos() : basic functionality *** -array(43) { +array(44) { [%d]=> string(3) "md2" [%d]=> @@ -64,6 +64,8 @@ array(43) { [%d]=> string(4) "gost" [%d]=> + string(11) "gost-crypto" + [%d]=> string(7) "adler32" [%d]=> string(5) "crc32" @@ -106,4 +108,4 @@ array(43) { [%d]=> string(10) "haval256,5" } -===Done=== \ No newline at end of file +===Done=== diff --git a/ext/hash/tests/hash_copy_001.phpt b/ext/hash/tests/hash_copy_001.phpt index 638b7f5fc109a..bb4a49da89712 100644 --- a/ext/hash/tests/hash_copy_001.phpt +++ b/ext/hash/tests/hash_copy_001.phpt @@ -97,6 +97,9 @@ string(64) "fbe88daa74c89b9e29468fa3cd3a657d31845e21bb58dd3f8d806f5179a85c26" string(4) "gost" string(64) "5820c7c4a0650587538b30ef4099f2b5993069758d5c847a552e6ef7360766a5" string(64) "5820c7c4a0650587538b30ef4099f2b5993069758d5c847a552e6ef7360766a5" +string(11) "gost-crypto" +string(64) "f7c4e35548d66aabe2b106f20515d289fde90969225d3d7b83f6dd12d694f043" +string(64) "f7c4e35548d66aabe2b106f20515d289fde90969225d3d7b83f6dd12d694f043" string(7) "adler32" string(8) "6f7c0928" string(8) "6f7c0928" @@ -226,6 +229,9 @@ string(64) "614ca924864fa0e8fa309aa0944e047d5edbfd4964a35858f4d8ec66a0fb88b0" string(4) "gost" string(64) "5820c7c4a0650587538b30ef4099f2b5993069758d5c847a552e6ef7360766a5" string(64) "a00961e371287c71c527a41c14564f13b6ed12ac7cd9d5f5dfb3542a25e28d3b" +string(11) "gost-crypto" +string(64) "f7c4e35548d66aabe2b106f20515d289fde90969225d3d7b83f6dd12d694f043" +string(64) "68ca9aea6729dc07d995fbe071a4b5c6490bb27fc4dc65ec0e96200d5e082996" string(7) "adler32" string(8) "6f7c0928" string(8) "d9141747" diff --git a/ext/intl/collator/collator_create.c b/ext/intl/collator/collator_create.c index b2a8c7f6bac07..7ed4c534394b4 100644 --- a/ext/intl/collator/collator_create.c +++ b/ext/intl/collator/collator_create.c @@ -27,7 +27,7 @@ /* {{{ */ static void collator_ctor(INTERNAL_FUNCTION_PARAMETERS) { - char* locale; + const char* locale; int locale_len = 0; zval* object; Collator_object* co; diff --git a/ext/intl/dateformat/dateformat_parse.c b/ext/intl/dateformat/dateformat_parse.c index 4193e890175b9..993077854646e 100644 --- a/ext/intl/dateformat/dateformat_parse.c +++ b/ext/intl/dateformat/dateformat_parse.c @@ -62,7 +62,7 @@ static void internal_parse_to_timestamp(IntlDateFormatter_object *dfo, char* tex } /* }}} */ -static void add_to_localtime_arr( IntlDateFormatter_object *dfo, zval* return_value, UCalendar parsed_calendar, long calendar_field, char* key_name TSRMLS_DC) +static void add_to_localtime_arr( IntlDateFormatter_object *dfo, zval* return_value, const UCalendar *parsed_calendar, long calendar_field, char* key_name TSRMLS_DC) { long calendar_field_val = ucal_get( parsed_calendar, calendar_field, &INTL_DATA_ERROR_CODE(dfo)); INTL_METHOD_CHECK_STATUS( dfo, "Date parsing - localtime failed : could not get a field from calendar" ); @@ -83,7 +83,7 @@ static void add_to_localtime_arr( IntlDateFormatter_object *dfo, zval* return_va */ static void internal_parse_to_localtime(IntlDateFormatter_object *dfo, char* text_to_parse, int32_t text_len, int32_t *parse_pos, zval *return_value TSRMLS_DC) { - UCalendar* parsed_calendar = NULL; + UCalendar *parsed_calendar = NULL; UChar* text_utf16 = NULL; int32_t text_utf16_len = 0; long isInDST = 0; @@ -92,7 +92,7 @@ static void internal_parse_to_localtime(IntlDateFormatter_object *dfo, char* tex intl_convert_utf8_to_utf16(&text_utf16, &text_utf16_len, text_to_parse, text_len, &INTL_DATA_ERROR_CODE(dfo)); INTL_METHOD_CHECK_STATUS(dfo, "Error converting timezone to UTF-16" ); - parsed_calendar = udat_getCalendar(DATE_FORMAT_OBJECT(dfo)); + parsed_calendar = (UCalendar *)udat_getCalendar(DATE_FORMAT_OBJECT(dfo)); udat_parseCalendar( DATE_FORMAT_OBJECT(dfo), parsed_calendar, text_utf16, text_utf16_len, parse_pos, &INTL_DATA_ERROR_CODE(dfo)); if (text_utf16) { diff --git a/ext/intl/formatter/formatter_main.c b/ext/intl/formatter/formatter_main.c index d0671a88b5e47..0a568472c4835 100644 --- a/ext/intl/formatter/formatter_main.c +++ b/ext/intl/formatter/formatter_main.c @@ -27,7 +27,7 @@ /* {{{ */ static void numfmt_ctor(INTERNAL_FUNCTION_PARAMETERS) { - char* locale; + const char* locale; char* pattern = NULL; int locale_len = 0, pattern_len = 0; long style; diff --git a/ext/intl/locale/locale_methods.c b/ext/intl/locale/locale_methods.c index d1a86d8ee27f4..21b5847f2d339 100644 --- a/ext/intl/locale/locale_methods.c +++ b/ext/intl/locale/locale_methods.c @@ -121,12 +121,15 @@ static int16_t findOffset(const char* const* list, const char* key) } /*}}}*/ -static char* getPreferredTag(char* gf_tag) +static char* getPreferredTag(const char* gf_tag) { char* result = NULL; int grOffset = 0; grOffset = findOffset( LOC_GRANDFATHERED ,gf_tag); + if(grOffset < 0) { + return NULL; + } if( grOffset < LOC_PREFERRED_GRANDFATHERED_LEN ){ /* return preferred tag */ result = estrdup( LOC_PREFERRED_GRANDFATHERED[grOffset] ); @@ -172,7 +175,7 @@ static int getStrrtokenPos(char* str, int savedPos) * returns -1 if no singleton * strtok equivalent search for singleton */ -static int getSingletonPos(char* str) +static int getSingletonPos(const char* str) { int result =-1; int i=0; @@ -248,7 +251,7 @@ PHP_NAMED_FUNCTION(zif_locale_set_default) * common code shared by get_primary_language,get_script or get_region or get_variant * result = 0 if error, 1 if successful , -1 if no value */ -static char* get_icu_value_internal( char* loc_name , char* tag_name, int* result , int fromParseLocale) +static char* get_icu_value_internal( const char* loc_name , char* tag_name, int* result , int fromParseLocale) { char* tag_value = NULL; int32_t tag_value_len = 512; @@ -278,7 +281,7 @@ static char* get_icu_value_internal( char* loc_name , char* tag_name, int* resul /* Handle singletons */ if( strcmp(tag_name , LOC_LANG_TAG)==0 ){ if( strlen(loc_name)>1 && (isIDPrefix(loc_name) ==1 ) ){ - return loc_name; + return (char *)loc_name; } } @@ -367,7 +370,7 @@ static char* get_icu_value_internal( char* loc_name , char* tag_name, int* resul static void get_icu_value_src_php( char* tag_name, INTERNAL_FUNCTION_PARAMETERS) { - char* loc_name = NULL; + const char* loc_name = NULL; int loc_name_len = 0; char* tag_value = NULL; @@ -462,10 +465,10 @@ PHP_FUNCTION(locale_get_primary_language ) }}} */ static void get_icu_disp_value_src_php( char* tag_name, INTERNAL_FUNCTION_PARAMETERS) { - char* loc_name = NULL; + const char* loc_name = NULL; int loc_name_len = 0; - char* disp_loc_name = NULL; + const char* disp_loc_name = NULL; int disp_loc_name_len = 0; int free_loc_name = 0; @@ -558,7 +561,7 @@ static void get_icu_disp_value_src_php( char* tag_name, INTERNAL_FUNCTION_PARAME efree( mod_loc_name ); } if (free_loc_name) { - efree(disp_loc_name); + efree((void *)disp_loc_name); disp_loc_name = NULL; } RETURN_FALSE; @@ -569,7 +572,7 @@ static void get_icu_disp_value_src_php( char* tag_name, INTERNAL_FUNCTION_PARAME efree( mod_loc_name ); } if (free_loc_name) { - efree(disp_loc_name); + efree((void *)disp_loc_name); disp_loc_name = NULL; } /* Convert display locale name from UTF-16 to UTF-8. */ @@ -663,10 +666,10 @@ PHP_FUNCTION( locale_get_keywords ) UEnumeration* e = NULL; UErrorCode status = U_ZERO_ERROR; - const char* kw_key = NULL; + const char* kw_key = NULL; int32_t kw_key_len = 0; - char* loc_name = NULL; + const char* loc_name = NULL; int loc_name_len = 0; /* @@ -713,7 +716,7 @@ PHP_FUNCTION( locale_get_keywords ) kw_value = erealloc( kw_value , kw_value_len+1); } if (U_FAILURE(status)) { - intl_error_set( NULL, FAILURE, "locale_get_keywords: Error encountered while getting the keyword value for the keyword", 0 TSRMLS_CC ); + intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "locale_get_keywords: Error encountered while getting the keyword value for the keyword", 0 TSRMLS_CC ); if( kw_value){ efree( kw_value ); } @@ -971,12 +974,12 @@ PHP_FUNCTION(locale_compose) * e.g. for locale='en_US-x-prv1-prv2-prv3' * returns a pointer to the string 'prv1-prv2-prv3' */ -static char* get_private_subtags(char* loc_name) +static char* get_private_subtags(const char* loc_name) { char* result =NULL; int singletonPos = 0; int len =0; - char* mod_loc_name =NULL; + const char* mod_loc_name =NULL; if( loc_name && (len = strlen(loc_name)>0 ) ){ mod_loc_name = loc_name ; @@ -1016,7 +1019,7 @@ static char* get_private_subtags(char* loc_name) /* {{{ code used by locale_parse */ -static int add_array_entry(char* loc_name, zval* hash_arr, char* key_name TSRMLS_DC) +static int add_array_entry(const char* loc_name, zval* hash_arr, char* key_name TSRMLS_DC) { char* key_value = NULL; char* cur_key_name = NULL; @@ -1081,7 +1084,7 @@ static int add_array_entry(char* loc_name, zval* hash_arr, char* key_name TSRMLS */ PHP_FUNCTION(locale_parse) { - char* loc_name = NULL; + const char* loc_name = NULL; int loc_name_len = 0; int grOffset = 0; @@ -1125,8 +1128,8 @@ PHP_FUNCTION(locale_parse) */ PHP_FUNCTION(locale_get_all_variants) { - char* loc_name = NULL; - int loc_name_len = 0; + const char* loc_name = NULL; + int loc_name_len = 0; int result = 0; char* token = NULL; @@ -1179,10 +1182,10 @@ PHP_FUNCTION(locale_get_all_variants) /*{{{ * Converts to lower case and also replaces all hyphens with the underscore */ -static int strToMatch(char* str ,char *retstr) +static int strToMatch(const char* str ,char *retstr) { char* anchor = NULL; - char* anchor1 = NULL; + const char* anchor1 = NULL; int result = 0; int len = 0; @@ -1222,7 +1225,7 @@ PHP_FUNCTION(locale_filter_matches) { char* lang_tag = NULL; int lang_tag_len = 0; - char* loc_range = NULL; + const char* loc_range = NULL; int loc_range_len = 0; int result = 0; @@ -1398,7 +1401,7 @@ static void array_cleanup( char* arr[] , int arr_size) * returns the lookup result to lookup_loc_range_src_php * internal function */ -static char* lookup_loc_range(char* loc_range, HashTable* hash_arr, int canonicalize TSRMLS_DC) +static char* lookup_loc_range(const char* loc_range, HashTable* hash_arr, int canonicalize TSRMLS_DC) { int i = 0; int cur_arr_len = 0; @@ -1520,7 +1523,7 @@ PHP_FUNCTION(locale_lookup) { char* fallback_loc = NULL; int fallback_loc_len = 0; - char* loc_range = NULL; + const char* loc_range = NULL; int loc_range_len = 0; zval* arr = NULL; diff --git a/ext/intl/msgformat/msgformat.c b/ext/intl/msgformat/msgformat.c index 6a9f04f32b463..7d8cd958e3c08 100644 --- a/ext/intl/msgformat/msgformat.c +++ b/ext/intl/msgformat/msgformat.c @@ -28,7 +28,7 @@ /* {{{ */ static void msgfmt_ctor(INTERNAL_FUNCTION_PARAMETERS) { - char* locale; + const char* locale; char* pattern; int locale_len = 0, pattern_len = 0; UChar* spattern = NULL; diff --git a/ext/intl/msgformat/msgformat_format.c b/ext/intl/msgformat/msgformat_format.c index 4b81cfe2b454c..55ec9e84ba0e8 100644 --- a/ext/intl/msgformat/msgformat_format.c +++ b/ext/intl/msgformat/msgformat_format.c @@ -103,7 +103,7 @@ PHP_FUNCTION( msgfmt_format_message ) int spattern_len = 0; char *pattern = NULL; int pattern_len = 0; - char *slocale = NULL; + const char *slocale = NULL; int slocale_len = 0; MessageFormatter_object mf = {0}; MessageFormatter_object *mfo = &mf; diff --git a/ext/intl/msgformat/msgformat_helpers.cpp b/ext/intl/msgformat/msgformat_helpers.cpp index c4456d54f3c84..f75fd91dce775 100644 --- a/ext/intl/msgformat/msgformat_helpers.cpp +++ b/ext/intl/msgformat/msgformat_helpers.cpp @@ -209,6 +209,9 @@ static HashTable *umsg_parse_format(MessageFormatter_object *mfo, continue; } } + } else { + intl_errors_set(&err, U_INVALID_FORMAT_ERROR, "Invalid part type encountered", 0 TSRMLS_CC); + continue; } UMessagePatternArgType argType = p.getArgType(); diff --git a/ext/intl/msgformat/msgformat_parse.c b/ext/intl/msgformat/msgformat_parse.c index 413d3b1f15d89..14a6363424bf0 100644 --- a/ext/intl/msgformat/msgformat_parse.c +++ b/ext/intl/msgformat/msgformat_parse.c @@ -93,7 +93,7 @@ PHP_FUNCTION( msgfmt_parse_message ) int spattern_len = 0; char *pattern = NULL; int pattern_len = 0; - char *slocale = NULL; + const char *slocale = NULL; int slocale_len = 0; char *source = NULL; int src_len = 0; diff --git a/ext/intl/tests/bug58756_MessageFormatter.phpt b/ext/intl/tests/bug58756_MessageFormatter.phpt index bbe96b7045a10..18566b666c9c4 100644 --- a/ext/intl/tests/bug58756_MessageFormatter.phpt +++ b/ext/intl/tests/bug58756_MessageFormatter.phpt @@ -4,6 +4,9 @@ Bug #58756: w.r.t MessageFormatter = 0) + die('skip for ICU < 51.2'); +?> --FILE-- format(array($time, 'date')), " ", --EXPECT-- date: Tuesday, July 7, 2009 8:41:13 PM EDT msgf: Tuesday, July 7, 2009 8:41:13 PM EDT -==DONE== \ No newline at end of file +==DONE== diff --git a/ext/intl/tests/bug58756_MessageFormatter_variant2.phpt b/ext/intl/tests/bug58756_MessageFormatter_variant2.phpt new file mode 100644 index 0000000000000..4fcfdbc08c073 --- /dev/null +++ b/ext/intl/tests/bug58756_MessageFormatter_variant2.phpt @@ -0,0 +1,37 @@ +--TEST-- +Bug #58756: w.r.t MessageFormatter +--SKIPIF-- += 51.2'); +?> +--FILE-- +format(array($time)) . "\n"; + +//NOT FIXED: +/*$msgf = new MessageFormatter('en_US', +'{1, select, date {{0,date,full}} other {{0,time,h:m:s a V}}}'); + +echo "msgf2: ", $msgf->format(array($time, 'date')), " ", + $msgf->format(array($time, 'time')), "\n"; +*/ + +?> +==DONE== +--EXPECT-- +date: Tuesday, July 7, 2009 8:41:13 PM EDT +msgf: Tuesday, July 7, 2009 8:41:13 PM usnyc +==DONE== diff --git a/ext/intl/tests/collator_asort.phpt b/ext/intl/tests/collator_asort.phpt index a614ddc3f88e2..308f3a3ca3742 100644 --- a/ext/intl/tests/collator_asort.phpt +++ b/ext/intl/tests/collator_asort.phpt @@ -2,6 +2,7 @@ asort() --SKIPIF-- += 0) die('skip for ICU < 51.2'); ?> --FILE-- += 51.2'); ?> +--FILE-- + 'y' , + 'c' => 'i' , + 'a' => 'k' ), + + array( 'a' => 'a' , + 'b' => 'aaa', + 'c' => 'aa' ), + + array( 'a' => 'a' , + 'aaa'=> 'a' , + 'aa' => 'a' ), + + array( '1' => 'abc', + '5' => '!' , + '2' => null , + '7' => '' ), + + array( '1' => '100', + '2' => '25' , + '3' => '36' ), + + array( '1' => 5 , + '2' => '30' , + '3' => 2 ) + ); + + $res_str .= sort_arrays( 'en_US', $test_params ); + + // Sort an array in SORT_STRING mode using en_US locale. + $test_params = array( + array( '1' => '100', + '2' => '25' , + '3' => '36' ), + + array( '1' => 5 , + '2' => '30' , + '3' => 2 ), + + array( '1' => 'd' , + '2' => '' , + '3' => ' a' ), + + array( '1' => 'y' , + '2' => 'k' , + '3' => 'i' ) + ); + + $res_str .= sort_arrays( 'en_US', $test_params, Collator::SORT_STRING ); + + // Sort a non-ASCII array using ru_RU locale. + $test_params = array( + array( 'п' => 'у', + 'б' => 'в', + 'е' => 'а' ), + + array( '1' => 'п', + '4' => '', + '7' => 'd', + '2' => 'пп' ) + ); + + $res_str .= sort_arrays( 'ru_RU', $test_params ); + + + // Sort an array using Lithuanian locale. + $test_params = array( + array( 'd' => 'y', + 'c' => 'i', + 'a' => 'k' ) + ); + + $res_str .= sort_arrays( 'lt_LT', $test_params ); + + return $res_str . "\n"; +} + +include_once( 'ut_common.inc' ); +ut_run(); +?> +--EXPECT-- +Test 1.162b81ac12878b817fc39063097e45b5: +array ( + 'c' => 'i', + 'a' => 'k', + 'd' => 'y', +) + Result: true + +Test 2.93d96e22f692d8a281b0a389f01f8d1e: +array ( + 'a' => 'a', + 'c' => 'aa', + 'b' => 'aaa', +) + Result: true + +Test 3.9f25de4482bc7b58de508e278113317c: +array ( + 'aa' => 'a', + 'aaa' => 'a', + 'a' => 'a', +) + Result: true + +Test 4.a85a41ea78e45b651080cfd98c0b431d: +array ( + 7 => '', + 2 => NULL, + 5 => '!', + 1 => 'abc', +) + Result: true + +Test 5.99dc71f405b286e03d489061b36e6900: +array ( + 2 => '25', + 3 => '36', + 1 => '100', +) + Result: true + +Test 6.bf5bba243307c9d12934e756ad4be190: +array ( + 3 => 2, + 1 => 5, + 2 => '30', +) + Result: true + +Test 7.e4ee7024c61476e9e7a6c28b5e47df6f: +array ( + 1 => '100', + 2 => '25', + 3 => '36', +) + Result: true + +Test 8.5fa7033dd43784be0db1474eb48b83c8: +array ( + 3 => 2, + 2 => '30', + 1 => 5, +) + Result: true + +Test 9.588cdf4692bc09aa92ffe7e48f9e4579: +array ( + 2 => '', + 3 => ' a', + 1 => 'd', +) + Result: true + +Test 10.be02641a47ebcccd23e4183ca3a415f7: +array ( + 3 => 'i', + 2 => 'k', + 1 => 'y', +) + Result: true + +Test 11.153d9b11d1e5936afc917a94a4e11f34: +array ( + 'е' => 'а', + 'б' => 'в', + 'п' => 'у', +) + Result: true + +Test 12.e1f5cb037b564dce39ffbd0a61562d59: +array ( + 4 => '', + 1 => 'п', + 2 => 'пп', + 7 => 'd', +) + Result: true + +Test 13.8800d48abb960a59002eef77f1d73ae0: +array ( + 'c' => 'i', + 'd' => 'y', + 'a' => 'k', +) + Result: true diff --git a/ext/intl/tests/collator_compare.phpt b/ext/intl/tests/collator_compare.phpt index f10b5708f405c..7c07204b70309 100644 --- a/ext/intl/tests/collator_compare.phpt +++ b/ext/intl/tests/collator_compare.phpt @@ -2,6 +2,7 @@ compare() --SKIPIF-- += 0) die('skip for ICU < 51.2'); ?> --FILE-- += 51.2'); ?> +--FILE-- +'; + case -1: // UCOL_LESS + return '<'; + default: + return '?'; + } +} + +/* + * Compare string pairs in the given array + * using specified locale. + */ +function compare_pairs( $locale, $test_array ) +{ + $res_str = ''; + + $coll = ut_coll_create( $locale ); + + foreach( $test_array as $test_strings ) + { + list( $str1, $str2 ) = $test_strings; + + // Compare strings. + $res_val = cmp_to_char( ut_coll_compare( $coll, $str1, $str2 ) ); + + // Concatenate result strings. + $res_str .= dump( $str1 ) . + ' ' . $res_val . ' ' . + dump( $str2 ) . "\n"; + } + + return $res_str; + +} + +function ut_main() +{ + $res_str = ''; + + // Compare strings using en_US locale. + $test_params = array( + array( 'abc', 'abc' ), + array( 'Abc', 'abc' ), + array( 'a' , 'abc' ), + array( 'a' , '' ), + array( '' , '' ), + array( 'a' , 'b' ), + array( 'ab' , 'b' ), + array( 'ab' , 'a' ), + array( 123 , 'abc' ), + array( 'ac' , null ), + array( '.' , '.' ), + // Try to compare long strings. + array( 'abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcde', + 'abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdea'), + array( null , null ) + ); + + $res_str .= compare_pairs( 'en_US', $test_params ); + + + // Compare strings using ru_RU locale. + $test_params = array( + array( 'а', 'б' ), + array( 'а', 'аа' ), + array( 'аб', 'ба' ), + array( 'а', ',' ), + array( 'а', 'b' ), + array( 'а', 'bb' ), + array( 'а', 'ab' ), + array( 'а', null ) + ); + + $res_str .= compare_pairs( 'ru_RU', $test_params ); + + + // Compare strings using lt_LT locale. + $test_params = array( + array( 'y', 'k' ) + ); + + $res_str .= compare_pairs( 'lt_LT', $test_params ); + + return $res_str; +} + +include_once( 'ut_common.inc' ); +ut_run(); +?> +--EXPECT-- +'abc' = 'abc' +'Abc' > 'abc' +'a' < 'abc' +'a' > '' +'' = '' +'a' < 'b' +'ab' < 'b' +'ab' > 'a' +123 < 'abc' +'ac' > NULL +'.' = '.' +'abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcde' < 'abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdea' +NULL = NULL +'а' < 'б' +'а' < 'аа' +'аб' < 'ба' +'а' > ',' +'а' < 'b' +'а' < 'bb' +'а' < 'ab' +'а' > NULL +'y' < 'k' diff --git a/ext/intl/tests/collator_get_sort_key.phpt b/ext/intl/tests/collator_get_sort_key.phpt index a9c4d71348129..58240d426c52c 100644 --- a/ext/intl/tests/collator_get_sort_key.phpt +++ b/ext/intl/tests/collator_get_sort_key.phpt @@ -3,6 +3,8 @@ collator_get_sort_key() --SKIPIF-- = 4.8 only'; ?> += 4.8 and < 51.2 */ +if (version_compare(INTL_ICU_VERSION, '51.2') >= 0) die('skip for ICU < 51.2'); ?> --FILE-- += 51.2'); ?> +--FILE-- + +--EXPECT-- +source: abc +key: 27292b01070107 +source: abd +key: 27292d01070107 +source: aaa +key: 27272701070107 +source: аа +key: 5c0a0a01060106 +source: а +key: 5c0a01050105 +source: z +key: 5901050105 +source: +key: 0101 +source: +key: 0101 +source: 3 +key: 1801050105 +source: y +key: 5701050105 +source: i +key: 3701050105 +source: k +key: 3b01050105 +source: абг +key: 260a161a01070107 +source: абв +key: 260a161801070107 +source: жжж +key: 263a3a3a01070107 +source: эюя +key: 273b3f4501070107 +source: абг +key: 5c0a161a01070107 +source: абв +key: 5c0a161801070107 +source: жжж +key: 5c3a3a3a01070107 +source: эюя +key: 5d3b3f4501070107 diff --git a/ext/intl/tests/collator_sort.phpt b/ext/intl/tests/collator_sort.phpt index 5cefe2fd7cefd..e16eeea1e8503 100644 --- a/ext/intl/tests/collator_sort.phpt +++ b/ext/intl/tests/collator_sort.phpt @@ -2,6 +2,7 @@ sort() --SKIPIF-- += 0) die('skip for ICU < 51.2'); ?> --FILE-- += 51.2'); ?> +--FILE-- + +--EXPECT-- +Test 1.e8f1cd28133d79ecd660002f1c660d0e: +array ( + 0 => 'aaa', + 1 => 'abc', + 2 => 'abd', +) + Result: true + +Test 2.c2ded12173dd2996927378cae37eb275: +array ( + 0 => '_', + 1 => '1', + 2 => 'm', +) + Result: true + +Test 3.54071c968d71cb98c5d379145f8d7d38: +array ( + 0 => 'a', + 1 => 'aa', + 2 => 'aaa', +) + Result: true + +Test 4.19abe63d6f6dfef65b0e3c9ab4826b07: +array ( + 0 => 'ab', + 1 => 'b', + 2 => 'ba', +) + Result: true + +Test 5.9a8dc0a9bc771368c2f1fc3d02754610: +array ( + 0 => 'a', + 1 => 'c', + 2 => 'e', +) + Result: true + +Test 6.ab530b060e5e54a65bfb8b9f8fc61870: +array ( + 0 => '25', + 1 => '36', + 2 => '100', +) + Result: true + +Test 7.0718dd838509017bded2ed307a6e785f: +array ( + 0 => 2, + 1 => 5, + 2 => '30', +) + Result: true + +Test 8.923d65739c5219c634616ffd100a50e4: +array ( + 0 => '', + 1 => ' a', + 2 => 'd', +) + Result: true + +Test 9.289bc2f28e87d3201ec9d7e8477ae1b0: +array ( + 0 => ' a', + 1 => 'd ', + 2 => 'f ', +) + Result: true + +Test 10.de0fd958484f2377a645835d7fbcf124: +array ( + 0 => NULL, + 1 => '3', + 2 => 'a', +) + Result: true + +Test 11.dd2b8f0adb37c45d528cad1a0cc0f361: +array ( + 0 => 'i', + 1 => 'k', + 2 => 'y', +) + Result: true + +Test 12.1e6b4d6f7df9d4580317634ea46d8208: +array ( + 0 => '100', + 1 => '25', + 2 => '36', +) + Result: true + +Test 13.cec115dc9850b98dfbdf102efa09e61b: +array ( + 0 => 2, + 1 => '30', + 2 => 5, +) + Result: true + +Test 14.923d65739c5219c634616ffd100a50e4: +array ( + 0 => '', + 1 => ' a', + 2 => 'd', +) + Result: true + +Test 15.dd2b8f0adb37c45d528cad1a0cc0f361: +array ( + 0 => 'i', + 1 => 'k', + 2 => 'y', +) + Result: true + +Test 16.49056308afb2b800363c5baa735ed247: +array ( + 0 => 'ааа', + 1 => 'абв', + 2 => 'абг', + 3 => 'abc', +) + Result: true + +Test 17.91480b10473a0c96a4cd6d88c23c577a: +array ( + 0 => 'а', + 1 => 'аа', + 2 => 'ааа', +) + Result: true + +Test 18.fdd3fe3981476039164aa000bf9177f2: +array ( + 0 => 'i', + 1 => 'y', + 2 => 'k', +) + Result: true diff --git a/ext/intl/tests/collator_sort_with_sort_keys.phpt b/ext/intl/tests/collator_sort_with_sort_keys.phpt index 2f489d745cb90..8be9c97789cc6 100644 --- a/ext/intl/tests/collator_sort_with_sort_keys.phpt +++ b/ext/intl/tests/collator_sort_with_sort_keys.phpt @@ -2,6 +2,7 @@ sort_with_sort_keys() --SKIPIF-- += 0) die('skip for ICU < 51.2'); ?> --FILE-- += 51.2'); ?> +--FILE-- + +--EXPECT-- +Test 1.e8f1cd28133d79ecd660002f1c660d0e: +array ( + 0 => 'aaa', + 1 => 'abc', + 2 => 'abd', +) + Result: true + +Test 2.c2ded12173dd2996927378cae37eb275: +array ( + 0 => '_', + 1 => '1', + 2 => 'm', +) + Result: true + +Test 3.54071c968d71cb98c5d379145f8d7d38: +array ( + 0 => 'a', + 1 => 'aa', + 2 => 'aaa', +) + Result: true + +Test 4.19abe63d6f6dfef65b0e3c9ab4826b07: +array ( + 0 => 'ab', + 1 => 'b', + 2 => 'ba', +) + Result: true + +Test 5.9a8dc0a9bc771368c2f1fc3d02754610: +array ( + 0 => 'a', + 1 => 'c', + 2 => 'e', +) + Result: true + +Test 6.923d65739c5219c634616ffd100a50e4: +array ( + 0 => '', + 1 => ' a', + 2 => 'd', +) + Result: true + +Test 7.289bc2f28e87d3201ec9d7e8477ae1b0: +array ( + 0 => ' a', + 1 => 'd ', + 2 => 'f ', +) + Result: true + +Test 8.de0fd958484f2377a645835d7fbcf124: +array ( + 0 => NULL, + 1 => '3', + 2 => 'a', +) + Result: true + +Test 9.dd2b8f0adb37c45d528cad1a0cc0f361: +array ( + 0 => 'i', + 1 => 'k', + 2 => 'y', +) + Result: true + +Test 10.49056308afb2b800363c5baa735ed247: +array ( + 0 => 'ааа', + 1 => 'абв', + 2 => 'абг', + 3 => 'abc', +) + Result: true + +Test 11.91480b10473a0c96a4cd6d88c23c577a: +array ( + 0 => 'а', + 1 => 'аа', + 2 => 'ааа', +) + Result: true + +Test 12.fdd3fe3981476039164aa000bf9177f2: +array ( + 0 => 'i', + 1 => 'y', + 2 => 'k', +) + Result: true diff --git a/ext/intl/tests/dateformat_calendars.phpt b/ext/intl/tests/dateformat_calendars.phpt index 6af02e51c14e6..2239af28dfc68 100644 --- a/ext/intl/tests/dateformat_calendars.phpt +++ b/ext/intl/tests/dateformat_calendars.phpt @@ -4,8 +4,8 @@ IntlDateFormatter, calendars and time zone date.timezone=Atlantic/Azores --SKIPIF-- += 0) die('skip for ICU < 51.2'); ?> --FILE-- += 51.2'); ?> +--FILE-- +format(strtotime('2012-01-01 00:00:00 +0000'))); +var_dump($fmt2->format(strtotime('2012-01-01 00:00:00 +0000'))); +var_dump($fmt3->format(strtotime('2012-01-01 00:00:00 +0000'))); + +new IntlDateFormatter('en_US@calendar=hebrew', + IntlDateFormatter::FULL, + IntlDateFormatter::FULL, + 'GMT+05:12', + -1); +?> +==DONE== +--EXPECTF-- +string(47) "Sunday, January 1, 2012 at 5:12:00 AM GMT+05:12" +string(47) "Sunday, January 1, 2012 at 5:12:00 AM GMT+05:12" +string(48) "Sunday, Tevet 6, 5772 AM at 5:12:00 AM GMT+05:12" + +Warning: IntlDateFormatter::__construct(): datefmt_create: invalid value for calendar type; it must be one of IntlDateFormatter::TRADITIONAL (locale's default calendar) or IntlDateFormatter::GREGORIAN. Alternatively, it can be an IntlCalendar object in %sdateformat_calendars_variant2.php on line %d +==DONE== diff --git a/ext/intl/tests/dateformat_create_cal_arg.phpt b/ext/intl/tests/dateformat_create_cal_arg.phpt index 53fb084af95e6..a8f351247bde4 100644 --- a/ext/intl/tests/dateformat_create_cal_arg.phpt +++ b/ext/intl/tests/dateformat_create_cal_arg.phpt @@ -2,8 +2,8 @@ IntlDateFormatter: several forms of the calendar arg --SKIPIF-- += 0) die('skip for ICU < 51.2'); ?> --FILE-- += 51.2'); ?> +--FILE-- +format($ts), "\n"; + +$cal = IntlCalendar::createInstance('UTC', 'en@calendar=islamic'); +$df = new IntlDateFormatter('es_ES', 0, 0, NULL, $cal); +echo $df->format($ts), "\n"; + +//override calendar's timezone +$cal = new IntlGregorianCalendar('UTC', NULL); +$df = new IntlDateFormatter('es_ES', 0, 0, 'Europe/Madrid', $cal); +echo $df->format($ts), "\n"; + +//default calendar is gregorian +$df = new IntlDateFormatter('es_ES@calendar=islamic', 0, 0); +echo $df->format($ts), "\n"; + +//try now with traditional +$df = new IntlDateFormatter('es_ES@calendar=islamic', 0, 0, NULL, IntlDateFormatter::TRADITIONAL); +echo $df->format($ts), "\n"; + +//the timezone can be overridden when not specifying a calendar +$df = new IntlDateFormatter('es_ES@calendar=islamic', 0, 0, 'UTC', IntlDateFormatter::TRADITIONAL); +echo $df->format($ts), "\n"; + +$df = new IntlDateFormatter('es_ES', 0, 0, 'UTC', 0); +echo $df->format($ts), "\n"; + +?> +==DONE== +--EXPECTF-- +domingo%S 1 de enero de 2012 00:00:00 GMT +domingo%S 8 de Safar de 1433 00:00:00 GMT +domingo%S 1 de enero de 2012 01:00:00 Hora estándar de Europa central +sábado%S 31 de diciembre de 2011 d.C. 23:00:00 Hora %Sde las Azores +sábado%S 7 de Safar de 1433 AH 23:00:00 Hora %Sde las Azores +domingo%S 8 de Safar de 1433 AH 00:00:00 GMT +domingo%S 1 de enero de 2012 00:00:00 GMT +==DONE== diff --git a/ext/intl/tests/dateformat_format.phpt b/ext/intl/tests/dateformat_format.phpt index 8664eea319888..c3f6c297d96df 100644 --- a/ext/intl/tests/dateformat_format.phpt +++ b/ext/intl/tests/dateformat_format.phpt @@ -2,6 +2,7 @@ datefmt_format_code() --SKIPIF-- += 0) die('skip for ICU < 51.2'); ?> --FILE-- += 0) die('skip for ICU < 51.2'); ?> --FILE-- += 51.2'); ?> +--FILE-- +setTime(strtotime('2012-01-01 00:00:00')*1000.); +echo IntlDateFormatter::formatObject($cal), "\n"; +echo IntlDateFormatter::formatObject($cal, IntlDateFormatter::FULL, "en-US"), "\n"; + +?> +==DONE== + +--EXPECTF-- +01/01/2012, 00:00:00 +Domingo, 1 de Janeiro de 2012 às 00:00:00 Hora %Sda Europa Ocidental +Jan 1, 2012, 12:00:00 AM +1/1/12, 12:00:00 AM Western European Standard %STime +Sun 2012-01-1 00,00,00.000 Portugal Time +Domingo, 1 de Janeiro de 2012 às 05:00:00 GMT+03:00 +06/02/1433, 00:00:00 +Sunday, Safar 6, 1433 at 12:00:00 AM Western European Standard Time +==DONE== diff --git a/ext/intl/tests/dateformat_formatObject_datetime.phpt b/ext/intl/tests/dateformat_formatObject_datetime.phpt index 6427ad5a988c6..d9ddb0e644324 100644 --- a/ext/intl/tests/dateformat_formatObject_datetime.phpt +++ b/ext/intl/tests/dateformat_formatObject_datetime.phpt @@ -2,8 +2,8 @@ IntlDateFormatter::formatObject(): DateTime tests --SKIPIF-- += 0) die('skip for ICU < 51.2'); ?> --FILE-- += 51.2'); ?> +--FILE-- + +==DONE== + +--EXPECTF-- +01/01/2012, 00:00:00 +Domingo, 1 de Janeiro de 2012 às 00:00:00 Hora %Sda Europa Ocidental +Jan 1, 2012, 12:00:00 AM +1/1/12, 12:00:00 AM Western European Standard %STime +Sun 2012-01-1 00,00,00.000 Portugal Time +Domingo, 1 de Janeiro de 2012 às 05:00:00 GMT+03:00 +==DONE== diff --git a/ext/intl/tests/dateformat_format_parse.phpt b/ext/intl/tests/dateformat_format_parse.phpt index 6bd3d8a8ff9ef..dfb479e937b97 100644 --- a/ext/intl/tests/dateformat_format_parse.phpt +++ b/ext/intl/tests/dateformat_format_parse.phpt @@ -2,6 +2,7 @@ datefmt_format_code() and datefmt_parse_code() --SKIPIF-- += 0) die('skip for ICU < 51.2'); ?> --FILE-- += 51.2'); ?> +--FILE-- + 24 , + 'tm_min' => 3, + 'tm_hour' => 19, + 'tm_mday' => 3, + 'tm_mon' => 3, + 'tm_year' => 105, + ); + $localtime_arr2 = array ( + 'tm_sec' => 21, + 'tm_min' => 5, + 'tm_hour' => 7, + 'tm_mday' => 13, + 'tm_mon' => 7, + 'tm_year' => 205, + ); + $localtime_arr3 = array ( + 'tm_sec' => 11, + 'tm_min' => 13, + 'tm_hour' => 0, + 'tm_mday' => 17, + 'tm_mon' => 11, + 'tm_year' => -5 + ); + + $localtime_arr = array ( + $localtime_arr1, + $localtime_arr2, + $localtime_arr3 + ); + + //Test format and parse with a timestamp : long + foreach( $time_arr as $timestamp_entry){ + $res_str .= "\n------------\n"; + $res_str .= "\nInput timestamp is : $timestamp_entry"; + $res_str .= "\n------------\n"; + foreach( $locale_arr as $locale_entry ){ + foreach( $datetype_arr as $datetype_entry ) { + $res_str .= "\nIntlDateFormatter locale= $locale_entry ,datetype = $datetype_entry ,timetype =$datetype_entry "; + $fmt = ut_datefmt_create( $locale_entry , $datetype_entry ,$datetype_entry,$timezone); + $formatted = ut_datefmt_format( $fmt , $timestamp_entry); + $res_str .= "\nFormatted timestamp is : $formatted"; + $parsed = ut_datefmt_parse( $fmt , $formatted); + if( intl_get_error_code() == U_ZERO_ERROR){ + $res_str .= "\nParsed timestamp is : $parsed"; + }else{ + $res_str .= "\nError while parsing as: '".intl_get_error_message()."'"; + } + } + } + } + + //Test format and parse with a localtime :array + foreach( $localtime_arr as $localtime_entry){ + $res_str .= "\n------------\n"; + $res_str .= "\nInput localtime is : "; + foreach( $localtime_entry as $key => $value){ + $res_str .= "$key : '$value' , "; + } + + $res_str .= "\n------------\n"; + foreach( $locale_arr as $locale_entry ){ + foreach( $datetype_arr as $datetype_entry ) { + $res_str .= "\nIntlDateFormatter locale= $locale_entry ,datetype = $datetype_entry ,timetype =$datetype_entry "; + $fmt = ut_datefmt_create( $locale_entry , $datetype_entry ,$datetype_entry,$timezone); + $formatted1 = ut_datefmt_format( $fmt , $localtime_entry); + if( intl_get_error_code() == U_ZERO_ERROR){ + $res_str .= "\nFormatted localtime_array is : $formatted1"; + }else{ + $res_str .= "\nError while formatting as: '".intl_get_error_message()."'"; + } + //Parsing + $parsed_arr = ut_datefmt_localtime( $fmt, $formatted1 ); + + if( $parsed_arr){ + $res_str .= "\nParsed array is: "; + foreach( $parsed_arr as $key => $value){ + $res_str .= "$key : '$value' , "; + } + } +/* + else{ + //$res_str .= "No values found from LocaleTime parsing."; + $res_str .= "\tError : '".intl_get_error_message()."'"; + } +*/ + } + } + } + + return $res_str; + +} + +include_once( 'ut_common.inc' ); + +// Run the test +ut_run(); +?> +--EXPECT-- +------------ + +Input timestamp is : 0 +------------ + +IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 +Formatted timestamp is : Thursday, January 1, 1970 at 5:00:00 AM GMT+05:00 +Parsed timestamp is : 0 +IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 +Formatted timestamp is : January 1, 1970 at 5:00:00 AM GMT+5 +Parsed timestamp is : 0 +IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 +Formatted timestamp is : Jan 1, 1970, 5:00:00 AM +Parsed timestamp is : 0 +------------ + +Input timestamp is : -1200000 +------------ + +IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 +Formatted timestamp is : Thursday, December 18, 1969 at 7:40:00 AM GMT+05:00 +Parsed timestamp is : -1200000 +IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 +Formatted timestamp is : December 18, 1969 at 7:40:00 AM GMT+5 +Parsed timestamp is : -1200000 +IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 +Formatted timestamp is : Dec 18, 1969, 7:40:00 AM +Parsed timestamp is : -1200000 +------------ + +Input timestamp is : 1200000 +------------ + +IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 +Formatted timestamp is : Thursday, January 15, 1970 at 2:20:00 AM GMT+05:00 +Parsed timestamp is : 1200000 +IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 +Formatted timestamp is : January 15, 1970 at 2:20:00 AM GMT+5 +Parsed timestamp is : 1200000 +IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 +Formatted timestamp is : Jan 15, 1970, 2:20:00 AM +Parsed timestamp is : 1200000 +------------ + +Input timestamp is : 2200000000 +------------ + +IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 +Formatted timestamp is : Monday, September 19, 2039 at 4:06:40 AM GMT+05:00 +Parsed timestamp is : 2200000000 +IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 +Formatted timestamp is : September 19, 2039 at 4:06:40 AM GMT+5 +Parsed timestamp is : 2200000000 +IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 +Formatted timestamp is : Sep 19, 2039, 4:06:40 AM +Parsed timestamp is : 2200000000 +------------ + +Input timestamp is : -2200000000 +------------ + +IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 +Formatted timestamp is : Sunday, April 15, 1900 at 5:53:20 AM GMT+05:00 +Parsed timestamp is : -2200000000 +IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 +Formatted timestamp is : April 15, 1900 at 5:53:20 AM GMT+5 +Parsed timestamp is : -2200000000 +IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 +Formatted timestamp is : Apr 15, 1900, 5:53:20 AM +Parsed timestamp is : -2200000000 +------------ + +Input timestamp is : 90099999 +------------ + +IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 +Formatted timestamp is : Thursday, November 9, 1972 at 12:46:39 AM GMT+05:00 +Parsed timestamp is : 90099999 +IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 +Formatted timestamp is : November 9, 1972 at 12:46:39 AM GMT+5 +Parsed timestamp is : 90099999 +IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 +Formatted timestamp is : Nov 9, 1972, 12:46:39 AM +Parsed timestamp is : 90099999 +------------ + +Input timestamp is : 3600 +------------ + +IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 +Formatted timestamp is : Thursday, January 1, 1970 at 6:00:00 AM GMT+05:00 +Parsed timestamp is : 3600 +IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 +Formatted timestamp is : January 1, 1970 at 6:00:00 AM GMT+5 +Parsed timestamp is : 3600 +IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 +Formatted timestamp is : Jan 1, 1970, 6:00:00 AM +Parsed timestamp is : 3600 +------------ + +Input timestamp is : -3600 +------------ + +IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 +Formatted timestamp is : Thursday, January 1, 1970 at 4:00:00 AM GMT+05:00 +Parsed timestamp is : -3600 +IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 +Formatted timestamp is : January 1, 1970 at 4:00:00 AM GMT+5 +Parsed timestamp is : -3600 +IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 +Formatted timestamp is : Jan 1, 1970, 4:00:00 AM +Parsed timestamp is : -3600 +------------ + +Input localtime is : tm_sec : '24' , tm_min : '3' , tm_hour : '19' , tm_mday : '3' , tm_mon : '3' , tm_year : '105' , +------------ + +IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 +Formatted localtime_array is : Sunday, April 3, 2005 at 7:03:24 PM GMT+05:00 +Parsed array is: tm_sec : '24' , tm_min : '3' , tm_hour : '19' , tm_year : '105' , tm_mday : '3' , tm_wday : '0' , tm_yday : '93' , tm_mon : '3' , tm_isdst : '0' , +IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 +Formatted localtime_array is : April 3, 2005 at 7:03:24 PM GMT+5 +Parsed array is: tm_sec : '24' , tm_min : '3' , tm_hour : '19' , tm_year : '105' , tm_mday : '3' , tm_wday : '0' , tm_yday : '93' , tm_mon : '3' , tm_isdst : '0' , +IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 +Formatted localtime_array is : Apr 3, 2005, 7:03:24 PM +Parsed array is: tm_sec : '24' , tm_min : '3' , tm_hour : '19' , tm_year : '105' , tm_mday : '3' , tm_wday : '0' , tm_yday : '93' , tm_mon : '3' , tm_isdst : '0' , +------------ + +Input localtime is : tm_sec : '21' , tm_min : '5' , tm_hour : '7' , tm_mday : '13' , tm_mon : '7' , tm_year : '205' , +------------ + +IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 +Formatted localtime_array is : Thursday, August 13, 2105 at 7:05:21 AM GMT+05:00 +Parsed array is: tm_sec : '21' , tm_min : '5' , tm_hour : '7' , tm_year : '205' , tm_mday : '13' , tm_wday : '4' , tm_yday : '225' , tm_mon : '7' , tm_isdst : '0' , +IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 +Formatted localtime_array is : August 13, 2105 at 7:05:21 AM GMT+5 +Parsed array is: tm_sec : '21' , tm_min : '5' , tm_hour : '7' , tm_year : '205' , tm_mday : '13' , tm_wday : '4' , tm_yday : '225' , tm_mon : '7' , tm_isdst : '0' , +IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 +Formatted localtime_array is : Aug 13, 2105, 7:05:21 AM +Parsed array is: tm_sec : '21' , tm_min : '5' , tm_hour : '7' , tm_year : '205' , tm_mday : '13' , tm_wday : '4' , tm_yday : '225' , tm_mon : '7' , tm_isdst : '0' , +------------ + +Input localtime is : tm_sec : '11' , tm_min : '13' , tm_hour : '0' , tm_mday : '17' , tm_mon : '11' , tm_year : '-5' , +------------ + +IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 +Formatted localtime_array is : Tuesday, December 17, 1895 at 12:13:11 AM GMT+05:00 +Parsed array is: tm_sec : '11' , tm_min : '13' , tm_hour : '0' , tm_year : '-5' , tm_mday : '17' , tm_wday : '2' , tm_yday : '351' , tm_mon : '11' , tm_isdst : '0' , +IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 +Formatted localtime_array is : December 17, 1895 at 12:13:11 AM GMT+5 +Parsed array is: tm_sec : '11' , tm_min : '13' , tm_hour : '0' , tm_year : '-5' , tm_mday : '17' , tm_wday : '2' , tm_yday : '351' , tm_mon : '11' , tm_isdst : '0' , +IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 +Formatted localtime_array is : Dec 17, 1895, 12:13:11 AM +Parsed array is: tm_sec : '11' , tm_min : '13' , tm_hour : '0' , tm_year : '-5' , tm_mday : '17' , tm_wday : '2' , tm_yday : '351' , tm_mon : '11' , tm_isdst : '0' , diff --git a/ext/intl/tests/dateformat_format_variant2.phpt b/ext/intl/tests/dateformat_format_variant2.phpt new file mode 100644 index 0000000000000..7c5bcfcfd43f5 --- /dev/null +++ b/ext/intl/tests/dateformat_format_variant2.phpt @@ -0,0 +1,423 @@ +--TEST-- +datefmt_format_code() +--SKIPIF-- + += 51.2'); ?> +--FILE-- + 24 , + 'tm_min' => 3, + 'tm_hour' => 19, + 'tm_mday' => 3, + 'tm_mon' => 3, + 'tm_year' => 105, + ); + $localtime_arr2 = array ( + 'tm_sec' => 21, + 'tm_min' => 5, + 'tm_hour' => 7, + 'tm_mday' => 13, + 'tm_mon' => 4, + 'tm_year' => 205, + ); + $localtime_arr3 = array ( + 'tm_sec' => 11, + 'tm_min' => 13, + 'tm_hour' => 0, + 'tm_mday' => 17, + 'tm_mon' => 11, + 'tm_year' => -5 + ); + + $localtime_arr = array ( + $localtime_arr1, + $localtime_arr2, + $localtime_arr3 + ); + + $d1 = new DateTime("2010-01-01 01:02:03", new DateTimeZone("UTC")); + $d2 = new DateTime("2000-12-31 03:04:05", new DateTimeZone("UTC")); + $d2->setTimezone(new DateTimeZone("PDT")); + $dates = array( + $d1, + $d2, + new StdClass(), + ); + + //Test format with input as a timestamp : integer + foreach( $time_arr as $timestamp_entry){ + $res_str .= "\n------------\n"; + $res_str .= "\nInput timestamp is : $timestamp_entry"; + $res_str .= "\n------------\n"; + foreach( $locale_arr as $locale_entry ){ + foreach( $datetype_arr as $datetype_entry ) + { + $res_str .= "\nIntlDateFormatter locale= $locale_entry ,datetype = $datetype_entry ,timetype =$datetype_entry "; + $fmt = ut_datefmt_create( $locale_entry , $datetype_entry ,$datetype_entry, $timezone, IntlDateFormatter::GREGORIAN); + $formatted = ut_datefmt_format( $fmt , $timestamp_entry); + $res_str .= "\nFormatted timestamp is : $formatted"; + } + } + } + + //Test format with input as a localtime :array + foreach( $localtime_arr as $localtime_entry){ + $res_str .= "\n------------\n"; + $res_str .= "\nInput localtime is : "; + foreach( $localtime_entry as $key => $value){ + $res_str .= "$key : '$value' , "; + } + + $res_str .= "\n------------\n"; + foreach( $locale_arr as $locale_entry ){ + foreach( $datetype_arr as $datetype_entry ) + { + $res_str .= "\nIntlDateFormatter locale= $locale_entry ,datetype = $datetype_entry ,timetype =$datetype_entry "; + $fmt = ut_datefmt_create( $locale_entry , $datetype_entry ,$datetype_entry, $timezone, IntlDateFormatter::GREGORIAN ); + $formatted1 = ut_datefmt_format( $fmt , $localtime_entry); + if( intl_get_error_code() == U_ZERO_ERROR){ + $res_str .= "\nFormatted localtime_array is : $formatted1"; + }else{ + $res_str .= "\nError while formatting as: '".intl_get_error_message()."'"; + } + } + } + } + + foreach($dates as $date_entry) { + foreach( $locale_arr as $locale_entry ){ + foreach( $datetype_arr as $datetype_entry ) { + $res_str .= "\n------------"; + $res_str .= "\nDate is: ".var_export($date_entry, true); + $res_str .= "\n------------"; + + $fmt = ut_datefmt_create( $locale_entry , $datetype_entry ,$datetype_entry, $timezone, IntlDateFormatter::GREGORIAN ); + $formatted1 = ut_datefmt_format( $fmt , $date_entry); + if( intl_get_error_code() == U_ZERO_ERROR){ + $res_str .= "\nFormatted DateTime is : $formatted1"; + }else{ + $res_str .= "\nError while formatting as: '".intl_get_error_message()."'"; + } + } + } + } + + return $res_str; + +} + +include_once( 'ut_common.inc' ); + +// Run the test +ut_run(); +?> +--EXPECT-- +------------ + +Input timestamp is : 0 +------------ + +IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 +Formatted timestamp is : Wednesday, December 31, 1969 at 2:00:00 PM GMT-10:00 +IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 +Formatted timestamp is : December 31, 1969 at 2:00:00 PM GMT-10 +IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 +Formatted timestamp is : Dec 31, 1969, 2:00:00 PM +IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 +Formatted timestamp is : 12/31/69, 2:00 PM +IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 +Formatted timestamp is : 19691231 02:00 PM +------------ + +Input timestamp is : -1200000 +------------ + +IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 +Formatted timestamp is : Wednesday, December 17, 1969 at 4:40:00 PM GMT-10:00 +IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 +Formatted timestamp is : December 17, 1969 at 4:40:00 PM GMT-10 +IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 +Formatted timestamp is : Dec 17, 1969, 4:40:00 PM +IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 +Formatted timestamp is : 12/17/69, 4:40 PM +IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 +Formatted timestamp is : 19691217 04:40 PM +------------ + +Input timestamp is : 1200000 +------------ + +IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 +Formatted timestamp is : Wednesday, January 14, 1970 at 11:20:00 AM GMT-10:00 +IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 +Formatted timestamp is : January 14, 1970 at 11:20:00 AM GMT-10 +IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 +Formatted timestamp is : Jan 14, 1970, 11:20:00 AM +IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 +Formatted timestamp is : 1/14/70, 11:20 AM +IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 +Formatted timestamp is : 19700114 11:20 AM +------------ + +Input timestamp is : 2200000000 +------------ + +IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 +Formatted timestamp is : Sunday, September 18, 2039 at 1:06:40 PM GMT-10:00 +IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 +Formatted timestamp is : September 18, 2039 at 1:06:40 PM GMT-10 +IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 +Formatted timestamp is : Sep 18, 2039, 1:06:40 PM +IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 +Formatted timestamp is : 9/18/39, 1:06 PM +IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 +Formatted timestamp is : 20390918 01:06 PM +------------ + +Input timestamp is : -2200000000 +------------ + +IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 +Formatted timestamp is : Saturday, April 14, 1900 at 2:53:20 PM GMT-10:00 +IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 +Formatted timestamp is : April 14, 1900 at 2:53:20 PM GMT-10 +IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 +Formatted timestamp is : Apr 14, 1900, 2:53:20 PM +IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 +Formatted timestamp is : 4/14/00, 2:53 PM +IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 +Formatted timestamp is : 19000414 02:53 PM +------------ + +Input timestamp is : 90099999 +------------ + +IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 +Formatted timestamp is : Wednesday, November 8, 1972 at 9:46:39 AM GMT-10:00 +IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 +Formatted timestamp is : November 8, 1972 at 9:46:39 AM GMT-10 +IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 +Formatted timestamp is : Nov 8, 1972, 9:46:39 AM +IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 +Formatted timestamp is : 11/8/72, 9:46 AM +IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 +Formatted timestamp is : 19721108 09:46 AM +------------ + +Input timestamp is : 3600 +------------ + +IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 +Formatted timestamp is : Wednesday, December 31, 1969 at 3:00:00 PM GMT-10:00 +IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 +Formatted timestamp is : December 31, 1969 at 3:00:00 PM GMT-10 +IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 +Formatted timestamp is : Dec 31, 1969, 3:00:00 PM +IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 +Formatted timestamp is : 12/31/69, 3:00 PM +IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 +Formatted timestamp is : 19691231 03:00 PM +------------ + +Input timestamp is : -3600 +------------ + +IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 +Formatted timestamp is : Wednesday, December 31, 1969 at 1:00:00 PM GMT-10:00 +IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 +Formatted timestamp is : December 31, 1969 at 1:00:00 PM GMT-10 +IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 +Formatted timestamp is : Dec 31, 1969, 1:00:00 PM +IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 +Formatted timestamp is : 12/31/69, 1:00 PM +IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 +Formatted timestamp is : 19691231 01:00 PM +------------ + +Input localtime is : tm_sec : '24' , tm_min : '3' , tm_hour : '19' , tm_mday : '3' , tm_mon : '3' , tm_year : '105' , +------------ + +IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 +Formatted localtime_array is : Sunday, April 3, 2005 at 7:03:24 PM GMT-10:00 +IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 +Formatted localtime_array is : April 3, 2005 at 7:03:24 PM GMT-10 +IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 +Formatted localtime_array is : Apr 3, 2005, 7:03:24 PM +IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 +Formatted localtime_array is : 4/3/05, 7:03 PM +IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 +Formatted localtime_array is : 20050403 07:03 PM +------------ + +Input localtime is : tm_sec : '21' , tm_min : '5' , tm_hour : '7' , tm_mday : '13' , tm_mon : '4' , tm_year : '205' , +------------ + +IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 +Formatted localtime_array is : Wednesday, May 13, 2105 at 7:05:21 AM GMT-10:00 +IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 +Formatted localtime_array is : May 13, 2105 at 7:05:21 AM GMT-10 +IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 +Formatted localtime_array is : May 13, 2105, 7:05:21 AM +IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 +Formatted localtime_array is : 5/13/05, 7:05 AM +IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 +Formatted localtime_array is : 21050513 07:05 AM +------------ + +Input localtime is : tm_sec : '11' , tm_min : '13' , tm_hour : '0' , tm_mday : '17' , tm_mon : '11' , tm_year : '-5' , +------------ + +IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0 +Formatted localtime_array is : Tuesday, December 17, 1895 at 12:13:11 AM GMT-10:00 +IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1 +Formatted localtime_array is : December 17, 1895 at 12:13:11 AM GMT-10 +IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2 +Formatted localtime_array is : Dec 17, 1895, 12:13:11 AM +IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3 +Formatted localtime_array is : 12/17/95, 12:13 AM +IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1 +Formatted localtime_array is : 18951217 12:13 AM +------------ +Date is: DateTime::__set_state(array( + 'date' => '2010-01-01 01:02:03', + 'timezone_type' => 3, + 'timezone' => 'UTC', +)) +------------ +Formatted DateTime is : Thursday, December 31, 2009 at 3:02:03 PM GMT-10:00 +------------ +Date is: DateTime::__set_state(array( + 'date' => '2010-01-01 01:02:03', + 'timezone_type' => 3, + 'timezone' => 'UTC', +)) +------------ +Formatted DateTime is : December 31, 2009 at 3:02:03 PM GMT-10 +------------ +Date is: DateTime::__set_state(array( + 'date' => '2010-01-01 01:02:03', + 'timezone_type' => 3, + 'timezone' => 'UTC', +)) +------------ +Formatted DateTime is : Dec 31, 2009, 3:02:03 PM +------------ +Date is: DateTime::__set_state(array( + 'date' => '2010-01-01 01:02:03', + 'timezone_type' => 3, + 'timezone' => 'UTC', +)) +------------ +Formatted DateTime is : 12/31/09, 3:02 PM +------------ +Date is: DateTime::__set_state(array( + 'date' => '2010-01-01 01:02:03', + 'timezone_type' => 3, + 'timezone' => 'UTC', +)) +------------ +Formatted DateTime is : 20091231 03:02 PM +------------ +Date is: DateTime::__set_state(array( + 'date' => '2000-12-30 19:04:05', + 'timezone_type' => 3, + 'timezone' => 'America/Los_Angeles', +)) +------------ +Formatted DateTime is : Saturday, December 30, 2000 at 5:04:05 PM GMT-10:00 +------------ +Date is: DateTime::__set_state(array( + 'date' => '2000-12-30 19:04:05', + 'timezone_type' => 3, + 'timezone' => 'America/Los_Angeles', +)) +------------ +Formatted DateTime is : December 30, 2000 at 5:04:05 PM GMT-10 +------------ +Date is: DateTime::__set_state(array( + 'date' => '2000-12-30 19:04:05', + 'timezone_type' => 3, + 'timezone' => 'America/Los_Angeles', +)) +------------ +Formatted DateTime is : Dec 30, 2000, 5:04:05 PM +------------ +Date is: DateTime::__set_state(array( + 'date' => '2000-12-30 19:04:05', + 'timezone_type' => 3, + 'timezone' => 'America/Los_Angeles', +)) +------------ +Formatted DateTime is : 12/30/00, 5:04 PM +------------ +Date is: DateTime::__set_state(array( + 'date' => '2000-12-30 19:04:05', + 'timezone_type' => 3, + 'timezone' => 'America/Los_Angeles', +)) +------------ +Formatted DateTime is : 20001230 05:04 PM +------------ +Date is: stdClass::__set_state(array( +)) +------------ +Error while formatting as: 'datefmt_format: invalid object type for date/time (only IntlCalendar and DateTime permitted): U_ILLEGAL_ARGUMENT_ERROR' +------------ +Date is: stdClass::__set_state(array( +)) +------------ +Error while formatting as: 'datefmt_format: invalid object type for date/time (only IntlCalendar and DateTime permitted): U_ILLEGAL_ARGUMENT_ERROR' +------------ +Date is: stdClass::__set_state(array( +)) +------------ +Error while formatting as: 'datefmt_format: invalid object type for date/time (only IntlCalendar and DateTime permitted): U_ILLEGAL_ARGUMENT_ERROR' +------------ +Date is: stdClass::__set_state(array( +)) +------------ +Error while formatting as: 'datefmt_format: invalid object type for date/time (only IntlCalendar and DateTime permitted): U_ILLEGAL_ARGUMENT_ERROR' +------------ +Date is: stdClass::__set_state(array( +)) +------------ +Error while formatting as: 'datefmt_format: invalid object type for date/time (only IntlCalendar and DateTime permitted): U_ILLEGAL_ARGUMENT_ERROR' diff --git a/ext/intl/tests/dateformat_get_set_calendar.phpt b/ext/intl/tests/dateformat_get_set_calendar.phpt index dbb3e6cd2391c..f91fe5c775a21 100644 --- a/ext/intl/tests/dateformat_get_set_calendar.phpt +++ b/ext/intl/tests/dateformat_get_set_calendar.phpt @@ -2,8 +2,8 @@ IntlDateFormatter: setCalendar()/getCalendar()/getCalendarObject() --SKIPIF-- += 0) die('skip for ICU < 51.2'); ?> --FILE-- += 51.2'); ?> +--FILE-- +format($ts), "\n"; +var_dump($df->getCalendar(), +$df->getCalendarObject()->getType(), +$df->getCalendarObject()->getTimeZone()->getId()); +echo "\n"; +} + +$df = new IntlDateFormatter('fr@calendar=islamic', 0, 0, 'Europe/Minsk'); +d($df); + + +//changing the calendar with a cal type should not change tz +$df->setCalendar(IntlDateFormatter::TRADITIONAL); +d($df); + +//but changing with an actual calendar should +$cal = IntlCalendar::createInstance("UTC"); +$df->setCalendar($cal); +d($df); + +?> +==DONE== +--EXPECT-- +dimanche 1 janvier 2012 ap. J.-C. 03:00:00 UTC+03:00 +int(1) +string(9) "gregorian" +string(12) "Europe/Minsk" + +dimanche 8 safar 1433 AH 03:00:00 UTC+03:00 +int(0) +string(7) "islamic" +string(12) "Europe/Minsk" + +dimanche 1 janvier 2012 ap. J.-C. 00:00:00 UTC +bool(false) +string(9) "gregorian" +string(3) "UTC" + +==DONE== diff --git a/ext/intl/tests/dateformat_get_set_timezone.phpt b/ext/intl/tests/dateformat_get_set_timezone.phpt index 41aa35b9cf3c6..2a7ffa6c7393c 100644 --- a/ext/intl/tests/dateformat_get_set_timezone.phpt +++ b/ext/intl/tests/dateformat_get_set_timezone.phpt @@ -2,8 +2,8 @@ IntlDateFormatter: get/setTimeZone() --SKIPIF-- += 0) die('skip for ICU < 51.2'); ?> --FILE-- += 51.2'); ?> +--FILE-- +format($ts), "\n"; +var_dump( +$df->getTimeZoneID(), +$df->getTimeZone()->getID()); +echo "\n"; +} + +$df = new IntlDateFormatter('pt_PT', 0, 0, 'Europe/Minsk'); +d($df); + +$df->setTimeZone(NULL); +d($df); + +$df->setTimeZone('Europe/Madrid'); +d($df); + +$df->setTimeZone(IntlTimeZone::createTimeZone('Europe/Paris')); +d($df); + +$df->setTimeZone(new DateTimeZone('Europe/Amsterdam')); +d($df); + +?> +==DONE== +--EXPECTF-- +Domingo, 1 de Janeiro de 2012 às 03:00:00 GMT+03:00 +string(12) "Europe/Minsk" +string(12) "Europe/Minsk" + +Sábado, 31 de Dezembro de 2011 às 23:00:00 Hor%s %Sdos Açores +string(15) "Atlantic/Azores" +string(15) "Atlantic/Azores" + +Domingo, 1 de Janeiro de 2012 às 01:00:00 Hor%s %Sda Europa Central +string(13) "Europe/Madrid" +string(13) "Europe/Madrid" + +Domingo, 1 de Janeiro de 2012 às 01:00:00 Hor%s %Sda Europa Central +string(12) "Europe/Paris" +string(12) "Europe/Paris" + +Domingo, 1 de Janeiro de 2012 às 01:00:00 Hor%s %Sda Europa Central +string(16) "Europe/Amsterdam" +string(16) "Europe/Amsterdam" + +==DONE== diff --git a/ext/intl/tests/dateformat_set_timezone_id2.phpt b/ext/intl/tests/dateformat_set_timezone_id2.phpt index ce9b89d1fdbbf..a1ee440e71d99 100644 --- a/ext/intl/tests/dateformat_set_timezone_id2.phpt +++ b/ext/intl/tests/dateformat_set_timezone_id2.phpt @@ -5,6 +5,7 @@ date.timezone=Atlantic/Azores --SKIPIF-- += 0) die('skip for ICU < 51.2'); ?> --FILE-- = 4.8 +--INI-- +date.timezone=Atlantic/Azores +--SKIPIF-- + += 51.2'); ?> +--FILE-- + +--EXPECTF-- +Warning: IntlDateFormatter::setTimeZoneId(): datefmt_set_timezone: no such time zone: 'CN' in %sut_common.inc on line %d + +Warning: datefmt_set_timezone_id(): datefmt_set_timezone: no such time zone: 'CN' in %sut_common.inc on line %d + +After creation of the dateformatter : timezone_id= US/Pacific +----------- +Trying to set timezone_id= America/New_York +After call to set_timezone_id : timezone_id= America/New_York +Formatting timestamp=0 resulted in Wednesday, December 31, 1969 at 7:00:00 PM Eastern Standard Time +Formatting timestamp=3600 resulted in Wednesday, December 31, 1969 at 8:00:00 PM Eastern Standard Time +----------- +Trying to set timezone_id= America/Los_Angeles +After call to set_timezone_id : timezone_id= America/Los_Angeles +Formatting timestamp=0 resulted in Wednesday, December 31, 1969 at 4:00:00 PM Pacific Standard Time +Formatting timestamp=3600 resulted in Wednesday, December 31, 1969 at 5:00:00 PM Pacific Standard Time +----------- +Trying to set timezone_id= America/Chicago +After call to set_timezone_id : timezone_id= America/Chicago +Formatting timestamp=0 resulted in Wednesday, December 31, 1969 at 6:00:00 PM Central Standard Time +Formatting timestamp=3600 resulted in Wednesday, December 31, 1969 at 7:00:00 PM Central Standard Time +----------- +Trying to set timezone_id= CN +After call to set_timezone_id : timezone_id= America/Chicago +Formatting timestamp=0 resulted in Wednesday, December 31, 1969 at 6:00:00 PM Central Standard Time +Formatting timestamp=3600 resulted in Wednesday, December 31, 1969 at 7:00:00 PM Central Standard Time diff --git a/ext/intl/tests/dateformat_timezone_arg_variations.phpt b/ext/intl/tests/dateformat_timezone_arg_variations.phpt index ccfb5e19646a6..9fbb145c72e0b 100644 --- a/ext/intl/tests/dateformat_timezone_arg_variations.phpt +++ b/ext/intl/tests/dateformat_timezone_arg_variations.phpt @@ -2,8 +2,8 @@ IntlDateFormatter: several forms of the timezone arg --SKIPIF-- += 0) die('skip for ICU < 51.2'); ?> --FILE-- += 51.2'); ?> +--FILE-- +format($ts), "\n"; + +$df = new IntlDateFormatter('es_ES', 0, 0, 'Europe/Amsterdam'); +echo $df->format($ts), "\n"; + +$df = new IntlDateFormatter('es_ES', 0, 0, new DateTimeZone('Europe/Lisbon')); +echo $df->format($ts), "\n"; + +$df = new IntlDateFormatter('es_ES', 0, 0, IntlTimeZone::createTimeZone('America/New_York')); +echo $df->format($ts), "\n"; + +//time zone has priority +$df = new IntlDateFormatter('es_ES', 0, 0, 'Europe/Amsterdam', new IntlGregorianCalendar('Europe/Lisbon')); +echo $df->format($ts), "\n"; + +//calendar has priority +$df = new IntlDateFormatter('es_ES', 0, 0, NULL, new IntlGregorianCalendar('Europe/Lisbon')); +echo $df->format($ts), "\n"; + +$df = new IntlDateFormatter('es_ES', 0, 0, 'Europe/Amsterdam', 0); +echo $df->format($ts), "\n"; + +--EXPECTF-- +sábado%S, 31 de diciembre de 2011 23:00:00 Hora estándar de las Azores +domingo%S, 1 de enero de 2012 01:00:00 Hora estándar de Europa central +domingo%S, 1 de enero de 2012 00:00:00 Hora%S de Europa occidental +sábado%S, 31 de diciembre de 2011 19:00:00 Hora estándar oriental +domingo%S, 1 de enero de 2012 01:00:00 Hora estándar de Europa central +domingo%S, 1 de enero de 2012 00:00:00 Hora%S de Europa occidental +domingo%S, 1 de enero de 2012 01:00:00 Hora estándar de Europa central diff --git a/ext/intl/tests/formatter_get_locale.phpt b/ext/intl/tests/formatter_get_locale.phpt index 3d4fb2ae4e036..7474eabbbacdd 100644 --- a/ext/intl/tests/formatter_get_locale.phpt +++ b/ext/intl/tests/formatter_get_locale.phpt @@ -2,6 +2,7 @@ numfmt_get_locale() --SKIPIF-- += 0) die('skip for ICU < 51.2'); ?> --FILE-- += 51.2'); ?> +--FILE-- + 'actual', + Locale::VALID_LOCALE => 'valid', + ); + + $res_str = ''; + + foreach( $locales as $locale ) + { + $fmt = ut_nfmt_create( $locale, NumberFormatter::DECIMAL ); + $res_str .= "$locale: "; + foreach( $loc_types as $loc_type => $loc_type_name ) + $res_str .= sprintf( " %s=%s", + $loc_type_name, + dump( ut_nfmt_get_locale( $fmt, $loc_type ) ) ); + $res_str .= "\n"; + } + + return $res_str; +} + +include_once( 'ut_common.inc' ); + +// Run the test +ut_run(); +?> +--EXPECT-- +en_UK: actual='en' valid='en' +en_US@California: actual='en' valid='en' +fr_CA: actual='fr' valid='fr_CA' diff --git a/ext/intl/tests/locale_filter_matches2.phpt b/ext/intl/tests/locale_filter_matches2.phpt index 37f9e5a37737a..12d247dc6be7e 100644 --- a/ext/intl/tests/locale_filter_matches2.phpt +++ b/ext/intl/tests/locale_filter_matches2.phpt @@ -1,8 +1,9 @@ --TEST-- -locale_filter_matches.phpt() icu >= 4.8 +locale_filter_matches.phpt() icu >= 4.8 && icu < 51.2 --SKIPIF-- += 0) die('skip for ICU < 51.2'); ?> --FILE-- = 51.2 +--SKIPIF-- + += 51.2'); ?> +--FILE-- + +--EXPECT-- +-------------- +loc_range:de-de matches lang_tag de-DEVA ? NO +loc_range:de_DE canonically matches lang_tag de_Deva ? NO +-------------- +loc_range:de-de matches lang_tag de-DE-1996 ? YES +loc_range:de_DE canonically matches lang_tag de_DE_1996 ? YES +-------------- +loc_range:de-de matches lang_tag de-DE ? YES +loc_range:de_DE canonically matches lang_tag de_DE ? YES +-------------- +loc_range:de-de matches lang_tag zh_Hans ? NO +loc_range:de_DE canonically matches lang_tag zh_Hans ? NO +-------------- +loc_range:de-de matches lang_tag de-CH-1996 ? NO +loc_range:de_DE canonically matches lang_tag de_CH_1996 ? NO +-------------- +loc_range:de-de matches lang_tag sl_IT ? NO +loc_range:de_DE canonically matches lang_tag sl_IT ? NO +-------------- +loc_range:de-de matches lang_tag sl_IT_nedis-a-kirti-x-xyz ? NO +loc_range:de_DE canonically matches lang_tag sl_IT_NEDIS_A_KIRTI_X_XYZ ? NO +-------------- +loc_range:de-de matches lang_tag sl_IT_rozaj ? NO +loc_range:de_DE canonically matches lang_tag sl_IT_ROZAJ ? NO +-------------- +loc_range:de-de matches lang_tag sl_IT_NEDIS_ROJAZ_1901 ? NO +loc_range:de_DE canonically matches lang_tag sl_IT_NEDIS_ROJAZ_1901 ? NO +-------------- +loc_range:de-de matches lang_tag i-enochian ? NO +loc_range:de_DE canonically matches lang_tag @x=i-enochian ? NO +-------------- +loc_range:de-de matches lang_tag sgn-CH-de ? NO +loc_range:de_DE canonically matches lang_tag sgn_CH_DE ? NO +-------------- +loc_range:de-de matches lang_tag art-lojban ? NO +loc_range:de_DE canonically matches lang_tag art__LOJBAN ? NO +-------------- +loc_range:de-de matches lang_tag i-lux ? NO +loc_range:de_DE canonically matches lang_tag lb ? NO +-------------- +loc_range:de-de matches lang_tag art-lojban ? NO +loc_range:de_DE canonically matches lang_tag art__LOJBAN ? NO +-------------- +loc_range:de-de matches lang_tag jbo ? NO +loc_range:de_DE canonically matches lang_tag jbo ? NO +-------------- +loc_range:de-de matches lang_tag en_sl_IT ? NO +loc_range:de_DE canonically matches lang_tag en_SL_IT ? NO +-------------- +loc_range:sl_IT matches lang_tag de-DEVA ? NO +loc_range:sl_IT canonically matches lang_tag de_Deva ? NO +-------------- +loc_range:sl_IT matches lang_tag de-DE-1996 ? NO +loc_range:sl_IT canonically matches lang_tag de_DE_1996 ? NO +-------------- +loc_range:sl_IT matches lang_tag de-DE ? NO +loc_range:sl_IT canonically matches lang_tag de_DE ? NO +-------------- +loc_range:sl_IT matches lang_tag zh_Hans ? NO +loc_range:sl_IT canonically matches lang_tag zh_Hans ? NO +-------------- +loc_range:sl_IT matches lang_tag de-CH-1996 ? NO +loc_range:sl_IT canonically matches lang_tag de_CH_1996 ? NO +-------------- +loc_range:sl_IT matches lang_tag sl_IT ? YES +loc_range:sl_IT canonically matches lang_tag sl_IT ? YES +-------------- +loc_range:sl_IT matches lang_tag sl_IT_nedis-a-kirti-x-xyz ? YES +loc_range:sl_IT canonically matches lang_tag sl_IT_NEDIS_A_KIRTI_X_XYZ ? YES +-------------- +loc_range:sl_IT matches lang_tag sl_IT_rozaj ? YES +loc_range:sl_IT canonically matches lang_tag sl_IT_ROZAJ ? YES +-------------- +loc_range:sl_IT matches lang_tag sl_IT_NEDIS_ROJAZ_1901 ? YES +loc_range:sl_IT canonically matches lang_tag sl_IT_NEDIS_ROJAZ_1901 ? YES +-------------- +loc_range:sl_IT matches lang_tag i-enochian ? NO +loc_range:sl_IT canonically matches lang_tag @x=i-enochian ? NO +-------------- +loc_range:sl_IT matches lang_tag sgn-CH-de ? NO +loc_range:sl_IT canonically matches lang_tag sgn_CH_DE ? NO +-------------- +loc_range:sl_IT matches lang_tag art-lojban ? NO +loc_range:sl_IT canonically matches lang_tag art__LOJBAN ? NO +-------------- +loc_range:sl_IT matches lang_tag i-lux ? NO +loc_range:sl_IT canonically matches lang_tag lb ? NO +-------------- +loc_range:sl_IT matches lang_tag art-lojban ? NO +loc_range:sl_IT canonically matches lang_tag art__LOJBAN ? NO +-------------- +loc_range:sl_IT matches lang_tag jbo ? NO +loc_range:sl_IT canonically matches lang_tag jbo ? NO +-------------- +loc_range:sl_IT matches lang_tag en_sl_IT ? NO +loc_range:sl_IT canonically matches lang_tag en_SL_IT ? NO +-------------- +loc_range:sl_IT_Nedis matches lang_tag de-DEVA ? NO +loc_range:sl_IT_NEDIS canonically matches lang_tag de_Deva ? NO +-------------- +loc_range:sl_IT_Nedis matches lang_tag de-DE-1996 ? NO +loc_range:sl_IT_NEDIS canonically matches lang_tag de_DE_1996 ? NO +-------------- +loc_range:sl_IT_Nedis matches lang_tag de-DE ? NO +loc_range:sl_IT_NEDIS canonically matches lang_tag de_DE ? NO +-------------- +loc_range:sl_IT_Nedis matches lang_tag zh_Hans ? NO +loc_range:sl_IT_NEDIS canonically matches lang_tag zh_Hans ? NO +-------------- +loc_range:sl_IT_Nedis matches lang_tag de-CH-1996 ? NO +loc_range:sl_IT_NEDIS canonically matches lang_tag de_CH_1996 ? NO +-------------- +loc_range:sl_IT_Nedis matches lang_tag sl_IT ? NO +loc_range:sl_IT_NEDIS canonically matches lang_tag sl_IT ? NO +-------------- +loc_range:sl_IT_Nedis matches lang_tag sl_IT_nedis-a-kirti-x-xyz ? YES +loc_range:sl_IT_NEDIS canonically matches lang_tag sl_IT_NEDIS_A_KIRTI_X_XYZ ? YES +-------------- +loc_range:sl_IT_Nedis matches lang_tag sl_IT_rozaj ? NO +loc_range:sl_IT_NEDIS canonically matches lang_tag sl_IT_ROZAJ ? NO +-------------- +loc_range:sl_IT_Nedis matches lang_tag sl_IT_NEDIS_ROJAZ_1901 ? YES +loc_range:sl_IT_NEDIS canonically matches lang_tag sl_IT_NEDIS_ROJAZ_1901 ? YES +-------------- +loc_range:sl_IT_Nedis matches lang_tag i-enochian ? NO +loc_range:sl_IT_NEDIS canonically matches lang_tag @x=i-enochian ? NO +-------------- +loc_range:sl_IT_Nedis matches lang_tag sgn-CH-de ? NO +loc_range:sl_IT_NEDIS canonically matches lang_tag sgn_CH_DE ? NO +-------------- +loc_range:sl_IT_Nedis matches lang_tag art-lojban ? NO +loc_range:sl_IT_NEDIS canonically matches lang_tag art__LOJBAN ? NO +-------------- +loc_range:sl_IT_Nedis matches lang_tag i-lux ? NO +loc_range:sl_IT_NEDIS canonically matches lang_tag lb ? NO +-------------- +loc_range:sl_IT_Nedis matches lang_tag art-lojban ? NO +loc_range:sl_IT_NEDIS canonically matches lang_tag art__LOJBAN ? NO +-------------- +loc_range:sl_IT_Nedis matches lang_tag jbo ? NO +loc_range:sl_IT_NEDIS canonically matches lang_tag jbo ? NO +-------------- +loc_range:sl_IT_Nedis matches lang_tag en_sl_IT ? NO +loc_range:sl_IT_NEDIS canonically matches lang_tag en_SL_IT ? NO +-------------- +loc_range:jbo matches lang_tag de-DEVA ? NO +loc_range:jbo canonically matches lang_tag de_Deva ? NO +-------------- +loc_range:jbo matches lang_tag de-DE-1996 ? NO +loc_range:jbo canonically matches lang_tag de_DE_1996 ? NO +-------------- +loc_range:jbo matches lang_tag de-DE ? NO +loc_range:jbo canonically matches lang_tag de_DE ? NO +-------------- +loc_range:jbo matches lang_tag zh_Hans ? NO +loc_range:jbo canonically matches lang_tag zh_Hans ? NO +-------------- +loc_range:jbo matches lang_tag de-CH-1996 ? NO +loc_range:jbo canonically matches lang_tag de_CH_1996 ? NO +-------------- +loc_range:jbo matches lang_tag sl_IT ? NO +loc_range:jbo canonically matches lang_tag sl_IT ? NO +-------------- +loc_range:jbo matches lang_tag sl_IT_nedis-a-kirti-x-xyz ? NO +loc_range:jbo canonically matches lang_tag sl_IT_NEDIS_A_KIRTI_X_XYZ ? NO +-------------- +loc_range:jbo matches lang_tag sl_IT_rozaj ? NO +loc_range:jbo canonically matches lang_tag sl_IT_ROZAJ ? NO +-------------- +loc_range:jbo matches lang_tag sl_IT_NEDIS_ROJAZ_1901 ? NO +loc_range:jbo canonically matches lang_tag sl_IT_NEDIS_ROJAZ_1901 ? NO +-------------- +loc_range:jbo matches lang_tag i-enochian ? NO +loc_range:jbo canonically matches lang_tag @x=i-enochian ? NO +-------------- +loc_range:jbo matches lang_tag sgn-CH-de ? NO +loc_range:jbo canonically matches lang_tag sgn_CH_DE ? NO +-------------- +loc_range:jbo matches lang_tag art-lojban ? NO +loc_range:jbo canonically matches lang_tag art__LOJBAN ? NO +-------------- +loc_range:jbo matches lang_tag i-lux ? NO +loc_range:jbo canonically matches lang_tag lb ? NO +-------------- +loc_range:jbo matches lang_tag art-lojban ? NO +loc_range:jbo canonically matches lang_tag art__LOJBAN ? NO +-------------- +loc_range:jbo matches lang_tag jbo ? YES +loc_range:jbo canonically matches lang_tag jbo ? YES +-------------- +loc_range:jbo matches lang_tag en_sl_IT ? NO +loc_range:jbo canonically matches lang_tag en_SL_IT ? NO +-------------- +loc_range:art-lojban matches lang_tag de-DEVA ? NO +loc_range:art__LOJBAN canonically matches lang_tag de_Deva ? NO +-------------- +loc_range:art-lojban matches lang_tag de-DE-1996 ? NO +loc_range:art__LOJBAN canonically matches lang_tag de_DE_1996 ? NO +-------------- +loc_range:art-lojban matches lang_tag de-DE ? NO +loc_range:art__LOJBAN canonically matches lang_tag de_DE ? NO +-------------- +loc_range:art-lojban matches lang_tag zh_Hans ? NO +loc_range:art__LOJBAN canonically matches lang_tag zh_Hans ? NO +-------------- +loc_range:art-lojban matches lang_tag de-CH-1996 ? NO +loc_range:art__LOJBAN canonically matches lang_tag de_CH_1996 ? NO +-------------- +loc_range:art-lojban matches lang_tag sl_IT ? NO +loc_range:art__LOJBAN canonically matches lang_tag sl_IT ? NO +-------------- +loc_range:art-lojban matches lang_tag sl_IT_nedis-a-kirti-x-xyz ? NO +loc_range:art__LOJBAN canonically matches lang_tag sl_IT_NEDIS_A_KIRTI_X_XYZ ? NO +-------------- +loc_range:art-lojban matches lang_tag sl_IT_rozaj ? NO +loc_range:art__LOJBAN canonically matches lang_tag sl_IT_ROZAJ ? NO +-------------- +loc_range:art-lojban matches lang_tag sl_IT_NEDIS_ROJAZ_1901 ? NO +loc_range:art__LOJBAN canonically matches lang_tag sl_IT_NEDIS_ROJAZ_1901 ? NO +-------------- +loc_range:art-lojban matches lang_tag i-enochian ? NO +loc_range:art__LOJBAN canonically matches lang_tag @x=i-enochian ? NO +-------------- +loc_range:art-lojban matches lang_tag sgn-CH-de ? NO +loc_range:art__LOJBAN canonically matches lang_tag sgn_CH_DE ? NO +-------------- +loc_range:art-lojban matches lang_tag art-lojban ? YES +loc_range:art__LOJBAN canonically matches lang_tag art__LOJBAN ? YES +-------------- +loc_range:art-lojban matches lang_tag i-lux ? NO +loc_range:art__LOJBAN canonically matches lang_tag lb ? NO +-------------- +loc_range:art-lojban matches lang_tag art-lojban ? YES +loc_range:art__LOJBAN canonically matches lang_tag art__LOJBAN ? YES +-------------- +loc_range:art-lojban matches lang_tag jbo ? NO +loc_range:art__LOJBAN canonically matches lang_tag jbo ? NO +-------------- +loc_range:art-lojban matches lang_tag en_sl_IT ? NO +loc_range:art__LOJBAN canonically matches lang_tag en_SL_IT ? NO +-------------- +loc_range:sl_IT matches lang_tag de-DEVA ? NO +loc_range:sl_IT canonically matches lang_tag de_Deva ? NO +-------------- +loc_range:sl_IT matches lang_tag de-DE-1996 ? NO +loc_range:sl_IT canonically matches lang_tag de_DE_1996 ? NO +-------------- +loc_range:sl_IT matches lang_tag de-DE ? NO +loc_range:sl_IT canonically matches lang_tag de_DE ? NO +-------------- +loc_range:sl_IT matches lang_tag zh_Hans ? NO +loc_range:sl_IT canonically matches lang_tag zh_Hans ? NO +-------------- +loc_range:sl_IT matches lang_tag de-CH-1996 ? NO +loc_range:sl_IT canonically matches lang_tag de_CH_1996 ? NO +-------------- +loc_range:sl_IT matches lang_tag sl_IT ? YES +loc_range:sl_IT canonically matches lang_tag sl_IT ? YES +-------------- +loc_range:sl_IT matches lang_tag sl_IT_nedis-a-kirti-x-xyz ? YES +loc_range:sl_IT canonically matches lang_tag sl_IT_NEDIS_A_KIRTI_X_XYZ ? YES +-------------- +loc_range:sl_IT matches lang_tag sl_IT_rozaj ? YES +loc_range:sl_IT canonically matches lang_tag sl_IT_ROZAJ ? YES +-------------- +loc_range:sl_IT matches lang_tag sl_IT_NEDIS_ROJAZ_1901 ? YES +loc_range:sl_IT canonically matches lang_tag sl_IT_NEDIS_ROJAZ_1901 ? YES +-------------- +loc_range:sl_IT matches lang_tag i-enochian ? NO +loc_range:sl_IT canonically matches lang_tag @x=i-enochian ? NO +-------------- +loc_range:sl_IT matches lang_tag sgn-CH-de ? NO +loc_range:sl_IT canonically matches lang_tag sgn_CH_DE ? NO +-------------- +loc_range:sl_IT matches lang_tag art-lojban ? NO +loc_range:sl_IT canonically matches lang_tag art__LOJBAN ? NO +-------------- +loc_range:sl_IT matches lang_tag i-lux ? NO +loc_range:sl_IT canonically matches lang_tag lb ? NO +-------------- +loc_range:sl_IT matches lang_tag art-lojban ? NO +loc_range:sl_IT canonically matches lang_tag art__LOJBAN ? NO +-------------- +loc_range:sl_IT matches lang_tag jbo ? NO +loc_range:sl_IT canonically matches lang_tag jbo ? NO +-------------- +loc_range:sl_IT matches lang_tag en_sl_IT ? NO +loc_range:sl_IT canonically matches lang_tag en_SL_IT ? NO diff --git a/ext/intl/tests/locale_get_display_name2.phpt b/ext/intl/tests/locale_get_display_name2.phpt index 40ccc0c2c50fb..bd8cb50cd53c8 100644 --- a/ext/intl/tests/locale_get_display_name2.phpt +++ b/ext/intl/tests/locale_get_display_name2.phpt @@ -1,8 +1,9 @@ --TEST-- -locale_get_display_name() icu >= 4.8 +locale_get_display_name() icu >= 4.8 && icu < 51.2 --SKIPIF-- += 0) die('skip for ICU < 51.2'); ?> --FILE-- = 51.2 +--SKIPIF-- + += 51.2'); ?> +--FILE-- + +--EXPECTREGEX-- +locale='sl_IT_nedis_KIRTI' +disp_locale=en : display_name=Slovenian #Italy, NEDIS_KIRTI# +disp_locale=fr : display_name=slovène #Italie, NEDIS_KIRTI# +disp_locale=de : display_name=Slowenisch #Italien, NEDIS_KIRTI# +----------------- +locale='sl_IT_nedis-a-kirti-x-xyz' +disp_locale=en : display_name=Slovenian #Italy, NEDIS_A_KIRTI_X_XYZ# +disp_locale=fr : display_name=slovène #Italie, NEDIS_A_KIRTI_X_XYZ# +disp_locale=de : display_name=Slowenisch #Italien, NEDIS_A_KIRTI_X_XYZ# +----------------- +locale='sl_IT_rozaj' +disp_locale=en : display_name=Slovenian #Italy, Resian# +disp_locale=fr : display_name=slovène #Italie, dialecte de Resia# +disp_locale=de : display_name=Slowenisch #Italien, (ROZAJ|Resianisch)# +----------------- +locale='sl_IT_NEDIS_ROJAZ_1901' +disp_locale=en : display_name=Slovenian #Italy, NEDIS_ROJAZ_1901# +disp_locale=fr : display_name=slovène #Italie, NEDIS_ROJAZ_1901# +disp_locale=de : display_name=Slowenisch #Italien, NEDIS_ROJAZ_1901# +----------------- +locale='i-enochian' +disp_locale=en : display_name=i-enochian #Private-Use=i-enochian# +disp_locale=fr : display_name=i-enochian #Usage privé=i-enochian# +disp_locale=de : display_name=i-enochian #Privatnutzung=i-enochian# +----------------- +locale='zh-hakka' +disp_locale=en : display_name=Chinese( #HAKKA#)? +disp_locale=fr : display_name=chinois( #HAKKA#)? +disp_locale=de : display_name=Chinesisch( #HAKKA#)? +----------------- +locale='zh-wuu' +disp_locale=en : display_name=Chinese #WUU# +disp_locale=fr : display_name=chinois #WUU# +disp_locale=de : display_name=Chinesisch #WUU# +----------------- +locale='i-tay' +disp_locale=en : display_name=i-tay +disp_locale=fr : display_name=i-tay +disp_locale=de : display_name=i-tay +----------------- +locale='sgn-BE-nl' +disp_locale=en : display_name=Sign Languages? #Belgium, NL# +disp_locale=fr : display_name=langues? des signes #Belgique, NL# +disp_locale=de : display_name=Gebärdensprache #Belgien, NL# +----------------- +locale='sgn-CH-de' +disp_locale=en : display_name=Sign Languages? #Switzerland, DE# +disp_locale=fr : display_name=langues? des signes #Suisse, DE# +disp_locale=de : display_name=Gebärdensprache #Schweiz, DE# +----------------- +locale='sl_IT_rozaj@currency=EUR' +disp_locale=en : display_name=Slovenian #Italy, Resian, [Cc]urrency=Euro# +disp_locale=fr : display_name=slovène #Italie, dialecte de Resia, [Dd]evise=euro# +disp_locale=de : display_name=Slowenisch #Italien, (ROZAJ|Resianisch), Währung=Euro# +----------------- +locale='uk-ua_CALIFORNIA@currency=;currency=GRN' +disp_locale=en : display_name=Ukrainian #Ukraine, CALIFORNIA, [Cc]urrency# +disp_locale=fr : display_name=ukrainien #Ukraine, CALIFORNIA, [Dd]evise# +disp_locale=de : display_name=Ukrainisch #Ukraine, CALIFORNIA, Währung# +----------------- +locale='root' +disp_locale=en : display_name=Root +disp_locale=fr : display_name=racine +disp_locale=de : display_name=[Rr]oot +----------------- +locale='uk@currency=EURO' +disp_locale=en : display_name=Ukrainian #[Cc]urrency=EURO# +disp_locale=fr : display_name=ukrainien #[Dd]evise=EURO# +disp_locale=de : display_name=Ukrainisch #Währung=EURO# +----------------- +locale='Hindi' +disp_locale=en : display_name=hindi +disp_locale=fr : display_name=hindi +disp_locale=de : display_name=hindi +----------------- +locale='de' +disp_locale=en : display_name=German +disp_locale=fr : display_name=allemand +disp_locale=de : display_name=Deutsch +----------------- +locale='fr' +disp_locale=en : display_name=French +disp_locale=fr : display_name=français +disp_locale=de : display_name=Französisch +----------------- +locale='ja' +disp_locale=en : display_name=Japanese +disp_locale=fr : display_name=japonais +disp_locale=de : display_name=Japanisch +----------------- +locale='i-enochian' +disp_locale=en : display_name=i-enochian #Private-Use=i-enochian# +disp_locale=fr : display_name=i-enochian #Usage privé=i-enochian# +disp_locale=de : display_name=i-enochian #Privatnutzung=i-enochian# +----------------- +locale='zh-Hant' +disp_locale=en : display_name=Chinese #Traditional# +disp_locale=fr : display_name=chinois #traditionnel# +disp_locale=de : display_name=Chinesisch #Traditionell# +----------------- +locale='zh-Hans' +disp_locale=en : display_name=Chinese #Simplified# +disp_locale=fr : display_name=chinois #simplifié# +disp_locale=de : display_name=Chinesisch #Vereinfacht# +----------------- +locale='sr-Cyrl' +disp_locale=en : display_name=Serbian #Cyrillic# +disp_locale=fr : display_name=serbe #cyrillique# +disp_locale=de : display_name=Serbisch #Kyrillisch# +----------------- +locale='sr-Latn' +disp_locale=en : display_name=Serbian #Latin# +disp_locale=fr : display_name=serbe #latin# +disp_locale=de : display_name=Serbisch #Lateinisch# +----------------- +locale='zh-Hans-CN' +disp_locale=en : display_name=Chinese #Simplified, China# +disp_locale=fr : display_name=chinois #simplifié, Chine# +disp_locale=de : display_name=Chinesisch #Vereinfacht, China# +----------------- +locale='sr-Latn-CS' +disp_locale=en : display_name=Serbian #Latin, Serbia# +disp_locale=fr : display_name=serbe #latin, Serbie# +disp_locale=de : display_name=Serbisch #Lateinisch, Serbien# +----------------- +locale='sl-rozaj' +disp_locale=en : display_name=Slovenian #Resian# +disp_locale=fr : display_name=slovène #dialecte de Resia# +disp_locale=de : display_name=Slowenisch( #(ROZAJ|Resianisch)#)? +----------------- +locale='sl-nedis' +disp_locale=en : display_name=Slovenian #Natisone dialect# +disp_locale=fr : display_name=slovène #dialecte de Natisone# +disp_locale=de : display_name=Slowenisch #Natisone-Dialekt# +----------------- +locale='de-CH-1901' +disp_locale=en : display_name=German #Switzerland, Traditional German orthography# +disp_locale=fr : display_name=allemand #Suisse, orthographe allemande traditionnelle# +disp_locale=de : display_name=Deutsch #Schweiz, (1901|[aA]lte deutsche Rechtschreibung)# +----------------- +locale='sl-IT-nedis' +disp_locale=en : display_name=Slovenian #Italy, Natisone dialect# +disp_locale=fr : display_name=slovène #Italie, dialecte de Natisone# +disp_locale=de : display_name=Slowenisch #Italien, (NEDIS|Natisone-Dialekt)# +----------------- +locale='sl-Latn-IT-nedis' +disp_locale=en : display_name=Slovenian #Latin, Italy, Natisone dialect# +disp_locale=fr : display_name=slovène #latin, Italie, dialecte de Natisone# +disp_locale=de : display_name=Slowenisch #Lateinisch, Italien, (NEDIS|Natisone-Dialekt)# +----------------- +locale='de-DE' +disp_locale=en : display_name=German #Germany# +disp_locale=fr : display_name=allemand #Allemagne# +disp_locale=de : display_name=Deutsch #Deutschland# +----------------- +locale='en-US' +disp_locale=en : display_name=English #United States# +disp_locale=fr : display_name=anglais #États-Unis# +disp_locale=de : display_name=Englisch #Vereinigte Staaten# +----------------- +locale='es-419' +disp_locale=en : display_name=Spanish #Latin America# +disp_locale=fr : display_name=espagnol #Amérique latine# +disp_locale=de : display_name=Spanisch #Lateinamerika# +----------------- +locale='de-CH-x-phonebk' +disp_locale=en : display_name=German #Switzerland, Private-Use=phonebk# +disp_locale=fr : display_name=allemand #Suisse, Usage privé=phonebk# +disp_locale=de : display_name=Deutsch #Schweiz, Privatnutzung=phonebk# +----------------- +locale='az-Arab-x-AZE-derbend' +disp_locale=en : display_name=Azerbaijani #Arabic, Private-Use=aze-derbend# +disp_locale=fr : display_name=azéri #arabe, Usage privé=aze-derbend# +disp_locale=de : display_name=Aserbaidschanisch #Arabisch, Privatnutzung=aze-derbend# +----------------- +locale='zh-min' +disp_locale=en : display_name=Chinese #MIN# +disp_locale=fr : display_name=chinois #MIN# +disp_locale=de : display_name=Chinesisch #MIN# +----------------- +locale='zh-min-nan-Hant-CN' +disp_locale=en : display_name=Chinese #MIN, NAN_HANT_CN# +disp_locale=fr : display_name=chinois #MIN, NAN_HANT_CN# +disp_locale=de : display_name=Chinesisch #MIN, NAN_HANT_CN# +----------------- +locale='x-whatever' +disp_locale=en : display_name=x-whatever #Private-Use=whatever# +disp_locale=fr : display_name=x-whatever #Usage privé=whatever# +disp_locale=de : display_name=x-whatever #Privatnutzung=whatever# +----------------- +locale='qaa-Qaaa-QM-x-southern' +disp_locale=en : display_name=qaa #Qaaa, QM, Private-Use=southern# +disp_locale=fr : display_name=qaa #Qaaa, QM, Usage privé=southern# +disp_locale=de : display_name=qaa #Qaaa, QM, Privatnutzung=southern# +----------------- +locale='sr-Latn-QM' +disp_locale=en : display_name=Serbian #Latin, QM# +disp_locale=fr : display_name=serbe #latin, QM# +disp_locale=de : display_name=Serbisch #Lateinisch, QM# +----------------- +locale='sr-Qaaa-CS' +disp_locale=en : display_name=Serbian #Qaaa, Serbia# +disp_locale=fr : display_name=serbe #Qaaa, Serbie# +disp_locale=de : display_name=Serbisch #Qaaa, Serbien# +----------------- +locale='en-US-u-islamCal' +disp_locale=en : display_name=English #United States, attribute=islamcal# +disp_locale=fr : display_name=anglais #États-Unis, attribute=islamcal# +disp_locale=de : display_name=Englisch #Vereinigte Staaten, attribute=islamcal# +----------------- +locale='zh-CN-a-myExt-x-private' +disp_locale=en : display_name=Chinese #China, a=myext, Private-Use=private# +disp_locale=fr : display_name=chinois #Chine, a=myext, Usage privé=private# +disp_locale=de : display_name=Chinesisch #China, a=myext, Privatnutzung=private# +----------------- +locale='en-a-myExt-b-another' +disp_locale=en : display_name=English #a=myext, b=another# +disp_locale=fr : display_name=anglais #a=myext, b=another# +disp_locale=de : display_name=Englisch #a=myext, b=another# +----------------- +locale='de-419-DE' +disp_locale=en : display_name=German #Latin America, DE# +disp_locale=fr : display_name=allemand #Amérique latine, DE# +disp_locale=de : display_name=Deutsch #Lateinamerika, DE# +----------------- +locale='a-DE' +disp_locale=en : display_name=a #Germany# +disp_locale=fr : display_name=a #Allemagne# +disp_locale=de : display_name=a #Deutschland# +----------------- +locale='ar-a-aaa-b-bbb-a-ccc' +disp_locale=en : display_name=Arabic #a=aaa, b=bbb# +disp_locale=fr : display_name=arabe #a=aaa, b=bbb# +disp_locale=de : display_name=Arabisch #a=aaa, b=bbb# +----------------- diff --git a/ext/intl/tests/locale_get_display_region2.phpt b/ext/intl/tests/locale_get_display_region2.phpt index f1b584188aa22..1d7354bd1bc87 100644 --- a/ext/intl/tests/locale_get_display_region2.phpt +++ b/ext/intl/tests/locale_get_display_region2.phpt @@ -1,8 +1,9 @@ --TEST-- -locale_get_display_region() icu >= 4.8 +locale_get_display_region() icu >= 4.8 && icu < 51.2 --SKIPIF-- += 0) die('skip for ICU < 51.2'); ?> --FILE-- = 51.2 +--SKIPIF-- + += 51.2'); ?> +--FILE-- + +--EXPECTREGEX-- +locale='uk-ua_CALIFORNIA@currency=;currency=GRN' +disp_locale=en : display_region=Ukraine +disp_locale=fr : display_region=Ukraine +disp_locale=de : display_region=Ukraine +----------------- +locale='root' +disp_locale=en : display_region= +disp_locale=fr : display_region= +disp_locale=de : display_region= +----------------- +locale='uk@currency=EURO' +disp_locale=en : display_region= +disp_locale=fr : display_region= +disp_locale=de : display_region= +----------------- +locale='Hindi' +disp_locale=en : display_region= +disp_locale=fr : display_region= +disp_locale=de : display_region= +----------------- +locale='de' +disp_locale=en : display_region= +disp_locale=fr : display_region= +disp_locale=de : display_region= +----------------- +locale='fr' +disp_locale=en : display_region= +disp_locale=fr : display_region= +disp_locale=de : display_region= +----------------- +locale='ja' +disp_locale=en : display_region= +disp_locale=fr : display_region= +disp_locale=de : display_region= +----------------- +locale='i-enochian' +disp_locale=en : display_region= +disp_locale=fr : display_region= +disp_locale=de : display_region= +----------------- +locale='zh-Hant' +disp_locale=en : display_region= +disp_locale=fr : display_region= +disp_locale=de : display_region= +----------------- +locale='zh-Hans' +disp_locale=en : display_region= +disp_locale=fr : display_region= +disp_locale=de : display_region= +----------------- +locale='sr-Cyrl' +disp_locale=en : display_region= +disp_locale=fr : display_region= +disp_locale=de : display_region= +----------------- +locale='sr-Latn' +disp_locale=en : display_region= +disp_locale=fr : display_region= +disp_locale=de : display_region= +----------------- +locale='zh-Hans-CN' +disp_locale=en : display_region=China +disp_locale=fr : display_region=Chine +disp_locale=de : display_region=China +----------------- +locale='sr-Latn-CS' +disp_locale=en : display_region=Serbia +disp_locale=fr : display_region=Serbie +disp_locale=de : display_region=Serbien +----------------- +locale='sl-rozaj' +disp_locale=en : display_region=(ROZAJ)? +disp_locale=fr : display_region=(ROZAJ)? +disp_locale=de : display_region=(ROZAJ)? +----------------- +locale='sl-nedis' +disp_locale=en : display_region=(NEDIS)? +disp_locale=fr : display_region=(NEDIS)? +disp_locale=de : display_region=(NEDIS)? +----------------- +locale='de-CH-1901' +disp_locale=en : display_region=Switzerland +disp_locale=fr : display_region=Suisse +disp_locale=de : display_region=Schweiz +----------------- +locale='sl-IT-nedis' +disp_locale=en : display_region=Italy +disp_locale=fr : display_region=Italie +disp_locale=de : display_region=Italien +----------------- +locale='sl-Latn-IT-nedis' +disp_locale=en : display_region=Italy +disp_locale=fr : display_region=Italie +disp_locale=de : display_region=Italien +----------------- +locale='de-DE' +disp_locale=en : display_region=Germany +disp_locale=fr : display_region=Allemagne +disp_locale=de : display_region=Deutschland +----------------- +locale='en-US' +disp_locale=en : display_region=United States +disp_locale=fr : display_region=États-Unis +disp_locale=de : display_region=Vereinigte Staaten +----------------- +locale='es-419' +disp_locale=en : display_region=Latin America +disp_locale=fr : display_region=Amérique latine +disp_locale=de : display_region=Lateinamerika +----------------- +locale='de-CH-x-phonebk' +disp_locale=en : display_region=Switzerland +disp_locale=fr : display_region=Suisse +disp_locale=de : display_region=Schweiz +----------------- +locale='az-Arab-x-AZE-derbend' +disp_locale=en : display_region=X? +disp_locale=fr : display_region=X? +disp_locale=de : display_region=X? +----------------- +locale='zh-min' +disp_locale=en : display_region= +disp_locale=fr : display_region= +disp_locale=de : display_region= +----------------- +locale='zh-min-nan-Hant-CN' +disp_locale=en : display_region=MIN +disp_locale=fr : display_region=MIN +disp_locale=de : display_region=MIN +----------------- +locale='x-whatever' +disp_locale=en : display_region= +disp_locale=fr : display_region= +disp_locale=de : display_region= +----------------- +locale='qaa-Qaaa-QM-x-southern' +disp_locale=en : display_region=QM +disp_locale=fr : display_region=QM +disp_locale=de : display_region=QM +----------------- +locale='sr-Latn-QM' +disp_locale=en : display_region=QM +disp_locale=fr : display_region=QM +disp_locale=de : display_region=QM +----------------- +locale='sr-Qaaa-CS' +disp_locale=en : display_region=Serbia +disp_locale=fr : display_region=Serbie +disp_locale=de : display_region=Serbien +----------------- +locale='en-US-u-islamCal' +disp_locale=en : display_region=United States +disp_locale=fr : display_region=États-Unis +disp_locale=de : display_region=Vereinigte Staaten +----------------- +locale='zh-CN-a-myExt-x-private' +disp_locale=en : display_region=China +disp_locale=fr : display_region=Chine +disp_locale=de : display_region=China +----------------- +locale='en-a-myExt-b-another' +disp_locale=en : display_region=A? +disp_locale=fr : display_region=A? +disp_locale=de : display_region=A? +----------------- +locale='de-419-DE' +disp_locale=en : display_region=Latin America +disp_locale=fr : display_region=Amérique latine +disp_locale=de : display_region=Lateinamerika +----------------- +locale='a-DE' +disp_locale=en : display_region=Germany +disp_locale=fr : display_region=Allemagne +disp_locale=de : display_region=Deutschland +----------------- +locale='ar-a-aaa-b-bbb-a-ccc' +disp_locale=en : display_region=A? +disp_locale=fr : display_region=A? +disp_locale=de : display_region=A? +----------------- diff --git a/ext/intl/tests/locale_lookup.phpt b/ext/intl/tests/locale_lookup.phpt index f0affafa6f2bb..df5204f07d84b 100644 --- a/ext/intl/tests/locale_lookup.phpt +++ b/ext/intl/tests/locale_lookup.phpt @@ -2,6 +2,7 @@ locale_lookup.phpt() --SKIPIF-- += 0) die('skip for ICU < 51.2'); ?> --FILE-- += 51.2'); ?> +--FILE-- + +--EXPECT-- +-------------- +loc_range:de-de +lang_tags: de-DEVA,de-DE-1996,de-DE,zh_Hans,de-CH-1996,sl_IT,sl_IT_nedis-a-kirti-x-xyz,sl_IT_rozaj,sl_IT_NEDIS_ROJAZ_1901,i-enochian,sgn-CH-de,art-lojban,i-lux,art-lojban,jbo,en_sl_IT,zh-Hant-CN-x-prv1-prv2 + +lookup result:de-DE +Canonical lookup result:de_de +-------------- +loc_range:sl_IT +lang_tags: de-DEVA,de-DE-1996,de-DE,zh_Hans,de-CH-1996,sl_IT,sl_IT_nedis-a-kirti-x-xyz,sl_IT_rozaj,sl_IT_NEDIS_ROJAZ_1901,i-enochian,sgn-CH-de,art-lojban,i-lux,art-lojban,jbo,en_sl_IT,zh-Hant-CN-x-prv1-prv2 + +lookup result:sl_IT +Canonical lookup result:sl_it +-------------- +loc_range:sl_IT_Nedis +lang_tags: de-DEVA,de-DE-1996,de-DE,zh_Hans,de-CH-1996,sl_IT,sl_IT_nedis-a-kirti-x-xyz,sl_IT_rozaj,sl_IT_NEDIS_ROJAZ_1901,i-enochian,sgn-CH-de,art-lojban,i-lux,art-lojban,jbo,en_sl_IT,zh-Hant-CN-x-prv1-prv2 + +lookup result:sl_IT +Canonical lookup result:sl_it +-------------- +loc_range:jbo +lang_tags: de-DEVA,de-DE-1996,de-DE,zh_Hans,de-CH-1996,sl_IT,sl_IT_nedis-a-kirti-x-xyz,sl_IT_rozaj,sl_IT_NEDIS_ROJAZ_1901,i-enochian,sgn-CH-de,art-lojban,i-lux,art-lojban,jbo,en_sl_IT,zh-Hant-CN-x-prv1-prv2 + +lookup result:jbo +Canonical lookup result:jbo +-------------- +loc_range:art-lojban +lang_tags: de-DEVA,de-DE-1996,de-DE,zh_Hans,de-CH-1996,sl_IT,sl_IT_nedis-a-kirti-x-xyz,sl_IT_rozaj,sl_IT_NEDIS_ROJAZ_1901,i-enochian,sgn-CH-de,art-lojban,i-lux,art-lojban,jbo,en_sl_IT,zh-Hant-CN-x-prv1-prv2 + +lookup result:art-lojban +Canonical lookup result:art__lojban diff --git a/ext/intl/tests/msgfmt_format_intlcalendar.phpt b/ext/intl/tests/msgfmt_format_intlcalendar.phpt index 6ae78a91400c0..a6bff2ecddfba 100644 --- a/ext/intl/tests/msgfmt_format_intlcalendar.phpt +++ b/ext/intl/tests/msgfmt_format_intlcalendar.phpt @@ -2,8 +2,8 @@ MessageFormat accepts IntlCalendar args --SKIPIF-- += 0) die('skip for ICU < 51.2'); ?> --FILE-- format(array($time, 'date')), " ", ==DONE== --EXPECT-- Quinta-feira, 17 de Maio de 2012 5:35:36 p.m. WEST -==DONE== \ No newline at end of file +==DONE== diff --git a/ext/intl/tests/msgfmt_format_intlcalendar_variant2.phpt b/ext/intl/tests/msgfmt_format_intlcalendar_variant2.phpt new file mode 100644 index 0000000000000..f2d16b899dcdf --- /dev/null +++ b/ext/intl/tests/msgfmt_format_intlcalendar_variant2.phpt @@ -0,0 +1,30 @@ +--TEST-- +MessageFormat accepts IntlCalendar args +--SKIPIF-- + += 51.2'); ?> +--FILE-- +format(array($cal)), "\n"; + +//NOT FIXED: +/*$msgf = new MessageFormatter('en_US', +'{1, select, date {{0,date,full}} other {{0,time,h:m:s a V}}}'); + +echo "msgf2: ", $msgf->format(array($time, 'date')), " ", + $msgf->format(array($time, 'time')), "\n"; +*/ + +?> +==DONE== +--EXPECT-- +Quinta-feira, 17 de Maio de 2012 5:35:36 PM ptlis +==DONE== diff --git a/ext/intl/tests/resourcebundle_null_mandatory_args.phpt b/ext/intl/tests/resourcebundle_null_mandatory_args.phpt index 17fab6d630a5e..bbbc1b1e91ce2 100644 --- a/ext/intl/tests/resourcebundle_null_mandatory_args.phpt +++ b/ext/intl/tests/resourcebundle_null_mandatory_args.phpt @@ -3,11 +3,9 @@ ResourceBundle constructor bundle accepts NULL for first two arguments --INI-- date.timezone=Atlantic/Azores --SKIPIF-- -= 4.8 only'); + += 4.8 only'); ?> += 0) die('skip for ICU < 51.2'); ?> --FILE-- += 51.2'); ?> +--FILE-- +get('calendar')->get('gregorian')->get('DateTimePatterns')->get(0); +var_dump($c); + +ini_set('intl.default_locale', 'pt_PT'); +$r = new ResourceBundle(NULL, NULL); +$c = $r->get('calendar')->get('gregorian')->get('DateTimePatterns')->get(0); +var_dump($c); +?> +==DONE== +--EXPECT-- +string(14) "h:mm:ss a zzzz" +string(13) "HH:mm:ss zzzz" +==DONE== diff --git a/ext/intl/tests/timezone_getDisplayName_variant2-49+.phpt b/ext/intl/tests/timezone_getDisplayName_variant2-49+.phpt index 4ee30aee12642..8f60f2904021f 100644 --- a/ext/intl/tests/timezone_getDisplayName_variant2-49+.phpt +++ b/ext/intl/tests/timezone_getDisplayName_variant2-49+.phpt @@ -1,11 +1,9 @@ --TEST-- -IntlTimeZone::getDisplayName(): type parameter (ICU >= 49) +IntlTimeZone::getDisplayName(): type parameter (ICU >= 49 && ICU < 51.2) --SKIPIF-- - + += 0) die('skip for ICU < 51.2'); ?> --FILE-- = 51.2) +--SKIPIF-- + += 51.2'); ?> +--FILE-- +getDisplayName(false, IntlTimeZone::DISPLAY_SHORT)); +var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_LONG)); +var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_SHORT_GENERIC)); +var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_LONG_GENERIC)); +var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_SHORT_GMT)); +var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_LONG_GMT)); +var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_SHORT_COMMONLY_USED)); +var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_GENERIC_LOCATION)); + +?> +==DONE== +--EXPECT-- +string(3) "GMT" +string(30) "Western European Standard Time" +string(13) "Portugal Time" +string(21) "Western European Time" +string(5) "+0000" +string(3) "GMT" +string(3) "GMT" +string(13) "Portugal Time" +==DONE== diff --git a/ext/json/json.c b/ext/json/json.c index 782375e3717cc..d017753de6fbc 100644 --- a/ext/json/json.c +++ b/ext/json/json.c @@ -190,10 +190,10 @@ static int json_determine_array_type(zval **val TSRMLS_DC) /* {{{ */ } if (i == HASH_KEY_IS_STRING) { - return 1; + return PHP_JSON_OUTPUT_OBJECT; } else { if (index != idx) { - return 1; + return PHP_JSON_OUTPUT_OBJECT; } } idx++; @@ -695,21 +695,35 @@ PHP_JSON_API void php_json_decode_ex(zval *return_value, char *str, int str_len, double d; int type, overflow_info; long p; + char *trim = str; + int trim_len = str_len; + + /* Increment trimmed string pointer to strip leading whitespace */ + /* JSON RFC says to consider as whitespace: space, tab, LF or CR */ + while (trim_len && (*trim == ' ' || *trim == '\t' || *trim == '\n' || *trim == '\r')) { + trim++; + trim_len--; + } + + /* Decrement trimmed string length to strip trailing whitespace */ + while (trim_len && (trim[trim_len - 1] == ' ' || trim[trim_len - 1] == '\t' || trim[trim_len - 1] == '\n' || trim[trim_len - 1] == '\r')) { + trim_len--; + } RETVAL_NULL(); - if (str_len == 4) { - if (!strcasecmp(str, "null")) { + if (trim_len == 4) { + if (!strncmp(trim, "null", trim_len)) { /* We need to explicitly clear the error because its an actual NULL and not an error */ jp->error_code = PHP_JSON_ERROR_NONE; RETVAL_NULL(); - } else if (!strcasecmp(str, "true")) { + } else if (!strncmp(trim, "true", trim_len)) { RETVAL_BOOL(1); } - } else if (str_len == 5 && !strcasecmp(str, "false")) { + } else if (trim_len == 5 && !strncmp(trim, "false", trim_len)) { RETVAL_BOOL(0); } - if ((type = is_numeric_string_ex(str, str_len, &p, &d, 0, &overflow_info)) != 0) { + if ((type = is_numeric_string_ex(trim, trim_len, &p, &d, 0, &overflow_info)) != 0) { if (type == IS_LONG) { RETVAL_LONG(p); } else if (type == IS_DOUBLE) { @@ -722,10 +736,10 @@ PHP_JSON_API void php_json_decode_ex(zval *return_value, char *str, int str_len, int i; zend_bool is_float = 0; - for (i = (str[0] == '-' ? 1 : 0); i < str_len; i++) { + for (i = (trim[0] == '-' ? 1 : 0); i < trim_len; i++) { /* Not using isdigit() because it's locale specific, * but we expect JSON input to always be UTF-8. */ - if (str[i] < '0' || str[i] > '9') { + if (trim[i] < '0' || trim[i] > '9') { is_float = 1; break; } @@ -734,7 +748,7 @@ PHP_JSON_API void php_json_decode_ex(zval *return_value, char *str, int str_len, if (is_float) { RETVAL_DOUBLE(d); } else { - RETVAL_STRINGL(str, str_len, 1); + RETVAL_STRINGL(trim, trim_len, 1); } } else { RETVAL_DOUBLE(d); diff --git a/ext/json/tests/bug64874_part1.phpt b/ext/json/tests/bug64874_part1.phpt new file mode 100644 index 0000000000000..6b79b8dc047ed --- /dev/null +++ b/ext/json/tests/bug64874_part1.phpt @@ -0,0 +1,117 @@ +--TEST-- +Whitespace part of bug #64874 ("json_decode handles whitespace and case-sensitivity incorrectly") +--SKIPIF-- + +--FILE-- + +--FILE-- + + bool(true) +} +SUCCESS +NULL +ERROR + +bool(false) +SUCCESS +NULL +ERROR +array(1) { + [0]=> + bool(false) +} +SUCCESS +NULL +ERROR + +NULL +SUCCESS +NULL +ERROR +array(1) { + [0]=> + NULL +} +SUCCESS +NULL +ERROR + +Done diff --git a/ext/ldap/config.m4 b/ext/ldap/config.m4 index 3c8e23ea8e852..2804cd5968ebf 100644 --- a/ext/ldap/config.m4 +++ b/ext/ldap/config.m4 @@ -15,6 +15,28 @@ AC_DEFUN([PHP_LDAP_CHECKS], [ LDAP_DIR=$1 LDAP_INCDIR=$1/ldap/public LDAP_LIBDIR=$1/$PHP_LIBDIR + else + + dnl Find Oracle Instant Client RPM header location corresponding to the given lib path e.g. for --with-ldap=/usr/lib/oracle/12.1/client64/lib + AC_CHECK_SIZEOF(long int, 4) + if test "$ac_cv_sizeof_long_int" = "4"; then + PHP_OCI8_IC_LIBDIR_SUFFIX="" + else + PHP_OCI8_IC_LIBDIR_SUFFIX=64 + fi + OCISDKRPMINC=`echo "$1" | $SED -e 's!^/usr/lib/oracle/\(.*\)/client\('${PHP_OCI8_IC_LIBDIR_SUFFIX}'\)*/lib[/]*$!/usr/include/oracle/\1/client\2!'` + + dnl Check for Oracle Instant Client RPM install + if test -f $OCISDKRPMINC/ldap.h; then + LDAP_DIR=$1 + LDAP_INCDIR=$OCISDKRPMINC + LDAP_LIBDIR=$1 + dnl Check for Oracle Instant Client ZIP install + elif test -f $1/sdk/include/ldap.h; then + LDAP_DIR=$1 + LDAP_INCDIR=$1/sdk/include + LDAP_LIBDIR=$1 + fi fi ]) @@ -143,12 +165,21 @@ if test "$PHP_LDAP" != "no"; then PHP_ADD_LIBRARY_WITH_PATH(umich_lber, $LDAP_LIBDIR, LDAP_SHARED_LIBADD) PHP_ADD_LIBRARY_WITH_PATH(umich_ldap, $LDAP_LIBDIR, LDAP_SHARED_LIBADD) - elif test -f $LDAP_LIBDIR/libclntsh.$SHLIB_SUFFIX_NAME; then + elif test -f $LDAP_LIBDIR/libclntsh.$SHLIB_SUFFIX_NAME.12.1; then PHP_ADD_LIBRARY_WITH_PATH(clntsh, $LDAP_LIBDIR, LDAP_SHARED_LIBADD) AC_DEFINE(HAVE_ORALDAP,1,[ ]) - if test -f $LDAP_LIBDIR/libclntsh.$SHLIB_SUFFIX_NAME.10.1; then - AC_DEFINE(HAVE_ORALDAP_10,1,[ ]) - fi + AC_DEFINE(HAVE_ORALDAP_12,1,[ ]) + + elif test -f $LDAP_LIBDIR/libclntsh.$SHLIB_SUFFIX_NAME.11.1; then + PHP_ADD_LIBRARY_WITH_PATH(clntsh, $LDAP_LIBDIR, LDAP_SHARED_LIBADD) + AC_DEFINE(HAVE_ORALDAP,1,[ ]) + AC_DEFINE(HAVE_ORALDAP_11,1,[ ]) + + elif test -f $LDAP_LIBDIR/libclntsh.$SHLIB_SUFFIX_NAME; then + PHP_ADD_LIBRARY_WITH_PATH(clntsh, $LDAP_LIBDIR, LDAP_SHARED_LIBADD) + AC_DEFINE(HAVE_ORALDAP,1,[ ]) + AC_DEFINE(HAVE_ORALDAP_10,1,[ ]) + else AC_MSG_ERROR(Cannot find ldap libraries in $LDAP_LIBDIR.) fi diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c index 3cfa2092e776e..d50b78321fb89 100644 --- a/ext/ldap/ldap.c +++ b/ext/ldap/ldap.c @@ -67,6 +67,9 @@ #include #endif +#define PHP_LDAP_ESCAPE_FILTER 0x01 +#define PHP_LDAP_ESCAPE_DN 0x02 + typedef struct { LDAP *link; #if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(HAVE_3ARG_SETREBINDPROC) @@ -152,7 +155,7 @@ PHP_MINIT_FUNCTION(ldap) REGISTER_LONG_CONSTANT("LDAP_DEREF_FINDING", LDAP_DEREF_FINDING, CONST_PERSISTENT | CONST_CS); REGISTER_LONG_CONSTANT("LDAP_DEREF_ALWAYS", LDAP_DEREF_ALWAYS, CONST_PERSISTENT | CONST_CS); -#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 +#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP /* LDAP options */ REGISTER_LONG_CONSTANT("LDAP_OPT_DEREF", LDAP_OPT_DEREF, CONST_PERSISTENT | CONST_CS); REGISTER_LONG_CONSTANT("LDAP_OPT_SIZELIMIT", LDAP_OPT_SIZELIMIT, CONST_PERSISTENT | CONST_CS); @@ -195,6 +198,9 @@ PHP_MINIT_FUNCTION(ldap) REGISTER_LONG_CONSTANT("GSLC_SSL_TWOWAY_AUTH", GSLC_SSL_TWOWAY_AUTH, CONST_PERSISTENT | CONST_CS); #endif + REGISTER_LONG_CONSTANT("LDAP_ESCAPE_FILTER", PHP_LDAP_ESCAPE_FILTER, CONST_PERSISTENT | CONST_CS); + REGISTER_LONG_CONSTANT("LDAP_ESCAPE_DN", PHP_LDAP_ESCAPE_DN, CONST_PERSISTENT | CONST_CS); + le_link = zend_register_list_destructors_ex(_close_ldap_link, NULL, "ldap link", module_number); le_result = zend_register_list_destructors_ex(_free_ldap_result, NULL, "ldap result", module_number); le_result_entry = zend_register_list_destructors_ex(_free_ldap_result_entry, NULL, "ldap result entry", module_number); @@ -361,7 +367,7 @@ PHP_FUNCTION(ldap_connect) static int _get_lderrno(LDAP *ldap) { #if !HAVE_NSLDAP -#if LDAP_API_VERSION > 2000 || HAVE_ORALDAP_10 +#if LDAP_API_VERSION > 2000 || HAVE_ORALDAP int lderr; /* New versions of OpenLDAP do it this way */ @@ -550,7 +556,7 @@ static void php_set_opts(LDAP *ldap, int sizelimit, int timelimit, int deref, in { /* sizelimit */ if (sizelimit > -1) { -#if (LDAP_API_VERSION >= 2004) || HAVE_NSLDAP || HAVE_ORALDAP_10 +#if (LDAP_API_VERSION >= 2004) || HAVE_NSLDAP || HAVE_ORALDAP ldap_get_option(ldap, LDAP_OPT_SIZELIMIT, old_sizelimit); ldap_set_option(ldap, LDAP_OPT_SIZELIMIT, &sizelimit); #else @@ -561,7 +567,7 @@ static void php_set_opts(LDAP *ldap, int sizelimit, int timelimit, int deref, in /* timelimit */ if (timelimit > -1) { -#if (LDAP_API_VERSION >= 2004) || HAVE_NSLDAP || HAVE_ORALDAP_10 +#if (LDAP_API_VERSION >= 2004) || HAVE_NSLDAP || HAVE_ORALDAP ldap_get_option(ldap, LDAP_OPT_SIZELIMIT, old_timelimit); ldap_set_option(ldap, LDAP_OPT_TIMELIMIT, &timelimit); #else @@ -572,7 +578,7 @@ static void php_set_opts(LDAP *ldap, int sizelimit, int timelimit, int deref, in /* deref */ if (deref > -1) { -#if (LDAP_API_VERSION >= 2004) || HAVE_NSLDAP || HAVE_ORALDAP_10 +#if (LDAP_API_VERSION >= 2004) || HAVE_NSLDAP || HAVE_ORALDAP ldap_get_option(ldap, LDAP_OPT_SIZELIMIT, old_deref); ldap_set_option(ldap, LDAP_OPT_DEREF, &deref); #else @@ -975,12 +981,12 @@ PHP_FUNCTION(ldap_get_entries) add_index_string(tmp1, num_attrib, attribute, 1); num_attrib++; -#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 || WINDOWS +#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP || WINDOWS ldap_memfree(attribute); #endif attribute = ldap_next_attribute(ldap, ldap_result_entry, ber); } -#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 || WINDOWS +#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP || WINDOWS if (ber != NULL) { ber_free(ber, 0); } @@ -989,7 +995,7 @@ PHP_FUNCTION(ldap_get_entries) add_assoc_long(tmp1, "count", num_attrib); dn = ldap_get_dn(ldap, ldap_result_entry); add_assoc_string(tmp1, "dn", dn, 1); -#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 || WINDOWS +#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP || WINDOWS ldap_memfree(dn); #else free(dn); @@ -1027,7 +1033,7 @@ PHP_FUNCTION(ldap_first_attribute) RETURN_FALSE; } else { RETVAL_STRING(attribute, 1); -#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 || WINDOWS +#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP || WINDOWS ldap_memfree(attribute); #endif } @@ -1057,7 +1063,7 @@ PHP_FUNCTION(ldap_next_attribute) } if ((attribute = ldap_next_attribute(ld->link, resultentry->data, resultentry->ber)) == NULL) { -#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 || WINDOWS +#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP || WINDOWS if (resultentry->ber != NULL) { ber_free(resultentry->ber, 0); resultentry->ber = NULL; @@ -1066,7 +1072,7 @@ PHP_FUNCTION(ldap_next_attribute) RETURN_FALSE; } else { RETVAL_STRING(attribute, 1); -#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 || WINDOWS +#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP || WINDOWS ldap_memfree(attribute); #endif } @@ -1113,12 +1119,12 @@ PHP_FUNCTION(ldap_get_attributes) add_index_string(return_value, num_attrib, attribute, 1); num_attrib++; -#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 || WINDOWS +#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP || WINDOWS ldap_memfree(attribute); #endif attribute = ldap_next_attribute(ld->link, resultentry->data, ber); } -#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 || WINDOWS +#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP || WINDOWS if (ber != NULL) { ber_free(ber, 0); } @@ -1183,7 +1189,7 @@ PHP_FUNCTION(ldap_get_dn) text = ldap_get_dn(ld->link, resultentry->data); if (text != NULL) { RETVAL_STRING(text, 1); -#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 || WINDOWS +#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP || WINDOWS ldap_memfree(text); #else free(text); @@ -1241,7 +1247,7 @@ PHP_FUNCTION(ldap_dn2ufn) if (ufn != NULL) { RETVAL_STRING(ufn, 1); -#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 || WINDOWS +#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP || WINDOWS ldap_memfree(ufn); #endif } else { @@ -1546,7 +1552,7 @@ PHP_FUNCTION(ldap_sort) } /* }}} */ -#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 +#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP /* {{{ proto bool ldap_get_option(resource link, int option, mixed retval) Get the current value of various session-wide parameters */ PHP_FUNCTION(ldap_get_option) @@ -2003,7 +2009,7 @@ PHP_FUNCTION(ldap_rename) newparent = NULL; } -#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 +#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP rc = ldap_rename_s(ld->link, dn, newrdn, newparent, deleteoldrdn, NULL, NULL); #else if (newparent_len != 0) { @@ -2047,7 +2053,7 @@ PHP_FUNCTION(ldap_start_tls) } /* }}} */ #endif -#endif /* (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 */ +#endif /* (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP */ #if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(HAVE_3ARG_SETREBINDPROC) /* {{{ _ldap_rebind_proc() @@ -2107,6 +2113,7 @@ PHP_FUNCTION(ldap_set_rebind_proc) /* unregister rebind procedure */ if (ld->rebindproc != NULL) { zval_dtor(ld->rebindproc); + FREE_ZVAL(ld->rebindproc); ld->rebindproc = NULL; ldap_set_rebind_proc(ld->link, NULL, NULL); } @@ -2136,6 +2143,83 @@ PHP_FUNCTION(ldap_set_rebind_proc) /* }}} */ #endif +static void php_ldap_do_escape(const zend_bool *map, const char *value, size_t valuelen, char **result, size_t *resultlen) +{ + char hex[] = "0123456789abcdef"; + int i, p = 0; + size_t len = 0; + + for (i = 0; i < valuelen; i++) { + len += (map[(unsigned char) value[i]]) ? 3 : 1; + } + + (*result) = (char *) safe_emalloc(1, len, 1); + (*resultlen) = len; + + for (i = 0; i < valuelen; i++) { + unsigned char v = (unsigned char) value[i]; + + if (map[v]) { + (*result)[p++] = '\\'; + (*result)[p++] = hex[v >> 4]; + (*result)[p++] = hex[v & 0x0f]; + } else { + (*result)[p++] = v; + } + } + + (*result)[p++] = '\0'; +} + +static void php_ldap_escape_map_set_chars(zend_bool *map, const char *chars, const int charslen, char escape) +{ + int i = 0; + while (i < charslen) { + map[(unsigned char) chars[i++]] = escape; + } +} + +PHP_FUNCTION(ldap_escape) +{ + char *value, *ignores, *result; + int valuelen = 0, ignoreslen = 0, i; + size_t resultlen; + long flags = 0; + zend_bool map[256] = {0}, havecharlist = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|sl", &value, &valuelen, &ignores, &ignoreslen, &flags) != SUCCESS) { + return; + } + + if (!valuelen) { + RETURN_EMPTY_STRING(); + } + + if (flags & PHP_LDAP_ESCAPE_FILTER) { + havecharlist = 1; + php_ldap_escape_map_set_chars(map, "\\*()\0", sizeof("\\*()\0") - 1, 1); + } + + if (flags & PHP_LDAP_ESCAPE_DN) { + havecharlist = 1; + php_ldap_escape_map_set_chars(map, "\\,=+<>;\"#", sizeof("\\,=+<>;\"#") - 1, 1); + } + + if (!havecharlist) { + for (i = 0; i < 256; i++) { + map[i] = 1; + } + } + + if (ignoreslen) { + php_ldap_escape_map_set_chars(map, ignores, ignoreslen, 0); + } + + php_ldap_do_escape(map, value, valuelen, &result, &resultlen); + + RETURN_STRINGL(result, resultlen, 0); +} + #ifdef STR_TRANSLATION /* {{{ php_ldap_do_translate */ @@ -2566,7 +2650,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_control_paged_result_response, 0, 0, 2) ZEND_END_ARG_INFO(); #endif -#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 +#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_rename, 0, 0, 5) ZEND_ARG_INFO(0, link_identifier) ZEND_ARG_INFO(0, dn) @@ -2625,6 +2709,12 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_set_rebind_proc, 0, 0, 2) ZEND_END_ARG_INFO() #endif +ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_escape, 0, 0, 1) + ZEND_ARG_INFO(0, value) + ZEND_ARG_INFO(0, ignore) + ZEND_ARG_INFO(0, flags) +ZEND_END_ARG_INFO() + #ifdef STR_TRANSLATION ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_t61_to_8859, 0, 0, 1) ZEND_ARG_INFO(0, value) @@ -2682,7 +2772,7 @@ const zend_function_entry ldap_functions[] = { PHP_FE(ldap_compare, arginfo_ldap_compare) PHP_FE(ldap_sort, arginfo_ldap_sort) -#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 +#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP PHP_FE(ldap_rename, arginfo_ldap_rename) PHP_FE(ldap_get_option, arginfo_ldap_get_option) PHP_FE(ldap_set_option, arginfo_ldap_set_option) @@ -2703,6 +2793,8 @@ const zend_function_entry ldap_functions[] = { PHP_FE(ldap_set_rebind_proc, arginfo_ldap_set_rebind_proc) #endif + PHP_FE(ldap_escape, arginfo_ldap_escape) + #ifdef STR_TRANSLATION PHP_FE(ldap_t61_to_8859, arginfo_ldap_t61_to_8859) PHP_FE(ldap_8859_to_t61, arginfo_ldap_8859_to_t61) diff --git a/ext/ldap/tests/ldap_escape_all.phpt b/ext/ldap/tests/ldap_escape_all.phpt new file mode 100644 index 0000000000000..a79be004ffe56 --- /dev/null +++ b/ext/ldap/tests/ldap_escape_all.phpt @@ -0,0 +1,14 @@ +--TEST-- +ldap_escape() test all +--SKIPIF-- + +--FILE-- + +--EXPECT-- +string(39) "\66\6f\6f\3d\62\61\72\28\62\61\7a\29\2a" \ No newline at end of file diff --git a/ext/ldap/tests/ldap_escape_both.phpt b/ext/ldap/tests/ldap_escape_both.phpt new file mode 100644 index 0000000000000..2169c0ad2e75c --- /dev/null +++ b/ext/ldap/tests/ldap_escape_both.phpt @@ -0,0 +1,14 @@ +--TEST-- +ldap_escape() test filter and DN +--SKIPIF-- + +--FILE-- + +--EXPECT-- +string(21) "foo\3dbar\28baz\29\2a" \ No newline at end of file diff --git a/ext/ldap/tests/ldap_escape_dn.phpt b/ext/ldap/tests/ldap_escape_dn.phpt new file mode 100644 index 0000000000000..fbcb0545ae4e8 --- /dev/null +++ b/ext/ldap/tests/ldap_escape_dn.phpt @@ -0,0 +1,14 @@ +--TEST-- +ldap_escape() test DN +--SKIPIF-- + +--FILE-- + +--EXPECT-- +string(15) "foo\3dbar(baz)*" \ No newline at end of file diff --git a/ext/ldap/tests/ldap_escape_filter.phpt b/ext/ldap/tests/ldap_escape_filter.phpt new file mode 100644 index 0000000000000..e4540a452d3f6 --- /dev/null +++ b/ext/ldap/tests/ldap_escape_filter.phpt @@ -0,0 +1,14 @@ +--TEST-- +ldap_escape() test filter +--SKIPIF-- + +--FILE-- + +--EXPECT-- +string(19) "foo=bar\28baz\29\2a" \ No newline at end of file diff --git a/ext/ldap/tests/ldap_escape_ignore.phpt b/ext/ldap/tests/ldap_escape_ignore.phpt new file mode 100644 index 0000000000000..ab56aa2d0e91f --- /dev/null +++ b/ext/ldap/tests/ldap_escape_ignore.phpt @@ -0,0 +1,15 @@ +--TEST-- +ldap_escape() test ignore +--SKIPIF-- + +--FILE-- + +--EXPECT-- +string(31) "\66oo\3d\62a\72\28\62a\7a\29\2a" \ No newline at end of file diff --git a/ext/ldap/tests/ldap_search_variation6.phpt b/ext/ldap/tests/ldap_search_variation6.phpt index a29e4524df46b..5139ebb77dece 100644 --- a/ext/ldap/tests/ldap_search_variation6.phpt +++ b/ext/ldap/tests/ldap_search_variation6.phpt @@ -217,14 +217,26 @@ array(2) { [1]=> resource(%d) of type (ldap result) } -NULL -NULL +array(1) { + ["count"]=> + int(0) +} +array(1) { + ["count"]=> + int(0) +} array(2) { [0]=> resource(%d) of type (ldap result) [1]=> resource(%d) of type (ldap result) } -NULL -NULL +array(1) { + ["count"]=> + int(0) +} +array(1) { + ["count"]=> + int(0) +} ===DONE=== diff --git a/ext/mbstring/libmbfl/filters/mbfilter_iso2022jp_mobile.c b/ext/mbstring/libmbfl/filters/mbfilter_iso2022jp_mobile.c index 4deb02960c3a3..03e9633cae756 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_iso2022jp_mobile.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_iso2022jp_mobile.c @@ -142,7 +142,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_2022jp_kddi = { int mbfl_filt_conv_2022jp_mobile_wchar(int c, mbfl_convert_filter *filter) { - int c1, s, w, snd; + int c1, s, w, snd = 0; retry: switch (filter->status & 0xf) { diff --git a/ext/mbstring/libmbfl/filters/mbfilter_sjis_2004.c b/ext/mbstring/libmbfl/filters/mbfilter_sjis_2004.c index 4e1838f0601c5..87bb2f21fd5f2 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_sjis_2004.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_sjis_2004.c @@ -134,7 +134,7 @@ int mbfl_filt_conv_jis2004_wchar(int c, mbfl_convert_filter *filter) { int k; - int c1, c2, s, s1, s2, w = 0, w1; + int c1, c2, s, s1 = 0, s2 = 0, w = 0, w1; retry: switch (filter->status & 0xf) { diff --git a/ext/mbstring/libmbfl/filters/mbfilter_sjis_mobile.c b/ext/mbstring/libmbfl/filters/mbfilter_sjis_mobile.c index 7a549af666587..93ac34644a833 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_sjis_mobile.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_sjis_mobile.c @@ -605,7 +605,7 @@ mbfilter_unicode2sjis_emoji_sb(int c, int *s1, mbfl_convert_filter *filter) int mbfl_filt_conv_sjis_mobile_wchar(int c, mbfl_convert_filter *filter) { - int c1, s, s1, s2, w; + int c1, s, s1 = 0, s2 = 0, w; int snd = 0; retry: diff --git a/ext/mbstring/libmbfl/mbfl/mbfilter.c b/ext/mbstring/libmbfl/mbfl/mbfilter.c index b3759f940d549..3b14727d6b6c1 100644 --- a/ext/mbstring/libmbfl/mbfl/mbfilter.c +++ b/ext/mbstring/libmbfl/mbfl/mbfilter.c @@ -985,7 +985,7 @@ mbfl_strpos( { int result; mbfl_string _haystack_u8, _needle_u8; - const mbfl_string *haystack_u8, *needle_u8; + const mbfl_string *haystack_u8, *needle_u8 = NULL; const unsigned char *u8_tbl; if (haystack == NULL || haystack->val == NULL || needle == NULL || needle->val == NULL) { diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 4e430b6ea2364..168b133c6429f 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -402,10 +402,10 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_convert_kana, 0, 0, 1) ZEND_ARG_INFO(0, encoding) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_convert_variables, 1, 0, 3) +ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_convert_variables, 0, 0, 3) ZEND_ARG_INFO(0, to) ZEND_ARG_INFO(0, from) - ZEND_ARG_INFO(1, ...) + ZEND_ARG_VARIADIC_INFO(1, vars) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_encode_numericentity, 0, 0, 2) diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c index 3ee5c803a5508..e67aba8da04fa 100644 --- a/ext/mysqli/mysqli_api.c +++ b/ext/mysqli/mysqli_api.c @@ -385,7 +385,7 @@ mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval ***args, unsigned int argc, /* Changed to my_bool in MySQL 5.1. See MySQL Bug #16144 */ my_bool tmp; #else - uint tmp = 0; + ulong tmp = 0; #endif stmt->result.buf[ofs].type = IS_STRING; /* diff --git a/ext/mysqli/mysqli_fe.c b/ext/mysqli/mysqli_fe.c index 6f2e404087843..eb94ff65bbebf 100644 --- a/ext/mysqli/mysqli_fe.c +++ b/ext/mysqli/mysqli_fe.c @@ -43,23 +43,28 @@ #define MYSQLI_ZEND_ARG_OBJ_INFO_STMT() ZEND_ARG_INFO(0, stmt) #endif -ZEND_BEGIN_ARG_INFO(arginfo_mysqli_stmt_bind_result, 1) +ZEND_BEGIN_ARG_INFO(arginfo_mysqli_stmt_bind_result, 0) MYSQLI_ZEND_ARG_OBJ_INFO_STMT() + ZEND_ARG_VARIADIC_INFO(1, vars) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO(arginfo_mysqli_stmt_bind_param, 1) +ZEND_BEGIN_ARG_INFO(arginfo_mysqli_stmt_bind_param, 0) MYSQLI_ZEND_ARG_OBJ_INFO_STMT() ZEND_ARG_INFO(0, types) + ZEND_ARG_VARIADIC_INFO(1, vars) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO(arginfo_class_mysqli_stmt_bind_result, 1) +ZEND_BEGIN_ARG_INFO(arginfo_class_mysqli_stmt_bind_result, 0) + ZEND_ARG_VARIADIC_INFO(1, vars) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO(arginfo_class_mysqli_stmt_bind_param, 1) +ZEND_BEGIN_ARG_INFO(arginfo_class_mysqli_stmt_bind_param, 0) ZEND_ARG_INFO(0, types) + ZEND_ARG_VARIADIC_INFO(1, vars) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO(all_args_force_by_ref, 1) +ZEND_BEGIN_ARG_INFO(all_args_force_by_ref, 0) + ZEND_ARG_VARIADIC_INFO(1, vars) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_poll, 0, 0, 4) diff --git a/ext/mysqli/mysqli_nonapi.c b/ext/mysqli/mysqli_nonapi.c index c24b974de862b..b5630c3e7f9d0 100644 --- a/ext/mysqli/mysqli_nonapi.c +++ b/ext/mysqli/mysqli_nonapi.c @@ -775,7 +775,7 @@ PHP_FUNCTION(mysqli_poll) MYSQLND **new_r_array = NULL, **new_e_array = NULL, **new_dont_poll_array = NULL; long sec = 0, usec = 0; enum_func_status ret; - uint desc_num; + int desc_num; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a!a!al|l", &r_array, &e_array, &dont_poll_array, &sec, &usec) == FAILURE) { return; diff --git a/ext/mysqli/tests/bug66043.phpt b/ext/mysqli/tests/bug66043.phpt new file mode 100644 index 0000000000000..d0e8b1c3d391f --- /dev/null +++ b/ext/mysqli/tests/bug66043.phpt @@ -0,0 +1,24 @@ +--TEST-- +Bug #66043 (Segfault calling bind_param() on mysqli) +--SKIPIF-- + +--FILE-- +stmt_init(); +$stmt->prepare("SELECT User FROM user WHERE password=\"\""); +$stmt->execute(); +$stmt->bind_result($testArg); +echo "Okey"; +?> +--EXPECTF-- +Okey diff --git a/ext/mysqli/tests/bug66124.phpt b/ext/mysqli/tests/bug66124.phpt new file mode 100644 index 0000000000000..8c0027f9e66fb --- /dev/null +++ b/ext/mysqli/tests/bug66124.phpt @@ -0,0 +1,101 @@ +--TEST-- +Bug #66124 (mysqli under mysqlnd loses precision when bind_param with 'i') +--SKIPIF-- + +--FILE-- +query($table_drop); +$link->query($table_create); + +$stmt = $link->prepare($table_insert); +if (!$stmt) { + printf("Can't prepare\n"); + exit(1); +} + +echo "Using 'i':\n"; +$stmt->bind_param('i', $id); + +if ($stmt->execute()){ + echo "insert id:{$id}=>{$stmt->insert_id}\n"; +} else { + printf("Can't execute\n"); + exit(1); +} + + +$result = $link->query($table_select); + +if ($result){ + while ($row = $result->fetch_assoc()) { + echo "fetch id:{$row['id']}\n"; + } +} else { + printf("Can't select\n"); + exit(1); +} + +$stmt->close(); + +$link->query($table_drop); +$link->query($table_create); + + +$stmt = $link->prepare($table_insert); +$stmt->bind_param('s', $id); + +echo "Using 's':\n"; + +if ($stmt->execute()){ + echo "insert id:{$id}\n"; +} else{ + printf("Can't execute\n"); + exit(1); +} + +$result = $link->query($table_select); + +if ($result){ + while ($row = $result->fetch_assoc()) { + echo "fetch id:{$row['id']}\n"; + } +} else { + printf("Can't select\n"); + exit(1); +} + +$link->close(); +?> +done +--EXPECTF-- +Using 'i': +insert id:1311200011005001566=>1311200011005001566 +fetch id:1311200011005001566 +Using 's': +insert id:1311200011005001566 +fetch id:1311200011005001566 +done \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_class_mysqli_reflection.phpt b/ext/mysqli/tests/mysqli_class_mysqli_reflection.phpt index 259fcd9ae6785..e5d2c18d02630 100644 --- a/ext/mysqli/tests/mysqli_class_mysqli_reflection.phpt +++ b/ext/mysqli/tests/mysqli_class_mysqli_reflection.phpt @@ -657,7 +657,7 @@ isDestructor: no isInternal: yes isUserDefined: no returnsReference: no -Modifiers: 257 +Modifiers: 268435713 Number of Parameters: 5 Number of Required Parameters: 4 @@ -1345,4 +1345,4 @@ Default property 'sqlstate' Default property 'stat' Default property 'thread_id' Default property 'warning_count' -done! \ No newline at end of file +done! diff --git a/ext/mysqlnd/mysqlnd.c b/ext/mysqlnd/mysqlnd.c index b41e5424f590e..9e3e6e72dfb7a 100644 --- a/ext/mysqlnd/mysqlnd.c +++ b/ext/mysqlnd/mysqlnd.c @@ -257,6 +257,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, simple_command_handle_response)(MYSQLND_CONN_D conn->persistent); if (!ignore_upsert_status) { + memset(conn->upsert_status, 0, sizeof(*conn->upsert_status)); conn->upsert_status->warning_count = ok_response->warning_count; conn->upsert_status->server_status = ok_response->server_status; conn->upsert_status->affected_rows = ok_response->affected_rows; @@ -319,6 +320,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, simple_command_send_request)(MYSQLND_CONN_DATA DBG_ENTER("mysqlnd_conn_data::simple_command_send_request"); DBG_INF_FMT("command=%s silent=%u", mysqlnd_command_to_text[command], silent); + DBG_INF_FMT("conn->server_status=%u", conn->upsert_status->server_status); switch (CONN_GET_STATE(conn)) { case CONN_READY: @@ -333,10 +335,6 @@ MYSQLND_METHOD(mysqlnd_conn_data, simple_command_send_request)(MYSQLND_CONN_DATA DBG_RETURN(FAIL); } - /* clean UPSERT info */ - if (!ignore_upsert_status) { - memset(conn->upsert_status, 0, sizeof(*conn->upsert_status)); - } SET_ERROR_AFF_ROWS(conn); SET_EMPTY_ERROR(*conn->error_info); @@ -557,7 +555,7 @@ mysqlnd_run_authentication( if (!auth_plugin) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "The server requested authentication method unknown to the client [%s]", requested_protocol); - SET_CLIENT_ERROR(*conn->error_info, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE, "The server requested authentication method umknown to the client"); + SET_CLIENT_ERROR(*conn->error_info, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE, "The server requested authentication method unknown to the client"); goto end; } DBG_INF("plugin found"); @@ -811,6 +809,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, connect_handshake)(MYSQLND_CONN_DATA * conn, { goto err; } + memset(conn->upsert_status, 0, sizeof(*conn->upsert_status)); conn->upsert_status->warning_count = 0; conn->upsert_status->server_status = greet_packet->server_status; conn->upsert_status->affected_rows = 0; @@ -1183,6 +1182,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, send_query)(MYSQLND_CONN_DATA * conn, const ch enum_func_status ret = FAIL; DBG_ENTER("mysqlnd_conn_data::send_query"); DBG_INF_FMT("conn=%llu query=%s", conn->thread_id, query); + DBG_INF_FMT("conn->server_status=%u", conn->upsert_status->server_status); if (PASS == conn->m->local_tx_start(conn, this_func TSRMLS_CC)) { ret = conn->m->simple_command(conn, COM_QUERY, (zend_uchar *) query, query_len, @@ -1193,6 +1193,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, send_query)(MYSQLND_CONN_DATA * conn, const ch } conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC); } + DBG_INF_FMT("conn->server_status=%u", conn->upsert_status->server_status); DBG_RETURN(ret); } /* }}} */ @@ -1208,6 +1209,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, reap_query)(MYSQLND_CONN_DATA * conn TSRMLS_DC DBG_ENTER("mysqlnd_conn_data::reap_query"); DBG_INF_FMT("conn=%llu", conn->thread_id); + DBG_INF_FMT("conn->server_status=%u", conn->upsert_status->server_status); if (PASS == conn->m->local_tx_start(conn, this_func TSRMLS_CC)) { if (state <= CONN_READY || state == CONN_QUIT_SENT) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Connection not opened, clear or has been closed"); @@ -1218,6 +1220,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, reap_query)(MYSQLND_CONN_DATA * conn TSRMLS_DC conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC); } + DBG_INF_FMT("conn->server_status=%u", conn->upsert_status->server_status); DBG_RETURN(ret); } /* }}} */ @@ -1337,7 +1340,7 @@ static int mysqlnd_stream_array_from_fd_set(MYSQLND ** conn_array, fd_set * fds /* {{{ _mysqlnd_poll */ PHPAPI enum_func_status -_mysqlnd_poll(MYSQLND **r_array, MYSQLND **e_array, MYSQLND ***dont_poll, long sec, long usec, uint * desc_num TSRMLS_DC) +_mysqlnd_poll(MYSQLND **r_array, MYSQLND **e_array, MYSQLND ***dont_poll, long sec, long usec, int * desc_num TSRMLS_DC) { struct timeval tv; struct timeval *tv_p = NULL; @@ -1603,6 +1606,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, escape_string)(MYSQLND_CONN_DATA * const conn, DBG_INF_FMT("conn=%llu", conn->thread_id); if (PASS == conn->m->local_tx_start(conn, this_func TSRMLS_CC)) { + DBG_INF_FMT("server_status=%u", conn->upsert_status->server_status); if (conn->upsert_status->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES) { ret = mysqlnd_cset_escape_quotes(conn->charset, newstr, escapestr, escapestr_len TSRMLS_CC); } else { @@ -2247,7 +2251,6 @@ MYSQLND_METHOD(mysqlnd_conn_data, change_user)(MYSQLND_CONN_DATA * const conn, } if (!db) { db = ""; - } /* XXX: passwords that have \0 inside work during auth, but in this case won't work with change user */ diff --git a/ext/mysqlnd/mysqlnd.h b/ext/mysqlnd/mysqlnd.h index 40933630edef5..1514feb3700aa 100644 --- a/ext/mysqlnd/mysqlnd.h +++ b/ext/mysqlnd/mysqlnd.h @@ -117,7 +117,7 @@ PHPAPI void _mysqlnd_debug(const char *mode TSRMLS_DC); #define mysqlnd_reap_async_query(conn) ((conn)->data)->m->reap_query((conn)->data TSRMLS_CC) #define mysqlnd_unbuffered_skip_result(result) (result)->m.skip_result((result) TSRMLS_CC) -PHPAPI enum_func_status _mysqlnd_poll(MYSQLND **r_array, MYSQLND **e_array, MYSQLND ***dont_poll, long sec, long usec, uint * desc_num TSRMLS_DC); +PHPAPI enum_func_status _mysqlnd_poll(MYSQLND **r_array, MYSQLND **e_array, MYSQLND ***dont_poll, long sec, long usec, int * desc_num TSRMLS_DC); #define mysqlnd_use_result(conn) ((conn)->data)->m->use_result((conn)->data TSRMLS_CC) #define mysqlnd_store_result(conn) ((conn)->data)->m->store_result((conn)->data TSRMLS_CC) diff --git a/ext/mysqlnd/mysqlnd_net.c b/ext/mysqlnd/mysqlnd_net.c index fabceb4c8d661..cb6d0dc3a7186 100644 --- a/ext/mysqlnd/mysqlnd_net.c +++ b/ext/mysqlnd/mysqlnd_net.c @@ -900,7 +900,11 @@ MYSQLND_METHOD(mysqlnd_net, enable_ssl)(MYSQLND_NET * const net TSRMLS_DC) ZVAL_STRING(&cipher_zval, net->data->options.ssl_cipher, 0); php_stream_context_set_option(context, "ssl", "ciphers", &cipher_zval); } +#if PHP_API_VERSION >= 20131106 + php_stream_context_set(net_stream, context TSRMLS_CC); +#else php_stream_context_set(net_stream, context); +#endif if (php_stream_xport_crypto_setup(net_stream, STREAM_CRYPTO_METHOD_TLS_CLIENT, NULL TSRMLS_CC) < 0 || php_stream_xport_crypto_enable(net_stream, 1 TSRMLS_CC) < 0) { @@ -916,7 +920,11 @@ MYSQLND_METHOD(mysqlnd_net, enable_ssl)(MYSQLND_NET * const net TSRMLS_DC) of the context, which means usage of already freed memory, bad. Actually we don't need this context anymore after we have enabled SSL on the connection. Thus it is very simple, we remove it. */ +#if PHP_API_VERSION >= 20131106 + php_stream_context_set(net_stream, NULL TSRMLS_CC); +#else php_stream_context_set(net_stream, NULL); +#endif if (net->data->options.timeout_read) { struct timeval tv; diff --git a/ext/mysqlnd/mysqlnd_ps.c b/ext/mysqlnd/mysqlnd_ps.c index 15b293825b4ab..1eca92776f6b2 100644 --- a/ext/mysqlnd/mysqlnd_ps.c +++ b/ext/mysqlnd/mysqlnd_ps.c @@ -486,6 +486,7 @@ mysqlnd_stmt_execute_parse_response(MYSQLND_STMT * const s TSRMLS_DC) ret = mysqlnd_query_read_result_set_header(stmt->conn, s TSRMLS_CC); if (ret == FAIL) { COPY_CLIENT_ERROR(*stmt->error_info, *conn->error_info); + memset(stmt->upsert_status, 0, sizeof(*stmt->upsert_status)); stmt->upsert_status->affected_rows = conn->upsert_status->affected_rows; if (CONN_GET_STATE(conn) == CONN_QUIT_SENT) { /* close the statement here, the connection has been closed */ @@ -905,6 +906,7 @@ mysqlnd_stmt_fetch_row_unbuffered(MYSQLND_RES *result, void *param, unsigned int DBG_INF("EOF"); /* Mark the connection as usable again */ result->unbuf->eof_reached = TRUE; + memset(result->conn->upsert_status, 0, sizeof(*result->conn->upsert_status)); result->conn->upsert_status->warning_count = row_packet->warning_count; result->conn->upsert_status->server_status = row_packet->server_status; /* @@ -1014,6 +1016,7 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES *result, void *param, unsigned int fla row_packet->skip_extraction = stmt->result_bind? FALSE:TRUE; + memset(stmt->upsert_status, 0, sizeof(*stmt->upsert_status)); if (PASS == (ret = PACKET_READ(row_packet, result->conn)) && !row_packet->eof) { unsigned int i, field_count = result->field_count; diff --git a/ext/mysqlnd/mysqlnd_ps_codec.c b/ext/mysqlnd/mysqlnd_ps_codec.c index d8ad06c608102..a3a973e811818 100644 --- a/ext/mysqlnd/mysqlnd_ps_codec.c +++ b/ext/mysqlnd/mysqlnd_ps_codec.c @@ -569,9 +569,8 @@ mysqlnd_stmt_execute_store_params(MYSQLND_STMT * s, zend_uchar **buf, zend_uchar occur, and force resend for the next execution. */ for (i = 0; i < stmt->param_count; i++) { - if (Z_TYPE_P(stmt->param_bind[i].zv) != IS_NULL && - (stmt->param_bind[i].type == MYSQL_TYPE_LONG || stmt->param_bind[i].type == MYSQL_TYPE_LONGLONG)) - { + short current_type = stmt->param_bind[i].type; + if (Z_TYPE_P(stmt->param_bind[i].zv) != IS_NULL && (current_type == MYSQL_TYPE_LONG || current_type == MYSQL_TYPE_LONGLONG)) { /* always copy the var, because we do many conversions */ if (Z_TYPE_P(stmt->param_bind[i].zv) != IS_LONG && PASS != mysqlnd_stmt_copy_it(&copies, stmt->param_bind[i].zv, stmt->param_count, i TSRMLS_CC)) @@ -585,10 +584,31 @@ mysqlnd_stmt_execute_store_params(MYSQLND_STMT * s, zend_uchar **buf, zend_uchar */ if (Z_TYPE_P(stmt->param_bind[i].zv) != IS_LONG) { zval *tmp_data = (copies && copies[i])? copies[i]: stmt->param_bind[i].zv; - convert_to_double_ex(&tmp_data); - if (Z_DVAL_P(tmp_data) > LONG_MAX || Z_DVAL_P(tmp_data) < LONG_MIN) { + /* + Because converting to double and back to long can lead + to losing precision we need second variable. Conversion to double is to see if + value is too big for a long. As said, precision could be lost. + */ + zval *tmp_data_copy; + MAKE_STD_ZVAL(tmp_data_copy); + *tmp_data_copy = *tmp_data; + Z_SET_REFCOUNT_P(tmp_data_copy, 1); + zval_copy_ctor(tmp_data_copy); + convert_to_double_ex(&tmp_data_copy); + + /* + if it doesn't fit in a long send it as a string. + Check bug #52891 : Wrong data inserted with mysqli/mysqlnd when using bind_param, value > LONG_MAX + We do transformation here, which will be used later when sending types. The code later relies on this. + */ + if (Z_DVAL_P(tmp_data_copy) > LONG_MAX || Z_DVAL_P(tmp_data_copy) < LONG_MIN) { stmt->send_types_to_server = resend_types_next_time = 1; + convert_to_string_ex(&tmp_data); + } else { + convert_to_long_ex(&tmp_data); } + + zval_ptr_dtor(&tmp_data_copy); } } } @@ -631,10 +651,11 @@ mysqlnd_stmt_execute_store_params(MYSQLND_STMT * s, zend_uchar **buf, zend_uchar */ if (Z_TYPE_P(stmt->param_bind[i].zv) != IS_LONG) { zval *tmp_data = (copies && copies[i])? copies[i]: stmt->param_bind[i].zv; - - convert_to_double_ex(&tmp_data); - if (Z_DVAL_P(tmp_data) > LONG_MAX || Z_DVAL_P(tmp_data) < LONG_MIN) { - convert_to_string_ex(&tmp_data); + /* + In case of IS_LONG we do nothing, it is ok, in case of string, we just need to set current_type. + The actual transformation has been performed several dozens line above. + */ + if (Z_TYPE_P(tmp_data) == IS_STRING) { current_type = MYSQL_TYPE_VAR_STRING; /* don't change stmt->param_bind[i].type to MYSQL_TYPE_VAR_STRING @@ -642,8 +663,6 @@ mysqlnd_stmt_execute_store_params(MYSQLND_STMT * s, zend_uchar **buf, zend_uchar if the type is however not long, then we will do a goto in the next switch. We want to preserve the original bind type given by the user. Thus, we do these hacks. */ - } else { - convert_to_long_ex(&tmp_data); } } } diff --git a/ext/mysqlnd/mysqlnd_result.c b/ext/mysqlnd/mysqlnd_result.c index 20d941e05b6f0..4d9c65593225c 100644 --- a/ext/mysqlnd/mysqlnd_result.c +++ b/ext/mysqlnd/mysqlnd_result.c @@ -415,6 +415,7 @@ mysqlnd_query_read_result_set_header(MYSQLND_CONN_DATA * conn, MYSQLND_STMT * s DBG_INF("UPSERT"); conn->last_query_type = QUERY_UPSERT; conn->field_count = rset_header->field_count; + memset(conn->upsert_status, 0, sizeof(*conn->upsert_status)); conn->upsert_status->warning_count = rset_header->warning_count; conn->upsert_status->server_status = rset_header->server_status; conn->upsert_status->affected_rows = rset_header->affected_rows; @@ -702,6 +703,7 @@ mysqlnd_fetch_row_unbuffered_c(MYSQLND_RES * result TSRMLS_DC) /* Mark the connection as usable again */ DBG_INF_FMT("warnings=%u server_status=%u", row_packet->warning_count, row_packet->server_status); result->unbuf->eof_reached = TRUE; + memset(result->conn->upsert_status, 0, sizeof(*result->conn->upsert_status)); result->conn->upsert_status->warning_count = row_packet->warning_count; result->conn->upsert_status->server_status = row_packet->server_status; /* @@ -828,6 +830,7 @@ mysqlnd_fetch_row_unbuffered(MYSQLND_RES * result, void *param, unsigned int fla /* Mark the connection as usable again */ DBG_INF_FMT("warnings=%u server_status=%u", row_packet->warning_count, row_packet->server_status); result->unbuf->eof_reached = TRUE; + memset(result->conn->upsert_status, 0, sizeof(*result->conn->upsert_status)); result->conn->upsert_status->warning_count = row_packet->warning_count; result->conn->upsert_status->server_status = row_packet->server_status; /* @@ -1175,6 +1178,7 @@ MYSQLND_METHOD(mysqlnd_res, store_result_fetch_data)(MYSQLND_CONN_DATA * const c /* Finally clean */ if (row_packet->eof) { + memset(conn->upsert_status, 0, sizeof(*conn->upsert_status)); conn->upsert_status->warning_count = row_packet->warning_count; conn->upsert_status->server_status = row_packet->server_status; } diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.c b/ext/mysqlnd/mysqlnd_wireprotocol.c index 669970789bac5..0d29973cdea1e 100644 --- a/ext/mysqlnd/mysqlnd_wireprotocol.c +++ b/ext/mysqlnd/mysqlnd_wireprotocol.c @@ -827,6 +827,7 @@ php_mysqlnd_ok_read(void * _packet, MYSQLND_CONN_DATA * conn TSRMLS_DC) packet->error, sizeof(packet->error), &packet->error_no, packet->sqlstate TSRMLS_CC); + DBG_INF_FMT("conn->server_status=%u", conn->upsert_status->server_status); DBG_RETURN(PASS); } /* Everything was fine! */ @@ -1069,6 +1070,7 @@ php_mysqlnd_rset_header_read(void * _packet, MYSQLND_CONN_DATA * conn TSRMLS_DC) packet->error_info.error, sizeof(packet->error_info.error), &packet->error_info.error_no, packet->error_info.sqlstate TSRMLS_CC); + DBG_INF_FMT("conn->server_status=%u", conn->upsert_status->server_status); DBG_RETURN(PASS); } diff --git a/ext/oci8/LICENSE b/ext/oci8/LICENSE new file mode 100644 index 0000000000000..42536af320686 --- /dev/null +++ b/ext/oci8/LICENSE @@ -0,0 +1,68 @@ +-------------------------------------------------------------------- + The PHP License, version 3.01 +Copyright (c) 1999 - 2012 The PHP Group. All rights reserved. +-------------------------------------------------------------------- + +Redistribution and use in source and binary forms, with or without +modification, is permitted provided that the following conditions +are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + 3. The name "PHP" must not be used to endorse or promote products + derived from this software without prior written permission. For + written permission, please contact group@php.net. + + 4. Products derived from this software may not be called "PHP", nor + may "PHP" appear in their name, without prior written permission + from group@php.net. You may indicate that your software works in + conjunction with PHP by saying "Foo for PHP" instead of calling + it "PHP Foo" or "phpfoo" + + 5. The PHP Group may publish revised and/or new versions of the + license from time to time. Each version will be given a + distinguishing version number. + Once covered code has been published under a particular version + of the license, you may always continue to use it under the terms + of that version. You may also choose to use such covered code + under the terms of any subsequent version of the license + published by the PHP Group. No one other than the PHP Group has + the right to modify the terms applicable to covered code created + under this License. + + 6. Redistributions of any form whatsoever must retain the following + acknowledgment: + "This product includes PHP software, freely available from + ". + +THIS SOFTWARE IS PROVIDED BY THE PHP DEVELOPMENT TEAM ``AS IS'' AND +ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PHP +DEVELOPMENT TEAM OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +OF THE POSSIBILITY OF SUCH DAMAGE. + +-------------------------------------------------------------------- + +This software consists of voluntary contributions made by many +individuals on behalf of the PHP Group. + +The PHP Group can be contacted via Email at group@php.net. + +For more information on the PHP Group and the PHP project, +please see . + +PHP includes the Zend Engine, freely available at +. diff --git a/ext/oci8/README b/ext/oci8/README index af5beeb5c0745..d662072743fd1 100644 --- a/ext/oci8/README +++ b/ext/oci8/README @@ -1,13 +1,20 @@ The OCI8 Extension ------------------ -Use the OCI8 extension to access Oracle Database. +Use the OCI8 extension to access Oracle Database. Documentation is at http://php.net/oci8 -The extension can be built with PHP versions 4.3.9 to 5.x using Oracle -Database 9.2, 10, 11 or 12 client libraries. Oracle's standard -cross-version connectivity applies. For example PHP linked with -Oracle 11.2 client libraries can connect to Oracle Database 9.2 -onwards. See Oracle's note "Oracle Client / Server Interoperability -Support" (ID 207303.1) for details. +The extension can be linked with Oracle client libraries from Oracle +Database 10.2, 11, or 12.1. These libraries are found in the database +installation, or in the free Oracle Instant Client available from +Oracle. + +Oracle's standard cross-version connectivity applies. For example, +PHP OCI8 linked with Instant Client 11.2 can connect to Oracle +Database 9.2 onward. See Oracle's note "Oracle Client / Server +Interoperability Support" (ID 207303.1) for details. + +PHP OCI8 2.0 can be built with PHP 5.2 onward. Use the older PHP OCI8 +1.4.10 when using PHP 4.3.9 through to PHP 5.1.x, or when only Oracle +Database 9.2 client libraries are available. diff --git a/ext/oci8/config.m4 b/ext/oci8/config.m4 index 49998d18f08ba..0d08d21c29e61 100644 --- a/ext/oci8/config.m4 +++ b/ext/oci8/config.m4 @@ -124,7 +124,7 @@ dnl in GNU Make which causes the .d file to be overwritten (Bug 61268) PHP_EXT_SRCDIR([oci8])/$ac_provsrc:; $ac_bdir[$]ac_hdrobj: $ac_srcdir[$]ac_provsrc - CFLAGS="\$(CFLAGS_CLEAN)" dtrace -h -C -s $ac_srcdir[$]ac_provsrc -o \$[]@.bak && \$(SED) -e 's,PHP_,DTRACE_,g' \$[]@.bak > \$[]@ + CFLAGS="\$(CFLAGS_CLEAN)" dtrace -h -C -s $ac_srcdir[$]ac_provsrc -o \$[]@.bak && \$(SED) -e 's,PHPOCI_,DTRACE_,g' \$[]@.bak > \$[]@ \$(OCI8_DTRACE_OBJS): $ac_bdir[$]ac_hdrobj @@ -208,8 +208,8 @@ if test "$PHP_OCI8" != "no"; then IFS=$ac_IFS oci8_php_version=`expr [$]1 \* 1000000 + [$]2 \* 1000 + [$]3` - if test "$oci8_php_version" -lt "4003009"; then - AC_MSG_ERROR([You need at least PHP 4.3.9 to be able to use this version of OCI8. PHP $php_version found]) + if test "$oci8_php_version" -lt "5002000"; then + AC_MSG_ERROR([You need at least PHP 5.2.0 to be able to use this version of OCI8. PHP $php_version found]) else AC_MSG_RESULT([$php_version, ok]) fi @@ -332,24 +332,8 @@ if test "$PHP_OCI8" != "no"; then AC_OCI8_ORACLE_VERSION($OCI8_DIR) case $OCI8_ORACLE_VERSION in - 7.3|8.0|8.1) - AC_MSG_ERROR([Oracle client libraries < 9.2 are not supported]) - ;; - - 9.0) - PHP_CHECK_LIBRARY(clntsh, OCIEnvNlsCreate, - [ - OCI8_ORACLE_VERSION=9.2 - ], - [ - AC_MSG_ERROR([Oracle client libraries < 9.2 are not supported]) - ], [ - -L$OCI8_DIR/$OCI8_LIB_DIR $OCI8_SHARED_LIBADD - ]) - ;; - - *) - AC_DEFINE(HAVE_OCI_LOB_READ2,1,[Defined to 1 if OCI8 configuration located Oracle's OCILobRead2 function]) + 7.3|8.0|8.1|9.0) + AC_MSG_ERROR([Oracle client libraries < 10 are not supported]) ;; esac @@ -425,7 +409,6 @@ if test "$PHP_OCI8" != "no"; then PHP_ADD_LIBPATH($PHP_OCI8_INSTANT_CLIENT, OCI8_SHARED_LIBADD) AC_DEFINE(HAVE_OCI_INSTANT_CLIENT,1,[Defined to 1 if OCI8 configuration located Oracle's Instant Client libraries]) - AC_DEFINE(HAVE_OCI_LOB_READ2,1,[Defined to 1 if OCI8 configuration located Oracle's OCILobRead2 function]) PHP_NEW_EXTENSION(oci8, oci8.c oci8_lob.c oci8_statement.c oci8_collection.c oci8_interface.c, $ext_shared) AC_DEFINE(HAVE_OCI8,1,[Defined to 1 if the PHP OCI8 extension for Oracle Database is configured]) diff --git a/ext/oci8/config.w32 b/ext/oci8/config.w32 index ac573a8af39a1..d83bf3fbdb7d5 100644 --- a/ext/oci8/config.w32 +++ b/ext/oci8/config.w32 @@ -1,6 +1,97 @@ // $Id$ // vim:ft=javascript +if (PHP_OCI8 != "no" && PHP_OCI8_11G != "no") { + if (!PHP_OCI8_SHARED && !PHP_OCI8_11G_SHARED) { + WARNING("oci8 and oci8-11g provide the same extension and cannot both be built statically"); + PHP_OCI8 = "no" + } +} + +if (PHP_OCI8 != "no" && PHP_OCI8_12C != "no") { + if (!PHP_OCI8_SHARED && !PHP_OCI8_12C_SHARED) { + WARNING("oci8 and oci8-12c provide the same extension and cannot both be built statically"); + PHP_OCI8 = "no" + } +} + +if (PHP_OCI8_11G != "no" && PHP_OCI8_12C != "no") { + if (!PHP_OCI8_11G_SHARED && !PHP_OCI8_12C_SHARED) { + WARNING("oci8-11g and oci8-12c provide the same extension and cannot both be built statically"); + PHP_OCI8_11G = "no" + } +} + +ARG_WITH("oci8", "OCI8 support", "no"); + +if (PHP_OCI8 != "no") { + + oci8_dirs = new Array( + PHP_OCI8 + ); + + oci8_lib_paths = ""; + oci8_inc_paths = ""; + + // find the Oracle install + for (i = 0; i < oci8_dirs.length; i++) { + oci8_lib_paths += oci8_dirs[i] + "\\lib;"; + oci8_lib_paths += oci8_dirs[i] + "\\lib\\msvc;"; + oci8_inc_paths += oci8_dirs[i] + "\\include;"; + } + + oci8_inc_paths += PHP_PHP_BUILD + "\\include\\instantclient;" + oci8_lib_paths += PHP_PHP_BUILD + "\\lib\\instantclient;"; + + if (CHECK_HEADER_ADD_INCLUDE("oci.h", "CFLAGS_OCI8", oci8_inc_paths) && + CHECK_LIB("oci.lib", "oci8", oci8_lib_paths)) + { + EXTENSION('oci8', 'oci8.c oci8_lob.c oci8_statement.c oci8_collection.c oci8_interface.c'); + + AC_DEFINE('HAVE_OCI8', 1); + AC_DEFINE('HAVE_OCI_INSTANT_CLIENT', 1); + + } else { + WARNING("oci8 not enabled: Oracle Database client libraries or Oracle 10g Instant Client not found"); + PHP_OCI8 = "no" + } +} + +ARG_WITH("oci8-11g", "OCI8 support using Oracle 11g Instant Client", "no"); + +if (PHP_OCI8_11G != "no") { + + oci8_11g_dirs = new Array( + PHP_OCI8_11G + ); + + oci8_11g_lib_paths = ""; + oci8_11g_inc_paths = ""; + + // find the Oracle install + for (i = 0; i < oci8_11g_dirs.length; i++) { + oci8_11g_lib_paths += oci8_11g_dirs[i] + "\\lib;"; + oci8_11g_lib_paths += oci8_11g_dirs[i] + "\\lib\\msvc;"; + oci8_11g_inc_paths += oci8_11g_dirs[i] + "\\include;"; + } + + oci8_11g_inc_paths += PHP_PHP_BUILD + "\\include\\instantclient_11;" + oci8_11g_lib_paths += PHP_PHP_BUILD + "\\lib\\instantclient_11;"; + + if (CHECK_HEADER_ADD_INCLUDE("oci.h", "CFLAGS_OCI8_11G", oci8_11g_inc_paths) && + CHECK_LIB("oci.lib", "oci8_11g", oci8_11g_lib_paths)) + { + EXTENSION('oci8_11g', 'oci8.c oci8_lob.c oci8_statement.c oci8_collection.c oci8_interface.c', null, null, null, "ext\\oci8_11g") + + AC_DEFINE('HAVE_OCI8', 1); + AC_DEFINE('HAVE_OCI_INSTANT_CLIENT', 1); + + } else { + WARNING("oci8-11g not enabled: Oracle Database client libraries or Oracle 11g Instant Client not found"); + PHP_OCI8_11G = "no" + } +} + ARG_WITH("oci8-12c", "OCI8 support using Oracle Database 12c Instant Client", "no"); if (PHP_OCI8_12C != "no") { @@ -29,8 +120,6 @@ if (PHP_OCI8_12C != "no") { AC_DEFINE('HAVE_OCI8', 1); AC_DEFINE('HAVE_OCI_INSTANT_CLIENT', 1); - AC_DEFINE('HAVE_OCI_LOB_READ2', 1); - } else { WARNING("oci8-12c not enabled: Oracle Database client libraries or Oracle Database 12c Instant Client not found"); PHP_OCI8_12C = "no" diff --git a/ext/oci8/oci8.c b/ext/oci8/oci8.c index bccaa529b0c93..1e505f13e9978 100644 --- a/ext/oci8/oci8.c +++ b/ext/oci8/oci8.c @@ -12,7 +12,7 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Stig S�ther Bakken | + | Authors: Stig Sæther Bakken | | Thies C. Arntzen | | Maxim Maletsky | | | @@ -39,12 +39,9 @@ #if HAVE_OCI8 -#if PHP_MAJOR_VERSION > 5 -#error This version of the PHP OCI8 extension is not compatible with PHP 6 or later -#elif PHP_MAJOR_VERSION < 5 -#ifdef ZTS -#error The PHP OCI8 extension does not support ZTS mode in PHP 4 -#endif +/* PHP 5.2 is the minimum supported version for OCI8 2.0 */ +#if PHP_MAJOR_VERSION < 5 || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION <= 1) +#error Use PHP OCI8 1.4 for your version of PHP #endif #include "php_oci8.h" @@ -66,11 +63,8 @@ #endif ZEND_DECLARE_MODULE_GLOBALS(oci) -#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION > 5) -/* This "if" allows PECL builds from this file to be portable to older PHP releases */ static PHP_GINIT_FUNCTION(oci); static PHP_GSHUTDOWN_FUNCTION(oci); -#endif /* Allow PHP 5.3 branch to be used in PECL for 5.x compatible builds */ #ifndef Z_ADDREF_P @@ -151,7 +145,7 @@ static sword php_oci_ping_init(php_oci_connection *connection, OCIError *errh TS /* }}} */ /* {{{ dynamically loadable module stuff */ -#if defined(COMPILE_DL_OCI8) || defined(COMPILE_DL_OCI8_11G) +#if defined(COMPILE_DL_OCI8) || defined(COMPILE_DL_OCI8_11G) || defined(COMPILE_DL_OCI8_12C) ZEND_GET_MODULE(oci8) #endif /* COMPILE_DL */ /* }}} */ @@ -457,6 +451,13 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_set_client_info, 0, 0, 2) ZEND_ARG_INFO(0, client_information) ZEND_END_ARG_INFO() +#ifdef WAITIING_ORACLE_BUG_16695981_FIX +ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_set_db_operation, 0, 0, 2) +ZEND_ARG_INFO(0, connection_resource) +ZEND_ARG_INFO(0, action) +ZEND_END_ARG_INFO() +#endif + ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_password_change, 0, 0, 4) ZEND_ARG_INFO(0, connection_resource_or_connection_string) ZEND_ARG_INFO(0, username) @@ -708,6 +709,9 @@ static unsigned char arginfo_oci_bind_array_by_name[] = { 3, BYREF_NONE, BYREF_N #define arginfo_oci_set_module_name NULL #define arginfo_oci_set_action NULL #define arginfo_oci_set_client_info NULL +#ifdef WAITIING_ORACLE_BUG_16695981_FIX +#define arginfo_oci_set_db_operation NULL +#endif #define arginfo_oci_password_change NULL #define arginfo_oci_new_cursor NULL #define arginfo_oci_result NULL @@ -799,6 +803,9 @@ PHP_FUNCTION(oci_statement_type); PHP_FUNCTION(oci_num_rows); PHP_FUNCTION(oci_set_prefetch); PHP_FUNCTION(oci_set_client_identifier); +#ifdef WAITIING_ORACLE_BUG_16695981_FIX +PHP_FUNCTION(oci_set_db_operation); +#endif PHP_FUNCTION(oci_set_edition); PHP_FUNCTION(oci_set_module_name); PHP_FUNCTION(oci_set_action); @@ -904,6 +911,9 @@ zend_function_entry php_oci_functions[] = { PHP_FE(oci_new_descriptor, arginfo_oci_new_descriptor) PHP_FE(oci_set_prefetch, arginfo_oci_set_prefetch) PHP_FE(oci_set_client_identifier, arginfo_oci_set_client_identifier) +#ifdef WAITIING_ORACLE_BUG_16695981_FIX + PHP_FE(oci_set_db_operation, arginfo_oci_set_db_operation) +#endif PHP_FE(oci_set_edition, arginfo_oci_set_edition) PHP_FE(oci_set_module_name, arginfo_oci_set_module_name) PHP_FE(oci_set_action, arginfo_oci_set_action) @@ -1039,16 +1049,11 @@ zend_module_entry oci8_module_entry = { PHP_RSHUTDOWN(oci), /* per-request shutdown function */ PHP_MINFO(oci), /* information function */ PHP_OCI8_VERSION, -#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION > 5) - /* This check allows PECL builds from this file to be portable to older PHP releases */ PHP_MODULE_GLOBALS(oci), /* globals descriptor */ PHP_GINIT(oci), /* globals ctor */ PHP_GSHUTDOWN(oci), /* globals dtor */ NULL, /* post deactivate */ STANDARD_MODULE_PROPERTIES_EX -#else - STANDARD_MODULE_PROPERTIES -#endif }; /* }}} */ @@ -1167,12 +1172,7 @@ static void php_oci_cleanup_global_handles(TSRMLS_D) * * Zerofill globals during module init */ -#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION > 5) -/* This check allows PECL builds from this file to be portable to older PHP releases */ static PHP_GINIT_FUNCTION(oci) -#else -static void php_oci_init_globals(zend_oci_globals *oci_globals TSRMLS_DC) -#endif { memset(oci_globals, 0, sizeof(zend_oci_globals)); } @@ -1182,12 +1182,7 @@ static void php_oci_init_globals(zend_oci_globals *oci_globals TSRMLS_DC) * * Called for thread shutdown in ZTS, after module shutdown for non-ZTS */ -/* This check allows PECL builds from this file to be portable to older PHP releases */ -#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION > 5) static PHP_GSHUTDOWN_FUNCTION(oci) -#else -static void php_oci_shutdown_globals(zend_oci_globals *oci_globals TSRMLS_DC) -#endif { php_oci_cleanup_global_handles(TSRMLS_C); } @@ -1198,12 +1193,6 @@ PHP_MINIT_FUNCTION(oci) zend_class_entry oci_lob_class_entry; zend_class_entry oci_coll_class_entry; -#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION > 5) - /* This check allows PECL builds from this file to be portable to older PHP releases */ - /* this is handled by new globals management code */ -#else - ZEND_INIT_MODULE_GLOBALS(oci, php_oci_init_globals, php_oci_shutdown_globals); -#endif REGISTER_INI_ENTRIES(); le_statement = zend_register_list_destructors_ex(php_oci_statement_list_dtor, NULL, "oci8 statement", module_number); @@ -1315,13 +1304,6 @@ PHP_RINIT_FUNCTION(oci) PHP_MSHUTDOWN_FUNCTION(oci) { -/* Work around PHP_GSHUTDOWN_FUNCTION not being called in older versions of PHP */ -#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 2) || (PHP_MAJOR_VERSION < 5) -#ifndef ZTS - php_oci_cleanup_global_handles(TSRMLS_C); -#endif -#endif - OCI_G(shutdown) = 1; UNREGISTER_INI_ENTRIES(); @@ -2097,6 +2079,9 @@ php_oci_connection *php_oci_do_connect_ex(char *username, int username_len, char connection = (php_oci_connection *) ecalloc(1, sizeof(php_oci_connection)); connection->hash_key = estrndup(hashed_details.c, hashed_details.len); connection->is_persistent = 0; +#ifdef HAVE_OCI8_DTRACE + connection->client_id = NULL; +#endif } else { connection = (php_oci_connection *) calloc(1, sizeof(php_oci_connection)); if (connection == NULL) { @@ -2108,11 +2093,17 @@ php_oci_connection *php_oci_do_connect_ex(char *username, int username_len, char return NULL; } connection->is_persistent = 1; +#ifdef HAVE_OCI8_DTRACE + connection->client_id = NULL; +#endif } } else { connection = (php_oci_connection *) ecalloc(1, sizeof(php_oci_connection)); connection->hash_key = estrndup(hashed_details.c, hashed_details.len); connection->is_persistent = 0; +#ifdef HAVE_OCI8_DTRACE + connection->client_id = NULL; +#endif } /* {{{ Get the session pool that suits this connection request from the persistent list. This @@ -2210,6 +2201,9 @@ php_oci_connection *php_oci_do_connect_ex(char *username, int username_len, char static int php_oci_connection_ping(php_oci_connection *connection TSRMLS_DC) { sword errstatus; +#if (!((OCI_MAJOR_VERSION > 10) || ((OCI_MAJOR_VERSION == 10) && (OCI_MINOR_VERSION >= 2)))) + char version[256]; +#endif OCI_G(errcode) = 0; /* assume ping is successful */ @@ -2221,7 +2215,6 @@ static int php_oci_connection_ping(php_oci_connection *connection TSRMLS_DC) #if ((OCI_MAJOR_VERSION > 10) || ((OCI_MAJOR_VERSION == 10) && (OCI_MINOR_VERSION >= 2))) /* OCIPing available 10.2 onwards */ PHP_OCI_CALL_RETURN(errstatus, OCIPing, (connection->svc, OCI_G(err), OCI_DEFAULT)); #else - char version[256]; /* use good old OCIServerVersion() */ PHP_OCI_CALL_RETURN(errstatus, OCIServerVersion, (connection->svc, OCI_G(err), (text *)version, sizeof(version), OCI_HTYPE_SVCCTX)); #endif @@ -2366,17 +2359,15 @@ static int php_oci_connection_close(php_oci_connection *connection TSRMLS_DC) php_oci_spool_close(connection->private_spool TSRMLS_CC); } - if (connection->is_persistent) { - if (connection->hash_key) { - free(connection->hash_key); - } - free(connection); - } else { - if (connection->hash_key) { - efree(connection->hash_key); - } - efree(connection); + if (connection->hash_key) { + pefree(connection->hash_key, connection->is_persistent); + } +#ifdef HAVE_OCI8_DTRACE + if (connection->client_id) { + pefree(connection->client_id, connection->is_persistent); } +#endif /* HAVE_OCI8_DTRACE */ + pefree(connection, connection->is_persistent); connection = NULL; OCI_G(in_call) = in_call_save; return result; @@ -2463,6 +2454,12 @@ int php_oci_connection_release(php_oci_connection *connection TSRMLS_DC) * the OCI session */ connection->next_pingp = NULL; +#ifdef HAVE_OCI8_DTRACE + if (connection->client_id) { + pefree(connection->client_id, connection->is_persistent); + connection->client_id = NULL; + } +#endif /* HAVE_OCI8_DTRACE */ } OCI_G(in_call) = in_call_save; @@ -3500,7 +3497,7 @@ void php_oci_dtrace_check_connection(php_oci_connection *connection, sb4 errcode { #ifdef HAVE_OCI8_DTRACE if (DTRACE_OCI8_CHECK_CONNECTION_ENABLED()) { - DTRACE_OCI8_CHECK_CONNECTION(connection, connection && connection->is_open ? 1 : 0, (long)errcode, (unsigned long)serverStatus); + DTRACE_OCI8_CHECK_CONNECTION(connection, connection->client_id, connection->is_open ? 1 : 0, (long)errcode, (unsigned long)serverStatus); } #endif /* HAVE_OCI8_DTRACE */ } diff --git a/ext/oci8/oci8_collection.c b/ext/oci8/oci8_collection.c index 320e90a5b8999..35b70fa7af73f 100644 --- a/ext/oci8/oci8_collection.c +++ b/ext/oci8/oci8_collection.c @@ -361,13 +361,7 @@ int php_oci_collection_append_number(php_oci_collection *collection, char *numbe php_oci_connection *connection = collection->connection; sword errstatus; -#if (PHP_MAJOR_VERSION == 4 && PHP_MINOR_VERSION == 3 && PHP_RELEASE_VERSION < 10) - /* minimum PHP version ext/oci8/config.m4 accepts is 4.3.9 */ - element_double = strtod(number, NULL); -#else - /* zend_strtod was introduced in PHP 4.3.10 */ element_double = zend_strtod(number, NULL); -#endif PHP_OCI_CALL_RETURN(errstatus, OCINumberFromReal, (connection->err, &element_double, sizeof(double), &oci_number)); @@ -666,13 +660,7 @@ int php_oci_collection_element_set_number(php_oci_collection *collection, long i php_oci_connection *connection = collection->connection; sword errstatus; -#if (PHP_MAJOR_VERSION == 4 && PHP_MINOR_VERSION == 3 && PHP_RELEASE_VERSION < 10) - /* minimum PHP version ext/oci8/config.m4 accepts is 4.3.9 */ - element_double = strtod(number, NULL); -#else - /* zend_strtod was introduced in PHP 4.3.10 */ element_double = zend_strtod(number, NULL); -#endif PHP_OCI_CALL_RETURN(errstatus, OCINumberFromReal, (connection->err, &element_double, sizeof(double), &oci_number)); diff --git a/ext/oci8/oci8_dtrace.d b/ext/oci8/oci8_dtrace.d index 8ac94105c13cd..30c98de912828 100644 --- a/ext/oci8/oci8_dtrace.d +++ b/ext/oci8/oci8_dtrace.d @@ -16,14 +16,14 @@ +----------------------------------------------------------------------+ */ -provider php { - probe oci8__check__connection(void *connection, int is_open, long errcode, unsigned long server_status); +provider phpoci { + probe oci8__check__connection(void *connection, char *client_id, int is_open, long errcode, unsigned long server_status); probe oci8__connect__entry(char *username, char *dbname, char *charset, long session_mode, int persistent, int exclusive); probe oci8__connect__return(void *connection); probe oci8__connection__close(void *connection); probe oci8__error(int status, long errcode); - probe oci8__execute__mode(void *connection, unsigned int mode); - probe oci8__sqltext(void *connection, char *sql); + probe oci8__execute__mode(void *connection, char *client_id, void *statement, unsigned int mode); + probe oci8__sqltext(void *connection, char *client_id, void *statement, char *sql); probe oci8__connect__p__dtor__close(void *connection); probe oci8__connect__p__dtor__release(void *connection); diff --git a/ext/oci8/oci8_interface.c b/ext/oci8/oci8_interface.c index 8d70aff9c2b42..ccaed797429f1 100644 --- a/ext/oci8/oci8_interface.c +++ b/ext/oci8/oci8_interface.c @@ -1429,13 +1429,7 @@ PHP_FUNCTION(oci_fetch_all) if (flags & PHP_OCI_NUM) { zend_hash_next_index_insert(Z_ARRVAL_P(row), &element, sizeof(zval*), NULL); } else { /* default to ASSOC */ -#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION > 5) - /* zend_symtable_update is only available in 5.2+ */ zend_symtable_update(Z_ARRVAL_P(row), columns[ i ]->name, columns[ i ]->name_len+1, &element, sizeof(zval*), NULL); -#else - /* This code path means Bug #45458 will remain broken when OCI8 is built with PHP 4 */ - zend_hash_update(Z_ARRVAL_P(row), columns[ i ]->name, columns[ i ]->name_len+1, &element, sizeof(zval*), NULL); -#endif } } @@ -1467,13 +1461,7 @@ PHP_FUNCTION(oci_fetch_all) MAKE_STD_ZVAL(tmp); array_init(tmp); -#if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 1) || (PHP_MAJOR_VERSION > 5) - /* zend_symtable_update is only available in 5.2+ */ zend_symtable_update(Z_ARRVAL_P(array), columns[ i ]->name, columns[ i ]->name_len+1, (void *) &tmp, sizeof(zval*), (void **) &(outarrs[ i ])); -#else - /* This code path means Bug #45458 will remain broken when OCI8 is built with PHP 4 */ - zend_hash_update(Z_ARRVAL_P(array), columns[ i ]->name, columns[ i ]->name_len+1, (void *) &tmp, sizeof(zval*), (void **) &(outarrs[ i ])); -#endif } } @@ -1772,6 +1760,30 @@ PHP_FUNCTION(oci_set_client_identifier) RETURN_FALSE; } +#ifdef HAVE_OCI8_DTRACE + /* The alternatives to storing client_id like done below are + i) display it in a probe here in oci_set_client_identifier and + let the user D script correlate the connection address probe + argument and the client_id. This would likely require user D + script variables, which would use kernel memory. + ii) call OCIAttrGet for each probe definition that uses + client_id. This would be slower than storing it. + */ + + if (connection->client_id) { + pefree(connection->client_id, connection->is_persistent); + } + + if (client_id) { + /* this long winded copy allows compatibility with older PHP versions */ + connection->client_id = (char *)pemalloc(client_id_len+1, connection->is_persistent); + memcpy(connection->client_id, client_id, client_id_len); + connection->client_id[client_id_len] = '\0'; + } else { + connection->client_id = NULL; + } +#endif /* HAVE_OCI8_DTRACE */ + RETURN_TRUE; } /* }}} */ @@ -1790,13 +1802,14 @@ PHP_FUNCTION(oci_set_edition) if (OCI_G(edition)) { efree(OCI_G(edition)); - OCI_G(edition) = NULL; } if (edition) { - OCI_G(edition) = (char *)safe_emalloc(edition_len+1, sizeof(text), 0); + OCI_G(edition) = (char *)safe_emalloc(edition_len+1, sizeof(char), 0); memcpy(OCI_G(edition), edition, edition_len); OCI_G(edition)[edition_len] = '\0'; + } else { + OCI_G(edition) = NULL; } RETURN_TRUE; @@ -1903,6 +1916,38 @@ PHP_FUNCTION(oci_set_client_info) } /* }}} */ +#ifdef WAITIING_ORACLE_BUG_16695981_FIX +/* {{{ proto bool oci_set_db_operation(resource connection, string value) + Sets the "DB operation" on the connection for Oracle end-to-end tracing */ +PHP_FUNCTION(oci_set_db_operation) +{ +#if (OCI_MAJOR_VERSION > 11) + zval *z_connection; + php_oci_connection *connection; + char *dbop_name; + int dbop_name_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &z_connection, &dbop_name, &dbop_name_len) == FAILURE) { + return; + } + + PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection); + + PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, ((dvoid *) connection->session, (ub4) OCI_HTYPE_SESSION, (dvoid *) dbop_name, (ub4) dbop_name_len, (ub4) OCI_ATTR_DBOP, OCI_G(err))); + + if (OCI_G(errcode) != OCI_SUCCESS) { + php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); + RETURN_FALSE; + } + RETURN_TRUE; +#else + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unsupported attribute type"); + RETURN_FALSE; +#endif +} +/* }}} */ +#endif /* WAITIING_ORACLE_BUG_16695981_FIX */ + /* {{{ proto bool oci_password_change(resource connection, string username, string old_password, string new_password) Changes the password of an account */ PHP_FUNCTION(oci_password_change) diff --git a/ext/oci8/oci8_lob.c b/ext/oci8/oci8_lob.c index 8d14dc3f503aa..4f58c65737f97 100644 --- a/ext/oci8/oci8_lob.c +++ b/ext/oci8/oci8_lob.c @@ -165,11 +165,7 @@ int php_oci_lob_get_length (php_oci_descriptor *descriptor, ub4 *length TSRMLS_D /* {{{ php_oci_lob_callback() Append LOB portion to a memory buffer */ -#if defined(HAVE_OCI_LOB_READ2) sb4 php_oci_lob_callback (dvoid *ctxp, CONST dvoid *bufxp, oraub8 len, ub1 piece, dvoid **changed_bufpp, oraub8 *changed_lenp) -#else -sb4 php_oci_lob_callback (dvoid *ctxp, CONST dvoid *bufxp, ub4 len, ub1 piece) -#endif { ub4 lenp = (ub4) len; php_oci_lob_ctx *ctx = (php_oci_lob_ctx *)ctxp; @@ -251,14 +247,9 @@ int php_oci_lob_read (php_oci_descriptor *descriptor, long read_length, long ini int buffer_size = PHP_OCI_LOB_BUFFER_SIZE; php_oci_lob_ctx ctx; ub1 *bufp; -#if defined(HAVE_OCI_LOB_READ2) oraub8 bytes_read, offset = 0; oraub8 requested_len = read_length; /* this is by default */ oraub8 chars_read = 0; -#else - int bytes_read, offset = 0; - int requested_len = read_length; /* this is by default */ -#endif int is_clob = 0; sb4 bytes_per_char = 1; sword errstatus; @@ -336,7 +327,6 @@ int php_oci_lob_read (php_oci_descriptor *descriptor, long read_length, long ini ctx.alloc_len = (requested_len + 1) * bytes_per_char; *data = ecalloc(bytes_per_char, requested_len + 1); -#ifdef HAVE_OCI_LOB_READ2 if (is_clob) { chars_read = requested_len; bytes_read = 0; @@ -374,34 +364,6 @@ int php_oci_lob_read (php_oci_descriptor *descriptor, long read_length, long ini } else { offset = descriptor->lob_current_position + bytes_read; } - -#else - - bytes_read = requested_len; - buffer_size = (requested_len < buffer_size ) ? requested_len : buffer_size; /* optimize buffer size */ - buffer_size = php_oci_lob_calculate_buffer(descriptor, buffer_size TSRMLS_CC); /* use chunk size */ - - bufp = (ub1 *) ecalloc(1, buffer_size); - PHP_OCI_CALL_RETURN(errstatus, OCILobRead, - ( - connection->svc, - connection->err, - descriptor->descriptor, - &bytes_read, /* IN/OUT bytes toread/read */ - offset + 1, /* offset (starts with 1) */ - (dvoid *) bufp, - (ub4) buffer_size, /* size of buffer */ - (dvoid *)&ctx, - (OCICallbackLobRead) php_oci_lob_callback, /* callback... */ - (ub2) descriptor->charset_id, /* The character set ID of the buffer data. */ - (ub1) descriptor->charset_form /* The character set form of the buffer data. */ - ) - ); - - efree(bufp); - offset = descriptor->lob_current_position + bytes_read; - -#endif if (errstatus != OCI_SUCCESS) { connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); diff --git a/ext/oci8/oci8_statement.c b/ext/oci8/oci8_statement.c index 274c4e9e33b40..1e66308e53ca4 100644 --- a/ext/oci8/oci8_statement.c +++ b/ext/oci8/oci8_statement.c @@ -55,14 +55,8 @@ php_oci_statement *php_oci_statement_create(php_oci_connection *connection, char if (!query_len) { /* do not allocate stmt handle for refcursors, we'll get it from OCIStmtPrepare2() */ PHP_OCI_CALL(OCIHandleAlloc, (connection->env, (dvoid **)&(statement->stmt), OCI_HTYPE_STMT, 0, NULL)); - } else { -#ifdef HAVE_OCI8_DTRACE - if (DTRACE_OCI8_SQLTEXT_ENABLED()) { - DTRACE_OCI8_SQLTEXT(connection, query); - } -#endif /* HAVE_OCI8_DTRACE */ } - + PHP_OCI_CALL(OCIHandleAlloc, (connection->env, (dvoid **)&(statement->err), OCI_HTYPE_ERROR, 0, NULL)); if (query_len > 0) { @@ -79,6 +73,12 @@ php_oci_statement *php_oci_statement_create(php_oci_connection *connection, char OCI_DEFAULT ) ); +#ifdef HAVE_OCI8_DTRACE + if (DTRACE_OCI8_SQLTEXT_ENABLED()) { + DTRACE_OCI8_SQLTEXT(connection, connection->client_id, statement, query); + } +#endif /* HAVE_OCI8_DTRACE */ + if (errstatus != OCI_SUCCESS) { connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC); @@ -498,7 +498,7 @@ int php_oci_statement_execute(php_oci_statement *statement, ub4 mode TSRMLS_DC) /* only these are allowed */ #ifdef HAVE_OCI8_DTRACE if (DTRACE_OCI8_EXECUTE_MODE_ENABLED()) { - DTRACE_OCI8_EXECUTE_MODE(statement->connection, mode); + DTRACE_OCI8_EXECUTE_MODE(statement->connection, statement->connection->client_id, statement, mode); } #endif /* HAVE_OCI8_DTRACE */ break; diff --git a/ext/oci8/package.xml b/ext/oci8/package.xml index fcab20cc4544b..8e55b9abd5c3c 100644 --- a/ext/oci8/package.xml +++ b/ext/oci8/package.xml @@ -8,12 +8,17 @@ http://pear.php.net/dtd/package-2.0.xsd"> Extension for Oracle Database - This extension allows you to access Oracle Database. OCI8 2.0 can - be built with PHP 4.3.9 onwards. OCI8 can be linked with Oracle - Database 9.2, 10, 11, or 12.1 client libraries. Oracle's standard - cross-version connectivity applies. For example PHP linked with - Oracle Database 11.2 client libraries can connect to Oracle - Database 9.2 onwards. +Use the OCI8 extension to access Oracle Database. The extension can +be linked with Oracle client libraries from Oracle Database 10.2, 11, +or 12.1. These libraries are found in the database installation, or +in the free Oracle Instant Client available from Oracle. Oracle's +standard cross-version connectivity applies. For example, PHP OCI8 +linked with Instant Client 11.2 can connect to Oracle Database 9.2 +onward. See Oracle's note "Oracle Client / Server Interoperability +Support" (ID 207303.1) for details. PHP OCI8 2.0 can be built with +PHP 5.2 onward. Use the older PHP OCI8 1.4.10 when using PHP 4.3.9 +through to PHP 5.1.x, or when only Oracle Database 9.2 client +libraries are available. Christopher Jones @@ -40,23 +45,20 @@ http://pear.php.net/dtd/package-2.0.xsd"> no - 2013-09-06 + 2013-10-22 - 2.0.2 - 2.0.2 + 2.0.7 + 2.0.7 - devel - devel + stable + stable PHP -Review and improve error handling code and data types. -Fix oci_set_*($connection, ...) error handling so oci_error($connection) works. -Add DTrace oci8-connection-close probe -Add the connection handle to several DTrace probes. + Build change: Fix source variable definition for C89 compatibility @@ -142,7 +144,6 @@ Add the connection handle to several DTrace probes. - @@ -155,7 +156,6 @@ Add the connection handle to several DTrace probes. - @@ -224,6 +224,8 @@ Add the connection handle to several DTrace probes. + + @@ -269,6 +271,7 @@ Add the connection handle to several DTrace probes. + @@ -441,8 +444,7 @@ Add the connection handle to several DTrace probes. - 4.3.9 - 6.0.0 + 5.2.0 1.4.0b1 @@ -455,6 +457,93 @@ Add the connection handle to several DTrace probes. + + + 2.0.6 + 2.0.6 + + + stable + stable + + PHP + +Added a LICENSE file to make it easier for PECL binary distributions +to conform with the license. + + + + + + 2.0.5 + 2.0.5 + + + stable + stable + + PHP + +Bump PHP OCI8 2.0 mininum requirements to PHP 5.2 and Oracle client +library 10.2. (Use OCI8 1.4 for older PHP version support or if only +Oracle 9.2 client libraries are available.) + +Re-enable php_oci8.dll and php_oci8_11g.dll for Windows builds so URL +links work in the new Windows PECL infrastructure. + + + + + + 2.0.4 + 2.0.4 + + + devel + devel + + PHP + +Fix persistent memory usage with --enable-dtrace +Export get_module() for Windows php_oci8_12c.dll + + + + + + 2.0.3 + 2.0.3 + + + devel + devel + + PHP + +Add the oci_set_client_identifier() value and statement structure pointer to several DTrace probes. +Use 'phpoci' as the DTrace provider name since uniqueness is required by the Linux fasttrap module. +Update Windows builds to create only php_oci8_12c.dll. + + + + + + 2.0.2 + 2.0.2 + + + devel + devel + + PHP + +Review and improve error handling code and data types. +Fix oci_set_*($connection, ...) error handling so oci_error($connection) works. +Add DTrace oci8-connection-close probe +Add the connection handle to several DTrace probes. + + + 2.0.1 diff --git a/ext/oci8/php_oci8.h b/ext/oci8/php_oci8.h index 8c5fba9ab0873..86c5abfa8989b 100644 --- a/ext/oci8/php_oci8.h +++ b/ext/oci8/php_oci8.h @@ -41,12 +41,11 @@ */ #ifdef PHP_OCI8_VERSION /* The definition of PHP_OCI8_VERSION changed in PHP 5.3 and building - * this code with PHP 5.2 and earlier (e.g. when using OCI8 from PECL) - * will conflict. + * this code with PHP 5.2 (e.g. when using OCI8 from PECL) will conflict. */ #undef PHP_OCI8_VERSION #endif -#define PHP_OCI8_VERSION "2.0.2-dev" +#define PHP_OCI8_VERSION "2.0.7-dev" extern zend_module_entry oci8_module_entry; #define phpext_oci8_ptr &oci8_module_entry diff --git a/ext/oci8/php_oci8_int.h b/ext/oci8/php_oci8_int.h index 6155a883b02e1..e50983d75eb53 100644 --- a/ext/oci8/php_oci8_int.h +++ b/ext/oci8/php_oci8_int.h @@ -156,6 +156,9 @@ typedef struct { time_t idle_expiry; /* time when the connection will be considered as expired */ time_t *next_pingp; /* (pointer to) time of the next ping */ char *hash_key; /* hashed details of the connection */ +#ifdef HAVE_OCI8_DTRACE + char *client_id; /* The oci_set_client_identifier() value */ +#endif } php_oci_connection; /* }}} */ @@ -435,11 +438,7 @@ int php_oci_lob_append(php_oci_descriptor *descriptor_dest, php_oci_descriptor * int php_oci_lob_truncate(php_oci_descriptor *descriptor, long new_lob_length TSRMLS_DC); int php_oci_lob_erase(php_oci_descriptor *descriptor, long offset, ub4 length, ub4 *bytes_erased TSRMLS_DC); int php_oci_lob_is_equal(php_oci_descriptor *descriptor_first, php_oci_descriptor *descriptor_second, boolean *result TSRMLS_DC); -#if defined(HAVE_OCI_LOB_READ2) sb4 php_oci_lob_callback(dvoid *ctxp, CONST dvoid *bufxp, oraub8 len, ub1 piece, dvoid **changed_bufpp, oraub8 *changed_lenp); -#else -sb4 php_oci_lob_callback(dvoid *ctxp, CONST dvoid *bufxp, ub4 len, ub1 piece); -#endif /* }}} */ /* {{{ collection related prototypes */ diff --git a/ext/oci8/tests/bind_char_1.phpt b/ext/oci8/tests/bind_char_1.phpt index d68991a7f2baf..dc162ff943182 100644 --- a/ext/oci8/tests/bind_char_1.phpt +++ b/ext/oci8/tests/bind_char_1.phpt @@ -6,15 +6,8 @@ if (!extension_loaded('oci8')) die ("skip no oci8 extension"); require(dirname(__FILE__)."/connect.inc"); // The bind buffer size edge cases seem to change each DB version. preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); -if (!(isset($matches[0]) && - (($matches[1] == 10 && $matches[2] >= 2) || - ($matches[1] == 11 && $matches[2] == 2 && $matches[3] == 0 && $matches[4] == 2) - ))) { - die("skip expected output only valid when using Oracle 10gR2 or 11.2.0.2 databases"); -} -preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); -if (isset($matches[0]) && $matches[0] < 11) { - die("skip test expected to work only with Oracle 11g or greater version of client"); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle 12c database"); } ?> --ENV-- diff --git a/ext/oci8/tests/bind_char_1_11gR1.phpt b/ext/oci8/tests/bind_char_1_11gR1.phpt index 2a7c713aa7f15..bdc29f766dab3 100644 --- a/ext/oci8/tests/bind_char_1_11gR1.phpt +++ b/ext/oci8/tests/bind_char_1_11gR1.phpt @@ -6,11 +6,8 @@ if (!extension_loaded('oci8')) die ("skip no oci8 extension"); require(dirname(__FILE__)."/connect.inc"); // The bind buffer size edge cases seem to change each DB version. preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); -if (!(isset($matches[0]) && - (($matches[1] == 11 && $matches[2] == 1) || - ($matches[1] == 11 && $matches[2] == 2 && $matches[3] == 0 && $matches[4] == 3) - ))) { - die("skip expected output only valid when using Oracle 11gR1 or 11.2.0.3 databases"); +if (!(isset($matches[0]) && $matches[1] < 12)) { + die("skip expected output only valid when using pre-Oracle 12c database"); } ?> --ENV-- diff --git a/ext/oci8/tests/bind_char_2.phpt b/ext/oci8/tests/bind_char_2.phpt index 3695c85854904..9c61a858c8e71 100644 --- a/ext/oci8/tests/bind_char_2.phpt +++ b/ext/oci8/tests/bind_char_2.phpt @@ -6,15 +6,8 @@ if (!extension_loaded('oci8')) die ("skip no oci8 extension"); require(dirname(__FILE__)."/connect.inc"); // The bind buffer size edge cases seem to change each DB version. preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); -if (!(isset($matches[0]) && - (($matches[1] == 10 && $matches[2] >= 2) || - ($matches[1] == 11 && $matches[2] == 2 && $matches[3] == 0 && $matches[4] == 2) - ))) { - die("skip expected output only valid when using Oracle 10gR2 or 11.2.0.2 databases"); -} -preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); -if (isset($matches[0]) && $matches[0] < 11) { - die("skip test expected to work only with Oracle 11g or greater version of client"); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle 12c database"); } ?> --ENV-- diff --git a/ext/oci8/tests/bind_char_2_11gR1.phpt b/ext/oci8/tests/bind_char_2_11gR1.phpt index b9afd6940bcca..06c37afc93e20 100644 --- a/ext/oci8/tests/bind_char_2_11gR1.phpt +++ b/ext/oci8/tests/bind_char_2_11gR1.phpt @@ -6,11 +6,8 @@ if (!extension_loaded('oci8')) die ("skip no oci8 extension"); require(dirname(__FILE__)."/connect.inc"); // The bind buffer size edge cases seem to change each DB version. preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); -if (!(isset($matches[0]) && - (($matches[1] == 11 && $matches[2] == 1) || - ($matches[1] == 11 && $matches[2] == 2 && $matches[3] == 0 && $matches[4] == 3) - ))) { - die("skip expected output only valid when using Oracle 11gR1 or 11.2.0.3 databases"); +if (!(isset($matches[0]) && $matches[1] < 12)) { + die("skip expected output only valid when using pre-Oracle 12c database"); } ?> --ENV-- diff --git a/ext/oci8/tests/bind_char_3.phpt b/ext/oci8/tests/bind_char_3.phpt index 009e60a542b6a..177676e25ca3b 100644 --- a/ext/oci8/tests/bind_char_3.phpt +++ b/ext/oci8/tests/bind_char_3.phpt @@ -6,15 +6,8 @@ if (!extension_loaded('oci8')) die ("skip no oci8 extension"); require(dirname(__FILE__)."/connect.inc"); // The bind buffer size edge cases seem to change each DB version. preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); -if (!(isset($matches[0]) && - (($matches[1] == 10 && $matches[2] >= 2) || - ($matches[1] == 11 && $matches[2] == 2 && $matches[3] == 0 && $matches[4] == 2) - ))) { - die("skip expected output only valid when using Oracle 10gR2 or 11.2.0.2 databases"); -} -preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); -if (isset($matches[0]) && $matches[0] < 11) { - die("skip test expected to work only with Oracle 11g or greater version of client"); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle 12c database"); } ?> --ENV-- diff --git a/ext/oci8/tests/bind_char_3_11gR1.phpt b/ext/oci8/tests/bind_char_3_11gR1.phpt index a894de00c075f..c3ec999d0f10d 100644 --- a/ext/oci8/tests/bind_char_3_11gR1.phpt +++ b/ext/oci8/tests/bind_char_3_11gR1.phpt @@ -6,11 +6,8 @@ if (!extension_loaded('oci8')) die ("skip no oci8 extension"); require(dirname(__FILE__)."/connect.inc"); // The bind buffer size edge cases seem to change each DB version. preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); -if (!(isset($matches[0]) && - (($matches[1] == 11 && $matches[2] == 1) || - ($matches[1] == 11 && $matches[2] == 2 && $matches[3] == 0 && $matches[4] == 3) - ))) { - die("skip expected output only valid when using Oracle 11gR1 or 11.2.0.3 databases"); +if (!(isset($matches[0]) && $matches[1] < 12)) { + die("skip expected output only valid when using pre-Oracle 12c database"); } ?> --ENV-- diff --git a/ext/oci8/tests/bind_char_4.phpt b/ext/oci8/tests/bind_char_4.phpt index 0ac60e503de87..b4d3e089b136f 100644 --- a/ext/oci8/tests/bind_char_4.phpt +++ b/ext/oci8/tests/bind_char_4.phpt @@ -6,15 +6,8 @@ if (!extension_loaded('oci8')) die ("skip no oci8 extension"); require(dirname(__FILE__)."/connect.inc"); // The bind buffer size edge cases seem to change each DB version. preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); -if (!(isset($matches[0]) && - (($matches[1] == 10 && $matches[2] >= 2) || - ($matches[1] == 11 && $matches[2] == 2 && $matches[3] == 0 && $matches[4] == 2) - ))) { - die("skip expected output only valid when using Oracle 10gR2 or 11.2.0.2 databases"); -} -preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); -if (isset($matches[0]) && $matches[0] < 11) { - die("skip test expected to work only with Oracle 11g or greater version of client"); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle 12c database"); } ?> --ENV-- diff --git a/ext/oci8/tests/bind_char_4_11gR1.phpt b/ext/oci8/tests/bind_char_4_11gR1.phpt index d5ce116afb65a..ccad2cb7894c1 100644 --- a/ext/oci8/tests/bind_char_4_11gR1.phpt +++ b/ext/oci8/tests/bind_char_4_11gR1.phpt @@ -6,11 +6,8 @@ if (!extension_loaded('oci8')) die ("skip no oci8 extension"); require(dirname(__FILE__)."/connect.inc"); // The bind buffer size edge cases seem to change each DB version. preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); -if (!(isset($matches[0]) && - (($matches[1] == 11 && $matches[2] == 1) || - ($matches[1] == 11 && $matches[2] == 2 && $matches[3] == 0 && $matches[4] == 3) - ))) { - die("skip expected output only valid when using Oracle 11gR1 or 11.2.0.3 databases"); +if (!(isset($matches[0]) && $matches[1] < 12)) { + die("skip expected output only valid when using pre-Oracle 12c database"); } ?> --ENV-- diff --git a/ext/oci8/tests/bind_misccoltypes.phpt b/ext/oci8/tests/bind_misccoltypes.phpt index 0da8c8bf8803a..9e55b3b1ff74b 100644 --- a/ext/oci8/tests/bind_misccoltypes.phpt +++ b/ext/oci8/tests/bind_misccoltypes.phpt @@ -4,9 +4,6 @@ Bind miscellaneous column types using default types true, 'timesten' => false); // test runs on these DBs require(dirname(__FILE__).'/skipif.inc'); -if (preg_match('/^1[012]\./', oci_client_version()) != 1) { - die("skip test expected to work only with Oracle 10g or greater version of client"); -} ?> --FILE-- --INI-- precision = 14 diff --git a/ext/oci8/tests/bind_sqltnum.phpt b/ext/oci8/tests/bind_sqltnum.phpt index d3828b73eea95..93fc4809ec10d 100644 --- a/ext/oci8/tests/bind_sqltnum.phpt +++ b/ext/oci8/tests/bind_sqltnum.phpt @@ -3,9 +3,6 @@ Bind with SQLT_NUM --SKIPIF-- --FILE-- --FILE-- = 2) || - ($matches[1] == 11 && $matches[2] == 2 && $matches[3] == 0 && $matches[4] == 2) - ))) { - die("skip expected output only valid when using Oracle 10gR2 or 11.2.0.2 databases"); -} -preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); -if (isset($matches[0]) && $matches[0] < 11) { - die("skip test expected to work only with Oracle 11g or greater version of client"); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle 12c database"); } ?> --ENV-- diff --git a/ext/oci8/tests/bug27303_1_11gR1.phpt b/ext/oci8/tests/bug27303_1_11gR1.phpt index 7b4c158561959..d2018783bc925 100644 --- a/ext/oci8/tests/bug27303_1_11gR1.phpt +++ b/ext/oci8/tests/bug27303_1_11gR1.phpt @@ -6,12 +6,8 @@ if (!extension_loaded('oci8')) die ("skip no oci8 extension"); require(dirname(__FILE__)."/connect.inc"); // The bind buffer size edge cases seem to change each DB version. preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); -if (!(isset($matches[0]) && - (($matches[1] == 10 && $matches[2] == 2 && $matches[3] == 0 && $matches[4] == 3) || - ($matches[1] == 11 && $matches[2] == 1 && $matches[3] == 0 && $matches[4] == 6) || - ($matches[1] == 11 && $matches[2] == 2 && $matches[3] == 0 && $matches[4] == 3) - ))) { - die("skip expected output only valid when using Oracle 10gR2 or 11.2.0.2 databases"); +if (!(isset($matches[0]) && $matches[1] < 12)) { + die("skip expected output only valid when using pre-Oracle 12c database"); } ?> --FILE-- diff --git a/ext/oci8/tests/bug27303_2.phpt b/ext/oci8/tests/bug27303_2.phpt index 72d4e5a7ddbcf..ee2f7b52aa5e6 100644 --- a/ext/oci8/tests/bug27303_2.phpt +++ b/ext/oci8/tests/bug27303_2.phpt @@ -6,15 +6,8 @@ if (!extension_loaded('oci8')) die ("skip no oci8 extension"); require(dirname(__FILE__)."/connect.inc"); // The bind buffer size edge cases seem to change each DB version. preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); -if (!(isset($matches[0]) && - (($matches[1] == 10 && $matches[2] == 2 && $matches[3] == 0 && $matches[4] == 2) || - ($matches[1] == 11 && $matches[2] == 2 && $matches[3] == 0 && $matches[4] == 2) - ))) { - die("skip expected output only valid when using Oracle 10.2.0.2 or 11.2.0.2 databases"); -} -preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); -if (isset($matches[0]) && $matches[0] < 11) { - die("skip test expected to work only with Oracle 11g or greater version of client"); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle 12c database"); } ?> --ENV-- diff --git a/ext/oci8/tests/bug27303_2_11gR1.phpt b/ext/oci8/tests/bug27303_2_11gR1.phpt index 27d8a585bd452..06133e0115723 100644 --- a/ext/oci8/tests/bug27303_2_11gR1.phpt +++ b/ext/oci8/tests/bug27303_2_11gR1.phpt @@ -6,12 +6,8 @@ if (!extension_loaded('oci8')) die ("skip no oci8 extension"); require(dirname(__FILE__)."/connect.inc"); // The bind buffer size edge cases seem to change each DB version. preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); -if (!(isset($matches[0]) && - (($matches[1] == 10 && $matches[2] == 2 && $matches[3] == 0 && $matches[4] == 3) || - ($matches[1] == 11 && $matches[2] == 1 && $matches[3] == 0 && $matches[4] == 6) || - ($matches[1] == 11 && $matches[2] == 2 && $matches[3] == 0 && $matches[4] == 3) - ))) { - die("skip expected output only valid when using specific Oracle database versions"); +if (!(isset($matches[0]) && $matches[1] < 12)) { + die("skip expected output only valid when using pre-Oracle 12c database"); } ?> --FILE-- diff --git a/ext/oci8/tests/bug27303_4.phpt b/ext/oci8/tests/bug27303_4.phpt index a24ae705aba57..ed9d5a1fe6d43 100644 --- a/ext/oci8/tests/bug27303_4.phpt +++ b/ext/oci8/tests/bug27303_4.phpt @@ -6,16 +6,8 @@ if (!extension_loaded('oci8')) die ("skip no oci8 extension"); require(dirname(__FILE__)."/connect.inc"); // The bind buffer size edge cases seem to change each DB version. preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); -if (!(isset($matches[0]) && - (($matches[1] == 10 && $matches[2] == 2 && $matches[3] == 0 && $matches[4] == 2) || - ($matches[1] == 11 && $matches[2] == 2 && $matches[3] == 0 && $matches[4] == 2) - ))) { - die("skip expected output only valid when using Oracle 10.2.0.2 or 11.2.0.2 databases"); - // Other point releases may also work -} -preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); -if (isset($matches[0]) && $matches[0] < 11) { - die("skip test expected to work only with Oracle 11g or greater version of client"); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle 12c database"); } ?> --ENV-- diff --git a/ext/oci8/tests/bug27303_4_11gR1.phpt b/ext/oci8/tests/bug27303_4_11gR1.phpt index 01db1dc5a0bef..550d89fdcc52f 100644 --- a/ext/oci8/tests/bug27303_4_11gR1.phpt +++ b/ext/oci8/tests/bug27303_4_11gR1.phpt @@ -6,12 +6,8 @@ if (!extension_loaded('oci8')) die ("skip no oci8 extension"); require(dirname(__FILE__)."/connect.inc"); // The bind buffer size edge cases seem to change each DB version. preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); -if (!(isset($matches[0]) && - (($matches[1] == 10 && $matches[2] == 2 && $matches[3] == 0 && $matches[4] == 3) || - ($matches[1] == 11 && $matches[2] == 1 && $matches[3] == 0 && $matches[4] == 6) || - ($matches[1] == 11 && $matches[2] == 2 && $matches[3] == 0 && $matches[4] == 3) - ))) { - die("skip expected output only valid when using specific Oracle database versions"); +if (!(isset($matches[0]) && $matches[1] < 12)) { + die("skip expected output only valid when using pre-Oracle 12c database"); } ?> --FILE-- diff --git a/ext/oci8/tests/bug36403.phpt b/ext/oci8/tests/bug36403.phpt index 4ac32c4b069a5..122b06bbfa2b0 100644 --- a/ext/oci8/tests/bug36403.phpt +++ b/ext/oci8/tests/bug36403.phpt @@ -3,10 +3,6 @@ Bug #36403 (oci_execute no longer supports OCI_DESCRIBE_ONLY) --SKIPIF-- --FILE-- true, 'timesten' => false); // test runs on these DBs require(dirname(__FILE__).'/skipif.inc'); if (getenv('SKIP_SLOW_TESTS')) die('skip slow tests excluded by request'); -preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); -if (isset($matches[0]) && $matches[0] < 10) { - die("skip test expected to work only with Oracle 10g or greater version of client"); -} ?> --FILE-- true, 'timesten' => false); // test runs on these DBs -require(dirname(__FILE__).'/skipif.inc'); -if (getenv('SKIP_SLOW_TESTS')) die('skip slow tests excluded by request'); -ob_start(); -phpinfo(INFO_MODULES); -$phpinfo = ob_get_clean(); -$iv = preg_match('/Oracle .*Version => (9\.2)/', $phpinfo); -if ($iv != 1) { - die ("skip tests a feature that works only with Oracle 9iR2 client"); -} -?> ---FILE-- -free(); // cleanup properly - ++$cntchk; - } - } - echo "Loop count check = $cntchk\n"; -} - -// Read all XML data using explicit LOB locator but without freeing the temp lobs -function readxmltab_ex_nofree($c) -{ - $stmt = oci_parse($c, "select extract(xml, '/').getclobval() from bug43497_tab"); - - $cntchk = 0; - if (oci_execute($stmt)) { - while ($result = oci_fetch_array($stmt, OCI_NUM)) { - ++$cntchk; - } - } - echo "Loop count check = $cntchk\n"; -} - -// Read all XML data using implicit LOB locator -function readxmltab_im($c) -{ - $stmt = oci_parse($c, "select extract(xml, '/').getclobval() from bug43497_tab"); - - $cntchk = 0; - if (oci_execute($stmt)) { - while ($result = oci_fetch_array($stmt, OCI_NUM+OCI_RETURN_LOBS)) { - ++$cntchk; - } - } - echo "Loop count check = $cntchk\n"; -} - -function createxmltab($c) // create table w/ field of XML type -{ - @dropxmltab($c); - $stmt = oci_parse($c, "create table bug43497_tab (id number primary key, xml xmltype)"); - oci_execute($stmt); -} - -function dropxmltab($c) // delete table -{ - $stmt = oci_parse($c, "drop table bug43497_tab"); - oci_execute($stmt); -} - - -function fillxmltab($c) -{ - for ($id = 1; $id <= 100; $id++) { - - // create an XML element string with random data - $s = ""; - for ($j = 0; $j < 128; $j++) { - $s .= rand(); - } - $s .= "\n"; - for ($j = 0; $j < 4; $j++) { - $s .= $s; - } - $data = "" . $s . ""; - - // insert XML data into database - - $stmt = oci_parse($c, "insert into bug43497_tab(id, xml) values (:id, sys.xmltype.createxml(:xml))"); - oci_bind_by_name($stmt, ":id", $id); - $clob = oci_new_descriptor($c, OCI_D_LOB); - oci_bind_by_name($stmt, ":xml", $clob, -1, OCI_B_CLOB); - $clob->writetemporary($data); - oci_execute($stmt); - - $clob->close(); - $clob->free(); - } -} - - -// Initialize - -createxmltab($c); -fillxmltab($c); - -// Run Test - -$sid = sessionid($c); - -echo "Explicit LOB use\n"; -for ($i = 1; $i <= 10; $i++) { - echo "\nRun = " . $i . "\n"; - echo "Temporary LOBs = " . templobs($c, $sid) . "\n"; - readxmltab_ex($c); -} - -echo "\nImplicit LOB use\n"; -for ($i = 1; $i <= 10; $i++) { - echo "\nRun = " . $i . "\n"; - echo "Temporary LOBs = " . templobs($c, $sid) . "\n"; - readxmltab_im($c); -} - -echo "\nExplicit LOB with no free (i.e. a temp lob leak)\n"; -for ($i = 1; $i <= 10; $i++) { - echo "\nRun = " . $i . "\n"; - echo "Temporary LOBs = " . templobs($c, $sid) . "\n"; - readxmltab_ex_nofree($c); -} - - - -// Cleanup - -dropxmltab($c); - -oci_close($c); - -echo "Done\n"; -?> ---EXPECT-- -Explicit LOB use - -Run = 1 -Temporary LOBs = 0 -Loop count check = 100 - -Run = 2 -Temporary LOBs = 100 -Loop count check = 100 - -Run = 3 -Temporary LOBs = 200 -Loop count check = 100 - -Run = 4 -Temporary LOBs = 300 -Loop count check = 100 - -Run = 5 -Temporary LOBs = 400 -Loop count check = 100 - -Run = 6 -Temporary LOBs = 500 -Loop count check = 100 - -Run = 7 -Temporary LOBs = 600 -Loop count check = 100 - -Run = 8 -Temporary LOBs = 700 -Loop count check = 100 - -Run = 9 -Temporary LOBs = 800 -Loop count check = 100 - -Run = 10 -Temporary LOBs = 900 -Loop count check = 100 - -Implicit LOB use - -Run = 1 -Temporary LOBs = 1000 -Loop count check = 100 - -Run = 2 -Temporary LOBs = 1100 -Loop count check = 100 - -Run = 3 -Temporary LOBs = 1200 -Loop count check = 100 - -Run = 4 -Temporary LOBs = 1300 -Loop count check = 100 - -Run = 5 -Temporary LOBs = 1400 -Loop count check = 100 - -Run = 6 -Temporary LOBs = 1500 -Loop count check = 100 - -Run = 7 -Temporary LOBs = 1600 -Loop count check = 100 - -Run = 8 -Temporary LOBs = 1700 -Loop count check = 100 - -Run = 9 -Temporary LOBs = 1800 -Loop count check = 100 - -Run = 10 -Temporary LOBs = 1900 -Loop count check = 100 - -Explicit LOB with no free (i.e. a temp lob leak) - -Run = 1 -Temporary LOBs = 2000 -Loop count check = 100 - -Run = 2 -Temporary LOBs = 2100 -Loop count check = 100 - -Run = 3 -Temporary LOBs = 2200 -Loop count check = 100 - -Run = 4 -Temporary LOBs = 2300 -Loop count check = 100 - -Run = 5 -Temporary LOBs = 2400 -Loop count check = 100 - -Run = 6 -Temporary LOBs = 2500 -Loop count check = 100 - -Run = 7 -Temporary LOBs = 2600 -Loop count check = 100 - -Run = 8 -Temporary LOBs = 2700 -Loop count check = 100 - -Run = 9 -Temporary LOBs = 2800 -Loop count check = 100 - -Run = 10 -Temporary LOBs = 2900 -Loop count check = 100 -Done \ No newline at end of file diff --git a/ext/oci8/tests/bug47281.phpt b/ext/oci8/tests/bug47281.phpt index 0098ec5ebb772..00c43c22dac7c 100644 --- a/ext/oci8/tests/bug47281.phpt +++ b/ext/oci8/tests/bug47281.phpt @@ -6,9 +6,9 @@ $target_dbs = array('oracledb' => true, 'timesten' => false); // test runs on t require(dirname(__FILE__).'/skipif.inc'); // error3.phpt obsoletes this test for newer Oracle client versions // Assume runtime client version is >= compile time client version -preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); +preg_match('/^([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/', oci_client_version(), $matches); if (!isset($matches[0]) || - ($matches[0] > 11 || ($matches[0] == 11 && $matches[1] > 2) || ($matches[0] == 11 && $matches[1] == 2 && $matches[3] >= 3) + ($matches[1] > 11 || ($matches[1] == 11 && $matches[2] > 2) || ($matches[1] == 11 && $matches[2] == 2 && $matches[4] >= 3) )) { die("skip test works only with Oracle 11.2.0.2 or earlier Oracle client libraries"); } diff --git a/ext/oci8/tests/clientversion.phpt b/ext/oci8/tests/clientversion.phpt index db70b5affcea4..262ded462f9d9 100644 --- a/ext/oci8/tests/clientversion.phpt +++ b/ext/oci8/tests/clientversion.phpt @@ -3,9 +3,6 @@ oci_client_version() --SKIPIF-- --FILE-- ---FILE-- - -===DONE=== - ---EXPECTF-- -Unknown -===DONE=== diff --git a/ext/oci8/tests/conn_attr_1.phpt b/ext/oci8/tests/conn_attr_1.phpt index 631bc19c1d416..745b1cd93f906 100644 --- a/ext/oci8/tests/conn_attr_1.phpt +++ b/ext/oci8/tests/conn_attr_1.phpt @@ -13,10 +13,6 @@ preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit if (!(isset($matches[0]) && $matches[1] >= 10)) { die("skip expected output only valid when using Oracle 10g or greater database server"); } -preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); -if (isset($matches[0]) && $matches[0] < 10) { - die("skip test expected to work only with Oracle 10g or greater version of client"); -} ?> --FILE-- = 10)) { die("skip expected output only valid when using Oracle 10g or greater database server"); } -preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); -if (isset($matches[0]) && $matches[0] < 10) { - die("skip test expected to work only with Oracle 10g or greater version of client"); -} ?> --INI-- oci8.privileged_connect = On diff --git a/ext/oci8/tests/conn_attr_3.phpt b/ext/oci8/tests/conn_attr_3.phpt index 921487c9a00e1..1b00ac5a4ff45 100644 --- a/ext/oci8/tests/conn_attr_3.phpt +++ b/ext/oci8/tests/conn_attr_3.phpt @@ -12,10 +12,6 @@ preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit if (!(isset($matches[0]) && $matches[1] >= 10)) { die("skip expected output only valid when using Oracle 10g or greater database server"); } -preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); -if (isset($matches[0]) && $matches[0] < 10) { - die("skip test expected to work only with Oracle 10g or greater version of client"); -} ?> --FILE-- --FILE-- = 10)) { die("skip expected output only valid when using Oracle 10g or greater database server"); } -preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); -if (isset($matches[0]) && $matches[0] < 10) { - die("skip test expected to work only with Oracle 10g or greater version of client"); -} ?> --FILE-- --ENV-- diff --git a/ext/oci8/tests/connect_without_oracle_home_11.phpt b/ext/oci8/tests/connect_without_oracle_home_11.phpt index 40dc5a98fc7e3..42c45644567c4 100644 --- a/ext/oci8/tests/connect_without_oracle_home_11.phpt +++ b/ext/oci8/tests/connect_without_oracle_home_11.phpt @@ -10,10 +10,10 @@ $ov = preg_match('/Compile-time ORACLE_HOME/', $phpinfo); if ($ov != 1) { die ("skip Test only valid when OCI8 is built with an ORACLE_HOME"); } -preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); +preg_match('/^([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/', oci_client_version(), $matches); if (!(isset($matches[0]) && - (($matches[0] == 11 && $matches[1] >= 2) || - ($matches[0] >= 12) + (($matches[1] == 11 && $matches[2] >= 2) || + ($matches[1] >= 12) ))) { die("skip test expected to work only with Oracle 11gR2 or greater version of client"); } diff --git a/ext/oci8/tests/connect_without_oracle_home_old.phpt b/ext/oci8/tests/connect_without_oracle_home_old.phpt index 5a731337af13c..d6d12b47ba338 100644 --- a/ext/oci8/tests/connect_without_oracle_home_old.phpt +++ b/ext/oci8/tests/connect_without_oracle_home_old.phpt @@ -10,9 +10,6 @@ $ov = preg_match('/Compile-time ORACLE_HOME/', $phpinfo); if ($ov !== 1) { die ("skip Test only valid when OCI8 is built with an ORACLE_HOME"); } -if (preg_match('/^10\.2\./', oci_client_version()) != 1) { - die("skip test expected to work only with Oracle 10gR2 client libraries"); -} ?> --ENV-- ORACLE_HOME="" @@ -33,5 +30,8 @@ else { --EXPECTF-- Warning: ocilogon(): OCIEnvNlsCreate() failed. There is something wrong with your system - please check that ORACLE_HOME and %s are set and point to the right directories in %s on line %d + +Warning: ocilogon(): %s ORA-01804 + in %s on line %d bool(false) ===DONE=== diff --git a/ext/oci8/tests/connect_without_oracle_home_old_11.phpt b/ext/oci8/tests/connect_without_oracle_home_old_11.phpt index e04016f41a766..eb5fb0cc4d333 100644 --- a/ext/oci8/tests/connect_without_oracle_home_old_11.phpt +++ b/ext/oci8/tests/connect_without_oracle_home_old_11.phpt @@ -10,10 +10,10 @@ $ov = preg_match('/Compile-time ORACLE_HOME/', $phpinfo); if ($ov !== 1) { die ("skip Test only valid when OCI8 is built with an ORACLE_HOME"); } -preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); +preg_match('/^([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/', oci_client_version(), $matches); if (!(isset($matches[0]) && - (($matches[0] == 11 && $matches[1] >= 2) || - ($matches[0] >= 12) + (($matches[1] == 11 && $matches[2] >= 2) || + ($matches[1] >= 12) ))) { die("skip test expected to work only with Oracle 11gR2 or greater version of client"); } diff --git a/ext/oci8/tests/db_op_1.phpt b/ext/oci8/tests/db_op_1.phpt new file mode 100644 index 0000000000000..f645cf80ff3b2 --- /dev/null +++ b/ext/oci8/tests/db_op_1.phpt @@ -0,0 +1,61 @@ +--TEST-- +oci_set_db_operation: basic test for end-to-end tracing +--SKIPIF-- + true, 'timesten' => false); // test runs on these DBs +require(dirname(__FILE__).'/skipif.inc'); +if (strcasecmp($user, "system") && strcasecmp($user, "sys")) { + die("skip needs to be run as a DBA user"); +} +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle Database 12c or greater"); +} +preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); +if (!(isset($matches[0]) && $matches[0] >= 12)) { + die("skip works only with Oracle 12c or greater version of Oracle client libraries"); +} +if (!function_exists('oci_set_db_operation')) +{ + die("skip function oci_set_db_operation() does not exist"); +} +?> +--FILE-- + +===DONE=== + +--EXPECTF-- +Test 1 +array(1) { + ["DUMMY"]=> + string(1) "X" +} +array(1) { + ["DBOP_NAME"]=> + string(7) "db_op_1" +} +===DONE=== + diff --git a/ext/oci8/tests/db_op_2.phpt b/ext/oci8/tests/db_op_2.phpt new file mode 100644 index 0000000000000..05c2269ae0bfd --- /dev/null +++ b/ext/oci8/tests/db_op_2.phpt @@ -0,0 +1,69 @@ +--TEST-- +oci_set_db_operation: basic test for end-to-end tracing +--SKIPIF-- + true, 'timesten' => false); // test runs on these DBs +require(dirname(__FILE__).'/skipif.inc'); +if (strcasecmp($user, "system") && strcasecmp($user, "sys")) { + die("skip needs to be run as a DBA user"); +} +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && $matches[1] >= 12)) { + die("skip expected output only valid when using Oracle Database 12c or greater"); +} +preg_match('/^[[:digit:]]+/', oci_client_version(), $matches); +if (!(isset($matches[0]) && $matches[0] >= 12)) { + die("skip works only with Oracle 12c or greater version of Oracle client libraries"); +} +if (!function_exists('oci_set_db_operation')) +{ + die("skip function oci_set_db_operation() does not exist"); +} +?> +--FILE-- + +===DONE=== + +--XFAIL-- +Fails due to Oracle Bug 16695981 +--EXPECTF-- +Test 1 +array(1) { + ["DUMMY"]=> + string(1) "X" +} +Test 2 +array(1) { + ["DUMMY"]=> + string(1) "X" +} +Test 3 +array(2) { + ["DBOP_NAME"]=> + string(7) "db_op_2a" +} +===DONE=== + diff --git a/ext/oci8/tests/drcp_cclass1.phpt b/ext/oci8/tests/drcp_cclass1.phpt index 068331e5a95ae..5c78a2943e94e 100644 --- a/ext/oci8/tests/drcp_cclass1.phpt +++ b/ext/oci8/tests/drcp_cclass1.phpt @@ -3,9 +3,21 @@ DRCP: Test setting connection class inline --SKIPIF-- = 12) { + $s = oci_parse($c, "select nvl(sys_context('userenv', 'con_name'), 'notacdb') as dbtype from dual"); + $r = @oci_execute($s); + if (!$r) + die('skip could not identify container type'); + $r = oci_fetch_array($s); + if ($r['DBTYPE'] !== 'CDB$ROOT') + die('skip cannot run test using a PDB'); +} ?> --FILE-- += 11)) { + die("skip works only with Oracle 11g or greater version of Oracle client libraries"); +} +?> --INI-- oci8.connection_class=test --FILE-- diff --git a/ext/oci8/tests/drcp_privileged.phpt b/ext/oci8/tests/drcp_privileged.phpt index da8702e3c9204..3871341bc50cc 100644 --- a/ext/oci8/tests/drcp_privileged.phpt +++ b/ext/oci8/tests/drcp_privileged.phpt @@ -3,7 +3,8 @@ DRCP: privileged connect --SKIPIF-- = 12) { + $s = oci_parse($c, "select nvl(sys_context('userenv', 'con_name'), 'notacdb') as dbtype from dual"); + $r = @oci_execute($s); + if (!$r) + die('skip could not identify container type'); + $r = oci_fetch_array($s); + if ($r['DBTYPE'] !== 'CDB$ROOT') + die('skip cannot run test using a PDB'); +} ?> --INI-- oci8.privileged_connect=1 diff --git a/ext/oci8/tests/driver_name.phpt b/ext/oci8/tests/driver_name.phpt index bf86e66e7b64f..f63979d6b54c0 100644 --- a/ext/oci8/tests/driver_name.phpt +++ b/ext/oci8/tests/driver_name.phpt @@ -7,10 +7,19 @@ require(dirname(__FILE__)."/connect.inc"); if (strcasecmp($user, "system") && strcasecmp($user, "sys")) die("skip needs to be run as a DBA user"); if ($test_drcp) die("skip as Output might vary with DRCP"); -if (preg_match('/Release (11\.2|12)/', oci_server_version($c), $matches) !== 1) { - die("skip expected output only valid when using Oracle 11gR2 or greater databases"); -} else if (preg_match('/^(11\.2|12\.)/', oci_client_version()) != 1) { - die("skip test expected to work only with Oracle 11g or greater version of client"); +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && + (($matches[1] == 11 && $matches[2] >= 2) || + ($matches[1] >= 12) + ))) { + die("skip expected output only valid when using Oracle 11gR2 or greater database server"); +} +preg_match('/^([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/', oci_client_version(), $matches); +if (!(isset($matches[0]) && + (($matches[1] == 11 && $matches[2] >= 2) || + ($matches[1] >= 12) + ))) { + die("skip test expected to work only with Oracle 11gR2 or greater version of client"); } ?> diff --git a/ext/oci8/tests/edition_1.phpt b/ext/oci8/tests/edition_1.phpt index d8ca53cddf061..3e55ee902c970 100644 --- a/ext/oci8/tests/edition_1.phpt +++ b/ext/oci8/tests/edition_1.phpt @@ -10,9 +10,18 @@ if (strcasecmp($user, "system") && strcasecmp($user, "sys")) { if ($test_drcp) { die("skip as Output might vary with DRCP"); } -if (preg_match('/Release (1[1]\.2|12)\./', oci_server_version($c), $matches) !== 1) { - die("skip expected output only valid when using Oracle 11gR2 or greater databases"); -} else if (preg_match('/^(11\.2|12)\./', oci_client_version()) != 1) { +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && + (($matches[1] == 11 && $matches[2] >= 2) || + ($matches[1] >= 12) + ))) { + die("skip expected output only valid when using Oracle 11gR2 or greater database server"); +} +preg_match('/^([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/', oci_client_version(), $matches); +if (!(isset($matches[0]) && + (($matches[1] == 11 && $matches[2] >= 2) || + ($matches[1] >= 12) + ))) { die("skip test expected to work only with Oracle 11gR2 or greater version of client"); } ?> diff --git a/ext/oci8/tests/edition_2.phpt b/ext/oci8/tests/edition_2.phpt index 0ffb62dc32633..12e902667e621 100644 --- a/ext/oci8/tests/edition_2.phpt +++ b/ext/oci8/tests/edition_2.phpt @@ -8,10 +8,18 @@ if (strcasecmp($user, "system") && strcasecmp($user, "sys")) die("skip needs to be run as a DBA user"); if ($test_drcp) die("skip as Output might vary with DRCP"); - -if (preg_match('/Release (1[1]\.2|12)\./', oci_server_version($c), $matches) !== 1) { - die("skip expected output only valid when using Oracle 11gR2 or greater databases"); -} else if (preg_match('/^(11\.2|12)\./', oci_client_version()) != 1) { +preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches); +if (!(isset($matches[0]) && + (($matches[1] == 11 && $matches[2] >= 2) || + ($matches[1] >= 12) + ))) { + die("skip expected output only valid when using Oracle 11gR2 or greater database server"); +} +preg_match('/^([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/', oci_client_version(), $matches); +if (!(isset($matches[0]) && + (($matches[1] == 11 && $matches[2] >= 2) || + ($matches[1] >= 12) + ))) { die("skip test expected to work only with Oracle 11gR2 or greater version of client"); } diff --git a/ext/oci8/tests/ini_1.phpt b/ext/oci8/tests/ini_1.phpt index 4c23b72b41fdb..2fba79813e845 100644 --- a/ext/oci8/tests/ini_1.phpt +++ b/ext/oci8/tests/ini_1.phpt @@ -1,7 +1,13 @@ --TEST-- Test OCI8 php.ini settings --SKIPIF-- - += 11)) { + die("skip works only with Oracle 11g or greater version of Oracle client libraries"); +} +?> --INI-- oci8.privileged_connect = On oci8.max_persistent = 111 diff --git a/ext/oci8/tests/password_new.phpt b/ext/oci8/tests/password_new.phpt index 2c66dd94ab7dc..a29fb8f52ff2b 100644 --- a/ext/oci8/tests/password_new.phpt +++ b/ext/oci8/tests/password_new.phpt @@ -8,15 +8,18 @@ if (empty($dbase)) die ("skip requires database connection string be set"); if ($test_drcp) die("skip password change not supported in DRCP Mode"); preg_match('/.*Release ([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)*/', oci_server_version($c), $matches_sv); -if (isset($matches_sv[1]) && $matches_sv[1] >= 11) { - preg_match('/([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/', oci_client_version(), $matches); - if (isset($matches[0]) && $matches[1] == 10 && $matches[2] == 2 && $matches[3] == 0 && $matches[4] < 5) { - die ("skip test known to fail using Oracle 10.2.0.4 client libs connecting to Oracle 11 (6277160)"); - } +preg_match('/([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/', oci_client_version(), $matches); +if (!(isset($matches_sv[0]) && isset($matches[0]) + && $matches_sv[1] == $matches[1] + && $matches_sv[2] == $matches[2] + && $matches_sv[3] == $matches[3] + && $matches_sv[4] == $matches[4])) { + // Avoid diffs due to cross version protocol changes (e.g. like 11.2.0.2-11.2.0.3) and bugs like Oracle bug: 6277160 + die ("skip test only runs when database client libraries and database server are the same version"); } // This test in Oracle 12c needs a non-CDB or the root container -if (isset($matches_sv[1]) && $matches_sv[1] >= 12) { +if (isset($matches_sv[0]) && $matches_sv[1] >= 12) { $s = oci_parse($c, "select nvl(sys_context('userenv', 'con_name'), 'notacdb') as dbtype from dual"); $r = @oci_execute($s); if (!$r) @@ -29,22 +32,11 @@ if (isset($matches_sv[1]) && $matches_sv[1] >= 12) { --FILE-- = 11) { - preg_match('/([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/', oci_client_version(), $matches); - if (isset($matches[0]) && $matches[1] == 10 && $matches[2] == 2 && $matches[3] == 0 && $matches[4] < 5) { - die ("skip test known to fail using Oracle 10.2.0.4 client libs connecting to Oracle 11 (6277160)"); - } +preg_match('/([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/', oci_client_version(), $matches); +if (!(isset($matches_sv[0]) && isset($matches[0]) + && $matches_sv[1] == $matches[1] + && $matches_sv[2] == $matches[2] + && $matches_sv[3] == $matches[3] + && $matches_sv[4] == $matches[4])) { + // Avoid diffs due to cross version protocol changes (e.g. like 11.2.0.2-11.2.0.3) and bugs like Oracle bug: 6277160 + die ("skip test only runs when database client libraries and database server are the same version"); } // This test in Oracle 12c needs a non-CDB or the root container -if (isset($matches_sv[1]) && $matches_sv[1] >= 12) { +if (isset($matches_sv[0]) && $matches_sv[1] >= 12) { $s = oci_parse($c, "select nvl(sys_context('userenv', 'con_name'), 'notacdb') as dbtype from dual"); $r = @oci_execute($s); if (!$r) @@ -29,25 +32,13 @@ if (isset($matches_sv[1]) && $matches_sv[1] >= 12) { --FILE-- diff --git a/ext/oci8/tests/pecl_bug16035.phpt b/ext/oci8/tests/pecl_bug16035.phpt index ddd0038de1524..29ff6439d1c8a 100644 --- a/ext/oci8/tests/pecl_bug16035.phpt +++ b/ext/oci8/tests/pecl_bug16035.phpt @@ -10,9 +10,6 @@ $ov = preg_match('/Compile-time ORACLE_HOME/', $phpinfo); if ($ov !== 1) { die ("skip Test only valid when OCI8 is built with an ORACLE_HOME"); } -if (preg_match('/Unknown/', oci_client_version()) == 1) { - die("skip expected output only valid with Oracle clients > 9gR2"); -} ?> --ENV-- ORACLE_HOME="" diff --git a/ext/oci8/tests/refcur_prefetch_1.phpt b/ext/oci8/tests/refcur_prefetch_1.phpt index ea09fbcd979cf..c7e200932aece 100644 --- a/ext/oci8/tests/refcur_prefetch_1.phpt +++ b/ext/oci8/tests/refcur_prefetch_1.phpt @@ -4,9 +4,16 @@ Prefetch with REF cursor. Test different values for prefetch with oci_set_prefet = 10))) { + die("skip expected output only valid when using Oracle 10g or greater database server"); +} +preg_match('/^([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/', oci_client_version(), $matches); +if (!(isset($matches[0]) && + (($matches[1] == 11 && $matches[2] >= 2) || + ($matches[1] >= 12) + ))) { die("skip test expected to work only with Oracle 11gR2 or greater version of client"); } ?> diff --git a/ext/oci8/tests/refcur_prefetch_2.phpt b/ext/oci8/tests/refcur_prefetch_2.phpt index 8d65251077ea3..9b2472db5df44 100644 --- a/ext/oci8/tests/refcur_prefetch_2.phpt +++ b/ext/oci8/tests/refcur_prefetch_2.phpt @@ -4,9 +4,16 @@ Prefetch with REF cursor. Test No 2 = 10))) { + die("skip expected output only valid when using Oracle 10g or greater database server"); +} +preg_match('/^([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/', oci_client_version(), $matches); +if (!(isset($matches[0]) && + (($matches[1] == 11 && $matches[2] >= 2) || + ($matches[1] >= 12) + ))) { die("skip test expected to work only with Oracle 11gR2 or greater version of client"); } ?> diff --git a/ext/oci8/tests/refcur_prefetch_3.phpt b/ext/oci8/tests/refcur_prefetch_3.phpt index 974864cbd90e7..f29345e515d47 100644 --- a/ext/oci8/tests/refcur_prefetch_3.phpt +++ b/ext/oci8/tests/refcur_prefetch_3.phpt @@ -6,12 +6,20 @@ oci8.default_prefetch=5 = 2) || + ($matches[1] >= 12) + ))) { + die("skip expected output only valid when using Oracle 11gR2 or greater database server"); +} +preg_match('/^([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/', oci_client_version(), $matches); +if (!(isset($matches[0]) && + (($matches[1] == 11 && $matches[2] >= 2) || + ($matches[1] >= 12) + ))) { die("skip test expected to work only with Oracle 11gR2 or greater version of client"); } - ?> --FILE-- = 10))) { + die("skip expected output only valid when using Oracle 10g or greater database server"); +} +preg_match('/^([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/', oci_client_version(), $matches); +if (!(isset($matches[0]) && + (($matches[1] == 11 && $matches[2] >= 2) || + ($matches[1] >= 12) + ))) { die("skip test expected to work only with Oracle 11gR2 or greater version of client"); } ?> diff --git a/ext/odbc/php_odbc_includes.h b/ext/odbc/php_odbc_includes.h index ca237c0537bf7..c00583b16a215 100644 --- a/ext/odbc/php_odbc_includes.h +++ b/ext/odbc/php_odbc_includes.h @@ -232,7 +232,7 @@ typedef struct odbc_connection { } odbc_connection; typedef struct odbc_result_value { - char name[32]; + char name[256]; char *value; SQLLEN vallen; SQLLEN coltype; diff --git a/ext/opcache/Optimizer/block_pass.c b/ext/opcache/Optimizer/block_pass.c index 1c34cffbf76e7..835c9ee7162a0 100644 --- a/ext/opcache/Optimizer/block_pass.c +++ b/ext/opcache/Optimizer/block_pass.c @@ -643,8 +643,11 @@ static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array, opline->opcode != ZEND_FREE ) { zend_op *src = VAR_SOURCE(opline->op1); + zval c = ZEND_OP1_LITERAL(src); VAR_UNSET(opline->op1); - COPY_NODE(opline->op1, src->op1); + zval_copy_ctor(&c); + update_op1_const(op_array, opline, &c TSRMLS_CC); + literal_dtor(&ZEND_OP1_LITERAL(src)); MAKE_NOP(src); } @@ -654,51 +657,12 @@ static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array, VAR_SOURCE(opline->op2)->opcode == ZEND_QM_ASSIGN && ZEND_OP1_TYPE(VAR_SOURCE(opline->op2)) == IS_CONST) { zend_op *src = VAR_SOURCE(opline->op2); + zval c = ZEND_OP1_LITERAL(src); VAR_UNSET(opline->op2); - COPY_NODE(opline->op2, src->op1); + zval_copy_ctor(&c); + update_op2_const(op_array, opline, &c TSRMLS_CC); + literal_dtor(&ZEND_OP1_LITERAL(src)); MAKE_NOP(src); - -#if ZEND_EXTENSION_API_NO >= PHP_5_4_X_API_NO - /* numeric string constants used as array indeces have to be - converted to long at compile time */ - if (opline->opcode == ZEND_ADD_ARRAY_ELEMENT || - opline->opcode == ZEND_INIT_ARRAY || - opline->opcode == ZEND_UNSET_DIM || - opline->opcode == ZEND_ISSET_ISEMPTY_DIM_OBJ || - opline->opcode == ZEND_FETCH_DIM_R || - opline->opcode == ZEND_FETCH_DIM_W || - opline->opcode == ZEND_FETCH_DIM_RW || - opline->opcode == ZEND_FETCH_DIM_IS || - opline->opcode == ZEND_FETCH_DIM_FUNC_ARG || - opline->opcode == ZEND_FETCH_DIM_UNSET || - opline->opcode == ZEND_FETCH_DIM_TMP_VAR || - (opline->opcode == ZEND_OP_DATA && - ((opline-1)->opcode == ZEND_ASSIGN_DIM || - ((opline-1)->extended_value == ZEND_ASSIGN_DIM && - ((opline-1)->opcode == ZEND_ASSIGN_ADD || - (opline-1)->opcode == ZEND_ASSIGN_SUB || - (opline-1)->opcode == ZEND_ASSIGN_MUL || - (opline-1)->opcode == ZEND_ASSIGN_DIV || - (opline-1)->opcode == ZEND_ASSIGN_MOD || - (opline-1)->opcode == ZEND_ASSIGN_SL || - (opline-1)->opcode == ZEND_ASSIGN_SR || - (opline-1)->opcode == ZEND_ASSIGN_CONCAT || - (opline-1)->opcode == ZEND_ASSIGN_BW_OR || - (opline-1)->opcode == ZEND_ASSIGN_BW_AND || - (opline-1)->opcode == ZEND_ASSIGN_BW_XOR))))) { - - if (Z_TYPE(ZEND_OP2_LITERAL(opline)) == IS_STRING) { - ulong index; - int numeric = 0; - - ZEND_HANDLE_NUMERIC_EX(Z_STRVAL(ZEND_OP2_LITERAL(opline)), Z_STRLEN(ZEND_OP2_LITERAL(opline))+1, index, numeric = 1); - if (numeric) { - zval_dtor(&ZEND_OP2_LITERAL(opline)); - ZVAL_LONG(&ZEND_OP2_LITERAL(opline), index); - } - } - } -#endif } /* T = PRINT(X), F(T) => ECHO(X), F(1) */ @@ -1070,10 +1034,9 @@ static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array, literal_dtor(&ZEND_OP1_LITERAL(opline)); literal_dtor(&ZEND_OP2_LITERAL(opline)); - ZEND_OP1_LITERAL(opline) = result; - SET_UNUSED(opline->op2); - opline->opcode = ZEND_QM_ASSIGN; + SET_UNUSED(opline->op2); + update_op1_const(op_array, opline, &result TSRMLS_CC); } EG(error_reporting) = er; } else if ((opline->opcode == ZEND_BOOL || @@ -1097,8 +1060,8 @@ static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array, } PZ_SET_REFCOUNT_P(&result, 1); PZ_UNSET_ISREF_P(&result); - ZEND_OP1_LITERAL(opline) = result; opline->opcode = ZEND_QM_ASSIGN; + update_op1_const(op_array, opline, &result TSRMLS_CC); } else if ((opline->opcode == ZEND_RETURN || opline->opcode == ZEND_EXIT) && ZEND_OP1_TYPE(opline) == IS_TMP_VAR && VAR_SOURCE(opline->op1) && @@ -1502,7 +1465,12 @@ static void zend_jmp_optimization(zend_code_block *block, zend_op_array *op_arra case ZEND_JMPNZ: /* constant conditional JMPs */ if (ZEND_OP1_TYPE(last_op) == IS_CONST) { +#if ZEND_EXTENSION_API_NO > PHP_5_6_X_API_NO + int should_jmp = zend_is_true(&ZEND_OP1_LITERAL(last_op) TSRMLS_CC); +#else int should_jmp = zend_is_true(&ZEND_OP1_LITERAL(last_op)); +#endif + if (last_op->opcode == ZEND_JMPZ) { should_jmp = !should_jmp; } @@ -1645,7 +1613,12 @@ static void zend_jmp_optimization(zend_code_block *block, zend_op_array *op_arra case ZEND_JMPZ_EX: /* constant conditional JMPs */ if (ZEND_OP1_TYPE(last_op) == IS_CONST) { +#if ZEND_EXTENSION_API_NO > PHP_5_6_X_API_NO + int should_jmp = zend_is_true(&ZEND_OP1_LITERAL(last_op) TSRMLS_CC); +#else int should_jmp = zend_is_true(&ZEND_OP1_LITERAL(last_op)); +#endif + if (last_op->opcode == ZEND_JMPZ_EX) { should_jmp = !should_jmp; } @@ -1766,7 +1739,11 @@ static void zend_jmp_optimization(zend_code_block *block, zend_op_array *op_arra } if (ZEND_OP1_TYPE(last_op) == IS_CONST) { +#if ZEND_EXTENSION_API_NO > PHP_5_6_X_API_NO + if (!zend_is_true(&ZEND_OP1_LITERAL(last_op) TSRMLS_CC)) { +#else if (!zend_is_true(&ZEND_OP1_LITERAL(last_op))) { +#endif /* JMPZNZ(false,L1,L2) -> JMP(L1) */ zend_code_block *todel; @@ -1899,7 +1876,7 @@ static void zend_jmp_optimization(zend_code_block *block, zend_op_array *op_arra #endif /* Find a set of variables which are used outside of the block where they are - * defined. We won't apply some optimization patterns for sush variables. */ + * defined. We won't apply some optimization patterns for such variables. */ static void zend_t_usage(zend_code_block *block, zend_op_array *op_array, char *used_ext) { zend_code_block *next_block = block->next; @@ -1931,6 +1908,7 @@ static void zend_t_usage(zend_code_block *block, zend_op_array *op_array, char * if (RESULT_USED(opline)) { if (!defined_here[VAR_NUM(ZEND_RESULT(opline).var)] && !used_ext[VAR_NUM(ZEND_RESULT(opline).var)] && (opline->opcode == ZEND_RECV || opline->opcode == ZEND_RECV_INIT || + opline->opcode == ZEND_RECV_VARIADIC || (opline->opcode == ZEND_OP_DATA && ZEND_RESULT_TYPE(opline) == IS_TMP_VAR) || opline->opcode == ZEND_ADD_ARRAY_ELEMENT)) { /* these opcodes use the result as argument */ @@ -2015,6 +1993,7 @@ static void zend_t_usage(zend_code_block *block, zend_op_array *op_array, char * if (opline->opcode == ZEND_RECV || opline->opcode == ZEND_RECV_INIT || + opline->opcode == ZEND_RECV_VARIADIC || opline->opcode == ZEND_ADD_ARRAY_ELEMENT) { if (ZEND_OP1_TYPE(opline) == IS_VAR || ZEND_OP1_TYPE(opline) == IS_TMP_VAR) { usage[VAR_NUM(ZEND_RESULT(opline).var)] = 1; diff --git a/ext/opcache/Optimizer/pass1_5.c b/ext/opcache/Optimizer/pass1_5.c index 9309d4b462094..4601562566819 100644 --- a/ext/opcache/Optimizer/pass1_5.c +++ b/ext/opcache/Optimizer/pass1_5.c @@ -3,8 +3,15 @@ * - perform compile-time evaluation of constant binary and unary operations * - optimize series of ADD_STRING and/or ADD_CHAR * - convert CAST(IS_BOOL,x) into BOOL(x) + * - pre-evaluate constant function calls */ +#if ZEND_EXTENSION_API_NO > PHP_5_2_X_API_NO +# define ZEND_IS_CONSTANT_TYPE(t) (((t) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) +#else +# define ZEND_IS_CONSTANT_TYPE(t) ((t) == IS_CONSTANT) +#endif + if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { int i = 0; zend_op *opline = op_array->opcodes; @@ -37,7 +44,6 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC) = get_binary_op(opline->opcode); zend_uint tv = ZEND_RESULT(opline).var; /* temporary variable */ zval result; - zend_op *tmp_opline; int er; if (opline->opcode == ZEND_DIV && @@ -61,95 +67,7 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { literal_dtor(&ZEND_OP2_LITERAL(opline)); MAKE_NOP(opline); - /* substitute the following TMP_VAR usage with constant */ - for (tmp_opline = opline + 1; tmp_opline < end; tmp_opline++) { - if (ZEND_OP1_TYPE(tmp_opline) == IS_TMP_VAR && - ZEND_OP1(tmp_opline).var == tv) { - if (tmp_opline->opcode == ZEND_FREE) { - MAKE_NOP(tmp_opline); - zval_dtor(&result); - } else { - ZEND_OP1_TYPE(tmp_opline) = IS_CONST; -#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO - tmp_opline->op1.constant = zend_optimizer_add_literal(op_array, &result TSRMLS_CC); - if (Z_TYPE(result) == IS_STRING) { - Z_HASH_P(&ZEND_OP1_LITERAL(tmp_opline)) = zend_hash_func(Z_STRVAL(ZEND_OP1_LITERAL(tmp_opline)), Z_STRLEN(ZEND_OP1_LITERAL(tmp_opline)) + 1); - if (tmp_opline->opcode == ZEND_INIT_STATIC_METHOD_CALL || - tmp_opline->opcode == ZEND_DO_FCALL || - tmp_opline->opcode == ZEND_CATCH || - tmp_opline->opcode == ZEND_FETCH_CONSTANT) { - op_array->literals[tmp_opline->op1.constant].cache_slot = op_array->last_cache_slot++; - } - } -#else - ZEND_OP1_LITERAL(tmp_opline) = result; -#endif - } - /* TMP_VAR my be used only once */ - break; - } - if (ZEND_OP2_TYPE(tmp_opline) == IS_TMP_VAR && - ZEND_OP2(tmp_opline).var == tv) { - ZEND_OP2_TYPE(tmp_opline) = IS_CONST; -#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO - tmp_opline->op2.constant = zend_optimizer_add_literal(op_array, &result TSRMLS_CC); - if (Z_TYPE(result) == IS_STRING) { - Z_HASH_P(&ZEND_OP2_LITERAL(tmp_opline)) = zend_hash_func(Z_STRVAL(ZEND_OP2_LITERAL(tmp_opline)), Z_STRLEN(ZEND_OP2_LITERAL(tmp_opline)) + 1); - if (tmp_opline->opcode == ZEND_FETCH_R || - tmp_opline->opcode == ZEND_FETCH_W || - tmp_opline->opcode == ZEND_FETCH_RW || - tmp_opline->opcode == ZEND_FETCH_IS || - tmp_opline->opcode == ZEND_FETCH_UNSET || - tmp_opline->opcode == ZEND_FETCH_FUNC_ARG || - tmp_opline->opcode == ZEND_FETCH_CLASS || - tmp_opline->opcode == ZEND_INIT_FCALL_BY_NAME || - tmp_opline->opcode == ZEND_INIT_NS_FCALL_BY_NAME || - tmp_opline->opcode == ZEND_UNSET_VAR || - tmp_opline->opcode == ZEND_ISSET_ISEMPTY_VAR || - tmp_opline->opcode == ZEND_ADD_INTERFACE || - tmp_opline->opcode == ZEND_ADD_TRAIT) { - op_array->literals[tmp_opline->op2.constant].cache_slot = op_array->last_cache_slot++; - } else if (tmp_opline->opcode == ZEND_INIT_METHOD_CALL || - tmp_opline->opcode == ZEND_INIT_STATIC_METHOD_CALL || - tmp_opline->opcode == ZEND_FETCH_CONSTANT || - tmp_opline->opcode == ZEND_ASSIGN_OBJ || - tmp_opline->opcode == ZEND_FETCH_OBJ_R || - tmp_opline->opcode == ZEND_FETCH_OBJ_W || - tmp_opline->opcode == ZEND_FETCH_OBJ_RW || - tmp_opline->opcode == ZEND_FETCH_OBJ_IS || - tmp_opline->opcode == ZEND_FETCH_OBJ_UNSET || - tmp_opline->opcode == ZEND_FETCH_OBJ_FUNC_ARG || - tmp_opline->opcode == ZEND_UNSET_OBJ || - tmp_opline->opcode == ZEND_PRE_INC_OBJ || - tmp_opline->opcode == ZEND_PRE_DEC_OBJ || - tmp_opline->opcode == ZEND_POST_INC_OBJ || - tmp_opline->opcode == ZEND_POST_DEC_OBJ || - tmp_opline->opcode == ZEND_ISSET_ISEMPTY_PROP_OBJ) { - op_array->literals[tmp_opline->op2.constant].cache_slot = op_array->last_cache_slot; - op_array->last_cache_slot += 2; - } else if (tmp_opline->opcode == ZEND_ASSIGN_ADD || - tmp_opline->opcode == ZEND_ASSIGN_SUB || - tmp_opline->opcode == ZEND_ASSIGN_MUL || - tmp_opline->opcode == ZEND_ASSIGN_DIV || - tmp_opline->opcode == ZEND_ASSIGN_MOD || - tmp_opline->opcode == ZEND_ASSIGN_SL || - tmp_opline->opcode == ZEND_ASSIGN_SR || - tmp_opline->opcode == ZEND_ASSIGN_CONCAT || - tmp_opline->opcode == ZEND_ASSIGN_BW_OR || - tmp_opline->opcode == ZEND_ASSIGN_BW_AND || - tmp_opline->opcode == ZEND_ASSIGN_BW_XOR) { - if (tmp_opline->extended_value == ZEND_ASSIGN_OBJ) { - op_array->literals[tmp_opline->op2.constant].cache_slot = op_array->last_cache_slot; - op_array->last_cache_slot += 2; - } - } - } -#else - ZEND_OP2_LITERAL(tmp_opline) = result; -#endif - break; - } - } + replace_tmp_by_const(op_array, opline + 1, tv, &result TSRMLS_CC); } break; @@ -159,6 +77,7 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { opline->extended_value != IS_OBJECT && opline->extended_value != IS_RESOURCE) { /* cast of constant operand */ + zend_uint tv = ZEND_RESULT(opline).var; /* temporary variable */ zval res; res = ZEND_OP1_LITERAL(opline); zval_copy_ctor(&res); @@ -179,11 +98,11 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { convert_to_string(&res); break; } + literal_dtor(&ZEND_OP1_LITERAL(opline)); - opline->opcode = ZEND_QM_ASSIGN; - opline->extended_value = 0; - ZEND_OP1_LITERAL(opline) = res; - SET_UNUSED(opline->op2); + MAKE_NOP(opline); + + replace_tmp_by_const(op_array, opline + 1, tv, &res TSRMLS_CC); } else if (opline->extended_value == IS_BOOL) { /* T = CAST(X, IS_BOOL) => T = BOOL(X) */ opline->opcode = ZEND_BOOL; @@ -197,7 +116,6 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { /* unary operation on constant operand */ unary_op_type unary_op = get_unary_op(opline->opcode); zval result; - zend_op *tmp_opline; zend_uint tv = ZEND_RESULT(opline).var; /* temporary variable */ int er; @@ -218,34 +136,7 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { literal_dtor(&ZEND_OP1_LITERAL(opline)); MAKE_NOP(opline); - /* substitute the following TMP_VAR usage with constant */ - for (tmp_opline = opline + 1; tmp_opline < end; tmp_opline++) { - if (ZEND_OP1_TYPE(tmp_opline) == IS_TMP_VAR && - ZEND_OP1(tmp_opline).var == tv) { - if (tmp_opline->opcode == ZEND_FREE) { - MAKE_NOP(tmp_opline); - zval_dtor(&result); - } else { - ZEND_OP1_TYPE(tmp_opline) = IS_CONST; -#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO - tmp_opline->op1.constant = zend_optimizer_add_literal(op_array, &result TSRMLS_CC); -#else - ZEND_OP1_LITERAL(tmp_opline) = result; -#endif - } - break; - } - if (ZEND_OP2_TYPE(tmp_opline) == IS_TMP_VAR && - ZEND_OP2(tmp_opline).var == tv) { - ZEND_OP2_TYPE(tmp_opline) = IS_CONST; -#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO - tmp_opline->op2.constant = zend_optimizer_add_literal(op_array, &result TSRMLS_CC); -#else - ZEND_OP2_LITERAL(tmp_opline) = result; -#endif - break; - } - } + replace_tmp_by_const(op_array, opline + 1, tv, &result TSRMLS_CC); } break; @@ -335,15 +226,11 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { EG(in_execution) = 1; EG(active_op_array) = op_array; if (zend_get_constant("__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__") - 1, &offset TSRMLS_CC)) { + zend_uint tv = ZEND_RESULT(opline).var; + literal_dtor(&ZEND_OP2_LITERAL(opline)); - ZEND_OP1_TYPE(opline) = IS_CONST; -#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO - opline->op1.constant = zend_optimizer_add_literal(op_array, &offset TSRMLS_CC); -#else - ZEND_OP1_LITERAL(opline) = offset; -#endif - SET_UNUSED(opline->op2); - opline->opcode = ZEND_QM_ASSIGN; + MAKE_NOP(opline); + replace_tmp_by_const(op_array, opline, tv, &offset TSRMLS_CC); } EG(active_op_array) = orig_op_array; EG(in_execution) = orig_in_execution; @@ -354,6 +241,7 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { ZEND_OP2_TYPE(opline) == IS_CONST && ZEND_OP2_LITERAL(opline).type == IS_STRING) { /* substitute persistent constants */ + zend_uint tv = ZEND_RESULT(opline).var; zval c; if (!zend_get_persistent_constant(Z_STRVAL(ZEND_OP2_LITERAL(opline)), Z_STRLEN(ZEND_OP2_LITERAL(opline)), &c, 1 TSRMLS_CC)) { @@ -362,15 +250,74 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { } } literal_dtor(&ZEND_OP2_LITERAL(opline)); - ZEND_OP1_TYPE(opline) = IS_CONST; + MAKE_NOP(opline); + replace_tmp_by_const(op_array, opline, tv, &c TSRMLS_CC); + } + #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO - opline->op1.constant = zend_optimizer_add_literal(op_array, &c TSRMLS_CC); -#else - ZEND_OP1_LITERAL(opline) = c; -#endif - SET_UNUSED(opline->op2); - opline->opcode = ZEND_QM_ASSIGN; + /* class constant */ + if (ZEND_OP1_TYPE(opline) != IS_UNUSED && + ZEND_OP2_TYPE(opline) == IS_CONST && + ZEND_OP2_LITERAL(opline).type == IS_STRING) { + + zend_class_entry **pce = NULL; + + if (ZEND_OP1_TYPE(opline) == IS_CONST && + ZEND_OP1_LITERAL(opline).type == IS_STRING) { + /* for A::B */ + if (op_array->scope && + !strncasecmp(Z_STRVAL(ZEND_OP1_LITERAL(opline)), + op_array->scope->name, Z_STRLEN(ZEND_OP1_LITERAL(opline)) + 1)) { + pce = &op_array->scope; + } else { + if (zend_hash_quick_find(EG(class_table), + Z_STRVAL(op_array->literals[opline->op1.constant + 1].constant), + Z_STRLEN(op_array->literals[opline->op1.constant].constant) + 1, + Z_HASH_P(&op_array->literals[opline->op1.constant + 1].constant), + (void **)&pce) == FAILURE) { + break; + } + } + } else if (op_array->scope && + ZEND_OP1_TYPE(opline) == IS_VAR && + (opline - 1)->opcode == ZEND_FETCH_CLASS && + (ZEND_OP1_TYPE(opline - 1) == IS_UNUSED && + ((opline - 1)->extended_value & ~ZEND_FETCH_CLASS_NO_AUTOLOAD) == ZEND_FETCH_CLASS_SELF) && + ZEND_RESULT((opline - 1)).var == ZEND_OP1(opline).var) { + /* for self::B */ + pce = &op_array->scope; + } + + if (pce) { + zend_uint tv = ZEND_RESULT(opline).var; + zval **c, t; + + if (zend_hash_find(&(*pce)->constants_table, + Z_STRVAL(ZEND_OP2_LITERAL(opline)), + Z_STRLEN(ZEND_OP2_LITERAL(opline)) + 1, + (void **) &c) == SUCCESS) { + if (ZEND_IS_CONSTANT_TYPE(Z_TYPE_PP(c))) { + if (!zend_get_persistent_constant(Z_STRVAL_PP(c), Z_STRLEN_PP(c), &t, 1 TSRMLS_CC) || + ZEND_IS_CONSTANT_TYPE(Z_TYPE(t))) { + break; + } + } else { + t = **c; + zval_copy_ctor(&t); + } + + if (ZEND_OP1_TYPE(opline) == IS_CONST) { + literal_dtor(&ZEND_OP1_LITERAL(opline)); + } else { + MAKE_NOP((opline - 1)); + } + literal_dtor(&ZEND_OP2_LITERAL(opline)); + MAKE_NOP(opline); + replace_tmp_by_const(op_array, opline, tv, &t TSRMLS_CC); + } + } } +#endif break; case ZEND_DO_FCALL: @@ -389,7 +336,120 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { ZEND_OP1_TYPE(opline-2) == IS_CONST && Z_TYPE(ZEND_OP1_LITERAL(opline-2)) == IS_STRING) { zend_optimizer_collect_constant(constants, &ZEND_OP1_LITERAL(opline-2), &ZEND_OP1_LITERAL(opline-1)); + break; + } else { + /* don't colllect constants after any other function call */ + collect_constants = 0; } + + /* pre-evaluate constant functions: + defined(x) + constant(x) + function_exists(x) + is_callable(x) + extension_loaded(x) + */ + if (opline->extended_value == 1 && (opline - 1)->opcode == ZEND_SEND_VAL && + ZEND_OP1_TYPE(opline - 1) == IS_CONST && ZEND_OP1_LITERAL(opline - 1).type == IS_STRING && + ZEND_OP1_TYPE(opline) == IS_CONST && ZEND_OP1_LITERAL(opline).type == IS_STRING) { + if ((Z_STRLEN(ZEND_OP1_LITERAL(opline)) == sizeof("function_exists")-1 && + !memcmp(Z_STRVAL(ZEND_OP1_LITERAL(opline)), + "function_exists", sizeof("function_exists")-1)) || + (Z_STRLEN(ZEND_OP1_LITERAL(opline)) == sizeof("is_callable")-1 && + !memcmp(Z_STRVAL(ZEND_OP1_LITERAL(opline)), + "is_callable", sizeof("is_callable")))) { + zend_internal_function *func; + char *lc_name = zend_str_tolower_dup( + Z_STRVAL(ZEND_OP1_LITERAL(opline - 1)), Z_STRLEN(ZEND_OP1_LITERAL(opline - 1))); + + if (zend_hash_find(EG(function_table), lc_name, Z_STRLEN(ZEND_OP1_LITERAL(opline - 1)) + 1, + (void *)&func) == SUCCESS && + func->type == ZEND_INTERNAL_FUNCTION && + func->module->type == MODULE_PERSISTENT) { + zval t; + ZVAL_BOOL(&t, 1); + if (replace_var_by_const(op_array, opline + 1, ZEND_RESULT(opline).var, &t TSRMLS_CC)) { + literal_dtor(&ZEND_OP1_LITERAL(opline - 1)); + MAKE_NOP((opline - 1)); + literal_dtor(&ZEND_OP1_LITERAL(opline)); + MAKE_NOP(opline); + } + } + efree(lc_name); + } else if (Z_STRLEN(ZEND_OP1_LITERAL(opline)) == sizeof("extension_loaded")-1 && + !memcmp(Z_STRVAL(ZEND_OP1_LITERAL(opline)), + "extension_loaded", sizeof("extension_loaded")-1)) { + zval t; + zend_module_entry *m; + char *lc_name = zend_str_tolower_dup( + Z_STRVAL(ZEND_OP1_LITERAL(opline - 1)), Z_STRLEN(ZEND_OP1_LITERAL(opline - 1))); + + if (zend_hash_find(&module_registry, + lc_name, Z_STRLEN(ZEND_OP1_LITERAL(opline - 1)) + 1, (void *)&m) == FAILURE) { + if (!PG(enable_dl)) { + break; + } else { + ZVAL_BOOL(&t, 0); + } + } else { + if (m->type == MODULE_PERSISTENT) { + ZVAL_BOOL(&t, 1); + } else { + break; + } + } + + if (replace_var_by_const(op_array, opline + 1, ZEND_RESULT(opline).var, &t TSRMLS_CC)) { + literal_dtor(&ZEND_OP1_LITERAL(opline - 1)); + MAKE_NOP((opline - 1)); + literal_dtor(&ZEND_OP1_LITERAL(opline)); + MAKE_NOP(opline); + } + efree(lc_name); + } else if (Z_STRLEN(ZEND_OP1_LITERAL(opline)) == sizeof("defined")-1 && + !memcmp(Z_STRVAL(ZEND_OP1_LITERAL(opline)), + "defined", sizeof("defined")-1)) { + zval t; + + if (zend_get_persistent_constant(Z_STRVAL(ZEND_OP1_LITERAL(opline - 1)), + Z_STRLEN(ZEND_OP1_LITERAL(opline - 1)), &t, 0 TSRMLS_CC)) { + + ZVAL_BOOL(&t, 1); + if (replace_var_by_const(op_array, opline + 1, ZEND_RESULT(opline).var, &t TSRMLS_CC)) { + literal_dtor(&ZEND_OP1_LITERAL(opline - 1)); + MAKE_NOP((opline - 1)); + literal_dtor(&ZEND_OP1_LITERAL(opline)); + MAKE_NOP(opline); + } + } + } else if (Z_STRLEN(ZEND_OP1_LITERAL(opline)) == sizeof("constant")-1 && + !memcmp(Z_STRVAL(ZEND_OP1_LITERAL(opline)), + "constant", sizeof("constant")-1)) { + zval t; + + if (zend_get_persistent_constant(Z_STRVAL(ZEND_OP1_LITERAL(opline - 1)), + Z_STRLEN(ZEND_OP1_LITERAL(opline - 1)), &t, 0 TSRMLS_CC)) { + if (replace_var_by_const(op_array, opline + 1, ZEND_RESULT(opline).var, &t TSRMLS_CC)) { + literal_dtor(&ZEND_OP1_LITERAL(opline - 1)); + MAKE_NOP((opline - 1)); + literal_dtor(&ZEND_OP1_LITERAL(opline)); + MAKE_NOP(opline); + } + } + } else if (Z_STRLEN(ZEND_OP1_LITERAL(opline)) == sizeof("strlen")-1 && + !memcmp(Z_STRVAL(ZEND_OP1_LITERAL(opline)), + "strlen", sizeof("strlen")-1)) { + zval t; + + ZVAL_LONG(&t, Z_STRLEN(ZEND_OP1_LITERAL(opline - 1))); + if (replace_var_by_const(op_array, opline + 1, ZEND_RESULT(opline).var, &t TSRMLS_CC)) { + literal_dtor(&ZEND_OP1_LITERAL(opline - 1)); + MAKE_NOP((opline - 1)); + literal_dtor(&ZEND_OP1_LITERAL(opline)); + MAKE_NOP(opline); + } + } + } break; #if ZEND_EXTENSION_API_NO > PHP_5_2_X_API_NO case ZEND_DECLARE_CONST: @@ -430,6 +490,7 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { case ZEND_FE_RESET: case ZEND_FE_FETCH: case ZEND_NEW: + case ZEND_DO_FCALL_BY_NAME: #if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO case ZEND_JMP_SET: #endif @@ -453,7 +514,7 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { opline->op2_type == IS_UNUSED && Z_TYPE(ZEND_OP1_LITERAL(opline)) == IS_STRING && (Z_STRLEN(ZEND_OP1_LITERAL(opline)) != sizeof("this")-1 || - memcmp(Z_STRVAL(ZEND_OP1_LITERAL(opline)), "this", sizeof("this")) != 0)) { + memcmp(Z_STRVAL(ZEND_OP1_LITERAL(opline)), "this", sizeof("this") - 1) != 0)) { int var = opline->result.var; int level = 0; diff --git a/ext/opcache/Optimizer/pass2.c b/ext/opcache/Optimizer/pass2.c index 30708a0935baa..d5f4f0492bd1d 100644 --- a/ext/opcache/Optimizer/pass2.c +++ b/ext/opcache/Optimizer/pass2.c @@ -89,7 +89,11 @@ if (ZEND_OPTIMIZER_PASS_2 & OPTIMIZATION_LEVEL) { /* convert Ti = JMPZ_EX(C, L) => Ti = QM_ASSIGN(C) in case we know it wouldn't jump */ } else if (ZEND_OP1_TYPE(opline) == IS_CONST) { +#if ZEND_EXTENSION_API_NO > PHP_5_6_X_API_NO + int should_jmp = zend_is_true(&ZEND_OP1_LITERAL(opline) TSRMLS_CC); +#else int should_jmp = zend_is_true(&ZEND_OP1_LITERAL(opline)); +#endif if (opline->opcode == ZEND_JMPZ_EX) { should_jmp = !should_jmp; } @@ -103,7 +107,11 @@ if (ZEND_OPTIMIZER_PASS_2 & OPTIMIZATION_LEVEL) { case ZEND_JMPZ: case ZEND_JMPNZ: if (ZEND_OP1_TYPE(opline) == IS_CONST) { +#if ZEND_EXTENSION_API_NO > PHP_5_6_X_API_NO + int should_jmp = zend_is_true(&ZEND_OP1_LITERAL(opline) TSRMLS_CC); +#else int should_jmp = zend_is_true(&ZEND_OP1_LITERAL(opline)); +#endif if (opline->opcode == ZEND_JMPZ) { should_jmp = !should_jmp; @@ -139,8 +147,11 @@ if (ZEND_OPTIMIZER_PASS_2 & OPTIMIZATION_LEVEL) { case ZEND_JMPZNZ: if (ZEND_OP1_TYPE(opline) == IS_CONST) { int opline_num; - +#if ZEND_EXTENSION_API_NO > PHP_5_6_X_API_NO + if (zend_is_true(&ZEND_OP1_LITERAL(opline) TSRMLS_CC)) { +#else if (zend_is_true(&ZEND_OP1_LITERAL(opline))) { +#endif opline_num = opline->extended_value; /* JMPNZ */ } else { opline_num = ZEND_OP2(opline).opline_num; /* JMPZ */ diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c index a058bd73cbb14..0426f63514d60 100644 --- a/ext/opcache/Optimizer/zend_optimizer.c +++ b/ext/opcache/Optimizer/zend_optimizer.c @@ -19,6 +19,7 @@ +----------------------------------------------------------------------+ */ +#include "php.h" #include "Optimizer/zend_optimizer.h" #include "Optimizer/zend_optimizer_internal.h" #include "zend_API.h" @@ -138,6 +139,250 @@ int zend_optimizer_add_literal(zend_op_array *op_array, const zval *zv TSRMLS_DC #endif +static void update_op1_const(zend_op_array *op_array, + zend_op *opline, + zval *val TSRMLS_DC) +{ + if (opline->opcode == ZEND_FREE) { + MAKE_NOP(opline); + zval_dtor(val); + } else { + ZEND_OP1_TYPE(opline) = IS_CONST; +#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO + if (Z_TYPE_P(val) == IS_STRING) { + switch (opline->opcode) { + case ZEND_INIT_STATIC_METHOD_CALL: + case ZEND_CATCH: + case ZEND_FETCH_CONSTANT: + opline->op1.constant = zend_optimizer_add_literal(op_array, val TSRMLS_CC); + Z_HASH_P(&ZEND_OP1_LITERAL(opline)) = zend_hash_func(Z_STRVAL(ZEND_OP1_LITERAL(opline)), Z_STRLEN(ZEND_OP1_LITERAL(opline)) + 1); + op_array->literals[opline->op1.constant].cache_slot = op_array->last_cache_slot++; + zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val)); + zend_optimizer_add_literal(op_array, val TSRMLS_CC); + op_array->literals[opline->op1.constant+1].hash_value = zend_hash_func(Z_STRVAL(op_array->literals[opline->op1.constant+1].constant), Z_STRLEN(op_array->literals[opline->op1.constant+1].constant) + 1); + break; + case ZEND_DO_FCALL: + zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val)); + opline->op1.constant = zend_optimizer_add_literal(op_array, val TSRMLS_CC); + Z_HASH_P(&ZEND_OP1_LITERAL(opline)) = zend_hash_func(Z_STRVAL(ZEND_OP1_LITERAL(opline)), Z_STRLEN(ZEND_OP1_LITERAL(opline)) + 1); + op_array->literals[opline->op1.constant].cache_slot = op_array->last_cache_slot++; + break; + default: + opline->op1.constant = zend_optimizer_add_literal(op_array, val TSRMLS_CC); + Z_HASH_P(&ZEND_OP1_LITERAL(opline)) = zend_hash_func(Z_STRVAL(ZEND_OP1_LITERAL(opline)), Z_STRLEN(ZEND_OP1_LITERAL(opline)) + 1); + break; + } + } else { + opline->op1.constant = zend_optimizer_add_literal(op_array, val TSRMLS_CC); + } +#else + ZEND_OP1_LITERAL(opline) = *val; +#endif + } +} + +static void update_op2_const(zend_op_array *op_array, + zend_op *opline, + zval *val TSRMLS_DC) +{ + ZEND_OP2_TYPE(opline) = IS_CONST; +#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO + opline->op2.constant = zend_optimizer_add_literal(op_array, val TSRMLS_CC); + if (Z_TYPE_P(val) == IS_STRING) { + Z_HASH_P(&ZEND_OP2_LITERAL(opline)) = zend_hash_func(Z_STRVAL(ZEND_OP2_LITERAL(opline)), Z_STRLEN(ZEND_OP2_LITERAL(opline)) + 1); + switch (opline->opcode) { + case ZEND_FETCH_R: + case ZEND_FETCH_W: + case ZEND_FETCH_RW: + case ZEND_FETCH_IS: + case ZEND_FETCH_UNSET: + case ZEND_FETCH_FUNC_ARG: + case ZEND_FETCH_CLASS: + case ZEND_INIT_FCALL_BY_NAME: + /*case ZEND_INIT_NS_FCALL_BY_NAME:*/ + case ZEND_UNSET_VAR: + case ZEND_ISSET_ISEMPTY_VAR: + case ZEND_ADD_INTERFACE: + case ZEND_ADD_TRAIT: + op_array->literals[opline->op2.constant].cache_slot = op_array->last_cache_slot++; + zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val)); + zend_optimizer_add_literal(op_array, val TSRMLS_CC); + op_array->literals[opline->op2.constant+1].hash_value = zend_hash_func(Z_STRVAL(op_array->literals[opline->op2.constant+1].constant), Z_STRLEN(op_array->literals[opline->op2.constant+1].constant) + 1); + break; + case ZEND_INIT_METHOD_CALL: + case ZEND_INIT_STATIC_METHOD_CALL: + zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val)); + zend_optimizer_add_literal(op_array, val TSRMLS_CC); + op_array->literals[opline->op2.constant+1].hash_value = zend_hash_func(Z_STRVAL(op_array->literals[opline->op2.constant+1].constant), Z_STRLEN(op_array->literals[opline->op2.constant+1].constant) + 1); + /* break missing intentionally */ + /*case ZEND_FETCH_CONSTANT:*/ + case ZEND_ASSIGN_OBJ: + case ZEND_FETCH_OBJ_R: + case ZEND_FETCH_OBJ_W: + case ZEND_FETCH_OBJ_RW: + case ZEND_FETCH_OBJ_IS: + case ZEND_FETCH_OBJ_UNSET: + case ZEND_FETCH_OBJ_FUNC_ARG: + case ZEND_UNSET_OBJ: + case ZEND_PRE_INC_OBJ: + case ZEND_PRE_DEC_OBJ: + case ZEND_POST_INC_OBJ: + case ZEND_POST_DEC_OBJ: + case ZEND_ISSET_ISEMPTY_PROP_OBJ: + op_array->literals[opline->op2.constant].cache_slot = op_array->last_cache_slot; + op_array->last_cache_slot += 2; + break; + case ZEND_ASSIGN_ADD: + case ZEND_ASSIGN_SUB: + case ZEND_ASSIGN_MUL: + case ZEND_ASSIGN_DIV: + case ZEND_ASSIGN_MOD: + case ZEND_ASSIGN_SL: + case ZEND_ASSIGN_SR: + case ZEND_ASSIGN_CONCAT: + case ZEND_ASSIGN_BW_OR: + case ZEND_ASSIGN_BW_AND: + case ZEND_ASSIGN_BW_XOR: + if (opline->extended_value == ZEND_ASSIGN_OBJ) { + op_array->literals[opline->op2.constant].cache_slot = op_array->last_cache_slot; + op_array->last_cache_slot += 2; + } + break; +#if ZEND_EXTENSION_API_NO >= PHP_5_4_X_API_NO + case ZEND_OP_DATA: + if ((opline-1)->opcode == ZEND_ASSIGN_DIM || + ((opline-1)->extended_value == ZEND_ASSIGN_DIM && + ((opline-1)->opcode == ZEND_ASSIGN_ADD || + (opline-1)->opcode == ZEND_ASSIGN_SUB || + (opline-1)->opcode == ZEND_ASSIGN_MUL || + (opline-1)->opcode == ZEND_ASSIGN_DIV || + (opline-1)->opcode == ZEND_ASSIGN_MOD || + (opline-1)->opcode == ZEND_ASSIGN_SL || + (opline-1)->opcode == ZEND_ASSIGN_SR || + (opline-1)->opcode == ZEND_ASSIGN_CONCAT || + (opline-1)->opcode == ZEND_ASSIGN_BW_OR || + (opline-1)->opcode == ZEND_ASSIGN_BW_AND || + (opline-1)->opcode == ZEND_ASSIGN_BW_XOR))) { + goto check_numeric; + } + break; + case ZEND_ISSET_ISEMPTY_DIM_OBJ: + case ZEND_ADD_ARRAY_ELEMENT: + case ZEND_INIT_ARRAY: + case ZEND_UNSET_DIM: + case ZEND_FETCH_DIM_R: + case ZEND_FETCH_DIM_W: + case ZEND_FETCH_DIM_RW: + case ZEND_FETCH_DIM_IS: + case ZEND_FETCH_DIM_FUNC_ARG: + case ZEND_FETCH_DIM_UNSET: + case ZEND_FETCH_DIM_TMP_VAR: +check_numeric: + { + ulong index; + int numeric = 0; + + ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(val), Z_STRLEN_P(val)+1, index, numeric = 1); + if (numeric) { + zval_dtor(val); + ZVAL_LONG(val, index); + op_array->literals[opline->op2.constant].constant = *val; + } + } + break; +#endif + default: + break; + } + } +#else + ZEND_OP2_LITERAL(opline) = *val; +#endif +} + +static int replace_var_by_const(zend_op_array *op_array, + zend_op *opline, + zend_uint var, + zval *val TSRMLS_DC) +{ + zend_op *end = op_array->opcodes + op_array->last; + + while (opline < end) { + if (ZEND_OP1_TYPE(opline) == IS_VAR && + ZEND_OP1(opline).var == var) { + switch (opline->opcode) { + case ZEND_FETCH_DIM_W: + case ZEND_FETCH_DIM_RW: + case ZEND_FETCH_DIM_FUNC_ARG: + case ZEND_FETCH_DIM_UNSET: + case ZEND_ASSIGN_DIM: +#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO + case ZEND_SEPARATE: +#endif + return 0; + case ZEND_SEND_VAR_NO_REF: + if (opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) { + if (opline->extended_value & ZEND_ARG_SEND_BY_REF) { + return 0; + } + opline->extended_value = ZEND_DO_FCALL; + } else { + opline->extended_value = ZEND_DO_FCALL_BY_NAME; + } + opline->opcode = ZEND_SEND_VAL; + break; + default: + break; + } + update_op1_const(op_array, opline, val TSRMLS_CC); + break; + } + + if (ZEND_OP2_TYPE(opline) == IS_VAR && + ZEND_OP2(opline).var == var) { + switch (opline->opcode) { + case ZEND_ASSIGN_REF: + return 0; + default: + break; + } + update_op2_const(op_array, opline, val TSRMLS_CC); + break; + } + opline++; + } + + return 1; +} + +static void replace_tmp_by_const(zend_op_array *op_array, + zend_op *opline, + zend_uint var, + zval *val + TSRMLS_DC) +{ + zend_op *end = op_array->opcodes + op_array->last; + + while (opline < end) { + if (ZEND_OP1_TYPE(opline) == IS_TMP_VAR && + ZEND_OP1(opline).var == var) { + + update_op1_const(op_array, opline, val TSRMLS_CC); + /* TMP_VAR my be used only once */ + break; + } + + if (ZEND_OP2_TYPE(opline) == IS_TMP_VAR && + ZEND_OP2(opline).var == var) { + + update_op2_const(op_array, opline, val TSRMLS_CC); + /* TMP_VAR my be used only once */ + break; + } + opline++; + } +} + #include "Optimizer/nop_removal.c" #include "Optimizer/block_pass.c" #include "Optimizer/optimize_temp_vars_5.c" @@ -165,6 +410,7 @@ static void zend_optimize(zend_op_array *op_array, * - convert non-numeric constants to numeric constants in numeric operators * - optimize constant conditional JMPs * - optimize static BRKs and CONTs + * - pre-evaluate constant function calls */ #include "Optimizer/pass2.c" diff --git a/ext/opcache/README b/ext/opcache/README index 6c3cc746e77c0..cb6ac342c49b5 100644 --- a/ext/opcache/README +++ b/ext/opcache/README @@ -31,8 +31,8 @@ Quick Install zend_extension=/...full path.../opcache.so -NOTE: In case you are going to use Zend OPcache together with Xdebug, -be sure that Xdebug is loaded after OPcache. "php -v" must show Xdebug +NOTE: In case you are going to use Zend OPcache together with Xdebug or Zend Debugger, +be sure that the debugger is loaded after OPcache. "php -v" must show the debugger after OPcache. - Restart PHP @@ -80,8 +80,8 @@ opcache.max_accelerated_files (default "2000") The maximum number of keys (scripts) in the OPcache hash table. The number is actually the first one in the following set of prime numbers that is bigger than the one supplied: { 223, 463, 983, 1979, 3907, - 7963, 16229, 32531, 65407, 130987 }. Only numbers between 200 and 100000 - are allowed. + 7963, 16229, 32531, 65407, 130987, 262237, 524521, 1048793 }. Only numbers + between 200 and 1000000 are allowed. opcache.max_wasted_percentage (default "5") The maximum percentage of "wasted" memory until a restart is scheduled. @@ -103,6 +103,12 @@ opcache.revalidate_freq (default "2") memory storage allocation. ("1" means validate once per second, but only once per request. "0" means always validate) +opcache.file_update_protection (default "2") + Prevents caching files that are less than this number of seconds old. + It protects from caching of incompletely updated files. In case all file + updates on your site are atomic, you may increase performance setting it + to "0". + opcache.revalidate_path (default "0") Enables or disables file search in include_path optimization If the file search is disabled and a cached file is found that uses diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index 52e9e9844307d..7204acb9fac18 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -36,7 +36,7 @@ #include "main/php_open_temporary_file.h" #include "zend_API.h" #include "zend_ini.h" -#include "TSRM/tsrm_virtual_cwd.h" +#include "zend_virtual_cwd.h" #include "zend_accelerator_util_funcs.h" #include "zend_accelerator_hash.h" @@ -1157,8 +1157,9 @@ static zend_persistent_script *cache_script_in_shared_memory(zend_persistent_scr zend_persistent_script *existing_persistent_script = (zend_persistent_script *)bucket->data; if (!existing_persistent_script->corrupted) { - if (!ZCG(accel_directives).validate_timestamps || - (new_persistent_script->timestamp == existing_persistent_script->timestamp)) { + if (!ZCG(accel_directives).revalidate_path && + (!ZCG(accel_directives).validate_timestamps || + (new_persistent_script->timestamp == existing_persistent_script->timestamp))) { zend_accel_add_key(key, key_length, bucket TSRMLS_CC); } zend_shared_alloc_unlock(TSRMLS_C); @@ -1199,7 +1200,9 @@ static zend_persistent_script *cache_script_in_shared_memory(zend_persistent_scr /* store script structure in the hash table */ bucket = zend_accel_hash_update(&ZCSG(hash), new_persistent_script->full_path, new_persistent_script->full_path_len + 1, 0, new_persistent_script); - if (bucket && + if (bucket && !ZCG(accel_directives).revalidate_path && + /* key may contain non-persistent PHAR aliases (see issues #115 and #149) */ + memcmp(key, "phar://", sizeof("phar://") - 1) != 0 && (new_persistent_script->full_path_len != key_length || memcmp(new_persistent_script->full_path, key, key_length) != 0)) { /* link key to the same persistent script in hash table */ @@ -1333,7 +1336,9 @@ static zend_persistent_script *compile_and_cache_file(zend_file_handle *file_han } #endif - if (ZCG(accel_directives).validate_timestamps || ZCG(accel_directives).max_file_size > 0) { + if (ZCG(accel_directives).validate_timestamps || + ZCG(accel_directives).file_update_protection || + ZCG(accel_directives).max_file_size > 0) { size_t size = 0; /* Obtain the file timestamps, *before* actually compiling them, @@ -1349,6 +1354,13 @@ static zend_persistent_script *compile_and_cache_file(zend_file_handle *file_han return NULL; } + /* check if file is too new (may be it's not written completely yet) */ + if (ZCG(accel_directives).file_update_protection && + (ZCG(request_time) - ZCG(accel_directives).file_update_protection < timestamp)) { + *op_array_p = accelerator_orig_compile_file(file_handle, type TSRMLS_CC); + return NULL; + } + if (ZCG(accel_directives).max_file_size > 0 && size > (size_t)ZCG(accel_directives).max_file_size) { ZCSG(blacklist_misses)++; *op_array_p = accelerator_orig_compile_file(file_handle, type TSRMLS_CC); @@ -1450,7 +1462,7 @@ static zend_persistent_script *compile_and_cache_file(zend_file_handle *file_han } /* zend_compile() replacement */ -static zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type TSRMLS_DC) +zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type TSRMLS_DC) { zend_persistent_script *persistent_script = NULL; char *key = NULL; @@ -1655,7 +1667,18 @@ static zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int #endif void *dummy = (void *) 1; - zend_hash_quick_add(&EG(included_files), persistent_script->full_path, persistent_script->full_path_len + 1, persistent_script->hash_value, &dummy, sizeof(void *), NULL); + if (zend_hash_quick_add(&EG(included_files), persistent_script->full_path, persistent_script->full_path_len + 1, persistent_script->hash_value, &dummy, sizeof(void *), NULL) == SUCCESS) { + /* ext/phar has to load phar's metadata into memory */ + if (strstr(persistent_script->full_path, ".phar") && !strstr(persistent_script->full_path, "://")) { + php_stream_statbuf ssb; + char *fname = emalloc(sizeof("phar://") + persistent_script->full_path_len); + + memcpy(fname, "phar://", sizeof("phar://") - 1); + memcpy(fname + sizeof("phar://") - 1, persistent_script->full_path, persistent_script->full_path_len + 1); + php_stream_stat_path(fname, &ssb); + efree(fname); + } + } } } #if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO @@ -2411,14 +2434,14 @@ static inline int accel_find_sapi(TSRMLS_D) return FAILURE; } -static void zend_accel_init_shm(TSRMLS_D) +static int zend_accel_init_shm(TSRMLS_D) { zend_shared_alloc_lock(TSRMLS_C); accel_shared_globals = zend_shared_alloc(sizeof(zend_accel_shared_globals)); if (!accel_shared_globals) { zend_accel_error(ACCEL_LOG_FATAL, "Insufficient shared memory!"); - return; + return FAILURE; } ZSMMG(app_shared_globals) = accel_shared_globals; @@ -2433,7 +2456,8 @@ static void zend_accel_init_shm(TSRMLS_D) ZCSG(interned_strings).arBuckets = zend_shared_alloc(ZCSG(interned_strings).nTableSize * sizeof(Bucket *)); ZCSG(interned_strings_start) = zend_shared_alloc((ZCG(accel_directives).interned_strings_buffer * 1024 * 1024)); if (!ZCSG(interned_strings).arBuckets || !ZCSG(interned_strings_start)) { - zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME " cannot allocate buffer for interned strings"); + zend_accel_error(ACCEL_LOG_FATAL, ACCELERATOR_PRODUCT_NAME " cannot allocate buffer for interned strings"); + return FAILURE; } ZCSG(interned_strings_end) = ZCSG(interned_strings_start) + (ZCG(accel_directives).interned_strings_buffer * 1024 * 1024); ZCSG(interned_strings_top) = ZCSG(interned_strings_start); @@ -2472,6 +2496,8 @@ static void zend_accel_init_shm(TSRMLS_D) ZCSG(restart_in_progress) = 0; zend_shared_alloc_unlock(TSRMLS_C); + + return SUCCESS; } static void accel_globals_ctor(zend_accel_globals *accel_globals TSRMLS_DC) @@ -2503,7 +2529,11 @@ static int accel_startup(zend_extension *extension) _setmaxstdio(2048); /* The default configuration is limited to 512 stdio files */ #endif +#if ZEND_EXTENSION_API_NO > PHP_5_6_X_API_NO + if (start_accel_module(TSRMLS_C) == FAILURE) { +#else if (start_accel_module() == FAILURE) { +#endif accel_startup_ok = 0; zend_error(E_WARNING, ACCELERATOR_PRODUCT_NAME ": module registration failed!"); return FAILURE; @@ -2529,7 +2559,10 @@ static int accel_startup(zend_extension *extension) /********************************************/ switch (zend_shared_alloc_startup(ZCG(accel_directives).memory_consumption)) { case ALLOC_SUCCESS: - zend_accel_init_shm(TSRMLS_C); + if (zend_accel_init_shm(TSRMLS_C) == FAILURE) { + accel_startup_ok = 0; + return FAILURE; + } break; case ALLOC_FAILURE: accel_startup_ok = 0; @@ -2706,6 +2739,7 @@ void zend_accel_schedule_restart(zend_accel_restart_reason reason TSRMLS_DC) } zend_accel_error(ACCEL_LOG_DEBUG, "Restart Scheduled!"); + SHM_UNPROTECT(); ZCSG(restart_pending) = 1; ZCSG(restart_reason) = reason; ZCSG(cache_status_before_restart) = ZCSG(accelerator_enabled); @@ -2716,6 +2750,7 @@ void zend_accel_schedule_restart(zend_accel_restart_reason reason TSRMLS_DC) } else { ZCSG(force_restart_time) = 0; } + SHM_PROTECT(); } /* this is needed because on WIN32 lock is not decreased unless ZCG(counted) is set */ diff --git a/ext/opcache/ZendAccelerator.h b/ext/opcache/ZendAccelerator.h index 38f2e060f6e2e..7ffd0126b321f 100644 --- a/ext/opcache/ZendAccelerator.h +++ b/ext/opcache/ZendAccelerator.h @@ -80,6 +80,9 @@ # endif # include #else +# ifndef MAXPATHLEN +# define MAXPATHLEN 4096 +# endif # include #endif @@ -89,6 +92,7 @@ #define PHP_5_3_X_API_NO 220090626 #define PHP_5_4_X_API_NO 220100525 #define PHP_5_5_X_API_NO 220121212 +#define PHP_5_6_X_API_NO 220131106 /*** file locking ***/ #ifndef ZEND_WIN32 @@ -100,7 +104,7 @@ extern int lock_file; # elif defined(__svr4__) # define FLOCK_STRUCTURE(name, type, whence, start, len) \ struct flock name = {type, whence, start, len} -# elif defined(__linux__) || defined(__hpux) +# elif defined(__linux__) || defined(__hpux) || defined(__GNU__) # define FLOCK_STRUCTURE(name, type, whence, start, len) \ struct flock name = {type, whence, start, len, 0} # elif defined(_AIX) @@ -111,6 +115,12 @@ extern int lock_file; # define FLOCK_STRUCTURE(name, type, whence, start, len) \ struct flock name = {type, whence, start, len} # endif +# elif defined(HAVE_FLOCK_BSD) +# define FLOCK_STRUCTURE(name, type, whence, start, len) \ + struct flock name = {start, len, -1, type, whence} +# elif defined(HAVE_FLOCK_LINUX) +# define FLOCK_STRUCTURE(name, type, whence, start, len) \ + struct flock name = {type, whence, start, len} # else # error "Don't know how to define struct flock" # endif @@ -220,6 +230,7 @@ typedef struct _zend_accel_directives { zend_bool inherited_hack; zend_bool enable_cli; unsigned long revalidate_freq; + unsigned long file_update_protection; char *error_log; #ifdef ZEND_WIN32 char *mmap_base; @@ -326,6 +337,7 @@ int accelerator_shm_read_lock(TSRMLS_D); void accelerator_shm_read_unlock(TSRMLS_D); char *accel_make_persistent_key_ex(zend_file_handle *file_handle, int path_length, int *key_len TSRMLS_DC); +zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type TSRMLS_DC); #if !defined(ZEND_DECLARE_INHERITED_CLASS_DELAYED) # define ZEND_DECLARE_INHERITED_CLASS_DELAYED 145 diff --git a/ext/opcache/config.m4 b/ext/opcache/config.m4 index 1798fe13fa80d..60edeed966b36 100644 --- a/ext/opcache/config.m4 +++ b/ext/opcache/config.m4 @@ -326,40 +326,42 @@ int main() { msg=yes,msg=no,msg=no) AC_MSG_RESULT([$msg]) - AC_MSG_CHECKING(for known struct flock definition) - dnl Copied from ZendAccelerator.h - AC_TRY_RUN([ -#include -#include - -#ifndef ZEND_WIN32 -extern int lock_file; - -# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || (defined(__APPLE__) && defined(__MACH__)/* Darwin */) || defined(__OpenBSD__) || defined(__NetBSD__) -# define FLOCK_STRUCTURE(name, type, whence, start, len) \ - struct flock name = {start, len, -1, type, whence} -# elif defined(__svr4__) -# define FLOCK_STRUCTURE(name, type, whence, start, len) \ - struct flock name = {type, whence, start, len} -# elif defined(__linux__) || defined(__hpux) -# define FLOCK_STRUCTURE(name, type, whence, start, len) \ - struct flock name = {type, whence, start, len, 0} -# elif defined(_AIX) -# if defined(_LARGE_FILES) || defined(__64BIT__) -# define FLOCK_STRUCTURE(name, type, whence, start, len) \ - struct flock name = {type, whence, 0, 0, 0, start, len } -# else -# define FLOCK_STRUCTURE(name, type, whence, start, len) \ - struct flock name = {type, whence, start, len} -# endif -# else -# error "Don't know how to define struct flock" -# endif -#endif -int main() { return 0; } -], -[AC_MSG_RESULT([done])], -[AC_MSG_ERROR([Don't know how to define struct flock on this system[,] set --enable-opcache=no])], []) +flock_type=unknown +AC_MSG_CHECKING("whether flock struct is linux ordered") +AC_TRY_RUN([ + #include + struct flock lock = { 1, 2, 3, 4, 5 }; + int main() { + if(lock.l_type == 1 && lock.l_whence == 2 && lock.l_start == 3 && lock.l_len == 4) { + return 0; + } + return 1; + } +], [ + flock_type=linux + AC_DEFINE([HAVE_FLOCK_LINUX], [], [Struct flock is Linux-type]) + AC_MSG_RESULT("yes") +], AC_MSG_RESULT("no") ) + +AC_MSG_CHECKING("whether flock struct is BSD ordered") +AC_TRY_RUN([ + #include + struct flock lock = { 1, 2, 3, 4, 5 }; + int main() { + if(lock.l_start == 1 && lock.l_len == 2 && lock.l_type == 4 && lock.l_whence == 5) { + return 0; + } + return 1; + } +], [ + flock_type=bsd + AC_DEFINE([HAVE_FLOCK_BSD], [], [Struct flock is BSD-type]) + AC_MSG_RESULT("yes") +], AC_MSG_RESULT("no") ) + +if test "$flock_type" == "unknown"; then + AC_MSG_ERROR([Don't know how to define struct flock on this system[,] set --enable-opcache=no]) +fi PHP_NEW_EXTENSION(opcache, ZendAccelerator.c \ diff --git a/ext/opcache/tests/bug65559.phpt b/ext/opcache/tests/bug65559.phpt new file mode 100644 index 0000000000000..0d40cf10f88d8 --- /dev/null +++ b/ext/opcache/tests/bug65559.phpt @@ -0,0 +1,22 @@ +--TEST-- +Bug #65559 (cache not cleared if changes occur while running) +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=2 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +int(1) +int(2) diff --git a/ext/opcache/tests/bug65845.phpt b/ext/opcache/tests/bug65845.phpt new file mode 100644 index 0000000000000..2ae5f3974ae93 --- /dev/null +++ b/ext/opcache/tests/bug65845.phpt @@ -0,0 +1,14 @@ +--TEST-- +Bug #65845 (Error when Zend Opcache Optimizer is fully enabled) +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +string(4) "tutu" diff --git a/ext/opcache/tests/bug65915.phpt b/ext/opcache/tests/bug65915.phpt new file mode 100644 index 0000000000000..6496ee325301d --- /dev/null +++ b/ext/opcache/tests/bug65915.phpt @@ -0,0 +1,26 @@ +--TEST-- +Bug #65915 (Inconsistent results with require return value) +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +string(1) "a" +string(1) "b" diff --git a/ext/opcache/tests/bug66176.phpt b/ext/opcache/tests/bug66176.phpt new file mode 100644 index 0000000000000..a91024a6160b0 --- /dev/null +++ b/ext/opcache/tests/bug66176.phpt @@ -0,0 +1,19 @@ +--TEST-- +Bug #66176 (Invalid constant substitution) +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=-1 +opcache.file_update_protection=0 +--SKIPIF-- + +--FILE-- + 1); +var_dump(foo(PHP_VERSION)); +--EXPECT-- +int(1) diff --git a/ext/opcache/tests/bug66251.phpt b/ext/opcache/tests/bug66251.phpt new file mode 100644 index 0000000000000..23a5165234dc5 --- /dev/null +++ b/ext/opcache/tests/bug66251.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #66251 (Constants get statically bound at compile time when Optimized) +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=-1 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Notice: Use of undefined constant A - assumed 'A' in %sbug66251.php on line 4 +A=A diff --git a/ext/opcache/tests/issue0115.phpt b/ext/opcache/tests/issue0115.phpt new file mode 100644 index 0000000000000..a1e469ff2fec2 --- /dev/null +++ b/ext/opcache/tests/issue0115.phpt @@ -0,0 +1,48 @@ +--TEST-- +ISSUE #115 (path issue when using phar) +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +phar.readonly=0 +--SKIPIF-- + + + +--FILE-- +'; +$p = new Phar(__DIR__ . '/issue0115_1.phar.php', 0, 'this'); +$p['index.php'] = 'setStub($stub); +unset($p); +$p = new Phar(__DIR__ . '/issue0115_2.phar.php', 0, 'this'); +$p['index.php'] = 'setStub($stub); +unset($p); + +include "php_cli_server.inc"; +php_cli_server_start('-d opcache.enable=1 -d opcache.enable_cli=1'); +echo file_get_contents('http://' . PHP_CLI_SERVER_ADDRESS . '/issue0115_1.phar.php'); +echo file_get_contents('http://' . PHP_CLI_SERVER_ADDRESS . '/issue0115_2.phar.php'); +?> +--CLEAN-- + +--EXPECT-- +Hello from Index 1. +Hello World 1! +Hello from Index 2. +Hello World 2! diff --git a/ext/opcache/tests/issue0149.phpt b/ext/opcache/tests/issue0149.phpt new file mode 100644 index 0000000000000..7044d3938837a --- /dev/null +++ b/ext/opcache/tests/issue0149.phpt @@ -0,0 +1,35 @@ +--TEST-- +ISSUE #149 (Phar mount points not working this OPcache enabled) +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +phar.readonly=0 +--SKIPIF-- + + + +--FILE-- +"; +$p = new Phar(__DIR__ . '/issue0149.phar.php', 0, 'this'); +$p['index.php'] = ""; # A Phar must have at least one file, hence this dummy +$p->setStub($stub); +unset($p); + +include "php_cli_server.inc"; +php_cli_server_start('-d opcache.enable=1 -d opcache.enable_cli=1'); +echo file_get_contents('http://' . PHP_CLI_SERVER_ADDRESS . '/issue0149.phar.php'); +echo file_get_contents('http://' . PHP_CLI_SERVER_ADDRESS . '/issue0149.phar.php'); +echo file_get_contents('http://' . PHP_CLI_SERVER_ADDRESS . '/issue0149.phar.php'); +?> +--CLEAN-- + +--EXPECT-- +OK +OK +OK diff --git a/ext/opcache/tests/php_cli_server.inc b/ext/opcache/tests/php_cli_server.inc new file mode 100644 index 0000000000000..0878bfafc0d27 --- /dev/null +++ b/ext/opcache/tests/php_cli_server.inc @@ -0,0 +1,47 @@ + STDIN, + 1 => STDOUT, + 2 => STDERR, + ); + + if (substr(PHP_OS, 0, 3) == 'WIN') { + $cmd = "{$php_executable} -t {$doc_root} $ini -S " . PHP_CLI_SERVER_ADDRESS; + $handle = proc_open(addslashes($cmd), $descriptorspec, $pipes, $doc_root, NULL, array("bypass_shell" => true, "suppress_errors" => true)); + } else { + $cmd = "exec {$php_executable} -t {$doc_root} $ini -S " . PHP_CLI_SERVER_ADDRESS . " 2>/dev/null"; + $handle = proc_open($cmd, $descriptorspec, $pipes, $doc_root); + } + + // note: even when server prints 'Listening on localhost:8964...Press Ctrl-C to quit.' + // it might not be listening yet...need to wait until fsockopen() call returns + $i = 0; + while (($i++ < 30) && !($fp = @fsockopen(PHP_CLI_SERVER_HOSTNAME, PHP_CLI_SERVER_PORT))) { + usleep(10000); + } + + if ($fp) { + fclose($fp); + } + + register_shutdown_function( + function($handle) { + proc_terminate($handle); + }, + $handle + ); + // don't bother sleeping, server is already up + // server can take a variable amount of time to be up, so just sleeping a guessed amount of time + // does not work. this is why tests sometimes pass and sometimes fail. to get a reliable pass + // sleeping doesn't work. +} +?> + diff --git a/ext/opcache/tests/revalidate_path_01.phpt b/ext/opcache/tests/revalidate_path_01.phpt new file mode 100644 index 0000000000000..cf2ac0d829683 --- /dev/null +++ b/ext/opcache/tests/revalidate_path_01.phpt @@ -0,0 +1,61 @@ +--TEST-- +revalidate_path 01: OPCache must cache only resolved real paths when revalidate_path is set +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.revalidate_path=1 +--SKIPIF-- + + +--FILE-- + +--CLEAN-- + +--EXPECT-- +TEST 1 +TEST 1 +TEST 2 +TEST 2 diff --git a/ext/opcache/zend_accelerator_blacklist.c b/ext/opcache/zend_accelerator_blacklist.c index da83cfd3119e1..eb0bc2146cd55 100644 --- a/ext/opcache/zend_accelerator_blacklist.c +++ b/ext/opcache/zend_accelerator_blacklist.c @@ -314,6 +314,7 @@ void zend_accel_blacklist_load(zend_blacklist *blacklist, char *filename) blacklist->entries[blacklist->pos].path = (char *)malloc(path_length + 1); if (!blacklist->entries[blacklist->pos].path) { zend_accel_error(ACCEL_LOG_ERROR, "malloc() failed\n"); + fclose(fp); return; } blacklist->entries[blacklist->pos].id = blacklist->pos; diff --git a/ext/opcache/zend_accelerator_module.c b/ext/opcache/zend_accelerator_module.c index f9ddaa98b8ba0..1034e3e05d4eb 100644 --- a/ext/opcache/zend_accelerator_module.c +++ b/ext/opcache/zend_accelerator_module.c @@ -28,13 +28,13 @@ #include "zend_accelerator_blacklist.h" #include "php_ini.h" #include "SAPI.h" -#include "TSRM/tsrm_virtual_cwd.h" +#include "zend_virtual_cwd.h" #include "ext/standard/info.h" #include "ext/standard/php_filestat.h" #define STRING_NOT_NULL(s) (NULL == (s)?"":s) #define MIN_ACCEL_FILES 200 -#define MAX_ACCEL_FILES 100000 +#define MAX_ACCEL_FILES 1000000 #define TOKENTOSTR(X) #X static void (*orig_file_exists)(INTERNAL_FUNCTION_PARAMETERS) = NULL; @@ -48,6 +48,10 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_opcache_get_status, 0, 0, 0) ZEND_ARG_INFO(0, fetch_scripts) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(arginfo_opcache_compile_file, 0, 0, 1) + ZEND_ARG_INFO(0, file) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO_EX(arginfo_opcache_invalidate, 0, 0, 1) ZEND_ARG_INFO(0, script) ZEND_ARG_INFO(0, force) @@ -59,12 +63,14 @@ static ZEND_FUNCTION(opcache_invalidate); /* Private functions */ static ZEND_FUNCTION(opcache_get_status); +static ZEND_FUNCTION(opcache_compile_file); static ZEND_FUNCTION(opcache_get_configuration); static zend_function_entry accel_functions[] = { /* User functions */ ZEND_FE(opcache_reset, arginfo_opcache_none) ZEND_FE(opcache_invalidate, arginfo_opcache_invalidate) + ZEND_FE(opcache_compile_file, arginfo_opcache_compile_file) /* Private functions */ ZEND_FE(opcache_get_configuration, arginfo_opcache_none) ZEND_FE(opcache_get_status, arginfo_opcache_get_status) @@ -253,7 +259,8 @@ ZEND_INI_BEGIN() STD_PHP_INI_ENTRY("opcache.consistency_checks" , "0" , PHP_INI_ALL , OnUpdateLong, accel_directives.consistency_checks, zend_accel_globals, accel_globals) STD_PHP_INI_ENTRY("opcache.force_restart_timeout" , "180" , PHP_INI_SYSTEM, OnUpdateLong, accel_directives.force_restart_timeout, zend_accel_globals, accel_globals) STD_PHP_INI_ENTRY("opcache.revalidate_freq" , "2" , PHP_INI_ALL , OnUpdateLong, accel_directives.revalidate_freq, zend_accel_globals, accel_globals) - STD_PHP_INI_ENTRY("opcache.preferred_memory_model", "" , PHP_INI_SYSTEM, OnUpdateStringUnempty, accel_directives.memory_model, zend_accel_globals, accel_globals) + STD_PHP_INI_ENTRY("opcache.file_update_protection", "2" , PHP_INI_ALL , OnUpdateLong, accel_directives.file_update_protection, zend_accel_globals, accel_globals) + STD_PHP_INI_ENTRY("opcache.preferred_memory_model", "" , PHP_INI_SYSTEM, OnUpdateStringUnempty, accel_directives.memory_model, zend_accel_globals, accel_globals) STD_PHP_INI_ENTRY("opcache.blacklist_filename" , "" , PHP_INI_SYSTEM, OnUpdateString, accel_directives.user_blacklist_filename, zend_accel_globals, accel_globals) STD_PHP_INI_ENTRY("opcache.max_file_size" , "0" , PHP_INI_SYSTEM, OnUpdateLong, accel_directives.max_file_size, zend_accel_globals, accel_globals) @@ -461,10 +468,17 @@ static zend_module_entry accel_module_entry = { STANDARD_MODULE_PROPERTIES }; +#if ZEND_EXTENSION_API_NO > PHP_5_6_X_API_NO +int start_accel_module(TSRMLS_D) +{ + return zend_startup_module(&accel_module_entry TSRMLS_CC); +} +#else int start_accel_module(void) { return zend_startup_module(&accel_module_entry); } +#endif /* {{{ proto array accelerator_get_scripts() Get the scripts which are accelerated by ZendAccelerator */ @@ -709,3 +723,44 @@ static ZEND_FUNCTION(opcache_invalidate) RETURN_FALSE; } } + +static ZEND_FUNCTION(opcache_compile_file) +{ + char *script_name; + int script_name_len; + zend_file_handle handle; + zend_op_array *op_array = NULL; + zend_execute_data *orig_execute_data = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &script_name, &script_name_len) == FAILURE) { + return; + } + + if (!ZCG(enabled) || !accel_startup_ok || !ZCSG(accelerator_enabled)) { + zend_error(E_NOTICE, ACCELERATOR_PRODUCT_NAME " seems to be disabled, can't compile file"); + RETURN_FALSE; + } + + handle.filename = script_name; + handle.free_filename = 0; + handle.opened_path = NULL; + handle.type = ZEND_HANDLE_FILENAME; + + orig_execute_data = EG(current_execute_data); + + zend_try { + op_array = persistent_compile_file(&handle, ZEND_INCLUDE TSRMLS_CC); + } zend_catch { + EG(current_execute_data) = orig_execute_data; + zend_error(E_WARNING, ACCELERATOR_PRODUCT_NAME " could not compile file %s" TSRMLS_CC, handle.filename); + } zend_end_try(); + + if(op_array != NULL) { + destroy_op_array(op_array TSRMLS_CC); + efree(op_array); + RETVAL_TRUE; + } else { + RETVAL_FALSE; + } + zend_destroy_file_handle(&handle TSRMLS_CC); +} diff --git a/ext/opcache/zend_accelerator_module.h b/ext/opcache/zend_accelerator_module.h index 539b4e85af9c3..74728f3f72557 100644 --- a/ext/opcache/zend_accelerator_module.h +++ b/ext/opcache/zend_accelerator_module.h @@ -22,7 +22,12 @@ #ifndef ZEND_ACCELERATOR_MODULE_H #define ZEND_ACCELERATOR_MODULE_H +#if ZEND_EXTENSION_API_NO > PHP_5_6_X_API_NO +int start_accel_module(TSRMLS_D); +#else int start_accel_module(void); +#endif + void zend_accel_override_file_functions(TSRMLS_D); #endif /* _ZEND_ACCELERATOR_MODULE_H */ diff --git a/ext/opcache/zend_accelerator_util_funcs.c b/ext/opcache/zend_accelerator_util_funcs.c index 39b4c1fc2558b..e9582324c4ada 100644 --- a/ext/opcache/zend_accelerator_util_funcs.c +++ b/ext/opcache/zend_accelerator_util_funcs.c @@ -222,6 +222,52 @@ static void zend_destroy_property_info(zend_property_info *property_info) } } +#if ZEND_EXTENSION_API_NO > PHP_5_5_X_API_NO +static zend_ast *zend_ast_clone(zend_ast *ast TSRMLS_DC) +{ + int i; + zend_ast *node; + + if (ast->kind == ZEND_CONST) { + node = emalloc(sizeof(zend_ast) + sizeof(zval)); + node->kind = ZEND_CONST; + node->children = 0; + node->u.val = (zval*)(node + 1); + *node->u.val = *ast->u.val; + if ((Z_TYPE_P(ast->u.val) & IS_CONSTANT_TYPE_MASK) >= IS_ARRAY) { + switch ((Z_TYPE_P(ast->u.val) & IS_CONSTANT_TYPE_MASK)) { + case IS_STRING: + case IS_CONSTANT: + Z_STRVAL_P(node->u.val) = (char *) interned_estrndup(Z_STRVAL_P(ast->u.val), Z_STRLEN_P(ast->u.val)); + break; + case IS_ARRAY: + case IS_CONSTANT_ARRAY: + if (ast->u.val->value.ht && ast->u.val->value.ht != &EG(symbol_table)) { + ALLOC_HASHTABLE(node->u.val->value.ht); + zend_hash_clone_zval(node->u.val->value.ht, ast->u.val->value.ht, 0); + } + break; + case IS_CONSTANT_AST: + Z_AST_P(node->u.val) = zend_ast_clone(Z_AST_P(ast->u.val) TSRMLS_CC); + break; + } + } + } else { + node = emalloc(sizeof(zend_ast) + sizeof(zend_ast*) * (ast->children - 1)); + node->kind = ast->kind; + node->children = ast->children; + for (i = 0; i < ast->children; i++) { + if ((&ast->u.child)[i]) { + (&node->u.child)[i] = zend_ast_clone((&ast->u.child)[i] TSRMLS_CC); + } else { + (&node->u.child)[i] = NULL; + } + } + } + return node; +} +#endif + static inline zval* zend_clone_zval(zval *src, int bind TSRMLS_DC) { zval *ret, **ret_ptr = NULL; @@ -259,6 +305,11 @@ static inline zval* zend_clone_zval(zval *src, int bind TSRMLS_DC) zend_hash_clone_zval(ret->value.ht, src->value.ht, 0); } break; +#if ZEND_EXTENSION_API_NO > PHP_5_5_X_API_NO + case IS_CONSTANT_AST: + Z_AST_P(ret) = zend_ast_clone(Z_AST_P(ret) TSRMLS_CC); + break; +#endif } } return ret; @@ -376,6 +427,11 @@ static void zend_hash_clone_zval(HashTable *ht, HashTable *source, int bind) zend_hash_clone_zval(ppz->value.ht, ((zval*)p->pDataPtr)->value.ht, 0); } break; +#if ZEND_EXTENSION_API_NO > PHP_5_5_X_API_NO + case IS_CONSTANT_AST: + Z_AST_P(ppz) = zend_ast_clone(Z_AST_P(ppz) TSRMLS_CC); + break; +#endif } } @@ -478,7 +534,7 @@ static void zend_hash_clone_methods(HashTable *ht, HashTable *source, zend_class if (accel_xlat_get(new_entry->scope, new_ce) == SUCCESS) { new_entry->scope = *new_ce; } else { - zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME " class loading error, class %s, function %s. Please call Zend Support", ce->name, new_entry->function_name); + zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME " class loading error, class %s, function %s", ce->name, new_entry->function_name); } } @@ -487,7 +543,7 @@ static void zend_hash_clone_methods(HashTable *ht, HashTable *source, zend_class if (accel_xlat_get(new_entry->prototype, new_prototype) == SUCCESS) { new_entry->prototype = *new_prototype; } else { - zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME " class loading error, class %s, function %s. Please call Zend Support", ce->name, new_entry->function_name); + zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME " class loading error, class %s, function %s", ce->name, new_entry->function_name); } } @@ -589,7 +645,7 @@ static void zend_hash_clone_prop_info(HashTable *ht, HashTable *source, zend_cla } else if (accel_xlat_get(prop_info->ce, new_ce) == SUCCESS) { prop_info->ce = *new_ce; } else { - zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME" class loading error, class %s, property %s. Please call Zend Support", ce->name, prop_info->name); + zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME" class loading error, class %s, property %s", ce->name, prop_info->name); } p = p->pListNext; @@ -621,7 +677,7 @@ static int zend_prepare_function_for_execution(zend_op_array *op_array) if (accel_xlat_get(ce->handler, new_func) == SUCCESS) { \ ce->handler = *new_func; \ } else { \ - zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME " class loading error, class %s. Please call Zend Support", ce->name); \ + zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME " class loading error, class %s", ce->name); \ } \ } \ } @@ -710,7 +766,7 @@ static void zend_class_copy_ctor(zend_class_entry **pce) if (accel_xlat_get(ce->parent, new_ce) == SUCCESS) { ce->parent = *new_ce; } else { - zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME" class loading error, class %s. Please call Zend Support", ce->name); + zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME" class loading error, class %s", ce->name); } } @@ -835,7 +891,19 @@ static int zend_hash_unique_copy(HashTable *target, HashTable *source, unique_co } } else { if (p->nKeyLength > 0 && p->arKey[0] == 0) { - /* Mangled key, ignore and wait for runtime */ + /* Mangled key */ +#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO + if (((zend_function*)p->pData)->common.fn_flags & ZEND_ACC_CLOSURE) { + /* update closure */ + if (zend_hash_quick_update(target, p->arKey, p->nKeyLength, p->h, p->pData, size, &t) == SUCCESS) { + if (pCopyConstructor) { + pCopyConstructor(t); + } + } + } else { + /* ignore and wait for runtime */ + } +#endif } else if (!ignore_dups && zend_hash_quick_find(target, p->arKey, p->nKeyLength, p->h, &t) == SUCCESS) { *fail_data = p->pData; *conflict_data = t; diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c index 9f1940e061160..17147ac34f15e 100644 --- a/ext/opcache/zend_persist.c +++ b/ext/opcache/zend_persist.c @@ -51,6 +51,7 @@ typedef void (*zend_persist_func_t)(void * TSRMLS_DC); static void zend_persist_zval_ptr(zval **zp TSRMLS_DC); +static void zend_persist_zval(zval *z TSRMLS_DC); #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO static const Bucket *uninitialized_bucket = NULL; @@ -138,6 +139,29 @@ static void zend_hash_persist(HashTable *ht, void (*pPersistElement)(void *pElem #endif } +#if ZEND_EXTENSION_API_NO > PHP_5_5_X_API_NO +static zend_ast *zend_persist_ast(zend_ast *ast TSRMLS_DC) +{ + int i; + zend_ast *node; + + if (ast->kind == ZEND_CONST) { + node = zend_accel_memdup(ast, sizeof(zend_ast) + sizeof(zval)); + node->u.val = (zval*)(node + 1); + zend_persist_zval(node->u.val TSRMLS_CC); + } else { + node = zend_accel_memdup(ast, sizeof(zend_ast) + sizeof(zend_ast*) * (ast->children - 1)); + for (i = 0; i < ast->children; i++) { + if ((&node->u.child)[i]) { + (&node->u.child)[i] = zend_persist_ast((&node->u.child)[i] TSRMLS_CC); + } + } + } + efree(ast); + return node; +} +#endif + static void zend_persist_zval(zval *z TSRMLS_DC) { #if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO @@ -154,6 +178,11 @@ static void zend_persist_zval(zval *z TSRMLS_DC) zend_accel_store(z->value.ht, sizeof(HashTable)); zend_hash_persist(z->value.ht, (zend_persist_func_t) zend_persist_zval_ptr, sizeof(zval**) TSRMLS_CC); break; +#if ZEND_EXTENSION_API_NO > PHP_5_5_X_API_NO + case IS_CONSTANT_AST: + Z_AST_P(z) = zend_persist_ast(Z_AST_P(z) TSRMLS_CC); + break; +#endif } } diff --git a/ext/opcache/zend_persist_calc.c b/ext/opcache/zend_persist_calc.c index 18af756f6e8c9..8947c72ddc346 100644 --- a/ext/opcache/zend_persist_calc.c +++ b/ext/opcache/zend_persist_calc.c @@ -45,6 +45,7 @@ #endif static uint zend_persist_zval_ptr_calc(zval **zp TSRMLS_DC); +static uint zend_persist_zval_calc(zval *z TSRMLS_DC); static uint zend_hash_persist_calc(HashTable *ht, int (*pPersistElement)(void *pElement TSRMLS_DC), size_t el_size TSRMLS_DC) { @@ -91,6 +92,27 @@ static uint zend_hash_persist_calc(HashTable *ht, int (*pPersistElement)(void *p RETURN_SIZE(); } +#if ZEND_EXTENSION_API_NO > PHP_5_5_X_API_NO +static uint zend_persist_ast_calc(zend_ast *ast TSRMLS_DC) +{ + int i; + START_SIZE(); + + if (ast->kind == ZEND_CONST) { + ADD_SIZE(sizeof(zend_ast) + sizeof(zval)); + ADD_SIZE(zend_persist_zval_calc(ast->u.val TSRMLS_CC)); + } else { + ADD_SIZE(sizeof(zend_ast) + sizeof(zend_ast*) * (ast->children - 1)); + for (i = 0; i < ast->children; i++) { + if ((&ast->u.child)[i]) { + ADD_SIZE(zend_persist_ast_calc((&ast->u.child)[i] TSRMLS_CC)); + } + } + } + RETURN_SIZE(); +} +#endif + static uint zend_persist_zval_calc(zval *z TSRMLS_DC) { START_SIZE(); @@ -109,6 +131,11 @@ static uint zend_persist_zval_calc(zval *z TSRMLS_DC) ADD_DUP_SIZE(z->value.ht, sizeof(HashTable)); ADD_SIZE(zend_hash_persist_calc(z->value.ht, (int (*)(void* TSRMLS_DC)) zend_persist_zval_ptr_calc, sizeof(zval**) TSRMLS_CC)); break; +#if ZEND_EXTENSION_API_NO > PHP_5_5_X_API_NO + case IS_CONSTANT_AST: + ADD_SIZE(zend_persist_ast_calc(Z_AST_P(z) TSRMLS_CC)); + break; +#endif } RETURN_SIZE(); } diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 4aac4e3137cad..8d033035e250e 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -129,6 +129,12 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_x509_export, 0, 0, 2) ZEND_ARG_INFO(0, notext) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_x509_fingerprint, 0, 0, 1) + ZEND_ARG_INFO(0, x509) + ZEND_ARG_INFO(0, method) + ZEND_ARG_INFO(0, raw_output) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO(arginfo_openssl_x509_check_private_key, 0) ZEND_ARG_INFO(0, cert) ZEND_ARG_INFO(0, key) @@ -443,6 +449,7 @@ const zend_function_entry openssl_functions[] = { PHP_FE(openssl_x509_checkpurpose, arginfo_openssl_x509_checkpurpose) PHP_FE(openssl_x509_check_private_key, arginfo_openssl_x509_check_private_key) PHP_FE(openssl_x509_export, arginfo_openssl_x509_export) + PHP_FE(openssl_x509_fingerprint, arginfo_openssl_x509_fingerprint) PHP_FE(openssl_x509_export_to_file, arginfo_openssl_x509_export_to_file) /* PKCS12 funcs */ @@ -681,18 +688,28 @@ static time_t asn1_time_to_time_t(ASN1_UTCTIME * timestr TSRMLS_DC) /* {{{ */ char * thestr; long gmadjust = 0; - if (timestr->length < 13) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "extension author too lazy to parse %s correctly", timestr->data); + if (ASN1_STRING_type(timestr) != V_ASN1_UTCTIME) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "illegal ASN1 data type for timestamp"); return (time_t)-1; } - strbuf = estrdup((char *)timestr->data); + if (ASN1_STRING_length(timestr) != strlen(ASN1_STRING_data(timestr))) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "illegal length in timestamp"); + return (time_t)-1; + } + + if (ASN1_STRING_length(timestr) < 13) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to parse time string %s correctly", timestr->data); + return (time_t)-1; + } + + strbuf = estrdup((char *)ASN1_STRING_data(timestr)); memset(&thetime, 0, sizeof(thetime)); /* we work backwards so that we can use atoi more easily */ - thestr = strbuf + timestr->length - 3; + thestr = strbuf + ASN1_STRING_length(timestr) - 3; thetime.tm_sec = atoi(thestr); *thestr = '\0'; @@ -1176,6 +1193,10 @@ PHP_MINIT_FUNCTION(openssl) php_stream_xport_register("sslv2", php_openssl_ssl_socket_factory TSRMLS_CC); #endif php_stream_xport_register("tls", php_openssl_ssl_socket_factory TSRMLS_CC); +#if OPENSSL_VERSION_NUMBER >= 0x10001001L + php_stream_xport_register("tlsv1.1", php_openssl_ssl_socket_factory TSRMLS_CC); + php_stream_xport_register("tlsv1.2", php_openssl_ssl_socket_factory TSRMLS_CC); +#endif /* override the default tcp socket provider */ php_stream_xport_register("tcp", php_openssl_ssl_socket_factory TSRMLS_CC); @@ -1214,6 +1235,10 @@ PHP_MSHUTDOWN_FUNCTION(openssl) #endif php_stream_xport_unregister("sslv3" TSRMLS_CC); php_stream_xport_unregister("tls" TSRMLS_CC); +#if OPENSSL_VERSION_NUMBER >= 0x10001001L + php_stream_xport_unregister("tlsv1.1" TSRMLS_CC); + php_stream_xport_unregister("tlsv1.2" TSRMLS_CC); +#endif /* reinstate the default tcp handler */ php_stream_xport_register("tcp", php_stream_generic_socket_factory TSRMLS_CC); @@ -1595,7 +1620,7 @@ PHP_FUNCTION(openssl_spki_export_challenge) goto cleanup; } - RETVAL_STRING(ASN1_STRING_data(spki->spkac->challenge), 1); + RETVAL_STRING((char *) ASN1_STRING_data(spki->spkac->challenge), 1); goto cleanup; cleanup: @@ -1665,6 +1690,121 @@ PHP_FUNCTION(openssl_x509_export) } /* }}} */ +static int php_openssl_x509_fingerprint(X509 *peer, const char *method, zend_bool raw, char **out, int *out_len TSRMLS_DC) +{ + unsigned char md[EVP_MAX_MD_SIZE]; + const EVP_MD *mdtype; + unsigned int n; + + if (!(mdtype = EVP_get_digestbyname(method))) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown signature algorithm"); + return FAILURE; + } else if (!X509_digest(peer, mdtype, md, &n)) { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Could not generate signature"); + return FAILURE; + } + + if (raw) { + *out_len = n; + *out = estrndup((char *) md, n); + } else { + *out_len = n * 2; + *out = emalloc(*out_len + 1); + + make_digest_ex(*out, md, n); + } + + return SUCCESS; +} + +static int php_x509_fingerprint_cmp(X509 *peer, const char *method, const char *expected TSRMLS_DC) +{ + char *fingerprint; + int fingerprint_len; + int result = -1; + + if (php_openssl_x509_fingerprint(peer, method, 0, &fingerprint, &fingerprint_len TSRMLS_CC) == SUCCESS) { + result = strcmp(expected, fingerprint); + efree(fingerprint); + } + + return result; +} + +static zend_bool php_x509_fingerprint_match(X509 *peer, zval *val TSRMLS_DC) +{ + if (Z_TYPE_P(val) == IS_STRING) { + const char *method = NULL; + + switch (Z_STRLEN_P(val)) { + case 32: + method = "md5"; + break; + + case 40: + method = "sha1"; + break; + } + + return method && php_x509_fingerprint_cmp(peer, method, Z_STRVAL_P(val) TSRMLS_CC) == 0; + } else if (Z_TYPE_P(val) == IS_ARRAY) { + HashPosition pos; + zval **current; + char *key; + uint key_len; + ulong key_index; + + for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(val), &pos); + zend_hash_get_current_data_ex(Z_ARRVAL_P(val), (void **)¤t, &pos) == SUCCESS; + zend_hash_move_forward_ex(Z_ARRVAL_P(val), &pos) + ) { + int key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(val), &key, &key_len, &key_index, 0, &pos); + + if (key_type == HASH_KEY_IS_STRING + && Z_TYPE_PP(current) == IS_STRING + && php_x509_fingerprint_cmp(peer, key, Z_STRVAL_PP(current) TSRMLS_CC) != 0 + ) { + return 0; + } + } + return 1; + } + return 0; +} + +PHP_FUNCTION(openssl_x509_fingerprint) +{ + X509 *cert; + zval **zcert; + long certresource; + zend_bool raw_output = 0; + char *method = "sha1"; + int method_len; + + char *fingerprint; + int fingerprint_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|sb", &zcert, &method, &method_len, &raw_output) == FAILURE) { + return; + } + + cert = php_openssl_x509_from_zval(zcert, 0, &certresource TSRMLS_CC); + if (cert == NULL) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get cert from parameter 1"); + RETURN_FALSE; + } + + if (php_openssl_x509_fingerprint(cert, method, raw_output, &fingerprint, &fingerprint_len TSRMLS_CC) == SUCCESS) { + RETVAL_STRINGL(fingerprint, fingerprint_len, 0); + } else { + RETVAL_FALSE; + } + + if (certresource == -1 && cert) { + X509_free(cert); + } +} + /* {{{ proto bool openssl_x509_check_private_key(mixed cert, mixed key) Checks if a private key corresponds to a CERT */ PHP_FUNCTION(openssl_x509_check_private_key) @@ -4794,14 +4934,12 @@ static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) /* {{{ */ { php_stream *stream; SSL *ssl; - X509 *err_cert; int err, depth, ret; zval **val; ret = preverify_ok; /* determine the status for the current cert */ - err_cert = X509_STORE_CTX_get_current_cert(ctx); err = X509_STORE_CTX_get_error(ctx); depth = X509_STORE_CTX_get_error_depth(ctx); @@ -4829,12 +4967,91 @@ static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) /* {{{ */ } /* }}} */ +static zend_bool matches_wildcard_name(const char *subjectname, const char *certname) +{ + char *wildcard; + int prefix_len, suffix_len, subject_len; + + if (strcasecmp(subjectname, certname) == 0) { + return 1; + } + + if (!(wildcard = strchr(certname, '*'))) { + return 0; + } + + // 1) prefix, if not empty, must match subject + prefix_len = wildcard - certname; + if (prefix_len && strncasecmp(subjectname, certname, prefix_len) != 0) { + return 0; + } + + suffix_len = strlen(wildcard + 1); + subject_len = strlen(subjectname); + if (suffix_len <= subject_len) { + /* 2) suffix must match + * 3) no . between prefix and suffix + **/ + return strcasecmp(wildcard + 1, subjectname + subject_len - suffix_len) == 0 && + memchr(subjectname + prefix_len, '.', subject_len - suffix_len - prefix_len) == NULL; + } + + return 0; +} + +static zend_bool matches_san_list(X509 *peer, const char *subject_name) +{ + int i; + zend_bool is_match = 0; + unsigned char *cert_name; + + GENERAL_NAMES *alt_names = X509_get_ext_d2i(peer, NID_subject_alt_name, 0, 0); + int alt_name_count = sk_GENERAL_NAME_num(alt_names); + + for (i = 0; i < alt_name_count; i++) { + GENERAL_NAME *san = sk_GENERAL_NAME_value(alt_names, i); + + if (GEN_DNS == san->type) { + ASN1_STRING_to_UTF8(&cert_name, san->d.dNSName); + is_match = matches_wildcard_name(subject_name, (char *) cert_name); + OPENSSL_free(cert_name); + } + + if (is_match) { + break; + } + } + + return is_match; +} + +static zend_bool matches_common_name(X509 *peer, const char *subject_name TSRMLS_DC) +{ + char buf[1024]; + X509_NAME *cert_name; + zend_bool is_match = 0; + int cert_name_len; + + cert_name = X509_get_subject_name(peer); + cert_name_len = X509_NAME_get_text_by_NID(cert_name, NID_commonName, buf, sizeof(buf)); + + if (cert_name_len == -1) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to locate peer certificate CN"); + } else if (cert_name_len != strlen(buf)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Peer certificate CN=`%.*s' is malformed", cert_name_len, buf); + } else if (matches_wildcard_name(subject_name, buf)) { + is_match = 1; + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Peer certificate CN=`%.*s' did not match expected CN=`%s'", cert_name_len, buf, subject_name); + } + + return is_match; +} + int php_openssl_apply_verification_policy(SSL *ssl, X509 *peer, php_stream *stream TSRMLS_DC) /* {{{ */ { zval **val = NULL; char *cnmatch = NULL; - X509_NAME *name; - char buf[1024]; int err; /* verification is turned off */ @@ -4865,36 +5082,25 @@ int php_openssl_apply_verification_policy(SSL *ssl, X509 *peer, php_stream *stre /* if the cert passed the usual checks, apply our own local policies now */ - name = X509_get_subject_name(peer); - - /* Does the common name match ? (used primarily for https://) */ - GET_VER_OPT_STRING("CN_match", cnmatch); - if (cnmatch) { - int match = 0; - int name_len = X509_NAME_get_text_by_NID(name, NID_commonName, buf, sizeof(buf)); - - if (name_len == -1) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to locate peer certificate CN"); - return FAILURE; - } else if (name_len != strlen(buf)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Peer certificate CN=`%.*s' is malformed", name_len, buf); - return FAILURE; - } - - match = strcmp(cnmatch, buf) == 0; - if (!match && strlen(buf) > 3 && buf[0] == '*' && buf[1] == '.') { - /* Try wildcard */ - - if (strchr(buf+2, '.')) { - char *tmp = strstr(cnmatch, buf+1); - - match = tmp && strcmp(tmp, buf+2) && tmp == strchr(cnmatch, '.'); + if (GET_VER_OPT("peer_fingerprint")) { + if (Z_TYPE_PP(val) == IS_STRING || Z_TYPE_PP(val) == IS_ARRAY) { + if (!php_x509_fingerprint_match(peer, *val TSRMLS_CC)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Peer fingerprint doesn't match"); + return FAILURE; } + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expected peer fingerprint must be a string or an array"); } + } + + GET_VER_OPT_STRING("CN_match", cnmatch); - if (!match) { - /* didn't match */ - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Peer certificate CN=`%.*s' did not match expected CN=`%s'", name_len, buf, cnmatch); + if (cnmatch) { + if (matches_san_list(peer, cnmatch)) { + return SUCCESS; + } else if (matches_common_name(peer, cnmatch TSRMLS_CC)) { + return SUCCESS; + } else { return FAILURE; } } @@ -4974,9 +5180,6 @@ SSL *php_SSL_new_from_context(SSL_CTX *ctx, php_stream *stream TSRMLS_DC) /* {{{ GET_VER_OPT_STRING("local_cert", certfile); if (certfile) { - X509 *cert = NULL; - EVP_PKEY *key = NULL; - SSL *tmpssl; char resolved_path_buff[MAXPATHLEN]; const char * private_key = NULL; @@ -5003,16 +5206,22 @@ SSL *php_SSL_new_from_context(SSL_CTX *ctx, php_stream *stream TSRMLS_DC) /* {{{ } } - tmpssl = SSL_new(ctx); - cert = SSL_get_certificate(tmpssl); - - if (cert) { - key = X509_get_pubkey(cert); - EVP_PKEY_copy_parameters(key, SSL_get_privatekey(tmpssl)); - EVP_PKEY_free(key); - } - SSL_free(tmpssl); - +#if OPENSSL_VERSION_NUMBER < 0x10001001L + do { + /* Unnecessary as of OpenSSLv1.0.1 (will segfault if used with >= 10001001 ) */ + X509 *cert = NULL; + EVP_PKEY *key = NULL; + SSL *tmpssl = SSL_new(ctx); + cert = SSL_get_certificate(tmpssl); + + if (cert) { + key = X509_get_pubkey(cert); + EVP_PKEY_copy_parameters(key, SSL_get_privatekey(tmpssl)); + EVP_PKEY_free(key); + } + SSL_free(tmpssl); + } while (0); +#endif if (!SSL_CTX_check_private_key(ctx)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Private key does not match certificate!"); } diff --git a/ext/openssl/php_openssl.h b/ext/openssl/php_openssl.h index 8483bbf7626dd..a06e43db1ce5e 100644 --- a/ext/openssl/php_openssl.h +++ b/ext/openssl/php_openssl.h @@ -66,6 +66,7 @@ PHP_FUNCTION(openssl_x509_free); PHP_FUNCTION(openssl_x509_parse); PHP_FUNCTION(openssl_x509_checkpurpose); PHP_FUNCTION(openssl_x509_export); +PHP_FUNCTION(openssl_x509_fingerprint); PHP_FUNCTION(openssl_x509_export_to_file); PHP_FUNCTION(openssl_x509_check_private_key); diff --git a/ext/openssl/tests/bug65729.pem b/ext/openssl/tests/bug65729.pem new file mode 100644 index 0000000000000..dbeed6efd3011 --- /dev/null +++ b/ext/openssl/tests/bug65729.pem @@ -0,0 +1,28 @@ +-----BEGIN CERTIFICATE----- +MIICCTCCAXICCQDNMI29sowT7TANBgkqhkiG9w0BAQUFADBJMQswCQYDVQQGEwJT +RzESMBAGA1UECBMJVGVzdHZpbGxlMREwDwYDVQQKEwhkYXRpYmJhdzETMBEGA1UE +AxQKKi50ZXN0LmNvbTAeFw0xMzA5MjEwNzUyMjRaFw0xNDA5MjEwNzUyMjRaMEkx +CzAJBgNVBAYTAlNHMRIwEAYDVQQIEwlUZXN0dmlsbGUxETAPBgNVBAoTCGRhdGli +YmF3MRMwEQYDVQQDFAoqLnRlc3QuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB +iQKBgQCdzVnic8K5W4SVbwVuqezcTjeqVLoQ91vVNZB0Jnsuz6q3DoK03oAd1jTe +Vd0k+MQDbXpHoc37lA4+8z/g5Bs0UXxNx+nkbFTE7Ba2/G24caI9/cOXZPG3UViD +rtqXKL6h5/umqRG9Dt5liF2MVP9XFAesVC7B8+Ca+PbPlQoYzwIDAQABMA0GCSqG +SIb3DQEBBQUAA4GBAAS07u/Ke+EhEHidz6CG3Qcr+zg483JKRgZFyGz+YUKyyKKy +fmLs7JieGJxYQjOmIpj/6X9Gnb2HjIPDnI6A+MV1emXDTnnmsgf2/lZGcthhpZn2 +rMbj9bI0iH6HwOVGtp4ZJA5fB7nj3J+gWNTCQzDDOxwX36d2LL9ua+UMnk/g +-----END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +MIICXQIBAAKBgQCdzVnic8K5W4SVbwVuqezcTjeqVLoQ91vVNZB0Jnsuz6q3DoK0 +3oAd1jTeVd0k+MQDbXpHoc37lA4+8z/g5Bs0UXxNx+nkbFTE7Ba2/G24caI9/cOX +ZPG3UViDrtqXKL6h5/umqRG9Dt5liF2MVP9XFAesVC7B8+Ca+PbPlQoYzwIDAQAB +AoGAeyzTwKPDl5QMRejHQL57GOwlH1vLcXrjv+VzwHZZKQ0IoKM++5fCQYf29KXp +XPahaluGW2u9sWa8R/7wGcd0Q4RtquGzsgT3+AQsIc5KfIamyOyDaRVM/ymX3fWg +gHIU7OOzB+ihOU8sHyRIwfbk01/kmrBXLRj8E31sy3i3PIECQQDQQYE+aN7Acrdt +yN5CaqvbkiCGjRvASlemiTzPosgOtndyp21w1gakJwKYhYDk1N6A6Qb8REMZqM/U +wFypldV/AkEAwfq6NFuhpGL6hDA7MvlyY1KiZ0cHetPUX+PgdNqy2DA+1Sv4i7gm +Wd/uA651K7aPXuUaf9dKtPCmZwI4M6SEsQJBALW89HTqP7niYoDEEnITdPaghxHk +gptERUln6lGo1L1CLus3gSI/JHyMLo+7scgAnEwTD62GRKhX0Ubwt+ymfTECQAY5 +fHYnppU20+EgBxZIqOIFCc8UmWnYmE0Ha/Fz/x8u1SVUBuK84wYpSGL32yyu7ATY +hzQo/W229zABAzqtAdECQQCUdB7IBFpPnsfv/EUBFX7X/7zAc9JpACmu9It5ju8C +KIsMuz/02D+TQoJNjdAngBM+4AJDIaGFgTMIfaDMh5L7 +-----END RSA PRIVATE KEY----- diff --git a/ext/openssl/tests/bug65729.phpt b/ext/openssl/tests/bug65729.phpt new file mode 100644 index 0000000000000..c0ee4443ebee5 --- /dev/null +++ b/ext/openssl/tests/bug65729.phpt @@ -0,0 +1,54 @@ +--TEST-- +Bug #65729: CN_match gives false positive when wildcard is used +--SKIPIF-- + array( + 'verify_peer' => true, + 'allow_self_signed' => true, + 'CN_match' => $expected_name, + ) + )); + var_dump(stream_socket_client("ssl://127.0.0.1:64321", $errno, $errstr, 1, + STREAM_CLIENT_CONNECT, $contextC)); + } +} else { + @pcntl_wait($status); + foreach ($expected_names as $name) { + @stream_socket_accept($server, 1); + } +} +--EXPECTF-- +Warning: stream_socket_client(): Peer certificate CN=`*.test.com' did not match expected CN=`foo.test.com.sg' in %s on line %d + +Warning: stream_socket_client(): Failed to enable crypto in %s on line %d + +Warning: stream_socket_client(): unable to connect to ssl://127.0.0.1:64321 (Unknown error) in %s on line %d +bool(false) +resource(%d) of type (stream) +resource(%d) of type (stream) + +Warning: stream_socket_client(): Peer certificate CN=`*.test.com' did not match expected CN=`foo.bar.test.com' in %s on line %d + +Warning: stream_socket_client(): Failed to enable crypto in %s on line %d + +Warning: stream_socket_client(): unable to connect to ssl://127.0.0.1:64321 (Unknown error) in %s on line %d +bool(false) diff --git a/ext/openssl/tests/cve-2013-6420.crt b/ext/openssl/tests/cve-2013-6420.crt new file mode 100644 index 0000000000000..454331468bcb3 --- /dev/null +++ b/ext/openssl/tests/cve-2013-6420.crt @@ -0,0 +1,29 @@ +-----BEGIN CERTIFICATE----- +MIIEpDCCA4ygAwIBAgIJAJzu8r6u6eBcMA0GCSqGSIb3DQEBBQUAMIHDMQswCQYD +VQQGEwJERTEcMBoGA1UECAwTTm9yZHJoZWluLVdlc3RmYWxlbjEQMA4GA1UEBwwH +S8ODwrZsbjEUMBIGA1UECgwLU2VrdGlvbkVpbnMxHzAdBgNVBAsMFk1hbGljaW91 +cyBDZXJ0IFNlY3Rpb24xITAfBgNVBAMMGG1hbGljaW91cy5zZWt0aW9uZWlucy5k +ZTEqMCgGCSqGSIb3DQEJARYbc3RlZmFuLmVzc2VyQHNla3Rpb25laW5zLmRlMHUY +ZDE5NzAwMTAxMDAwMDAwWgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAXDTE0MTEyODExMzkzNVowgcMxCzAJBgNVBAYTAkRFMRwwGgYDVQQIDBNO +b3JkcmhlaW4tV2VzdGZhbGVuMRAwDgYDVQQHDAdLw4PCtmxuMRQwEgYDVQQKDAtT +ZWt0aW9uRWluczEfMB0GA1UECwwWTWFsaWNpb3VzIENlcnQgU2VjdGlvbjEhMB8G +A1UEAwwYbWFsaWNpb3VzLnNla3Rpb25laW5zLmRlMSowKAYJKoZIhvcNAQkBFhtz +dGVmYW4uZXNzZXJAc2VrdGlvbmVpbnMuZGUwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQDDAf3hl7JY0XcFniyEJpSSDqn0OqBr6QP65usJPRt/8PaDoqBu +wEYT/Na+6fsgPjC0uK9DZgWg2tHWWoanSblAMoz5PH6Z+S4SHRZ7e2dDIjPjdhjh +0mLg2UMO5yp0V797Ggs9lNt6JRfH81MN2obXWs4NtztLMuD6egqpr8dDbr34aOs8 +pkdui5UawTZksy5pLPHq5cMhFGm06v65CLo0V2Pd9+KAokPrPcN5KLKebz7mLpk6 +SMeEXOKP4idEqxyQ7O7fBuHMedsQhu+prY3si3BUyKfQtP5CZnX2bp0wKHxX12DX +1nfFIt9DbGvHTcyOuN+nZLPBm3vWxntyIIvVAgMBAAGjQjBAMAkGA1UdEwQCMAAw +EQYJYIZIAYb4QgEBBAQDAgeAMAsGA1UdDwQEAwIFoDATBgNVHSUEDDAKBggrBgEF +BQcDAjANBgkqhkiG9w0BAQUFAAOCAQEAG0fZYYCTbdj1XYc+1SnoaPR+vI8C8CaD +8+0UYhdnyU4gga0BAcDrY9e94eEAu6ZqycF6FjLqXXdAboppWocr6T6GD1x33Ckl +VArzG/KxQohGD2JeqkhIMlDomxHO7ka39+Oa8i2vWLVyjU8AZvWMAruHa4EENyG7 +lW2AagaFKFCr9TnXTfrdxGVEbv7KVQ6bdhg5p5SjpWH1+Mq03uR3ZXPBYdyV8319 +o0lVj1KFI2DCL/liWisJRoof+1cR35Ctd0wYBcpB6TZslMcOPl76dwKwJgeJo2Qg +Zsfmc2vC1/qOlNuNq/0TzzkVGv8ETT3CgaU+UXe4XOVvkccebJn2dg== +-----END CERTIFICATE----- + + diff --git a/ext/openssl/tests/cve-2013-6420.phpt b/ext/openssl/tests/cve-2013-6420.phpt new file mode 100644 index 0000000000000..87c0210b2efa9 --- /dev/null +++ b/ext/openssl/tests/cve-2013-6420.phpt @@ -0,0 +1,18 @@ +--TEST-- +CVE-2013-6420 +--SKIPIF-- + +--FILE-- + +Done +--EXPECTF-- +%s openssl_x509_parse(): illegal ASN1 data type for timestamp in %s%ecve-2013-6420.php on line 3 +string(27) "stefan.esser@sektioneins.de" +int(-1) +Done diff --git a/ext/openssl/tests/openssl_peer_fingerprint.phpt b/ext/openssl/tests/openssl_peer_fingerprint.phpt new file mode 100644 index 0000000000000..2960dffae506e --- /dev/null +++ b/ext/openssl/tests/openssl_peer_fingerprint.phpt @@ -0,0 +1,62 @@ +--TEST-- +Testing peer fingerprint on connection +--SKIPIF-- + array( + 'verify_peer' => true, + 'cafile' => __DIR__ . '/bug54992-ca.pem', + 'capture_peer_cert' => true, + 'peer_fingerprint' => '81cafc260aa8d82956ebc6212a362ece', + ) + ) + ); + // should be: 81cafc260aa8d82956ebc6212a362ecc + var_dump(stream_socket_client("ssl://127.0.0.1:64321", $errno, $errstr, 1, + STREAM_CLIENT_CONNECT, $contextC)); + + $contextC = stream_context_create( + array( + 'ssl' => array( + 'verify_peer' => true, + 'cafile' => __DIR__ . '/bug54992-ca.pem', + 'capture_peer_cert' => true, + 'peer_fingerprint' => array( + 'sha256' => '78ea579f2c3b439359dec5dac9d445108772927427c4780037e87df3799a0aa0', + ), + ) + ) + ); + + var_dump(stream_socket_client("ssl://127.0.0.1:64321", $errno, $errstr, 1, + STREAM_CLIENT_CONNECT, $contextC)); +} else { + @pcntl_wait($status); + @stream_socket_accept($server, 1); + @stream_socket_accept($server, 1); +} +--EXPECTF-- +Warning: stream_socket_client(): Peer fingerprint doesn't match in %s on line %d + +Warning: stream_socket_client(): Failed to enable crypto in %s on line %d + +Warning: stream_socket_client(): unable to connect to ssl://127.0.0.1:64321 (Unknown error) in %s on line %d +bool(false) +resource(9) of type (stream) diff --git a/ext/openssl/tests/openssl_x509_fingerprint.phpt b/ext/openssl/tests/openssl_x509_fingerprint.phpt new file mode 100644 index 0000000000000..6cd464a894872 --- /dev/null +++ b/ext/openssl/tests/openssl_x509_fingerprint.phpt @@ -0,0 +1,47 @@ +--TEST-- +Testing openssl_x509_fingerprint() +--SKIPIF-- + +--FILE-- + array( + 'local_cert' => __DIR__ . '/san-cert.pem', + 'allow_self_signed' => true, + ), +)); + +$server = stream_socket_server('ssl://127.0.0.1:64321', $errno, $errstr, + STREAM_SERVER_BIND|STREAM_SERVER_LISTEN, $context); + + +$pid = pcntl_fork(); +if ($pid == -1) { + die('could not fork'); +} else if ($pid) { + $contextC = stream_context_create( + array( + 'ssl' => array( + 'verify_peer' => true, + 'cafile' => __DIR__ . '/san-ca.pem', + 'CN_match' => 'example.org', + ) + ) + ); + var_dump(stream_socket_client("ssl://127.0.0.1:64321", $errno, $errstr, 1, + STREAM_CLIENT_CONNECT, $contextC)); + + $contextC = stream_context_create(array( + 'ssl' => array( + 'verify_peer' => true, + 'cafile' => __DIR__ . '/san-ca.pem', + 'CN_match' => 'moar.example.org', + ) + )); + + var_dump(stream_socket_client("ssl://127.0.0.1:64321", $errno, $errstr, 1, + STREAM_CLIENT_CONNECT, $contextC)); + +} else { + @pcntl_wait($status); + @stream_socket_accept($server, 1); + @stream_socket_accept($server, 1); +} +--EXPECTF-- +resource(%d) of type (stream) + +Warning: stream_socket_client(): Unable to locate peer certificate CN in %s on line %d + +Warning: stream_socket_client(): Failed to enable crypto in %s on line %d + +Warning: stream_socket_client(): unable to connect to ssl://127.0.0.1:64321 (Unknown error) in %s on line %d +bool(false) diff --git a/ext/openssl/tests/streams_crypto_method.pem b/ext/openssl/tests/streams_crypto_method.pem new file mode 100644 index 0000000000000..9d754d460d57c --- /dev/null +++ b/ext/openssl/tests/streams_crypto_method.pem @@ -0,0 +1,33 @@ +-----BEGIN CERTIFICATE----- +MIIC5jCCAk+gAwIBAgIBADANBgkqhkiG9w0BAQQFADBcMQswCQYDVQQGEwJBVTET +MBEGA1UECBMKUXVlZW5zbGFuZDEaMBgGA1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQx +HDAaBgNVBAMTE1Rlc3QgUENBICgxMDI0IGJpdCkwHhcNOTkxMjAyMjEzNTQ4WhcN +MDUwNzExMjEzNTQ4WjBcMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFu +ZDEaMBgGA1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQxHDAaBgNVBAMTE1Rlc3QgUENB +ICgxMDI0IGJpdCkwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJ2haT/f5Zwy +V+MiuSDjSR62adBoSiBB7Usty44lXqsp9RICw+DCCxpsn/CfxPEDXLLd4olsWXc6 +JRcxGynbYmnzk+Z6aIPPJQhK3CTvaqGnWKZsA1m+WaUIUqJCuNTK4N+7hMAGaf6S +S3e9HVgEQ4a34gXJ7VQFVIBNV1EnZRWHAgMBAAGjgbcwgbQwHQYDVR0OBBYEFE0R +aEcrj18q1dw+G6nJbsTWR213MIGEBgNVHSMEfTB7gBRNEWhHK49fKtXcPhupyW7E +1kdtd6FgpF4wXDELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQxGjAY +BgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRwwGgYDVQQDExNUZXN0IFBDQSAoMTAy +NCBiaXQpggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAUa8B3pho ++Mvxeq9HsEzJxHIFQla05S5J/e/V+DQTYoKiRFchKPrDAdrzYSEvP3h4QJEtsNqQ +JfOxg5M42uLFq7aPGWkF6ZZqZsYS+zA9IVT14g7gNA6Ne+5QtJqQtH9HA24st0T0 +Tga/lZ9M2ovImovaxSL/kRHbpCWcqWVxpOw= +-----END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQCdoWk/3+WcMlfjIrkg40ketmnQaEogQe1LLcuOJV6rKfUSAsPg +wgsabJ/wn8TxA1yy3eKJbFl3OiUXMRsp22Jp85PmemiDzyUIStwk72qhp1imbANZ +vlmlCFKiQrjUyuDfu4TABmn+kkt3vR1YBEOGt+IFye1UBVSATVdRJ2UVhwIDAQAB +AoGAba4fTtuap5l7/8ZsbE7Z1O32KJY4ZcOZukLOLUUhXxXduT+FTgGWujc0/rgc +z9qYCLlNZHOouMYTgtSfYvuMuLZ11VIt0GYH+nRioLShE59Yy+zCRyC+gPigS1kz +xvo14AsOIPYV14Tk/SsHyq6E0eTk7VzaIE197giiINUERPECQQDSKmtPTh/lRKw7 +HSZSM0I1mFWn/1zqrAbontRQY5w98QWIOe5qmzYyFbPXYT3d9BzlsMyhgiRNoBbD +yvohSHXJAkEAwAHx6ezAZeWWzD5yXD36nyjpkVCw7Tk7TSmOceLJMWt1QcrCfqlS +xA5jjpQ6Z8suU5DdtWAryM2sAir1WisYzwJAd6Zcx56jvAQ3xcPXsE6scBTVFzrj +7FqZ6E+cclPzfLQ+QQsyOBE7bpI6e/FJppY26XGZXo3YGzV8IGXrt40oOQJALETG +h86EFXo3qGOFbmsDy4pdP5nBERCu8X1xUCSfintiD4c2DInxgS5oGclnJeMcjTvL +QjQoJCX3UJCi/OUO1QJBAKgcDHWjMvt+l1pjJBsSEZ0HX9AAIIVx0RQmbFGS+F2Q +hhu5l77WnnZOQ9vvhV5u7NPCUF9nhU3jh60qWWO8mkc= +-----END RSA PRIVATE KEY----- diff --git a/ext/openssl/tests/streams_crypto_method.phpt b/ext/openssl/tests/streams_crypto_method.phpt new file mode 100644 index 0000000000000..97a6e9ee8ba85 --- /dev/null +++ b/ext/openssl/tests/streams_crypto_method.phpt @@ -0,0 +1,77 @@ +--TEST-- +Specific crypto method for ssl:// transports. +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Hello World! diff --git a/ext/openssl/tests/tlsv1.1_wrapper_001.phpt b/ext/openssl/tests/tlsv1.1_wrapper_001.phpt new file mode 100644 index 0000000000000..56211f0b965e0 --- /dev/null +++ b/ext/openssl/tests/tlsv1.1_wrapper_001.phpt @@ -0,0 +1,46 @@ +--TEST-- +tlsv1.1 stream wrapper +--SKIPIF-- + array( + 'local_cert' => __DIR__ . '/streams_crypto_method.pem', +))); + +$server = stream_socket_server('tlsv1.1://127.0.0.1:64321', $errno, $errstr, $flags, $ctx); +var_dump($server); + +$pid = pcntl_fork(); +if ($pid == -1) { + die('could not fork'); +} elseif ($pid) { + $flags = STREAM_CLIENT_CONNECT; + $ctx = stream_context_create(array('ssl' => array( + 'verify_peer' => false + ))); + + $client = stream_socket_client("tlsv1.1://127.0.0.1:64321", $errno, $errstr, 1, $flags, $ctx); + var_dump($client); + + $client = @stream_socket_client("sslv3://127.0.0.1:64321", $errno, $errstr, 1, $flags, $ctx); + var_dump($client); + + $client = @stream_socket_client("tlsv1.2://127.0.0.1:64321", $errno, $errstr, 1, $flags, $ctx); + var_dump($client); + +} else { + @pcntl_wait($status); + for ($i=0; $i < 3; $i++) { + @stream_socket_accept($server, 1); + } +} +--EXPECTF-- +resource(%d) of type (stream) +resource(%d) of type (stream) +bool(false) +bool(false) diff --git a/ext/openssl/tests/tlsv1.2_wrapper_002.phpt b/ext/openssl/tests/tlsv1.2_wrapper_002.phpt new file mode 100644 index 0000000000000..cb3f4106c727e --- /dev/null +++ b/ext/openssl/tests/tlsv1.2_wrapper_002.phpt @@ -0,0 +1,46 @@ +--TEST-- +tlsv1.2 stream wrapper +--SKIPIF-- + array( + 'local_cert' => __DIR__ . '/streams_crypto_method.pem', +))); + +$server = stream_socket_server('tlsv1.2://127.0.0.1:64321', $errno, $errstr, $flags, $ctx); +var_dump($server); + +$pid = pcntl_fork(); +if ($pid == -1) { + die('could not fork'); +} elseif ($pid) { + $flags = STREAM_CLIENT_CONNECT; + $ctx = stream_context_create(array('ssl' => array( + 'verify_peer' => false + ))); + + $client = stream_socket_client("tlsv1.2://127.0.0.1:64321", $errno, $errstr, 1, $flags, $ctx); + var_dump($client); + + $client = @stream_socket_client("sslv3://127.0.0.1:64321", $errno, $errstr, 1, $flags, $ctx); + var_dump($client); + + $client = @stream_socket_client("tlsv1.1://127.0.0.1:64321", $errno, $errstr, 1, $flags, $ctx); + var_dump($client); + +} else { + @pcntl_wait($status); + for ($i=0; $i < 3; $i++) { + @stream_socket_accept($server, 1); + } +} +--EXPECTF-- +resource(%d) of type (stream) +resource(%d) of type (stream) +bool(false) +bool(false) diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c index d7ef42e0b1ddd..919b0089635e1 100644 --- a/ext/openssl/xp_ssl.c +++ b/ext/openssl/xp_ssl.c @@ -346,6 +346,24 @@ static inline int php_openssl_setup_crypto(php_stream *stream, sslsock->is_client = 1; method = TLSv1_client_method(); break; + case STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT: +#if OPENSSL_VERSION_NUMBER >= 0x10001001L + sslsock->is_client = 1; + method = TLSv1_1_client_method(); + break; +#else + php_error_docref(NULL TSRMLS_CC, E_WARNING, "TLSv1.1 support is not compiled into the OpenSSL library PHP is linked against"); + return -1; +#endif + case STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT: +#if OPENSSL_VERSION_NUMBER >= 0x10001001L + sslsock->is_client = 1; + method = TLSv1_2_client_method(); + break; +#else + php_error_docref(NULL TSRMLS_CC, E_WARNING, "TLSv1.2 support is not compiled into the OpenSSL library PHP is linked against"); + return -1; +#endif case STREAM_CRYPTO_METHOD_SSLv23_SERVER: sslsock->is_client = 0; method = SSLv23_server_method(); @@ -367,6 +385,24 @@ static inline int php_openssl_setup_crypto(php_stream *stream, sslsock->is_client = 0; method = TLSv1_server_method(); break; + case STREAM_CRYPTO_METHOD_TLSv1_1_SERVER: +#if OPENSSL_VERSION_NUMBER >= 0x10001001L + sslsock->is_client = 0; + method = TLSv1_1_server_method(); + break; +#else + php_error_docref(NULL TSRMLS_CC, E_WARNING, "TLSv1.1 support is not compiled into the OpenSSL library PHP is linked against"); + return -1; +#endif + case STREAM_CRYPTO_METHOD_TLSv1_2_SERVER: +#if OPENSSL_VERSION_NUMBER >= 0x10001001L + sslsock->is_client = 0; + method = TLSv1_2_server_method(); + break; +#else + php_error_docref(NULL TSRMLS_CC, E_WARNING, "TLSv1.2 support is not compiled into the OpenSSL library PHP is linked against"); + return -1; +#endif default: return -1; @@ -667,6 +703,12 @@ static inline int php_openssl_tcp_sockop_accept(php_stream *stream, php_openssl_ case STREAM_CRYPTO_METHOD_TLS_CLIENT: sock->method = STREAM_CRYPTO_METHOD_TLS_SERVER; break; + case STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT: + sock->method = STREAM_CRYPTO_METHOD_TLSv1_1_SERVER; + break; + case STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT: + sock->method = STREAM_CRYPTO_METHOD_TLSv1_2_SERVER; + break; default: break; } @@ -825,7 +867,7 @@ static int php_openssl_sockop_cast(php_stream *stream, int castas, void **ret TS case PHP_STREAM_AS_FD_FOR_SELECT: if (ret) { - *(int *)ret = sslsock->s.socket; + *(php_socket_t *)ret = sslsock->s.socket; } return SUCCESS; @@ -835,7 +877,7 @@ static int php_openssl_sockop_cast(php_stream *stream, int castas, void **ret TS return FAILURE; } if (ret) { - *(int *)ret = sslsock->s.socket; + *(php_socket_t *)ret = sslsock->s.socket; } return SUCCESS; default: @@ -853,14 +895,38 @@ php_stream_ops php_openssl_socket_ops = { php_openssl_sockop_set_option, }; -static char * get_sni(php_stream_context *ctx, const char *resourcename, size_t resourcenamelen, int is_persistent TSRMLS_DC) { +static int get_crypto_method(php_stream_context *ctx) { + if (ctx) { + zval **val = NULL; + long crypto_method; + + if (php_stream_context_get_option(ctx, "ssl", "crypto_method", &val) == SUCCESS) { + convert_to_long_ex(val); + crypto_method = (long)Z_LVAL_PP(val); + + switch (crypto_method) { + case STREAM_CRYPTO_METHOD_SSLv2_CLIENT: + case STREAM_CRYPTO_METHOD_SSLv3_CLIENT: + case STREAM_CRYPTO_METHOD_SSLv23_CLIENT: + case STREAM_CRYPTO_METHOD_TLS_CLIENT: + case STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT: + case STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT: + return crypto_method; + } + + } + } + + return STREAM_CRYPTO_METHOD_SSLv23_CLIENT; +} +static char * get_sni(php_stream_context *ctx, const char *resourcename, size_t resourcenamelen, int is_persistent TSRMLS_DC) { php_url *url; if (ctx) { zval **val = NULL; - if (php_stream_context_get_option(ctx, "ssl", "SNI_enabled", &val) == SUCCESS && !zend_is_true(*val)) { + if (php_stream_context_get_option(ctx, "ssl", "SNI_enabled", &val) == SUCCESS && !zend_is_true(*val TSRMLS_CC)) { return NULL; } if (php_stream_context_get_option(ctx, "ssl", "SNI_server_name", &val) == SUCCESS) { @@ -939,7 +1005,12 @@ php_stream *php_openssl_ssl_socket_factory(const char *proto, size_t protolen, if (strncmp(proto, "ssl", protolen) == 0) { sslsock->enable_on_connect = 1; - sslsock->method = STREAM_CRYPTO_METHOD_SSLv23_CLIENT; + + /* General ssl:// transports can use a number + * of crypto methods. The actual methhod can be + * provided in the streams context options. + */ + sslsock->method = get_crypto_method(context); } else if (strncmp(proto, "sslv2", protolen) == 0) { #ifdef OPENSSL_NO_SSL2 php_error_docref(NULL TSRMLS_CC, E_WARNING, "SSLv2 support is not compiled into the OpenSSL library PHP is linked against"); @@ -954,8 +1025,24 @@ php_stream *php_openssl_ssl_socket_factory(const char *proto, size_t protolen, } else if (strncmp(proto, "tls", protolen) == 0) { sslsock->enable_on_connect = 1; sslsock->method = STREAM_CRYPTO_METHOD_TLS_CLIENT; + } else if (strncmp(proto, "tlsv1.1", protolen) == 0) { +#if OPENSSL_VERSION_NUMBER >= 0x10001001L + sslsock->enable_on_connect = 1; + sslsock->method = STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT; +#else + php_error_docref(NULL TSRMLS_CC, E_WARNING, "TLSv1.1 support is not compiled into the OpenSSL library PHP is linked against"); + return NULL; +#endif + } else if (strncmp(proto, "tlsv1.2", protolen) == 0) { +#if OPENSSL_VERSION_NUMBER >= 0x10001001L + sslsock->enable_on_connect = 1; + sslsock->method = STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT; +#else + php_error_docref(NULL TSRMLS_CC, E_WARNING, "TLSv1.2 support is not compiled into the OpenSSL library PHP is linked against"); + return NULL; +#endif } - + return stream; } diff --git a/ext/pcntl/pcntl.c b/ext/pcntl/pcntl.c index b66f4722e8108..8dfb254cf9a44 100644 --- a/ext/pcntl/pcntl.c +++ b/ext/pcntl/pcntl.c @@ -499,7 +499,7 @@ PHP_MINIT_FUNCTION(pcntl) { php_register_signal_constants(INIT_FUNC_ARGS_PASSTHRU); php_pcntl_register_errno_constants(INIT_FUNC_ARGS_PASSTHRU); - php_add_tick_function(pcntl_signal_dispatch); + php_add_tick_function(pcntl_signal_dispatch TSRMLS_CC); return SUCCESS; } diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 7d34d9feb15a8..1e882910d4b46 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -1343,6 +1343,7 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_repl int limit_val = -1; long limit = -1; char *string_key; + uint string_key_len; ulong num_key; char *callback_name; int replace_count=0, old_replace_count; @@ -1394,10 +1395,10 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_repl if ((result = php_replace_in_subject(*regex, *replace, subject_entry, &result_len, limit_val, is_callable_replace, &replace_count TSRMLS_CC)) != NULL) { if (!is_filter || replace_count > old_replace_count) { /* Add to return array */ - switch(zend_hash_get_current_key(Z_ARRVAL_PP(subject), &string_key, &num_key, 0)) + switch(zend_hash_get_current_key_ex(Z_ARRVAL_PP(subject), &string_key, &string_key_len, &num_key, 0, NULL)) { case HASH_KEY_IS_STRING: - add_assoc_stringl(return_value, string_key, result, result_len, 0); + add_assoc_stringl_ex(return_value, string_key, string_key_len, result, result_len, 0); break; case HASH_KEY_IS_LONG: @@ -1770,6 +1771,7 @@ PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return int size_offsets; /* Size of the offsets array */ int count = 0; /* Count of matched subpatterns */ char *string_key; + uint string_key_len; ulong num_key; zend_bool invert; /* Whether to return non-matching entries */ @@ -1828,11 +1830,11 @@ PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return Z_ADDREF_PP(entry); /* Add to return array */ - switch (zend_hash_get_current_key(Z_ARRVAL_P(input), &string_key, &num_key, 0)) + switch (zend_hash_get_current_key_ex(Z_ARRVAL_P(input), &string_key, &string_key_len, &num_key, 0, NULL)) { case HASH_KEY_IS_STRING: zend_hash_update(Z_ARRVAL_P(return_value), string_key, - strlen(string_key)+1, entry, sizeof(zval *), NULL); + string_key_len, entry, sizeof(zval *), NULL); break; case HASH_KEY_IS_LONG: diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c index aec388c03f5d9..67c6c58ed96b9 100644 --- a/ext/pdo/pdo_dbh.c +++ b/ext/pdo/pdo_dbh.c @@ -460,7 +460,7 @@ static void pdo_stmt_construct(pdo_stmt_t *stmt, zval *object, zend_class_entry if (dbstmt_ce->constructor) { zend_fcall_info fci; zend_fcall_info_cache fcc; - zval *retval; + zval *retval = NULL; fci.size = sizeof(zend_fcall_info); fci.function_table = &dbstmt_ce->function_table; @@ -495,7 +495,7 @@ static void pdo_stmt_construct(pdo_stmt_t *stmt, zval *object, zend_class_entry zval_dtor(object); ZVAL_NULL(object); object = NULL; /* marks failure */ - } else { + } else if (retval) { zval_ptr_dtor(&retval); } @@ -1328,16 +1328,12 @@ int pdo_hash_methods(pdo_dbh_t *dbh, int kind TSRMLS_DC) } else { ifunc->required_num_args = info->required_num_args; } - if (info->pass_rest_by_reference) { - if (info->pass_rest_by_reference == ZEND_SEND_PREFER_REF) { - ifunc->fn_flags |= ZEND_ACC_PASS_REST_PREFER_REF; - } else { - ifunc->fn_flags |= ZEND_ACC_PASS_REST_BY_REFERENCE; - } - } if (info->return_reference) { ifunc->fn_flags |= ZEND_ACC_RETURN_REFERENCE; } + if (funcs->arg_info[funcs->num_args].is_variadic) { + ifunc->fn_flags |= ZEND_ACC_VARIADIC; + } } else { ifunc->arg_info = NULL; ifunc->num_args = 0; diff --git a/ext/pdo/pdo_sql_parser.c b/ext/pdo/pdo_sql_parser.c index aea362fdb26d3..37d8752d62151 100644 --- a/ext/pdo/pdo_sql_parser.c +++ b/ext/pdo/pdo_sql_parser.c @@ -586,7 +586,9 @@ PDO_API int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len, } plc->freeq = 1; } else { - switch (Z_TYPE_P(param->parameter)) { + zval tmp_param = *param->parameter; + zval_copy_ctor(&tmp_param); + switch (Z_TYPE(tmp_param)) { case IS_NULL: plc->quoted = "NULL"; plc->qlen = sizeof("NULL")-1; @@ -594,20 +596,20 @@ PDO_API int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len, break; case IS_BOOL: - convert_to_long(param->parameter); - + convert_to_long(&tmp_param); + /* fall through */ case IS_LONG: case IS_DOUBLE: - convert_to_string(param->parameter); - plc->qlen = Z_STRLEN_P(param->parameter); - plc->quoted = Z_STRVAL_P(param->parameter); - plc->freeq = 0; + convert_to_string(&tmp_param); + plc->qlen = Z_STRLEN(tmp_param); + plc->quoted = estrdup(Z_STRVAL(tmp_param)); + plc->freeq = 1; break; default: - convert_to_string(param->parameter); - if (!stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL_P(param->parameter), - Z_STRLEN_P(param->parameter), &plc->quoted, &plc->qlen, + convert_to_string(&tmp_param); + if (!stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL(tmp_param), + Z_STRLEN(tmp_param), &plc->quoted, &plc->qlen, param->param_type TSRMLS_CC)) { /* bork */ ret = -1; @@ -616,6 +618,7 @@ PDO_API int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len, } plc->freeq = 1; } + zval_dtor(&tmp_param); } } else { plc->quoted = Z_STRVAL_P(param->parameter); diff --git a/ext/pdo/pdo_sql_parser.re b/ext/pdo/pdo_sql_parser.re index 1936a37340bb1..fa8ef187fa9a1 100644 --- a/ext/pdo/pdo_sql_parser.re +++ b/ext/pdo/pdo_sql_parser.re @@ -228,7 +228,9 @@ safe: } plc->freeq = 1; } else { - switch (Z_TYPE_P(param->parameter)) { + zval tmp_param = *param->parameter; + zval_copy_ctor(&tmp_param); + switch (Z_TYPE(tmp_param)) { case IS_NULL: plc->quoted = "NULL"; plc->qlen = sizeof("NULL")-1; @@ -236,20 +238,20 @@ safe: break; case IS_BOOL: - convert_to_long(param->parameter); - + convert_to_long(&tmp_param); + /* fall through */ case IS_LONG: case IS_DOUBLE: - convert_to_string(param->parameter); - plc->qlen = Z_STRLEN_P(param->parameter); - plc->quoted = Z_STRVAL_P(param->parameter); - plc->freeq = 0; + convert_to_string(&tmp_param); + plc->qlen = Z_STRLEN(tmp_param); + plc->quoted = estrdup(Z_STRVAL(tmp_param)); + plc->freeq = 1; break; default: - convert_to_string(param->parameter); - if (!stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL_P(param->parameter), - Z_STRLEN_P(param->parameter), &plc->quoted, &plc->qlen, + convert_to_string(&tmp_param); + if (!stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL(tmp_param), + Z_STRLEN(tmp_param), &plc->quoted, &plc->qlen, param->param_type TSRMLS_CC)) { /* bork */ ret = -1; @@ -258,6 +260,7 @@ safe: } plc->freeq = 1; } + zval_dtor(&tmp_param); } } else { plc->quoted = Z_STRVAL_P(param->parameter); diff --git a/ext/pdo/tests/bug65946.phpt b/ext/pdo/tests/bug65946.phpt new file mode 100644 index 0000000000000..1c4bd8d6c4287 --- /dev/null +++ b/ext/pdo/tests/bug65946.phpt @@ -0,0 +1,32 @@ +--TEST-- +Bug #65946 (pdo_sql_parser.c permanently converts values bound to strings) +--SKIPIF-- + +--FILE-- +setAttribute(PDO::ATTR_EMULATE_PREPARES, true); +$db->exec('CREATE TABLE test(id int)'); +$db->exec('INSERT INTO test VALUES(1)'); +$stmt = $db->prepare('SELECT * FROM test LIMIT :limit'); +$stmt->bindValue('limit', 1, PDO::PARAM_INT); +if(!($res = $stmt->execute())) var_dump($stmt->errorInfo()); +if(!($res = $stmt->execute())) var_dump($stmt->errorInfo()); +var_dump($stmt->fetchAll(PDO::FETCH_ASSOC)); +?> +--EXPECTF-- +array(1) { + [0]=> + array(1) { + ["id"]=> + string(1) "1" + } +} diff --git a/ext/pdo_dblib/dblib_driver.c b/ext/pdo_dblib/dblib_driver.c index b49ad2691f645..daf5494d5839f 100644 --- a/ext/pdo_dblib/dblib_driver.c +++ b/ext/pdo_dblib/dblib_driver.c @@ -350,9 +350,10 @@ static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_ DBSETLAPP(H->login, vars[1].optval); +/* DBSETLDBNAME is only available in FreeTDS 0.92 or above */ #ifdef DBSETLDBNAME if (vars[3].optval) { - DBSETLDBNAME(H->login, vars[3].optval); + if(FAIL == DBSETLDBNAME(H->login, vars[3].optval)) goto cleanup; } #endif @@ -362,36 +363,31 @@ static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_ goto cleanup; } +/* + * FreeTDS < 0.92 does not support the DBSETLDBNAME option + * Send use database here after login (Will not work with SQL Azure) + */ +#ifndef DBSETLDBNAME + if (vars[3].optval) { + if(FAIL == dbuse(H->link, vars[3].optval)) goto cleanup; + } +#endif + +#if PHP_DBLIB_IS_MSSQL /* dblib do not return more than this length from text/image */ DBSETOPT(H->link, DBTEXTLIMIT, "2147483647"); +#endif /* limit text/image from network */ DBSETOPT(H->link, DBTEXTSIZE, "2147483647"); /* allow double quoted indentifiers */ - DBSETOPT(H->link, DBQUOTEDIDENT, NULL); + DBSETOPT(H->link, DBQUOTEDIDENT, "1"); ret = 1; dbh->max_escaped_char_length = 2; dbh->alloc_own_columns = 1; -#if 0 - /* Cache the supported data types from the servers systypes table */ - if(dbcmd(H->link, "select usertype, name from systypes order by usertype") != FAIL) { - if(dbsqlexec(H->link) != FAIL) { - dbresults(H->link); - while (dbnextrow(H->link) == SUCCESS) { - val = dbdata(H->link, 1); - add_index_string(pdo_dblib_datatypes, *val, dbdata(H->link, 2), 1); - } - } - /* Throw out any remaining resultsets */ - dbcancel(H-link); - } -#endif - - - cleanup: for (i = 0; i < nvars; i++) { if (vars[i].freeme) { diff --git a/ext/pdo_mysql/tests/bug66141.phpt b/ext/pdo_mysql/tests/bug66141.phpt new file mode 100644 index 0000000000000..3a28509314eb7 --- /dev/null +++ b/ext/pdo_mysql/tests/bug66141.phpt @@ -0,0 +1,38 @@ +--TEST-- +Bug #66141 (mysqlnd quote function is wrong with NO_BACKSLASH_ESCAPES after failed query) +--SKIPIF-- + +--FILE-- +quote($input); + +$db->query('set session sql_mode="NO_BACKSLASH_ESCAPES"'); + +// injection text from some user input + +$quotedInput1 = $db->quote($input); + +$db->query('something that throws an exception'); + +$quotedInput2 = $db->quote($input); + +var_dump($quotedInput0); +var_dump($quotedInput1); +var_dump($quotedInput2); +?> +done +--EXPECTF-- +Warning: PDO::query(): SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'something that throws an exception' at line %d in %s on line %d +string(50) "'Something\', 1 as one, 2 as two FROM dual; -- f'" +string(50) "'Something'', 1 as one, 2 as two FROM dual; -- f'" +string(50) "'Something'', 1 as one, 2 as two FROM dual; -- f'" +done \ No newline at end of file diff --git a/ext/pdo_odbc/odbc_stmt.c b/ext/pdo_odbc/odbc_stmt.c index 0e3fd3cbb9f31..89b67210c5fb1 100644 --- a/ext/pdo_odbc/odbc_stmt.c +++ b/ext/pdo_odbc/odbc_stmt.c @@ -472,7 +472,7 @@ static int odbc_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *p if (P->outbuf) { unsigned long ulen; char *srcbuf; - unsigned long srclen; + unsigned long srclen = 0; switch (P->len) { case SQL_NULL_DATA: diff --git a/ext/pdo_sqlite/tests/bug66033.phpt b/ext/pdo_sqlite/tests/bug66033.phpt new file mode 100644 index 0000000000000..28da3b54bfff1 --- /dev/null +++ b/ext/pdo_sqlite/tests/bug66033.phpt @@ -0,0 +1,33 @@ +--TEST-- +Bug #66033 (Segmentation Fault when constructor of PDO statement throws an exception) +--SKIPIF-- + +--FILE-- +dbh = $dbh; + throw new Exception("Blah"); + } +} + +$pdo = new PDO('sqlite::memory:', null, null); +$pdo->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('DBStatement', + array($pdo))); +$pdo->exec("CREATE TABLE IF NOT EXISTS messages ( + id INTEGER PRIMARY KEY, + title TEXT, + message TEXT, + time INTEGER)"); + +try { + $pdoStatement = $pdo->query("select * from messages"); +} catch (Exception $e) { + var_dump($e->getMessage()); +} +?> +--EXPECTF-- +string(4) "Blah" diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index 35eb09e58466e..32d407af70ac3 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -2639,7 +2639,7 @@ static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, long result_type, Bucket *p; fci.param_count = 0; - fci.params = safe_emalloc(sizeof(zval*), ht->nNumOfElements, 0); + fci.params = safe_emalloc(sizeof(zval***), ht->nNumOfElements, 0); p = ht->pListHead; while (p != NULL) { fci.params[fci.param_count++] = (zval**)p->pData; diff --git a/ext/phar/config.m4 b/ext/phar/config.m4 index d424060f2a247..614d672eabd9d 100644 --- a/ext/phar/config.m4 +++ b/ext/phar/config.m4 @@ -28,5 +28,7 @@ if test "$PHP_PHAR" != "no"; then PHP_ADD_EXTENSION_DEP(phar, spl, true) PHP_ADD_MAKEFILE_FRAGMENT + PHP_INSTALL_HEADERS([ext/phar], [php_phar.h]) + PHP_OUTPUT(ext/phar/phar.1 ext/phar/phar.phar.1) fi diff --git a/ext/phar/dirstream.c b/ext/phar/dirstream.c index 62b19a79d929d..0f2580000ddd2 100644 --- a/ext/phar/dirstream.c +++ b/ext/phar/dirstream.c @@ -160,11 +160,7 @@ static int phar_compare_dir_name(const void *a, const void *b TSRMLS_DC) /* {{{ f = *((Bucket **) a); s = *((Bucket **) b); -#if (PHP_MAJOR_VERSION < 6) result = zend_binary_strcmp(f->arKey, f->nKeyLength, s->arKey, s->nKeyLength); -#else - result = zend_binary_strcmp(f->key.arKey.s, f->nKeyLength, s->key.arKey.s, s->nKeyLength); -#endif if (result < 0) { return -1; diff --git a/ext/phar/phar.c b/ext/phar/phar.c index 79f88b4362c0c..d4716bca914ea 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -3302,6 +3302,7 @@ static size_t phar_zend_stream_fsizer(void *handle TSRMLS_DC) /* {{{ */ zend_op_array *(*phar_orig_compile_file)(zend_file_handle *file_handle, int type TSRMLS_DC); #define phar_orig_zend_open zend_stream_open_function + static char *phar_resolve_path(const char *filename, int filename_len TSRMLS_DC) { return phar_find_in_include_path((char *) filename, filename_len, NULL TSRMLS_CC); diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index 64953f66b72d3..359f25b4c635b 100644 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -54,7 +54,7 @@ #ifndef PHP_WIN32 #include "TSRM/tsrm_strtok_r.h" #endif -#include "TSRM/tsrm_virtual_cwd.h" +#include "Zend/zend_virtual_cwd.h" #if HAVE_SPL #include "ext/spl/spl_array.h" #include "ext/spl/spl_directory.h" diff --git a/ext/phar/php_phar.h b/ext/phar/php_phar.h index a6d7bff414b8c..f8325d0c635e3 100644 --- a/ext/phar/php_phar.h +++ b/ext/phar/php_phar.h @@ -22,7 +22,7 @@ #ifndef PHP_PHAR_H #define PHP_PHAR_H -#define PHP_PHAR_VERSION "2.0.1" +#define PHP_PHAR_VERSION "2.0.2" #include "ext/standard/basic_functions.h" extern zend_module_entry phar_module_entry; @@ -31,9 +31,11 @@ extern zend_module_entry phar_module_entry; #ifdef PHP_WIN32 #define PHP_PHAR_API __declspec(dllexport) #else -#define PHP_PHAR_API +#define PHP_PHAR_API PHPAPI #endif +PHP_PHAR_API int phar_resolve_alias(char *alias, int alias_len, char **filename, int *filename_len TSRMLS_DC); + #endif /* PHP_PHAR_H */ diff --git a/ext/phar/util.c b/ext/phar/util.c index d42164a57c081..a887daecdce68 100644 --- a/ext/phar/util.c +++ b/ext/phar/util.c @@ -628,11 +628,6 @@ int phar_open_archive_fp(phar_archive_data *phar TSRMLS_DC) /* {{{ */ if (phar_get_pharfp(phar TSRMLS_CC)) { return SUCCESS; } -#if PHP_API_VERSION < 20100412 - if (PG(safe_mode) && (!php_checkuid(phar->fname, NULL, CHECKUID_ALLOW_ONLY_FILE))) { - return FAILURE; - } -#endif if (php_check_open_basedir(phar->fname TSRMLS_CC)) { return FAILURE; @@ -814,6 +809,7 @@ int phar_create_writeable_entry(phar_archive_data *phar, phar_entry_info *entry, if (entry->fp_type == PHAR_MOD) { /* already newly created, truncate */ php_stream_truncate_set_size(entry->fp, 0); + entry->old_flags = entry->flags; entry->is_modified = 1; phar->is_modified = 1; @@ -927,6 +923,18 @@ phar_entry_info * phar_open_jit(phar_archive_data *phar, phar_entry_info *entry, } /* }}} */ +PHP_PHAR_API int phar_resolve_alias(char *alias, int alias_len, char **filename, int *filename_len TSRMLS_DC) /* {{{ */ { + phar_archive_data **fd_ptr; + if (PHAR_GLOBALS->phar_alias_map.arBuckets + && SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void**)&fd_ptr)) { + *filename = (*fd_ptr)->fname; + *filename_len = (*fd_ptr)->fname_len; + return SUCCESS; + } + return FAILURE; +} +/* }}} */ + int phar_free_alias(phar_archive_data *phar, char *alias, int alias_len TSRMLS_DC) /* {{{ */ { if (phar->refcount || phar->is_persistent) { @@ -1004,8 +1012,10 @@ int phar_get_archive(phar_archive_data **archive, char *fname, int fname_len, ch spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, (*fd_ptr)->fname, fname); } if (SUCCESS == phar_free_alias(*fd_ptr, alias, alias_len TSRMLS_CC)) { - efree(*error); - *error = NULL; + if (error) { + efree(*error); + *error = NULL; + } } return FAILURE; } @@ -1410,11 +1420,7 @@ static int phar_call_openssl_signverify(int is_sign, php_stream *fp, off_t end, Z_TYPE_P(zdata) = IS_STRING; Z_STRLEN_P(zdata) = end; -#if PHP_MAJOR_VERSION > 5 - if (end != (off_t) php_stream_copy_to_mem(fp, (void **) &(Z_STRVAL_P(zdata)), (size_t) end, 0)) { -#else if (end != (off_t) php_stream_copy_to_mem(fp, &(Z_STRVAL_P(zdata)), (size_t) end, 0)) { -#endif zval_dtor(zdata); zval_dtor(zsig); zval_dtor(zkey); @@ -1447,6 +1453,7 @@ static int phar_call_openssl_signverify(int is_sign, php_stream *fp, off_t end, Z_ADDREF_P(zsig); } Z_ADDREF_P(zkey); + fci.retval_ptr_ptr = &retval_ptr; if (FAILURE == zend_call_function(&fci, &fcc TSRMLS_CC)) { @@ -1464,12 +1471,14 @@ static int phar_call_openssl_signverify(int is_sign, php_stream *fp, off_t end, zval_dtor(openssl); efree(openssl); Z_DELREF_P(zdata); + if (is_sign) { Z_UNSET_ISREF_P(zsig); } else { Z_DELREF_P(zsig); } Z_DELREF_P(zkey); + zval_dtor(zdata); efree(zdata); zval_dtor(zkey); diff --git a/ext/posix/tests/posix_getgrnam.phpt b/ext/posix/tests/posix_getgrnam.phpt deleted file mode 100644 index 854db4ac1614d..0000000000000 --- a/ext/posix/tests/posix_getgrnam.phpt +++ /dev/null @@ -1,19 +0,0 @@ ---TEST-- -posix_getgrnam(): Basic tests ---SKIPIF-- - ---FILE-- - ---EXPECT-- -bool(false) -bool(false) -bool(false) diff --git a/ext/posix/tests/posix_getgrnam_basic.phpt b/ext/posix/tests/posix_getgrnam_basic.phpt deleted file mode 100644 index fd5bf23172d86..0000000000000 --- a/ext/posix/tests/posix_getgrnam_basic.phpt +++ /dev/null @@ -1,23 +0,0 @@ ---TEST-- -posix_getgrnam(): Basic tests ---SKIPIF-- - ---FILE-- - -===DONE=== ---EXPECT-- -Basic test of POSIX posix_getgrnam function -bool(false) -bool(false) -bool(false) -===DONE=== \ No newline at end of file diff --git a/ext/posix/tests/posix_getpwnam.phpt b/ext/posix/tests/posix_getpwnam.phpt deleted file mode 100644 index b5de1e4ce233d..0000000000000 --- a/ext/posix/tests/posix_getpwnam.phpt +++ /dev/null @@ -1,19 +0,0 @@ ---TEST-- -posix_getpwnam(): Basic tests ---SKIPIF-- - ---FILE-- - ---EXPECT-- -bool(false) -bool(false) -bool(false) diff --git a/ext/posix/tests/posix_getpwnam_basic.phpt b/ext/posix/tests/posix_getpwnam_basic.phpt deleted file mode 100644 index d675d6c182382..0000000000000 --- a/ext/posix/tests/posix_getpwnam_basic.phpt +++ /dev/null @@ -1,23 +0,0 @@ ---TEST-- -posix_getpwnam(): Basic tests ---SKIPIF-- - ---FILE-- - -===DONE==== ---EXPECT-- -Basic test of POSIX posix_getpwnam function -bool(false) -bool(false) -bool(false) -===DONE==== diff --git a/ext/readline/readline.c b/ext/readline/readline.c index bd460696bd704..d4032ca94718a 100644 --- a/ext/readline/readline.c +++ b/ext/readline/readline.c @@ -170,7 +170,10 @@ ZEND_GET_MODULE(readline) PHP_MINIT_FUNCTION(readline) { - using_history(); +#if HAVE_LIBREADLINE + /* libedit don't need this call which set the tty in cooked mode */ + using_history(); +#endif return PHP_MINIT(cli_readline)(INIT_FUNC_ARGS_PASSTHRU); } diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index b1f7484f243ca..15cfec98c0cb6 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -681,8 +681,8 @@ static zend_op* _get_recv_op(zend_op_array *op_array, zend_uint offset) ++offset; while (op < end) { - if ((op->opcode == ZEND_RECV || op->opcode == ZEND_RECV_INIT) - && op->op1.num == (long)offset) + if ((op->opcode == ZEND_RECV || op->opcode == ZEND_RECV_INIT + || op->opcode == ZEND_RECV_VARIADIC) && op->op1.num == (long)offset) { return op; } @@ -715,6 +715,9 @@ static void _parameter_string(string *str, zend_function *fptr, struct _zend_arg if (arg_info->pass_by_reference) { string_write(str, "&", sizeof("&")-1); } + if (arg_info->is_variadic) { + string_write(str, "...", sizeof("...")-1); + } if (arg_info->name) { string_printf(str, "$%s", arg_info->name); } else { @@ -1105,29 +1108,26 @@ static void _extension_string(string *str, zend_module_entry *module, char *inde string_free(&str_constants); } - if (module->functions && module->functions->fname) { + { + HashPosition iterator; zend_function *fptr; - const zend_function_entry *func = module->functions; - - string_printf(str, "\n - Functions {\n"); - - /* Is there a better way of doing this? */ - while (func->fname) { - int fname_len = strlen(func->fname); - char *lc_name = zend_str_tolower_dup(func->fname, fname_len); - - if (zend_hash_find(EG(function_table), lc_name, fname_len + 1, (void**) &fptr) == FAILURE) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Internal error: Cannot find extension function %s in global function table", func->fname); - func++; - efree(lc_name); - continue; + int first = 1; + + zend_hash_internal_pointer_reset_ex(CG(function_table), &iterator); + while (zend_hash_get_current_data_ex(CG(function_table), (void **) &fptr, &iterator) == SUCCESS) { + if (fptr->common.type==ZEND_INTERNAL_FUNCTION + && fptr->internal_function.module == module) { + if (first) { + string_printf(str, "\n - Functions {\n"); + first = 0; + } + _function_string(str, fptr, NULL, " " TSRMLS_CC); } - - _function_string(str, fptr, NULL, " " TSRMLS_CC); - efree(lc_name); - func++; + zend_hash_move_forward_ex(CG(function_table), &iterator); + } + if (!first) { + string_printf(str, "%s }\n", indent); } - string_printf(str, "%s }\n", indent); } { @@ -2596,8 +2596,7 @@ ZEND_METHOD(reflection_parameter, getDefaultValue) *return_value = *precv->op2.zv; INIT_PZVAL(return_value); - if ((Z_TYPE_P(return_value) & IS_CONSTANT_TYPE_MASK) != IS_CONSTANT - && (Z_TYPE_P(return_value) & IS_CONSTANT_TYPE_MASK) != IS_CONSTANT_ARRAY) { + if (!IS_CONSTANT_TYPE(Z_TYPE_P(return_value))) { zval_copy_ctor(return_value); } zval_update_constant_ex(&return_value, (void*)0, param->fptr->common.scope TSRMLS_CC); @@ -2652,6 +2651,22 @@ ZEND_METHOD(reflection_parameter, getDefaultValueConstantName) } /* }}} */ +/* {{{ proto public bool ReflectionParameter::isVariadic() + Returns whether this parameter is a variadic parameter */ +ZEND_METHOD(reflection_parameter, isVariadic) +{ + reflection_object *intern; + parameter_reference *param; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + GET_REFLECTION_OBJECT_PTR(param); + + RETVAL_BOOL(param->arg_info->is_variadic); +} +/* }}} */ + /* {{{ proto public static mixed ReflectionMethod::export(mixed class, string name [, bool return]) throws ReflectionException Exports a reflection object. Returns the output if TRUE is specified for return, printing it otherwise. */ ZEND_METHOD(reflection_method, export) @@ -3095,6 +3110,14 @@ ZEND_METHOD(reflection_function, isGenerator) } /* }}} */ +/* {{{ proto public bool ReflectionFunction::isVariadic() + Returns whether this function is variadic */ +ZEND_METHOD(reflection_function, isVariadic) +{ + _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_VARIADIC); +} +/* }}} */ + /* {{{ proto public bool ReflectionFunction::inNamespace() Returns whether this function is defined in namespace */ ZEND_METHOD(reflection_function, inNamespace) @@ -3387,7 +3410,7 @@ static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value /* this is necessary to make it able to work with default array * properties, returned to user */ - if (Z_TYPE_P(prop_copy) == IS_CONSTANT_ARRAY || (Z_TYPE_P(prop_copy) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) { + if (IS_CONSTANT_TYPE(Z_TYPE_P(prop_copy))) { zval_update_constant(&prop_copy, (void *) 1 TSRMLS_CC); } @@ -5264,6 +5287,9 @@ ZEND_METHOD(reflection_extension, getFunctions) { reflection_object *intern; zend_module_entry *module; + HashPosition iterator; + zval *function; + zend_function *fptr; if (zend_parse_parameters_none() == FAILURE) { return; @@ -5271,29 +5297,15 @@ ZEND_METHOD(reflection_extension, getFunctions) GET_REFLECTION_OBJECT_PTR(module); array_init(return_value); - if (module->functions) { - zval *function; - zend_function *fptr; - const zend_function_entry *func = module->functions; - - /* Is there a better way of doing this? */ - while (func->fname) { - int fname_len = strlen(func->fname); - char *lc_name = zend_str_tolower_dup(func->fname, fname_len); - - if (zend_hash_find(EG(function_table), lc_name, fname_len + 1, (void**) &fptr) == FAILURE) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Internal error: Cannot find extension function %s in global function table", func->fname); - func++; - efree(lc_name); - continue; - } - + zend_hash_internal_pointer_reset_ex(CG(function_table), &iterator); + while (zend_hash_get_current_data_ex(CG(function_table), (void **) &fptr, &iterator) == SUCCESS) { + if (fptr->common.type==ZEND_INTERNAL_FUNCTION + && fptr->internal_function.module == module) { ALLOC_ZVAL(function); reflection_function_factory(fptr, NULL, function TSRMLS_CC); - add_assoc_zval_ex(return_value, func->fname, fname_len+1, function); - func++; - efree(lc_name); + add_assoc_zval(return_value, fptr->common.function_name, function); } + zend_hash_move_forward_ex(CG(function_table), &iterator); } } /* }}} */ @@ -5720,6 +5732,7 @@ static const zend_function_entry reflection_function_abstract_functions[] = { ZEND_ME(reflection_function, isInternal, arginfo_reflection__void, 0) ZEND_ME(reflection_function, isUserDefined, arginfo_reflection__void, 0) ZEND_ME(reflection_function, isGenerator, arginfo_reflection__void, 0) + ZEND_ME(reflection_function, isVariadic, arginfo_reflection__void, 0) ZEND_ME(reflection_function, getClosureThis, arginfo_reflection__void, 0) ZEND_ME(reflection_function, getClosureScopeClass, arginfo_reflection__void, 0) ZEND_ME(reflection_function, getDocComment, arginfo_reflection__void, 0) @@ -6022,6 +6035,7 @@ static const zend_function_entry reflection_parameter_functions[] = { ZEND_ME(reflection_parameter, getDefaultValue, arginfo_reflection__void, 0) ZEND_ME(reflection_parameter, isDefaultValueConstant, arginfo_reflection__void, 0) ZEND_ME(reflection_parameter, getDefaultValueConstantName, arginfo_reflection__void, 0) + ZEND_ME(reflection_parameter, isVariadic, arginfo_reflection__void, 0) PHP_FE_END }; diff --git a/ext/reflection/tests/ReflectionExtension_bug66218.phpt b/ext/reflection/tests/ReflectionExtension_bug66218.phpt new file mode 100644 index 0000000000000..e263624bada99 --- /dev/null +++ b/ext/reflection/tests/ReflectionExtension_bug66218.phpt @@ -0,0 +1,21 @@ +--TEST-- +ReflectionExtension::getFunctions() ##6218 zend_register_functions breaks reflection +--SKIPIF-- + +--FILE-- +getFunctions(); +var_dump($t['dl']); +?> +Done +--EXPECTF-- +object(ReflectionFunction)#%d (1) { + ["name"]=> + string(2) "dl" +} +Done diff --git a/ext/reflection/tests/ReflectionFunction_isVariadic_basic.phpt b/ext/reflection/tests/ReflectionFunction_isVariadic_basic.phpt new file mode 100644 index 0000000000000..50b6bb495e449 --- /dev/null +++ b/ext/reflection/tests/ReflectionFunction_isVariadic_basic.phpt @@ -0,0 +1,18 @@ +--TEST-- +ReflectionFunction::isVariadic() +--FILE-- +isVariadic()); +var_dump((new ReflectionFunction('test2'))->isVariadic()); +var_dump((new ReflectionFunction('test3'))->isVariadic()); + +?> +--EXPECT-- +bool(false) +bool(true) +bool(true) diff --git a/ext/reflection/tests/ReflectionParameter_canBePassedByValue.phpt b/ext/reflection/tests/ReflectionParameter_canBePassedByValue.phpt index 82c62001226b2..4772f6548dcae 100644 --- a/ext/reflection/tests/ReflectionParameter_canBePassedByValue.phpt +++ b/ext/reflection/tests/ReflectionParameter_canBePassedByValue.phpt @@ -61,6 +61,10 @@ Name: SORT_REGULAR_or_SORT_NUMERIC_or_SORT_STRING Is passed by reference: yes Can be passed by value: yes +Name: more_array_and_sort_options +Is passed by reference: yes +Can be passed by value: yes + => sort: Name: arg diff --git a/ext/reflection/tests/ReflectionParameter_isVariadic_basic.phpt b/ext/reflection/tests/ReflectionParameter_isVariadic_basic.phpt new file mode 100644 index 0000000000000..370edc388df39 --- /dev/null +++ b/ext/reflection/tests/ReflectionParameter_isVariadic_basic.phpt @@ -0,0 +1,24 @@ +--TEST-- +ReflectionParameter::isVariadic() +--FILE-- +getParameters()[0]->isVariadic()); +var_dump($r2->getParameters()[0]->isVariadic()); +var_dump($r3->getParameters()[0]->isVariadic()); +var_dump($r3->getParameters()[1]->isVariadic()); + +?> +--EXPECT-- +bool(false) +bool(true) +bool(false) +bool(true) diff --git a/ext/reflection/tests/ReflectionParameter_toString_basic.phpt b/ext/reflection/tests/ReflectionParameter_toString_basic.phpt index 268ced15eca32..d1a23c758d3a3 100644 --- a/ext/reflection/tests/ReflectionParameter_toString_basic.phpt +++ b/ext/reflection/tests/ReflectionParameter_toString_basic.phpt @@ -4,7 +4,7 @@ ReflectionParameter::__toString() Stefan Koopmanschap --FILE-- $value) { --EXPECT-- Parameter #0 [ $test ] Parameter #1 [ $test2 = NULL ] +Parameter #2 [ ...$test3 ] ==DONE== diff --git a/ext/session/tests/session_name_error.phpt b/ext/session/tests/session_name_error.phpt index 1b99d4ea3558e..9f0101d98b5de 100644 --- a/ext/session/tests/session_name_error.phpt +++ b/ext/session/tests/session_name_error.phpt @@ -231,6 +231,6 @@ string(12) "Hello World!" -- Iteration 24 -- Warning: session_name() expects parameter 1 to be string, resource given in %s on line %d -resource(5) of type (stream) +resource(%d) of type (stream) NULL Done \ No newline at end of file diff --git a/ext/skeleton/php_skeleton.h b/ext/skeleton/php_skeleton.h index 86836c03e287a..d0ba6f04abea4 100644 --- a/ext/skeleton/php_skeleton.h +++ b/ext/skeleton/php_skeleton.h @@ -6,6 +6,8 @@ extern zend_module_entry extname_module_entry; #define phpext_extname_ptr &extname_module_entry +#define PHP_EXTNAME_VERSION "0.1.0" /* Replace with version number for your extension */ + #ifdef PHP_WIN32 # define PHP_EXTNAME_API __declspec(dllexport) #elif defined(__GNUC__) && __GNUC__ >= 4 diff --git a/ext/skeleton/skeleton.c b/ext/skeleton/skeleton.c index b9a918806c810..462e48756ff07 100644 --- a/ext/skeleton/skeleton.c +++ b/ext/skeleton/skeleton.c @@ -142,7 +142,7 @@ zend_module_entry extname_module_entry = { PHP_RINIT(extname), /* Replace with NULL if there's nothing to do at request start */ PHP_RSHUTDOWN(extname), /* Replace with NULL if there's nothing to do at request end */ PHP_MINFO(extname), - "0.1", /* Replace with version number for your extension */ + PHP_EXTNAME_VERSION, STANDARD_MODULE_PROPERTIES }; /* }}} */ diff --git a/ext/snmp/snmp.c b/ext/snmp/snmp.c index 4e2510afc8da3..1b634e0cdd806 100644 --- a/ext/snmp/snmp.c +++ b/ext/snmp/snmp.c @@ -533,7 +533,7 @@ static void php_snmp_error(zval *object, const char *docref TSRMLS_DC, int type, } if (object && (snmp_object->exceptions_enabled & type)) { - zend_throw_exception_ex(php_snmp_exception_ce, type, snmp_object->snmp_errstr TSRMLS_CC); + zend_throw_exception_ex(php_snmp_exception_ce, type TSRMLS_CC, snmp_object->snmp_errstr); } else { va_start(args, format); php_verror(docref, "", E_WARNING, format, args TSRMLS_CC); @@ -896,6 +896,12 @@ static void php_snmp_internal(INTERNAL_FUNCTION_PARAMETERS, int st, keepwalking = 1; } } else { + if (st & SNMP_CMD_WALK && response->errstat == SNMP_ERR_TOOBIG && objid_query->max_repetitions > 1) { /* Answer will not fit into single packet */ + objid_query->max_repetitions /= 2; + snmp_free_pdu(response); + keepwalking = 1; + continue; + } if (!(st & SNMP_CMD_WALK) || response->errstat != SNMP_ERR_NOSUCHNAME || Z_TYPE_P(return_value) == IS_BOOL) { for ( count=1, vars = response->variables; vars && count != response->errindex; diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c index 5cec3e558eb13..748093a3efc0d 100644 --- a/ext/soap/php_encoding.c +++ b/ext/soap/php_encoding.c @@ -1189,7 +1189,7 @@ static xmlNodePtr to_xml_bool(encodeTypePtr type, zval *data, int style, xmlNode xmlAddChild(parent, ret); FIND_ZVAL_NULL(data, ret, style); - if (zend_is_true(data)) { + if (zend_is_true(data TSRMLS_CC)) { xmlNodeSetContent(ret, BAD_CAST("true")); } else { xmlNodeSetContent(ret, BAD_CAST("false")); diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c index 86ab03d9c80c7..14366f12cc407 100644 --- a/ext/soap/php_http.c +++ b/ext/soap/php_http.c @@ -807,6 +807,7 @@ int make_http_soap_request(zval *this_ptr, if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_cookies", sizeof("_cookies"), (void **)&cookies) == SUCCESS) { zval **data; char *key; + uint key_len; int i, n; has_cookies = 1; @@ -816,7 +817,7 @@ int make_http_soap_request(zval *this_ptr, smart_str_append_const(&soap_headers, "Cookie: "); for (i = 0; i < n; i++) { zend_hash_get_current_data(Z_ARRVAL_PP(cookies), (void **)&data); - zend_hash_get_current_key(Z_ARRVAL_PP(cookies), &key, NULL, FALSE); + zend_hash_get_current_key_ex(Z_ARRVAL_PP(cookies), &key, &key_len, NULL, 0, NULL); if (Z_TYPE_PP(data) == IS_ARRAY) { zval** value; @@ -829,7 +830,7 @@ int make_http_soap_request(zval *this_ptr, (zend_hash_index_find(Z_ARRVAL_PP(data), 2, (void**)&tmp) == FAILURE || in_domain(phpurl->host,Z_STRVAL_PP(tmp))) && (use_ssl || zend_hash_index_find(Z_ARRVAL_PP(data), 3, (void**)&tmp) == FAILURE)) { - smart_str_appendl(&soap_headers, key, strlen(key)); + smart_str_appendl(&soap_headers, key, key_len); smart_str_appendc(&soap_headers, '='); smart_str_appendl(&soap_headers, Z_STRVAL_PP(value), Z_STRLEN_PP(value)); smart_str_appendc(&soap_headers, ';'); diff --git a/ext/soap/php_sdl.c b/ext/soap/php_sdl.c index 0ac4c2ed7a9bf..f8c6940c1fb1c 100644 --- a/ext/soap/php_sdl.c +++ b/ext/soap/php_sdl.c @@ -24,7 +24,7 @@ #include "libxml/uri.h" #include "ext/standard/md5.h" -#include "tsrm_virtual_cwd.h" +#include "zend_virtual_cwd.h" #include #include @@ -2644,16 +2644,17 @@ static sdlAttributePtr make_persistent_sdl_attribute(sdlAttributePtr attr, HashT zend_hash_internal_pointer_reset(pattr->extraAttributes); while (zend_hash_get_current_data(attr->extraAttributes, (void**)&tmp) == SUCCESS) { - pextra = malloc(sizeof(sdlExtraAttribute)); - memset(pextra, 0, sizeof(sdlExtraAttribute)); - if ((*tmp)->ns) { - pextra->ns = strdup((*tmp)->ns); - } - if ((*tmp)->val) { - pextra->val = strdup((*tmp)->val); - } + if (zend_hash_get_current_key_ex(attr->extraAttributes, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) { + pextra = malloc(sizeof(sdlExtraAttribute)); + memset(pextra, 0, sizeof(sdlExtraAttribute)); - if (zend_hash_get_current_key_ex(attr->extraAttributes, &key, &key_len, &index, 0, NULL) == HASH_KEY_IS_STRING) { + if ((*tmp)->ns) { + pextra->ns = strdup((*tmp)->ns); + } + if ((*tmp)->val) { + pextra->val = strdup((*tmp)->val); + } + zend_hash_add(pattr->extraAttributes, key, key_len, (void*)&pextra, sizeof(sdlExtraAttributePtr), NULL); } diff --git a/ext/soap/soap.c b/ext/soap/soap.c index c5900dc645af4..b7495c166aaeb 100644 --- a/ext/soap/soap.c +++ b/ext/soap/soap.c @@ -2543,7 +2543,7 @@ static int do_request(zval *this_ptr, xmlDoc *request, char *location, char *act int ret = TRUE; char *buf; int buf_size; - zval func, param0, param1, param2, param3, param4; + zval func; zval *params[5]; zval **trace; zval **fault; @@ -2563,29 +2563,24 @@ static int do_request(zval *this_ptr, xmlDoc *request, char *location, char *act INIT_ZVAL(func); ZVAL_STRINGL(&func,"__doRequest",sizeof("__doRequest")-1,0); - INIT_ZVAL(param0); - params[0] = ¶m0; - ZVAL_STRINGL(params[0], buf, buf_size, 0); - INIT_ZVAL(param1); - params[1] = ¶m1; + ALLOC_INIT_ZVAL(params[0]); + ZVAL_STRINGL(params[0], buf, buf_size, 1); + ALLOC_INIT_ZVAL(params[1]); if (location == NULL) { ZVAL_NULL(params[1]); } else { - ZVAL_STRING(params[1], location, 0); + ZVAL_STRING(params[1], location, 1); } - INIT_ZVAL(param2); - params[2] = ¶m2; + ALLOC_INIT_ZVAL(params[2]); if (action == NULL) { ZVAL_NULL(params[2]); } else { - ZVAL_STRING(params[2], action, 0); + ZVAL_STRING(params[2], action, 1); } - INIT_ZVAL(param3); - params[3] = ¶m3; + ALLOC_INIT_ZVAL(params[3]); ZVAL_LONG(params[3], version); - INIT_ZVAL(param4); - params[4] = ¶m4; + ALLOC_INIT_ZVAL(params[4]); ZVAL_LONG(params[4], one_way); if (call_user_function(NULL, &this_ptr, &func, response, 5, params TSRMLS_CC) != SUCCESS) { @@ -2600,6 +2595,11 @@ static int do_request(zval *this_ptr, xmlDoc *request, char *location, char *act Z_LVAL_PP(trace) > 0) { add_property_stringl(this_ptr, "__last_response", Z_STRVAL_P(response), Z_STRLEN_P(response), 1); } + zval_ptr_dtor(¶ms[4]); + zval_ptr_dtor(¶ms[3]); + zval_ptr_dtor(¶ms[2]); + zval_ptr_dtor(¶ms[1]); + zval_ptr_dtor(¶ms[0]); xmlFree(buf); if (ret && zend_hash_find(Z_OBJPROP_P(this_ptr), "__soap_fault", sizeof("__soap_fault"), (void **) &fault) == SUCCESS) { return FALSE; @@ -2691,124 +2691,134 @@ static void do_soap_call(zval* this_ptr, SOAP_GLOBAL(features) = 0; } - if (sdl != NULL) { - fn = get_function(sdl, function); - if (fn != NULL) { - sdlBindingPtr binding = fn->binding; - int one_way = 0; - - if (fn->responseName == NULL && - fn->responseParameters == NULL && - soap_headers == NULL) { - one_way = 1; - } - - if (location == NULL) { - location = binding->location; - } - if (binding->bindingType == BINDING_SOAP) { - sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)fn->bindingAttributes; - request = serialize_function_call(this_ptr, fn, NULL, fnb->input.ns, real_args, arg_count, soap_version, soap_headers TSRMLS_CC); - ret = do_request(this_ptr, request, location, fnb->soapAction, soap_version, one_way, &response TSRMLS_CC); - } else { - request = serialize_function_call(this_ptr, fn, NULL, sdl->target_ns, real_args, arg_count, soap_version, soap_headers TSRMLS_CC); - ret = do_request(this_ptr, request, location, NULL, soap_version, one_way, &response TSRMLS_CC); - } - - xmlFreeDoc(request); - - if (ret && Z_TYPE(response) == IS_STRING) { - encode_reset_ns(); - ret = parse_packet_soap(this_ptr, Z_STRVAL(response), Z_STRLEN(response), fn, NULL, return_value, output_headers TSRMLS_CC); - encode_finish(); - } + zend_try { + if (sdl != NULL) { + fn = get_function(sdl, function); + if (fn != NULL) { + sdlBindingPtr binding = fn->binding; + int one_way = 0; + + if (fn->responseName == NULL && + fn->responseParameters == NULL && + soap_headers == NULL) { + one_way = 1; + } - zval_dtor(&response); + if (location == NULL) { + location = binding->location; + } + if (binding->bindingType == BINDING_SOAP) { + sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)fn->bindingAttributes; + request = serialize_function_call(this_ptr, fn, NULL, fnb->input.ns, real_args, arg_count, soap_version, soap_headers TSRMLS_CC); + ret = do_request(this_ptr, request, location, fnb->soapAction, soap_version, one_way, &response TSRMLS_CC); + } else { + request = serialize_function_call(this_ptr, fn, NULL, sdl->target_ns, real_args, arg_count, soap_version, soap_headers TSRMLS_CC); + ret = do_request(this_ptr, request, location, NULL, soap_version, one_way, &response TSRMLS_CC); + } + + xmlFreeDoc(request); + + if (ret && Z_TYPE(response) == IS_STRING) { + encode_reset_ns(); + ret = parse_packet_soap(this_ptr, Z_STRVAL(response), Z_STRLEN(response), fn, NULL, return_value, output_headers TSRMLS_CC); + encode_finish(); + } - } else { - smart_str error = {0}; - smart_str_appends(&error,"Function (\""); - smart_str_appends(&error,function); - smart_str_appends(&error,"\") is not a valid method for this service"); - smart_str_0(&error); - add_soap_fault(this_ptr, "Client", error.c, NULL, NULL TSRMLS_CC); - smart_str_free(&error); - } - } else { - zval **uri; - smart_str action = {0}; + zval_dtor(&response); - if (zend_hash_find(Z_OBJPROP_P(this_ptr), "uri", sizeof("uri"), (void *)&uri) == FAILURE) { - add_soap_fault(this_ptr, "Client", "Error finding \"uri\" property", NULL, NULL TSRMLS_CC); - } else if (location == NULL) { - add_soap_fault(this_ptr, "Client", "Error could not find \"location\" property", NULL, NULL TSRMLS_CC); - } else { - if (call_uri == NULL) { - call_uri = Z_STRVAL_PP(uri); + } else { + smart_str error = {0}; + smart_str_appends(&error,"Function (\""); + smart_str_appends(&error,function); + smart_str_appends(&error,"\") is not a valid method for this service"); + smart_str_0(&error); + add_soap_fault(this_ptr, "Client", error.c, NULL, NULL TSRMLS_CC); + smart_str_free(&error); } - request = serialize_function_call(this_ptr, NULL, function, call_uri, real_args, arg_count, soap_version, soap_headers TSRMLS_CC); + } else { + zval **uri; + smart_str action = {0}; - if (soap_action == NULL) { - smart_str_appends(&action, call_uri); - smart_str_appendc(&action, '#'); - smart_str_appends(&action, function); + if (zend_hash_find(Z_OBJPROP_P(this_ptr), "uri", sizeof("uri"), (void *)&uri) == FAILURE) { + add_soap_fault(this_ptr, "Client", "Error finding \"uri\" property", NULL, NULL TSRMLS_CC); + } else if (location == NULL) { + add_soap_fault(this_ptr, "Client", "Error could not find \"location\" property", NULL, NULL TSRMLS_CC); } else { - smart_str_appends(&action, soap_action); - } - smart_str_0(&action); + if (call_uri == NULL) { + call_uri = Z_STRVAL_PP(uri); + } + request = serialize_function_call(this_ptr, NULL, function, call_uri, real_args, arg_count, soap_version, soap_headers TSRMLS_CC); - ret = do_request(this_ptr, request, location, action.c, soap_version, 0, &response TSRMLS_CC); + if (soap_action == NULL) { + smart_str_appends(&action, call_uri); + smart_str_appendc(&action, '#'); + smart_str_appends(&action, function); + } else { + smart_str_appends(&action, soap_action); + } + smart_str_0(&action); - smart_str_free(&action); - xmlFreeDoc(request); + ret = do_request(this_ptr, request, location, action.c, soap_version, 0, &response TSRMLS_CC); - if (ret && Z_TYPE(response) == IS_STRING) { - encode_reset_ns(); - ret = parse_packet_soap(this_ptr, Z_STRVAL(response), Z_STRLEN(response), NULL, function, return_value, output_headers TSRMLS_CC); - encode_finish(); - } + smart_str_free(&action); + xmlFreeDoc(request); - zval_dtor(&response); - } - } + if (ret && Z_TYPE(response) == IS_STRING) { + encode_reset_ns(); + ret = parse_packet_soap(this_ptr, Z_STRVAL(response), Z_STRLEN(response), NULL, function, return_value, output_headers TSRMLS_CC); + encode_finish(); + } - if (!ret) { - zval** fault; - if (zend_hash_find(Z_OBJPROP_P(this_ptr), "__soap_fault", sizeof("__soap_fault"), (void **) &fault) == SUCCESS) { - *return_value = **fault; - zval_copy_ctor(return_value); + zval_dtor(&response); + } + } + + if (!ret) { + zval** fault; + if (zend_hash_find(Z_OBJPROP_P(this_ptr), "__soap_fault", sizeof("__soap_fault"), (void **) &fault) == SUCCESS) { + *return_value = **fault; + zval_copy_ctor(return_value); + } else { + *return_value = *add_soap_fault(this_ptr, "Client", "Unknown Error", NULL, NULL TSRMLS_CC); + zval_copy_ctor(return_value); + } } else { - *return_value = *add_soap_fault(this_ptr, "Client", "Unknown Error", NULL, NULL TSRMLS_CC); - zval_copy_ctor(return_value); - } - } else { - zval** fault; - if (zend_hash_find(Z_OBJPROP_P(this_ptr), "__soap_fault", sizeof("__soap_fault"), (void **) &fault) == SUCCESS) { - *return_value = **fault; - zval_copy_ctor(return_value); + zval** fault; + if (zend_hash_find(Z_OBJPROP_P(this_ptr), "__soap_fault", sizeof("__soap_fault"), (void **) &fault) == SUCCESS) { + *return_value = **fault; + zval_copy_ctor(return_value); + } } - } - if (!EG(exception) && - Z_TYPE_P(return_value) == IS_OBJECT && - instanceof_function(Z_OBJCE_P(return_value), soap_fault_class_entry TSRMLS_CC) && - (zend_hash_find(Z_OBJPROP_P(this_ptr), "_exceptions", sizeof("_exceptions"), (void **) &tmp) != SUCCESS || - Z_TYPE_PP(tmp) != IS_BOOL || Z_LVAL_PP(tmp) != 0)) { - zval *exception; + if (!EG(exception) && + Z_TYPE_P(return_value) == IS_OBJECT && + instanceof_function(Z_OBJCE_P(return_value), soap_fault_class_entry TSRMLS_CC) && + (zend_hash_find(Z_OBJPROP_P(this_ptr), "_exceptions", sizeof("_exceptions"), (void **) &tmp) != SUCCESS || + Z_TYPE_PP(tmp) != IS_BOOL || Z_LVAL_PP(tmp) != 0)) { + zval *exception; - MAKE_STD_ZVAL(exception); - MAKE_COPY_ZVAL(&return_value, exception); - zend_throw_exception_object(exception TSRMLS_CC); - } + MAKE_STD_ZVAL(exception); + MAKE_COPY_ZVAL(&return_value, exception); + zend_throw_exception_object(exception TSRMLS_CC); + } + } zend_catch { + _bailout = 1; + } zend_end_try(); + if (SOAP_GLOBAL(encoding) != NULL) { xmlCharEncCloseFunc(SOAP_GLOBAL(encoding)); } + SOAP_GLOBAL(features) = old_features; SOAP_GLOBAL(typemap) = old_typemap; SOAP_GLOBAL(class_map) = old_class_map; SOAP_GLOBAL(encoding) = old_encoding; SOAP_GLOBAL(sdl) = old_sdl; + if (_bailout) { + _bailout = 0; + zend_bailout(); + } SOAP_CLIENT_END_CODE(); } diff --git a/ext/soap/tests/bugs/bug66112.phpt b/ext/soap/tests/bugs/bug66112.phpt new file mode 100644 index 0000000000000..4d5be792963e5 --- /dev/null +++ b/ext/soap/tests/bugs/bug66112.phpt @@ -0,0 +1,36 @@ +--TEST-- +Bug #66112 (Use after free condition in SOAP extension) +--SKIPIF-- + +--INI-- +soap.wsdl_cache_enabled=0 +--FILE-- +array(array("type_ns"=>"uri:mist", "type_name"=>"A")))); + try{ + $client->Mist(array("XX"=>"xx")); + }catch(SoapFault $x){ + } + return array("A"=>"ABC","B"=>"sss"); +} +$s = new SoapServer(WSDL, array('typemap'=>array(array("type_ns"=>"uri:mist", "type_name"=>"A")))); +$s->addFunction("Mist"); +$_SERVER["REQUEST_METHOD"] = "POST"; +$HTTP_RAW_POST_DATA=<< + + + + XXXyyy + + +EOF; +$s->handle($HTTP_RAW_POST_DATA); +echo "OK\n"; +?> +--EXPECT-- + +ABCsss +OK diff --git a/ext/soap/tests/bugs/bug66112.wsdl b/ext/soap/tests/bugs/bug66112.wsdl new file mode 100644 index 0000000000000..8589a46bf21c9 --- /dev/null +++ b/ext/soap/tests/bugs/bug66112.wsdl @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ext/sockets/config.m4 b/ext/sockets/config.m4 index 9c752496463f5..a5a63dfb616e2 100644 --- a/ext/sockets/config.m4 +++ b/ext/sockets/config.m4 @@ -16,10 +16,10 @@ if test "$PHP_SOCKETS" != "no"; then if test "$ac_cv_cmsghdr" = yes; then AC_DEFINE(HAVE_CMSGHDR,1,[Whether you have struct cmsghdr]) - fi + fi AC_CHECK_FUNCS([hstrerror socketpair if_nametoindex if_indextoname]) - AC_CHECK_HEADERS([netdb.h netinet/tcp.h sys/un.h sys/sockio.h errno.h]) + AC_CHECK_HEADERS([netdb.h netinet/tcp.h sys/un.h sys/sockio.h errno.h]) AC_TRY_COMPILE([ #include #include @@ -27,7 +27,7 @@ if test "$PHP_SOCKETS" != "no"; then [AC_DEFINE(MISSING_MSGHDR_MSGFLAGS, 1, [ ])] ) AC_DEFINE([HAVE_SOCKETS], 1, [ ]) - + dnl Check for fied ss_family in sockaddr_storage (missing in AIX until 5.3) AC_CACHE_CHECK([for field ss_family in struct sockaddr_storage], ac_cv_ss_family, [ @@ -38,11 +38,24 @@ if test "$PHP_SOCKETS" != "no"; then ], [struct sockaddr_storage sa_store; sa_store.ss_family = AF_INET6;], ac_cv_ss_family=yes, ac_cv_ss_family=no) ]) - + if test "$ac_cv_ss_family" = yes; then AC_DEFINE(HAVE_SA_SS_FAMILY,1,[Whether you have sockaddr_storage.ss_family]) fi + dnl Check for AI_V4MAPPED flag + AC_CACHE_CHECK([if getaddrinfo supports AI_V4MAPPED],[ac_cv_gai_ai_v4mapped], + [ + AC_TRY_COMPILE([ +#include + ], [int flag = AI_V4MAPPED;], + ac_cv_gai_ai_v4mapped=yes, ac_cv_gai_ai_v4mapped=no) + ]) + + if test "$ac_cv_gai_ai_v4mapped" = yes; then + AC_DEFINE(HAVE_AI_V4MAPPED,1,[Whether you have AI_V4MAPPED]) + fi + PHP_NEW_EXTENSION([sockets], [sockets.c multicast.c conversions.c sockaddr_conv.c sendrecvmsg.c], [$ext_shared]) PHP_INSTALL_HEADERS([ext/sockets/], [php_sockets.h]) fi diff --git a/ext/sockets/conversions.c b/ext/sockets/conversions.c index ed55ed52fa754..d81484521d8c0 100644 --- a/ext/sockets/conversions.c +++ b/ext/sockets/conversions.c @@ -1257,7 +1257,7 @@ void to_zval_read_msghdr(const char *msghdr_c, zval *zv, res_context *ctx) /* CONVERSIONS for if_index */ static void from_zval_write_ifindex(const zval *zv, char *uinteger, ser_context *ctx) { - unsigned ret; + unsigned ret = 0; zval lzval = zval_used_for_init; if (Z_TYPE_P(zv) == IS_LONG) { diff --git a/ext/sockets/multicast.c b/ext/sockets/multicast.c index 7466c6266e7f1..ecf3a65a325e6 100644 --- a/ext/sockets/multicast.c +++ b/ext/sockets/multicast.c @@ -63,6 +63,28 @@ static const char *_php_source_op_to_string(enum source_op sop); static int _php_source_op_to_ipv4_op(enum source_op sop); #endif +int php_string_to_if_index(const char *val, unsigned *out TSRMLS_DC) +{ +#if HAVE_IF_NAMETOINDEX + unsigned int ind; + + ind = if_nametoindex(val); + if (ind == 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, + "no interface with name \"%s\" could be found", val); + return FAILURE; + } else { + *out = ind; + return SUCCESS; + } +#else + php_error_docref(NULL TSRMLS_CC, E_WARNING, + "this platform does not support looking up an interface by " + "name, an integer interface index must be supplied instead"); + return FAILURE; +#endif +} + static int php_get_if_index_from_zval(zval *val, unsigned *out TSRMLS_DC) { int ret; @@ -78,31 +100,17 @@ static int php_get_if_index_from_zval(zval *val, unsigned *out TSRMLS_DC) ret = SUCCESS; } } else { -#if HAVE_IF_NAMETOINDEX - unsigned int ind; zval_add_ref(&val); convert_to_string_ex(&val); - ind = if_nametoindex(Z_STRVAL_P(val)); - if (ind == 0) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, - "no interface with name \"%s\" could be found", Z_STRVAL_P(val)); - ret = FAILURE; - } else { - *out = ind; - ret = SUCCESS; - } + ret = php_string_to_if_index(Z_STRVAL_P(val), out TSRMLS_CC); zval_ptr_dtor(&val); -#else - php_error_docref(NULL TSRMLS_CC, E_WARNING, - "this platform does not support looking up an interface by " - "name, an integer interface index must be supplied instead"); - ret = FAILURE; -#endif } return ret; } + + static int php_get_if_index_from_array(const HashTable *ht, const char *key, php_socket *sock, unsigned int *if_index TSRMLS_DC) { diff --git a/ext/sockets/multicast.h b/ext/sockets/multicast.h index 3614306bbb219..81a1bca799322 100644 --- a/ext/sockets/multicast.h +++ b/ext/sockets/multicast.h @@ -65,6 +65,8 @@ int php_add4_to_if_index( php_socket *php_sock, unsigned *if_index TSRMLS_DC); +int php_string_to_if_index(const char *val, unsigned *out TSRMLS_DC); + int php_mcast_join( php_socket *sock, int level, diff --git a/ext/sockets/sockaddr_conv.c b/ext/sockets/sockaddr_conv.c index a40b6b4936cbb..1c1a90d58f07f 100644 --- a/ext/sockets/sockaddr_conv.c +++ b/ext/sockets/sockaddr_conv.c @@ -9,6 +9,8 @@ #include #endif +extern int php_string_to_if_index(const char *val, unsigned *out TSRMLS_DC); + #if HAVE_IPV6 /* Sets addr by hostname, or by ip in string form (AF_INET6) */ int php_set_inet6_addr(struct sockaddr_in6 *sin6, char *string, php_socket *php_sock TSRMLS_DC) /* {{{ */ @@ -18,6 +20,7 @@ int php_set_inet6_addr(struct sockaddr_in6 *sin6, char *string, php_socket *php_ struct addrinfo hints; struct addrinfo *addrinfo = NULL; #endif + char *scope = strchr(string, '%'); if (inet_pton(AF_INET6, string, &tmp)) { memcpy(&(sin6->sin6_addr.s6_addr), &(tmp.s6_addr), sizeof(struct in6_addr)); @@ -26,7 +29,11 @@ int php_set_inet6_addr(struct sockaddr_in6 *sin6, char *string, php_socket *php_ memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_INET6; +#if HAVE_AI_V4MAPPED hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG; +#else + hints.ai_flags = AI_ADDRCONFIG; +#endif getaddrinfo(string, NULL, &hints, &addrinfo); if (!addrinfo) { #ifdef PHP_WIN32 @@ -53,6 +60,22 @@ int php_set_inet6_addr(struct sockaddr_in6 *sin6, char *string, php_socket *php_ } + if (scope++) { + long lval = 0; + double dval = 0; + unsigned scope_id = 0; + + if (IS_LONG == is_numeric_string(scope, strlen(scope), &lval, &dval, 0)) { + if (lval > 0 && lval <= UINT_MAX) { + scope_id = lval; + } + } else { + php_string_to_if_index(scope, &scope_id TSRMLS_CC); + } + + sin6->sin6_scope_id = scope_id; + } + return 1; } /* }}} */ diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index ca8076a95713c..3afa2b3ea844c 100644 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -599,7 +599,7 @@ static int spl_array_has_dimension_ex(int check_inherited, zval *object, zval *o SEPARATE_ARG_IF_REF(offset); zend_call_method_with_1_params(&object, Z_OBJCE_P(object), &intern->fptr_offset_has, "offsetExists", &rv, offset); zval_ptr_dtor(&offset); - if (rv && zend_is_true(rv)) { + if (rv && zend_is_true(rv TSRMLS_CC)) { zval_ptr_dtor(&rv); return 1; } @@ -620,7 +620,7 @@ static int spl_array_has_dimension_ex(int check_inherited, zval *object, zval *o case 2: return 1; default: - return zend_is_true(*tmp); + return zend_is_true(*tmp TSRMLS_CC); } } } @@ -643,7 +643,7 @@ static int spl_array_has_dimension_ex(int check_inherited, zval *object, zval *o case 2: return 1; default: - return zend_is_true(*tmp); + return zend_is_true(*tmp TSRMLS_CC); } } return 0; diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index 3dc7b7925c949..902161953ab1d 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -836,7 +836,7 @@ SPL_METHOD(DirectoryIterator, seek) int valid = 0; zend_call_method_with_0_params(&this_ptr, Z_OBJCE_P(getThis()), &intern->u.dir.func_valid, "valid", &retval); if (retval) { - valid = zend_is_true(retval); + valid = zend_is_true(retval TSRMLS_CC); zval_ptr_dtor(&retval); } if (!valid) { @@ -1497,7 +1497,7 @@ SPL_METHOD(RecursiveDirectoryIterator, hasChildren) spl_filesystem_object_get_file_name(intern TSRMLS_CC); if (!allow_links && !(intern->flags & SPL_FILE_DIR_FOLLOW_SYMLINKS)) { php_stat(intern->file_name, intern->file_name_len, FS_IS_LINK, return_value TSRMLS_CC); - if (zend_is_true(return_value)) { + if (zend_is_true(return_value TSRMLS_CC)) { RETURN_FALSE; } } @@ -2938,8 +2938,9 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fgetss, 0, 0, 0) ZEND_ARG_INFO(0, allowable_tags) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fscanf, 1, 0, 1) +ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fscanf, 0, 0, 1) ZEND_ARG_INFO(0, format) + ZEND_ARG_VARIADIC_INFO(1, vars) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fwrite, 0, 0, 1) diff --git a/ext/spl/spl_dllist.c b/ext/spl/spl_dllist.c index 273bc7506aa74..d5a9f83ae1411 100644 --- a/ext/spl/spl_dllist.c +++ b/ext/spl/spl_dllist.c @@ -603,7 +603,7 @@ SPL_METHOD(SplDoublyLinkedList, pop) zval *value; spl_dllist_object *intern; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) { + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -626,7 +626,7 @@ SPL_METHOD(SplDoublyLinkedList, shift) zval *value; spl_dllist_object *intern; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) { + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -649,7 +649,7 @@ SPL_METHOD(SplDoublyLinkedList, top) zval *value; spl_dllist_object *intern; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) { + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -672,7 +672,7 @@ SPL_METHOD(SplDoublyLinkedList, bottom) zval *value; spl_dllist_object *intern; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) { + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -695,7 +695,7 @@ SPL_METHOD(SplDoublyLinkedList, count) long count; spl_dllist_object *intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) { + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -710,7 +710,7 @@ SPL_METHOD(SplDoublyLinkedList, isEmpty) { long count; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) { + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -750,7 +750,7 @@ SPL_METHOD(SplDoublyLinkedList, getIteratorMode) { spl_dllist_object *intern; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) { + if (zend_parse_parameters_none() == FAILURE) { return; } diff --git a/ext/spl/spl_fixedarray.c b/ext/spl/spl_fixedarray.c index 86a5371ed30d3..ce9efb567d3f7 100644 --- a/ext/spl/spl_fixedarray.c +++ b/ext/spl/spl_fixedarray.c @@ -511,7 +511,7 @@ static inline int spl_fixedarray_object_has_dimension_helper(spl_fixedarray_obje if (!intern->array->elements[index]) { retval = 0; } else if (check_empty) { - if (zend_is_true(intern->array->elements[index])) { + if (zend_is_true(intern->array->elements[index] TSRMLS_CC)) { retval = 1; } else { retval = 0; @@ -540,7 +540,7 @@ static int spl_fixedarray_object_has_dimension(zval *object, zval *offset, int c zval_ptr_dtor(&intern->retval); MAKE_STD_ZVAL(intern->retval); ZVAL_ZVAL(intern->retval, rv, 1, 1); - return zend_is_true(intern->retval); + return zend_is_true(intern->retval TSRMLS_CC); } return 0; } @@ -583,7 +583,7 @@ SPL_METHOD(SplFixedArray, __construct) spl_fixedarray_object *intern; long size = 0; - if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &size)) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &size) == FAILURE) { return; } @@ -613,7 +613,7 @@ SPL_METHOD(SplFixedArray, __wakeup) HashTable *intern_ht = zend_std_get_properties(getThis() TSRMLS_CC); zval **data; - if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "")) { + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -643,7 +643,7 @@ SPL_METHOD(SplFixedArray, count) zval *object = getThis(); spl_fixedarray_object *intern; - if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "")) { + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -661,7 +661,7 @@ SPL_METHOD(SplFixedArray, toArray) { spl_fixedarray_object *intern; - if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "")) { + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -693,7 +693,7 @@ SPL_METHOD(SplFixedArray, fromArray) int num; zend_bool save_indexes = 1; - if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|b", &data, &save_indexes)) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|b", &data, &save_indexes) == FAILURE) { return; } @@ -777,7 +777,7 @@ SPL_METHOD(SplFixedArray, getSize) zval *object = getThis(); spl_fixedarray_object *intern; - if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "")) { + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -797,7 +797,7 @@ SPL_METHOD(SplFixedArray, setSize) spl_fixedarray_object *intern; long size; - if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &size)) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &size) == FAILURE) { return; } diff --git a/ext/spl/spl_heap.c b/ext/spl/spl_heap.c index cb1f68dcf1196..77b31c06dcdc7 100644 --- a/ext/spl/spl_heap.c +++ b/ext/spl/spl_heap.c @@ -587,7 +587,7 @@ SPL_METHOD(SplHeap, count) long count; spl_heap_object *intern = (spl_heap_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) { + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -602,7 +602,7 @@ SPL_METHOD(SplHeap, isEmpty) { spl_heap_object *intern = (spl_heap_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) { + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -643,7 +643,7 @@ SPL_METHOD(SplHeap, extract) zval *value; spl_heap_object *intern; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) { + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -705,7 +705,7 @@ SPL_METHOD(SplPriorityQueue, extract) zval *value, *value_out, **value_out_pp; spl_heap_object *intern; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) { + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -748,7 +748,7 @@ SPL_METHOD(SplPriorityQueue, top) zval *value, **value_out; spl_heap_object *intern; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) { + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -802,7 +802,7 @@ SPL_METHOD(SplHeap, recoverFromCorruption) { spl_heap_object *intern; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) { + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -835,7 +835,7 @@ SPL_METHOD(SplHeap, top) zval *value; spl_heap_object *intern; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) { + if (zend_parse_parameters_none() == FAILURE) { return; } diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c index 30532756cb6d6..11a2ba71cd1ae 100644 --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@ -249,7 +249,7 @@ static void spl_recursive_it_move_forward_ex(spl_recursive_it_object *object, zv } } if (retval) { - has_children = zend_is_true(retval); + has_children = zend_is_true(retval TSRMLS_CC); zval_ptr_dtor(&retval); if (has_children) { if (object->max_depth == -1 || object->max_depth > object->level) { @@ -1774,7 +1774,7 @@ static inline void spl_filter_it_fetch(zval *zthis, spl_dual_it_object *intern T while (spl_dual_it_fetch(intern, 1 TSRMLS_CC) == SUCCESS) { zend_call_method_with_0_params(&zthis, intern->std.ce, NULL, "accept", &retval); if (retval) { - if (zend_is_true(retval)) { + if (zend_is_true(retval TSRMLS_CC)) { zval_ptr_dtor(&retval); return; } @@ -2598,7 +2598,7 @@ static inline void spl_caching_it_next(spl_dual_it_object *intern TSRMLS_DC) return; } } else { - if (zend_is_true(retval)) { + if (zend_is_true(retval TSRMLS_CC)) { zend_call_method_with_0_params(&intern->inner.zobject, intern->inner.ce, NULL, "getchildren", &zchildren); if (EG(exception)) { if (zchildren) { @@ -3573,7 +3573,7 @@ static int spl_iterator_func_apply(zend_object_iterator *iter, void *puser TSRML apply_info->count++; zend_fcall_info_call(&apply_info->fci, &apply_info->fcc, &retval, NULL TSRMLS_CC); if (retval) { - result = zend_is_true(retval) ? ZEND_HASH_APPLY_KEEP : ZEND_HASH_APPLY_STOP; + result = zend_is_true(retval TSRMLS_CC) ? ZEND_HASH_APPLY_KEEP : ZEND_HASH_APPLY_STOP; zval_ptr_dtor(&retval); } else { result = ZEND_HASH_APPLY_STOP; diff --git a/ext/spl/tests/SplFileObject_getflags_basic.phpt b/ext/spl/tests/SplFileObject_getflags_basic.phpt index 5addadf38046e..88cf6861a2921 100644 --- a/ext/spl/tests/SplFileObject_getflags_basic.phpt +++ b/ext/spl/tests/SplFileObject_getflags_basic.phpt @@ -7,16 +7,16 @@ Erwin Poeze --FILE-- setFlags(SplFileObject::DROP_NEW_LINE); var_dump($fo->getFlags()); ?> --CLEAN-- --EXPECT-- int(1) diff --git a/ext/spl/tests/SplFileObject_getflags_error001.phpt b/ext/spl/tests/SplFileObject_getflags_error001.phpt index 1602f88885e11..ca53c857e7e6b 100644 --- a/ext/spl/tests/SplFileObject_getflags_error001.phpt +++ b/ext/spl/tests/SplFileObject_getflags_error001.phpt @@ -7,10 +7,10 @@ Erwin Poeze --FILE-- setFlags(SplFileObject::READ_CSV); $fo->setFlags(SplFileObject::DROP_NEW_LINE); @@ -20,7 +20,7 @@ var_dump($fo->getFlags()); ?> --CLEAN-- --EXPECT-- int(1) diff --git a/ext/spl/tests/SplFileObject_getflags_error002.phpt b/ext/spl/tests/SplFileObject_getflags_error002.phpt index e2c8255f44960..00fd351db8cca 100644 --- a/ext/spl/tests/SplFileObject_getflags_error002.phpt +++ b/ext/spl/tests/SplFileObject_getflags_error002.phpt @@ -5,9 +5,9 @@ Erwin Poeze --FILE-- setFlags(SplFileObject::READ_CSV); $fo->getFlags('fake'); @@ -15,7 +15,7 @@ $fo->getFlags('fake'); ?> --CLEAN-- --EXPECTF-- Warning: SplFileObject::getFlags() expects exactly 0 parameters, 1 given in %s on line %d diff --git a/ext/spl/tests/SplFileObject_rewind_error001.phpt b/ext/spl/tests/SplFileObject_rewind_error001.phpt index ac536a0a44af5..5f2379aa13911 100644 --- a/ext/spl/tests/SplFileObject_rewind_error001.phpt +++ b/ext/spl/tests/SplFileObject_rewind_error001.phpt @@ -7,16 +7,16 @@ Erwin Poeze --FILE-- rewind( "invalid" ); ?> --CLEAN-- --EXPECTF-- Warning: SplFileObject::rewind() expects exactly 0 parameters, 1 given in %s on line %d diff --git a/ext/spl/tests/bug51532.phpt b/ext/spl/tests/bug51532.phpt index 3a0722b2af68d..26eaa8f82f87d 100644 --- a/ext/spl/tests/bug51532.phpt +++ b/ext/spl/tests/bug51532.phpt @@ -4,7 +4,7 @@ SPL: Allow valid extension of SplFileObject::fscanf nApplyCount > 1) || (*src_entry == *dest_entry && Z_ISREF_PP(dest_entry) && (Z_REFCOUNT_PP(dest_entry) % 2))) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "recursion detected"); return 0; } SEPARATE_ZVAL(dest_entry); - SEPARATE_ZVAL(src_entry); if (Z_TYPE_PP(dest_entry) == IS_NULL) { convert_to_array_ex(dest_entry); @@ -2237,23 +2245,34 @@ PHPAPI int php_array_merge(HashTable *dest, HashTable *src, int recursive TSRMLS } else { convert_to_array_ex(dest_entry); } - if (Z_TYPE_PP(src_entry) == IS_NULL) { - convert_to_array_ex(src_entry); - add_next_index_null(*src_entry); + if (Z_TYPE_PP(src_entry) == IS_OBJECT) { + ALLOC_ZVAL(src_zval); + INIT_PZVAL_COPY(src_zval, *src_entry); + zval_copy_ctor(src_zval); + convert_to_array(src_zval); + tmp = src_zval; } else { - convert_to_array_ex(src_entry); + src_zval = *src_entry; } - if (thash) { - thash->nApplyCount++; - } - if (!php_array_merge(Z_ARRVAL_PP(dest_entry), Z_ARRVAL_PP(src_entry), recursive TSRMLS_CC)) { + if (Z_TYPE_P(src_zval) == IS_ARRAY) { + if (thash) { + thash->nApplyCount++; + } + if (!php_array_merge(Z_ARRVAL_PP(dest_entry), Z_ARRVAL_P(src_zval), recursive TSRMLS_CC)) { + if (thash) { + thash->nApplyCount--; + } + return 0; + } if (thash) { thash->nApplyCount--; } - return 0; + } else { + Z_ADDREF_PP(src_entry); + zend_hash_next_index_insert(Z_ARRVAL_PP(dest_entry), &src_zval, sizeof(zval *), NULL); } - if (thash) { - thash->nApplyCount--; + if (tmp) { + zval_ptr_dtor(&tmp); } } else { Z_ADDREF_PP(src_entry); @@ -2357,7 +2376,6 @@ static void php_array_merge_or_replace_wrapper(INTERNAL_FUNCTION_PARAMETERS, int array_init_size(return_value, init_size); for (i = 0; i < argc; i++) { - SEPARATE_ZVAL(args[i]); if (!replace) { php_array_merge(Z_ARRVAL_P(return_value), Z_ARRVAL_PP(args[i]), recursive TSRMLS_CC); } else if (recursive && i > 0) { /* First array will be copied directly instead */ @@ -4194,9 +4212,11 @@ PHP_FUNCTION(array_filter) { zval *array; zval **operand; - zval **args[1]; + zval **args[2]; zval *retval = NULL; + zval *key = NULL; zend_bool have_callback = 0; + long use_type = 0; char *string_key; zend_fcall_info fci = empty_fcall_info; zend_fcall_info_cache fci_cache = empty_fcall_info_cache; @@ -4204,7 +4224,7 @@ PHP_FUNCTION(array_filter) ulong num_key; HashPosition pos; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|f", &array, &fci, &fci_cache) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|fl", &array, &fci, &fci_cache, &use_type) == FAILURE) { return; } @@ -4217,34 +4237,65 @@ PHP_FUNCTION(array_filter) have_callback = 1; fci.no_separation = 0; fci.retval_ptr_ptr = &retval; - fci.param_count = 1; + + if (use_type == ARRAY_FILTER_USE_BOTH) { + fci.param_count = 2; + args[1] = &key; + } else { + fci.param_count = 1; + if (use_type == ARRAY_FILTER_USE_KEY) { + args[0] = &key; + } + } } for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(array), &pos); zend_hash_get_current_data_ex(Z_ARRVAL_P(array), (void **)&operand, &pos) == SUCCESS; zend_hash_move_forward_ex(Z_ARRVAL_P(array), &pos) ) { + int key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(array), &string_key, &string_key_len, &num_key, 0, &pos); + if (have_callback) { - args[0] = operand; + if (use_type) { + MAKE_STD_ZVAL(key); + /* Set up the key */ + switch (key_type) { + case HASH_KEY_IS_LONG: + Z_TYPE_P(key) = IS_LONG; + Z_LVAL_P(key) = num_key; + break; + + case HASH_KEY_IS_STRING: + ZVAL_STRINGL(key, string_key, string_key_len - 1, 1); + break; + } + } + + if (use_type != ARRAY_FILTER_USE_KEY) { + args[0] = operand; + } fci.params = args; if (zend_call_function(&fci, &fci_cache TSRMLS_CC) == SUCCESS && retval) { - if (!zend_is_true(retval)) { - zval_ptr_dtor(&retval); + int retval_true = zend_is_true(retval TSRMLS_CC); + + zval_ptr_dtor(&retval); + if (use_type) { + zval_ptr_dtor(&key); + } + if (!retval_true) { continue; - } else { - zval_ptr_dtor(&retval); } } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "An error occurred while invoking the filter callback"); return; } - } else if (!zend_is_true(*operand)) { + } else if (!zend_is_true(*operand TSRMLS_CC)) { continue; } zval_add_ref(operand); - switch (zend_hash_get_current_key_ex(Z_ARRVAL_P(array), &string_key, &string_key_len, &num_key, 0, &pos)) { + switch (key_type) { case HASH_KEY_IS_STRING: zend_hash_update(Z_ARRVAL_P(return_value), string_key, string_key_len, operand, sizeof(zval *), NULL); break; diff --git a/ext/standard/assert.c b/ext/standard/assert.c index 631834c97c0f3..1a24ade79e64f 100644 --- a/ext/standard/assert.c +++ b/ext/standard/assert.c @@ -200,7 +200,7 @@ PHP_FUNCTION(assert) } if (ASSERTG(callback)) { - zval **args = safe_emalloc(description_len == 0 ? 3 : 4, sizeof(zval **), 0); + zval **args = safe_emalloc(description_len == 0 ? 3 : 4, sizeof(zval *), 0); zval *retval; int i; uint lineno = zend_get_executed_lineno(TSRMLS_C); diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 3e5084e837642..33f13649cc146 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -288,11 +288,11 @@ ZEND_BEGIN_ARG_INFO(arginfo_reset, 0) ZEND_ARG_INFO(1, arg) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO(arginfo_current, ZEND_SEND_PREFER_REF) +ZEND_BEGIN_ARG_INFO(arginfo_current, 0) ZEND_ARG_INFO(ZEND_SEND_PREFER_REF, arg) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO(arginfo_key, ZEND_SEND_PREFER_REF) +ZEND_BEGIN_ARG_INFO(arginfo_key, 0) ZEND_ARG_INFO(ZEND_SEND_PREFER_REF, arg) ZEND_END_ARG_INFO() @@ -564,13 +564,14 @@ ZEND_BEGIN_ARG_INFO(arginfo_array_udiff_uassoc, 0) ZEND_ARG_INFO(0, callback_key_comp_func) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_array_multisort, ZEND_SEND_PREFER_REF, 0, 1) +ZEND_BEGIN_ARG_INFO_EX(arginfo_array_multisort, 0, 0, 1) ZEND_ARG_INFO(ZEND_SEND_PREFER_REF, arr1) /* ARRAY_INFO(0, arg1, 0) */ ZEND_ARG_INFO(ZEND_SEND_PREFER_REF, SORT_ASC_or_SORT_DESC) ZEND_ARG_INFO(ZEND_SEND_PREFER_REF, SORT_REGULAR_or_SORT_NUMERIC_or_SORT_STRING) ZEND_ARG_INFO(ZEND_SEND_PREFER_REF, arr2) ZEND_ARG_INFO(ZEND_SEND_PREFER_REF, SORT_ASC_or_SORT_DESC) ZEND_ARG_INFO(ZEND_SEND_PREFER_REF, SORT_REGULAR_or_SORT_NUMERIC_or_SORT_STRING) + ZEND_ARG_VARIADIC_INFO(ZEND_SEND_PREFER_REF, more_array_and_sort_options) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_array_rand, 0, 0, 1) @@ -595,6 +596,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_array_filter, 0, 0, 1) ZEND_ARG_INFO(0, arg) /* ARRAY_INFO(0, arg, 0) */ ZEND_ARG_INFO(0, callback) + ZEND_ARG_INFO(0, use_keys) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_array_map, 0, 0, 2) @@ -1139,10 +1141,10 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_fgetss, 0, 0, 1) ZEND_ARG_INFO(0, allowable_tags) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_fscanf, 1, 0, 2) +ZEND_BEGIN_ARG_INFO_EX(arginfo_fscanf, 0, 0, 2) ZEND_ARG_INFO(0, stream) ZEND_ARG_INFO(0, format) - ZEND_ARG_INFO(1, ...) + ZEND_ARG_VARIADIC_INFO(1, vars) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_fwrite, 0, 0, 2) @@ -2450,10 +2452,10 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_str_pad, 0, 0, 2) ZEND_ARG_INFO(0, pad_type) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_sscanf, 1, 0, 2) +ZEND_BEGIN_ARG_INFO_EX(arginfo_sscanf, 0, 0, 2) ZEND_ARG_INFO(0, str) ZEND_ARG_INFO(0, format) - ZEND_ARG_INFO(1, ...) + ZEND_ARG_VARIADIC_INFO(1, vars) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO(arginfo_str_rot13, 0) @@ -3640,6 +3642,7 @@ PHP_MINIT_FUNCTION(basic) /* {{{ */ BASIC_ADD_SUBMODULE(dl) BASIC_ADD_SUBMODULE(mail) + BASIC_ADD_SUBMODULE(streams) BASIC_MINIT_SUBMODULE(file) BASIC_MINIT_SUBMODULE(pack) BASIC_MINIT_SUBMODULE(browscap) @@ -5748,7 +5751,7 @@ PHP_FUNCTION(register_tick_function) zend_llist_init(BG(user_tick_functions), sizeof(user_tick_function_entry), (llist_dtor_func_t) user_tick_function_dtor, 0); - php_add_tick_function(run_user_tick_functions); + php_add_tick_function(run_user_tick_functions TSRMLS_CC); } for (i = 0; i < tick_fe.arg_count; i++) { @@ -5776,7 +5779,7 @@ PHP_FUNCTION(unregister_tick_function) return; } - if (Z_TYPE_P(function) != IS_ARRAY) { + if (Z_TYPE_P(function) != IS_ARRAY && Z_TYPE_P(function) != IS_OBJECT) { convert_to_string(function); } diff --git a/ext/standard/crypt.c b/ext/standard/crypt.c index 113a5bd0f516c..354c263afbd0c 100644 --- a/ext/standard/crypt.c +++ b/ext/standard/crypt.c @@ -272,6 +272,8 @@ PHP_FUNCTION(crypt) if (salt_in) { memcpy(salt, salt_in, MIN(PHP_MAX_SALT_LEN, salt_in_len)); + } else { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "No salt parameter was specified. You must use a randomly generated salt and a strong hash function to produce a secure hash."); } /* The automatic salt generation covers standard DES, md5-crypt and Blowfish (simple) */ diff --git a/ext/standard/file.c b/ext/standard/file.c index 1ec6a74f3f0b5..2bd35bf8941ae 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -223,10 +223,14 @@ PHP_MINIT_FUNCTION(file) REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv3_CLIENT", STREAM_CRYPTO_METHOD_SSLv3_CLIENT, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv23_CLIENT", STREAM_CRYPTO_METHOD_SSLv23_CLIENT, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_TLS_CLIENT", STREAM_CRYPTO_METHOD_TLS_CLIENT, CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT", STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT, CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT", STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv2_SERVER", STREAM_CRYPTO_METHOD_SSLv2_SERVER, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv3_SERVER", STREAM_CRYPTO_METHOD_SSLv3_SERVER, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_SSLv23_SERVER", STREAM_CRYPTO_METHOD_SSLv23_SERVER, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_TLS_SERVER", STREAM_CRYPTO_METHOD_TLS_SERVER, CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_TLSv1_1_SERVER", STREAM_CRYPTO_METHOD_TLSv1_1_SERVER, CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_TLSv1_2_SERVER", STREAM_CRYPTO_METHOD_TLSv1_2_SERVER, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("STREAM_SHUT_RD", STREAM_SHUT_RD, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("STREAM_SHUT_WR", STREAM_SHUT_WR, CONST_CS|CONST_PERSISTENT); diff --git a/ext/standard/ftp_fopen_wrapper.c b/ext/standard/ftp_fopen_wrapper.c index d04ef52be7494..2c12857560ec5 100644 --- a/ext/standard/ftp_fopen_wrapper.c +++ b/ext/standard/ftp_fopen_wrapper.c @@ -163,7 +163,7 @@ static php_stream *php_ftp_fopen_connect(php_stream_wrapper *wrapper, const char goto connect_errexit; } - php_stream_context_set(stream, context); + php_stream_context_set(stream, context TSRMLS_CC); php_stream_notify_info(context, PHP_STREAM_NOTIFY_CONNECT, NULL, 0); /* Start talking to ftp server */ @@ -571,7 +571,7 @@ php_stream * php_stream_url_wrap_ftp(php_stream_wrapper *wrapper, const char *pa goto errexit; } - php_stream_context_set(datastream, context); + php_stream_context_set(datastream, context TSRMLS_CC); php_stream_notify_progress_init(context, 0, file_size); if (use_ssl_on_data && (php_stream_xport_crypto_setup(datastream, @@ -745,7 +745,7 @@ php_stream * php_stream_ftp_opendir(php_stream_wrapper *wrapper, const char *pat goto opendir_errexit; } - php_stream_context_set(datastream, context); + php_stream_context_set(datastream, context TSRMLS_CC); if (use_ssl_on_data && (php_stream_xport_crypto_setup(stream, STREAM_CRYPTO_METHOD_SSLv23_CLIENT, NULL TSRMLS_CC) < 0 || diff --git a/ext/standard/http_fopen_wrapper.c b/ext/standard/http_fopen_wrapper.c index 8762fa4849db1..0a1ea1f467850 100644 --- a/ext/standard/http_fopen_wrapper.c +++ b/ext/standard/http_fopen_wrapper.c @@ -85,8 +85,33 @@ #define HTTP_WRAPPER_HEADER_INIT 1 #define HTTP_WRAPPER_REDIRECTED 2 -php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, const char *path, const char *mode, int options, - char **opened_path, php_stream_context *context, int redirect_max, int flags STREAMS_DC TSRMLS_DC) /* {{{ */ +static inline void strip_header(char *header_bag, char *lc_header_bag, + const char *lc_header_name) +{ + char *lc_header_start = strstr(lc_header_bag, lc_header_name); + char *header_start = header_bag + (lc_header_start - lc_header_bag); + + if (lc_header_start + && (lc_header_start == lc_header_bag || *(lc_header_start-1) == '\n') + ) { + char *lc_eol = strchr(lc_header_start, '\n'); + char *eol = header_start + (lc_eol - lc_header_start); + + if (lc_eol) { + size_t eollen = strlen(lc_eol); + + memmove(lc_header_start, lc_eol+1, eollen); + memmove(header_start, eol+1, eollen); + } else { + *lc_header_start = '\0'; + *header_start = '\0'; + } + } +} + +php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, + const char *path, const char *mode, int options, char **opened_path, + php_stream_context *context, int redirect_max, int flags STREAMS_DC TSRMLS_DC) /* {{{ */ { php_stream *stream = NULL; php_url *resource = NULL; @@ -312,7 +337,7 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, const char eol_detect = stream->flags & (PHP_STREAM_FLAG_DETECT_EOL | PHP_STREAM_FLAG_EOL_MAC); stream->flags &= ~(PHP_STREAM_FLAG_DETECT_EOL | PHP_STREAM_FLAG_EOL_MAC); - php_stream_context_set(stream, context); + php_stream_context_set(stream, context TSRMLS_CC); php_stream_notify_info(context, PHP_STREAM_NOTIFY_CONNECT, NULL, 0); @@ -425,40 +450,17 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, const char if (tmp && strlen(tmp) > 0) { char *s; - if (!header_init) { /* Remove post headers for redirects */ - int l = strlen(tmp); - char *s2, *tmp_c = estrdup(tmp); - - php_strtolower(tmp_c, l); - if ((s = strstr(tmp_c, "content-length:"))) { - if ((s2 = memchr(s, '\n', tmp_c + l - s))) { - int b = tmp_c + l - 1 - s2; - memmove(tmp, tmp + (s2 + 1 - tmp_c), b); - memmove(tmp_c, s2 + 1, b); - - } else { - tmp[s - tmp_c] = *s = '\0'; - } - l = strlen(tmp_c); - } - if ((s = strstr(tmp_c, "content-type:"))) { - if ((s2 = memchr(s, '\n', tmp_c + l - s))) { - memmove(tmp, tmp + (s2 + 1 - tmp_c), tmp_c + l - 1 - s2); - } else { - tmp[s - tmp_c] = '\0'; - } - } - - efree(tmp_c); - tmp_c = php_trim(tmp, strlen(tmp), NULL, 0, NULL, 3 TSRMLS_CC); - efree(tmp); - tmp = tmp_c; - } - user_headers = estrdup(tmp); /* Make lowercase for easy comparison against 'standard' headers */ php_strtolower(tmp, strlen(tmp)); + + if (!header_init) { + /* strip POST headers on redirect */ + strip_header(user_headers, tmp, "content-length:"); + strip_header(user_headers, tmp, "content-type:"); + } + if ((s = strstr(tmp, "user-agent:")) && (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' || *(s-1) == '\t' || *(s-1) == ' ')) { @@ -680,7 +682,7 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, const char response_code = 0; } if (context && SUCCESS==php_stream_context_get_option(context, "http", "ignore_errors", &tmpzval)) { - ignore_errors = zend_is_true(*tmpzval); + ignore_errors = zend_is_true(*tmpzval TSRMLS_CC); } /* when we request only the header, don't fail even on error codes */ if ((options & STREAM_ONLY_GET_HEADERS) || ignore_errors) { diff --git a/ext/standard/password.c b/ext/standard/password.c index ca852038a67ed..9c5280a4cb7c2 100644 --- a/ext/standard/password.c +++ b/ext/standard/password.c @@ -183,7 +183,7 @@ PHP_FUNCTION(password_get_info) return; } - if (hash_len < 0 || (size_t) hash_len < 0) { + if (hash_len < 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Supplied password hash too long to safely identify"); RETURN_FALSE; } diff --git a/ext/standard/php_array.h b/ext/standard/php_array.h index 1cf27790718d7..ef43cddfcc416 100644 --- a/ext/standard/php_array.h +++ b/ext/standard/php_array.h @@ -117,6 +117,9 @@ PHPAPI int php_multisort_compare(const void *a, const void *b TSRMLS_DC); #define PHP_SORT_NATURAL 6 #define PHP_SORT_FLAG_CASE 8 +#define ARRAY_FILTER_USE_BOTH 1 +#define ARRAY_FILTER_USE_KEY 2 + ZEND_BEGIN_MODULE_GLOBALS(array) int *multisort_flags[2]; int (*compare_func)(zval *result, zval *op1, zval *op2 TSRMLS_DC); diff --git a/ext/standard/php_fopen_wrapper.c b/ext/standard/php_fopen_wrapper.c index 76f77ebf7b5f4..0adb1e05290a0 100644 --- a/ext/standard/php_fopen_wrapper.c +++ b/ext/standard/php_fopen_wrapper.c @@ -120,11 +120,11 @@ static int php_stream_input_flush(php_stream *stream TSRMLS_DC) /* {{{ */ static int php_stream_input_seek(php_stream *stream, off_t offset, int whence, off_t *newoffset TSRMLS_DC) /* {{{ */ { - php_stream *inner = stream->abstract; + php_stream_input_t *input = stream->abstract; - if (inner) { - int sought = php_stream_seek(inner, offset, whence); - *newoffset = inner->position; + if (*input->body_ptr) { + int sought = php_stream_seek(*input->body_ptr, offset, whence); + *newoffset = (*input->body_ptr)->position; return sought; } diff --git a/ext/standard/php_string.h b/ext/standard/php_string.h index 65219f257adee..1ce98ee07a21e 100644 --- a/ext/standard/php_string.h +++ b/ext/standard/php_string.h @@ -156,7 +156,7 @@ PHPAPI char *php_strerror(int errnum); # define php_mblen(ptr, len) 1 #else # if defined(_REENTRANT) && defined(HAVE_MBRLEN) && defined(HAVE_MBSTATE_T) -# define php_mblen(ptr, len) ((ptr) == NULL ? mbsinit(&BG(mblen_state)): (int)mbrlen(ptr, len, &BG(mblen_state))) +# define php_mblen(ptr, len) ((ptr) == NULL ? memset(&BG(mblen_state), 0, sizeof(BG(mblen_state))): (int)mbrlen(ptr, len, &BG(mblen_state))) # else # define php_mblen(ptr, len) mblen(ptr, len) # endif diff --git a/ext/standard/tests/array/array_fill.phpt b/ext/standard/tests/array/array_fill.phpt index 1de7c3142000b..c6c7e1e45708f 100644 --- a/ext/standard/tests/array/array_fill.phpt +++ b/ext/standard/tests/array/array_fill.phpt @@ -23,34 +23,28 @@ echo '== Done =='; --EXPECTF-- =========================== start: 0 num: 0 value: 1 - -Warning: array_fill(): Number of elements must be positive in %s on line %d -bool(false) +array(0) { +} =========================== start: 0 num: 0 value: - -Warning: array_fill(): Number of elements must be positive in %s on line %d -bool(false) +array(0) { +} =========================== start: 0 num: 0 value: - -Warning: array_fill(): Number of elements must be positive in %s on line %d -bool(false) +array(0) { +} =========================== start: 0 num: 0 value: d - -Warning: array_fill(): Number of elements must be positive in %s on line %d -bool(false) +array(0) { +} =========================== start: 0 num: 0 value: e - -Warning: array_fill(): Number of elements must be positive in %s on line %d -bool(false) +array(0) { +} =========================== start: 0 num: 0 value: f - -Warning: array_fill(): Number of elements must be positive in %s on line %d -bool(false) +array(0) { +} =========================== start: 0 num: 1 value: 1 array(1) { @@ -137,34 +131,28 @@ array(2) { } =========================== start: 1 num: 0 value: 1 - -Warning: array_fill(): Number of elements must be positive in %s on line %d -bool(false) +array(0) { +} =========================== start: 1 num: 0 value: - -Warning: array_fill(): Number of elements must be positive in %s on line %d -bool(false) +array(0) { +} =========================== start: 1 num: 0 value: - -Warning: array_fill(): Number of elements must be positive in %s on line %d -bool(false) +array(0) { +} =========================== start: 1 num: 0 value: d - -Warning: array_fill(): Number of elements must be positive in %s on line %d -bool(false) +array(0) { +} =========================== start: 1 num: 0 value: e - -Warning: array_fill(): Number of elements must be positive in %s on line %d -bool(false) +array(0) { +} =========================== start: 1 num: 0 value: f - -Warning: array_fill(): Number of elements must be positive in %s on line %d -bool(false) +array(0) { +} =========================== start: 1 num: 1 value: 1 array(1) { @@ -251,34 +239,28 @@ array(2) { } =========================== start: 2.5 num: 0 value: 1 - -Warning: array_fill(): Number of elements must be positive in %s on line %d -bool(false) +array(0) { +} =========================== start: 2.5 num: 0 value: - -Warning: array_fill(): Number of elements must be positive in %s on line %d -bool(false) +array(0) { +} =========================== start: 2.5 num: 0 value: - -Warning: array_fill(): Number of elements must be positive in %s on line %d -bool(false) +array(0) { +} =========================== start: 2.5 num: 0 value: d - -Warning: array_fill(): Number of elements must be positive in %s on line %d -bool(false) +array(0) { +} =========================== start: 2.5 num: 0 value: e - -Warning: array_fill(): Number of elements must be positive in %s on line %d -bool(false) +array(0) { +} =========================== start: 2.5 num: 0 value: f - -Warning: array_fill(): Number of elements must be positive in %s on line %d -bool(false) +array(0) { +} =========================== start: 2.5 num: 1 value: 1 array(1) { diff --git a/ext/standard/tests/array/array_fill_error.phpt b/ext/standard/tests/array/array_fill_error.phpt index 167163228d574..33ee2b3858a11 100644 --- a/ext/standard/tests/array/array_fill_error.phpt +++ b/ext/standard/tests/array/array_fill_error.phpt @@ -32,10 +32,6 @@ var_dump( array_fill($start_key,$num) ); $num = -1; var_dump( array_fill($start_key,$num,$val) ); -//callin array_fill with 'num' equal to zero value -$num = 0; -var_dump( array_fill($start_key,$num,$val) ); - echo "Done"; ?> --EXPECTF-- @@ -53,9 +49,6 @@ NULL Warning: array_fill() expects exactly 3 parameters, 2 given in %s on line %d NULL -Warning: array_fill(): Number of elements must be positive in %s on line %d -bool(false) - -Warning: array_fill(): Number of elements must be positive in %s on line %d +Warning: array_fill(): Number of elements can't be negative in %s on line %d bool(false) Done diff --git a/ext/standard/tests/array/array_fill_variation2.phpt b/ext/standard/tests/array/array_fill_variation2.phpt index 9e9df29b0bb13..ecf4ef435ec9d 100644 --- a/ext/standard/tests/array/array_fill_variation2.phpt +++ b/ext/standard/tests/array/array_fill_variation2.phpt @@ -106,7 +106,7 @@ array(2) { } -- Iteration 2 -- -Warning: array_fill(): Number of elements must be positive in %s on line %d +Warning: array_fill(): Number of elements can't be negative in %s on line %d bool(false) -- Iteration 3 -- array(5) { @@ -122,13 +122,11 @@ array(5) { int(100) } -- Iteration 4 -- - -Warning: array_fill(): Number of elements must be positive in %s on line %d -bool(false) +array(0) { +} -- Iteration 5 -- - -Warning: array_fill(): Number of elements must be positive in %s on line %d -bool(false) +array(0) { +} -- Iteration 6 -- Warning: array_fill() expects parameter 2 to be long, array given in %s on line %d @@ -150,31 +148,27 @@ NULL Warning: array_fill() expects parameter 2 to be long, array given in %s on line %d NULL -- Iteration 11 -- - -Warning: array_fill(): Number of elements must be positive in %s on line %d -bool(false) +array(0) { +} -- Iteration 12 -- - -Warning: array_fill(): Number of elements must be positive in %s on line %d -bool(false) +array(0) { +} -- Iteration 13 -- array(1) { [0]=> int(100) } -- Iteration 14 -- - -Warning: array_fill(): Number of elements must be positive in %s on line %d -bool(false) +array(0) { +} -- Iteration 15 -- array(1) { [0]=> int(100) } -- Iteration 16 -- - -Warning: array_fill(): Number of elements must be positive in %s on line %d -bool(false) +array(0) { +} -- Iteration 17 -- Warning: array_fill() expects parameter 2 to be long, string given in %s on line %d @@ -196,11 +190,9 @@ NULL Warning: array_fill() expects parameter 2 to be long, object given in %s on line %d NULL -- Iteration 22 -- - -Warning: array_fill(): Number of elements must be positive in %s on line %d -bool(false) +array(0) { +} -- Iteration 23 -- - -Warning: array_fill(): Number of elements must be positive in %s on line %d -bool(false) +array(0) { +} Done diff --git a/ext/standard/tests/array/array_filter_error.phpt b/ext/standard/tests/array/array_filter_error.phpt index 20e89aa4b776e..3f8f51bc14a5b 100644 --- a/ext/standard/tests/array/array_filter_error.phpt +++ b/ext/standard/tests/array/array_filter_error.phpt @@ -28,7 +28,7 @@ $extra_arg = 10; // with one more than the expected number of arguments echo "-- Testing array_filter() function with more than expected no. of arguments --"; -var_dump( array_filter($input, "odd", $extra_arg) ); +var_dump( array_filter($input, "odd", $extra_arg, $extra_arg) ); // with incorrect callback function echo "-- Testing array_filter() function with incorrect callback --"; @@ -42,7 +42,7 @@ echo "Done" Warning: array_filter() expects at least 1 parameter, 0 given in %s on line %d NULL -- Testing array_filter() function with more than expected no. of arguments -- -Warning: array_filter() expects at most 2 parameters, 3 given in %s on line %d +Warning: array_filter() expects at most 3 parameters, 4 given in %s on line %d NULL -- Testing array_filter() function with incorrect callback -- Warning: array_filter() expects parameter 2 to be a valid callback, function 'even' not found or invalid function name in %s on line %d diff --git a/ext/standard/tests/array/array_filter_variation10.phpt b/ext/standard/tests/array/array_filter_variation10.phpt new file mode 100644 index 0000000000000..f0a6115f79ccf --- /dev/null +++ b/ext/standard/tests/array/array_filter_variation10.phpt @@ -0,0 +1,103 @@ +--TEST-- +Test array_filter() function : usage variations - using the array keys inside 'callback' +--FILE-- + 4; +} + +var_dump( array_filter($input, 'dump2', true) ); + +echo "*** Testing array_filter() : usage variations - 'callback' expecting second argument ***\n"; + +var_dump( array_filter($small, 'dump', false) ); + +echo "*** Testing array_filter() with various use types ***\n"; + +$mixed = array(1 => 'a', 2 => 'b', 'a' => 1, 'b' => 2); + +var_dump(array_filter($mixed, 'is_numeric', ARRAY_FILTER_USE_KEY)); + +var_dump(array_filter($mixed, 'is_numeric', 0)); + +var_dump(array_filter($mixed, 'is_numeric', ARRAY_FILTER_USE_BOTH)); + +echo "Done" +?> +--EXPECTF-- +*** Testing array_filter() : usage variations - using array keys in 'callback' *** +0 = 0 +1 = 1 +2 = -1 +3 = 10 +4 = 100 +5 = 1000 +6 = Hello +7 = +array(0) { +} +*** Testing array_filter() : usage variations - 'callback' filters based on key value *** +array(3) { + [5]=> + int(1000) + [6]=> + string(5) "Hello" + [7]=> + NULL +} +*** Testing array_filter() : usage variations - 'callback' expecting second argument *** + +Warning: Missing argument 2 for dump() in %s on line %d + +Notice: Undefined variable: key in %s on line %d + = 123 +array(0) { +} +*** Testing array_filter() with various use types *** +array(2) { + [1]=> + string(1) "a" + [2]=> + string(1) "b" +} +array(2) { + ["a"]=> + int(1) + ["b"]=> + int(2) +} + +Warning: is_numeric() expects exactly 1 parameter, 2 given in %s on line 44 + +Warning: is_numeric() expects exactly 1 parameter, 2 given in %s on line 44 + +Warning: is_numeric() expects exactly 1 parameter, 2 given in %s on line 44 + +Warning: is_numeric() expects exactly 1 parameter, 2 given in %s on line 44 +array(0) { +} +Done diff --git a/ext/standard/tests/array/each.phpt b/ext/standard/tests/array/each.phpt index 19ee728fd2ee5..974808c08c808 100644 Binary files a/ext/standard/tests/array/each.phpt and b/ext/standard/tests/array/each.phpt differ diff --git a/ext/standard/tests/class_object/class_exists_variation_001.phpt b/ext/standard/tests/class_object/class_exists_variation_001.phpt index 52a3584763e13..5f51b4bd93d3e 100644 --- a/ext/standard/tests/class_object/class_exists_variation_001.phpt +++ b/ext/standard/tests/class_object/class_exists_variation_001.phpt @@ -100,15 +100,12 @@ In __autoload(12345) bool(false) Arg value -2345 -In __autoload(-2345) bool(false) Arg value 10.5 -In __autoload(10.5) bool(false) Arg value -10.5 -In __autoload(-10.5) bool(false) Arg value 101234567000 @@ -116,11 +113,9 @@ In __autoload(101234567000) bool(false) Arg value 1.07654321E-9 -In __autoload(1.07654321E-9) bool(false) Arg value 0.5 -In __autoload(0.5) bool(false) Error: 8 - Array to string conversion, %sclass_exists_variation_001.php(%d) diff --git a/ext/standard/tests/class_object/trait_exists_variation_001.phpt b/ext/standard/tests/class_object/trait_exists_variation_001.phpt index e7fa4afd1e8c4..81df711cfa19c 100644 --- a/ext/standard/tests/class_object/trait_exists_variation_001.phpt +++ b/ext/standard/tests/class_object/trait_exists_variation_001.phpt @@ -100,15 +100,12 @@ In __autoload(12345) bool(false) Arg value -2345 -In __autoload(-2345) bool(false) Arg value 10.5 -In __autoload(10.5) bool(false) Arg value -10.5 -In __autoload(-10.5) bool(false) Arg value 101234567000 @@ -116,11 +113,9 @@ In __autoload(101234567000) bool(false) Arg value 1.07654321E-9 -In __autoload(1.07654321E-9) bool(false) Arg value 0.5 -In __autoload(0.5) bool(false) Error: 8 - Array to string conversion, %strait_exists_variation_001.php(%d) diff --git a/ext/standard/tests/file/007_error.phpt b/ext/standard/tests/file/007_error.phpt index a369c9d97785d..112beb3059a03 100644 --- a/ext/standard/tests/file/007_error.phpt +++ b/ext/standard/tests/file/007_error.phpt @@ -76,7 +76,7 @@ bool(false) Warning: fopen() expects at least 2 parameters, 0 given in %s on line %d bool(false) -Warning: fclose(): 5 is not a valid stream resource in %s on line %d +Warning: fclose(): %d is not a valid stream resource in %s on line %d bool(false) Warning: fclose() expects parameter 1 to be resource, string given in %s on line %d @@ -85,7 +85,7 @@ bool(false) Warning: fclose() expects exactly 1 parameter, 0 given in %s on line %d bool(false) -Warning: feof(): 5 is not a valid stream resource in %s on line %d +Warning: feof(): %d is not a valid stream resource in %s on line %d bool(false) Warning: feof() expects parameter 1 to be resource, string given in %s on line %d diff --git a/ext/standard/tests/file/copy_variation16-win32.phpt b/ext/standard/tests/file/copy_variation16-win32.phpt index 7688f5eeabf86..d95d24adacb56 100644 --- a/ext/standard/tests/file/copy_variation16-win32.phpt +++ b/ext/standard/tests/file/copy_variation16-win32.phpt @@ -22,7 +22,7 @@ mkdir($base_dir); $sub_dir = $base_dir."/copy_variation16_sub"; mkdir($sub_dir); -$dirname_with_blank = $sub_dir."/copy variation6"; +$dirname_with_blank = $sub_dir."/copy variation16"; mkdir($dirname_with_blank); $src_file_name = dirname(__FILE__)."/copy_variation16.tmp"; @@ -139,6 +139,6 @@ Existence of destination file => bool(false) Size of source file => int(3500) Copy operation => bool(true) Existence of destination file => bool(true) -Destination file name is => %s/copy_variation16/copy_variation16_sub/copy variation6/copy_copy_variation16.tmp +Destination file name is => %s/copy_variation16/copy_variation16_sub/copy variation16/copy_copy_variation16.tmp Size of destination file => int(3500) *** Done *** diff --git a/ext/standard/tests/file/copy_variation16.phpt b/ext/standard/tests/file/copy_variation16.phpt index 9ad834bdb4192..e36fee1d666b7 100644 --- a/ext/standard/tests/file/copy_variation16.phpt +++ b/ext/standard/tests/file/copy_variation16.phpt @@ -22,7 +22,7 @@ mkdir($base_dir); $sub_dir = $base_dir."/copy_variation16_sub"; mkdir($sub_dir); -$dirname_with_blank = $sub_dir."/copy variation6"; +$dirname_with_blank = $sub_dir."/copy variation16"; mkdir($dirname_with_blank); $src_file_name = dirname(__FILE__)."/copy_variation16.tmp"; @@ -138,6 +138,6 @@ Size of destination file => int(3500) Size of source file => int(3500) Copy operation => bool(true) Existence of destination file => bool(true) -Destination file name is => %s/copy_variation16/copy_variation16_sub/copy variation6/copy_copy_variation16.tmp +Destination file name is => %s/copy_variation16/copy_variation16_sub/copy variation16/copy_copy_variation16.tmp Size of destination file => int(3500) *** Done *** diff --git a/ext/standard/tests/file/disk_free_space_basic.phpt b/ext/standard/tests/file/disk_free_space_basic.phpt index bfa1db9397f34..2904ff9a5bfe0 100644 --- a/ext/standard/tests/file/disk_free_space_basic.phpt +++ b/ext/standard/tests/file/disk_free_space_basic.phpt @@ -1,5 +1,9 @@ --TEST-- Test disk_free_space and its alias diskfreespace() functions : basic functionality +--SKIPIF-- + --INI-- memory_limit=32M --FILE-- @@ -33,7 +37,7 @@ echo "\n Free Space after writing to a file\n"; $space2 = disk_free_space($file_path.$dir); var_dump( $space2 ); -if( $space1 > $space2 ) +if($space1 > $space2 ) echo "\n Free Space Value Is Correct\n"; else { echo "\n Free Space Value Is Incorrect\n"; diff --git a/ext/standard/tests/file/fgets_socket_variation1.phpt b/ext/standard/tests/file/fgets_socket_variation1.phpt index 57944d8b563c1..429ad67d69677 100644 --- a/ext/standard/tests/file/fgets_socket_variation1.phpt +++ b/ext/standard/tests/file/fgets_socket_variation1.phpt @@ -5,11 +5,17 @@ Dave Kelsey --FILE-- --EXPECT-- diff --git a/ext/standard/tests/file/ftruncate_error.phpt b/ext/standard/tests/file/ftruncate_error.phpt index a28095bc2d96b..254ad7688d28a 100644 --- a/ext/standard/tests/file/ftruncate_error.phpt +++ b/ext/standard/tests/file/ftruncate_error.phpt @@ -114,7 +114,7 @@ Warning: ftruncate() expects parameter 1 to be resource, object given in %s on l bool(false) -- Testing ftruncate() with closed/unset file handle -- -Warning: ftruncate(): 5 is not a valid stream resource in %s on line %d +Warning: ftruncate(): %d is not a valid stream resource in %s on line %d bool(false) int(36) diff --git a/ext/standard/tests/general_functions/bug41445_1.phpt b/ext/standard/tests/general_functions/bug41445_1.phpt index e65e7afcc8c2c..4698de436a04d 100644 --- a/ext/standard/tests/general_functions/bug41445_1.phpt +++ b/ext/standard/tests/general_functions/bug41445_1.phpt @@ -3,7 +3,7 @@ Bug #41445 (parse_ini_file() function parses octal numbers in section names) - 2 --FILE-- +--EXPECTF-- +Tick! +done diff --git a/ext/standard/tests/general_functions/floatval.phpt b/ext/standard/tests/general_functions/floatval.phpt index b427bda7d5ecf..9b7a3281e4436 100644 --- a/ext/standard/tests/general_functions/floatval.phpt +++ b/ext/standard/tests/general_functions/floatval.phpt @@ -157,8 +157,8 @@ float(-5000000) *** Testing floatval() on non floating types *** float(-2147483648) float(2147483648) -float(5) -float(6) +float(%d) +float(%d) float(0) float(1) float(-1300) @@ -175,8 +175,8 @@ float(0) *** Testing doubleval() on non floating types *** float(-2147483648) float(2147483648) -float(5) -float(6) +float(%d) +float(%d) float(0) float(1) float(-1300) diff --git a/ext/standard/tests/general_functions/gettype_settype_basic.phpt b/ext/standard/tests/general_functions/gettype_settype_basic.phpt index d6fb0d495b853..d1fd4095be884 100644 --- a/ext/standard/tests/general_functions/gettype_settype_basic.phpt +++ b/ext/standard/tests/general_functions/gettype_settype_basic.phpt @@ -232,11 +232,11 @@ int(0) string(7) "integer" -- Iteration 12 -- bool(true) -int(5) +int(%d) string(7) "integer" -- Iteration 13 -- bool(true) -int(6) +int(%d) string(7) "integer" -- Iteration 14 -- 8: Object of class point could not be converted to int @@ -291,11 +291,11 @@ int(0) string(7) "integer" -- Iteration 12 -- bool(true) -int(5) +int(%d) string(7) "integer" -- Iteration 13 -- bool(true) -int(6) +int(%d) string(7) "integer" -- Iteration 14 -- 8: Object of class point could not be converted to int @@ -350,11 +350,11 @@ float(0) string(6) "double" -- Iteration 12 -- bool(true) -float(5) +float(%d) string(6) "double" -- Iteration 13 -- bool(true) -float(6) +float(%d) string(6) "double" -- Iteration 14 -- 8: Object of class point could not be converted to double @@ -409,11 +409,11 @@ float(0) string(6) "double" -- Iteration 12 -- bool(true) -float(5) +float(%d) string(6) "double" -- Iteration 13 -- bool(true) -float(6) +float(%d) string(6) "double" -- Iteration 14 -- 8: Object of class point could not be converted to double @@ -610,12 +610,12 @@ string(6) "string" -- Iteration 12 -- 2: settype(): Cannot convert to resource type bool(false) -resource(5) of type (stream) +resource(%d) of type (stream) string(8) "resource" -- Iteration 13 -- 2: settype(): Cannot convert to resource type bool(false) -resource(6) of type (stream) +resource(%d) of type (stream) string(8) "resource" -- Iteration 14 -- 2: settype(): Cannot convert to resource type @@ -716,14 +716,14 @@ string(5) "array" bool(true) array(1) { [0]=> - resource(5) of type (stream) + resource(%d) of type (stream) } string(5) "array" -- Iteration 13 -- bool(true) array(1) { [0]=> - resource(6) of type (stream) + resource(%d) of type (stream) } string(5) "array" -- Iteration 14 -- @@ -824,14 +824,14 @@ string(6) "object" bool(true) object(stdClass)#2 (1) { ["scalar"]=> - resource(5) of type (stream) + resource(%d) of type (stream) } string(6) "object" -- Iteration 13 -- bool(true) object(stdClass)#2 (1) { ["scalar"]=> - resource(6) of type (stream) + resource(%d) of type (stream) } string(6) "object" -- Iteration 14 -- @@ -893,11 +893,11 @@ string(6) "string" string(6) "string" -- Iteration 12 -- bool(true) -string(14) "Resource id #5" +string(14) "Resource id #%d" string(6) "string" -- Iteration 13 -- bool(true) -string(14) "Resource id #6" +string(14) "Resource id #%d" string(6) "string" -- Iteration 14 -- bool(true) diff --git a/ext/standard/tests/general_functions/print_r.phpt b/ext/standard/tests/general_functions/print_r.phpt index 81a523ad0bc90..19e71fbfd70e5 100644 --- a/ext/standard/tests/general_functions/print_r.phpt +++ b/ext/standard/tests/general_functions/print_r.phpt @@ -1484,13 +1484,13 @@ object_class Object *** Testing print_r() on resources *** -- Iteration 1 -- -Resource id #5 -Resource id #5 -Resource id #5 +Resource id #%d +Resource id #%d +Resource id #%d -- Iteration 2 -- -Resource id #6 -Resource id #6 -Resource id #6 +Resource id #%d +Resource id #%d +Resource id #%d *** Testing print_r() on different combinations of scalar and non-scalar variables *** diff --git a/ext/standard/tests/general_functions/strval.phpt b/ext/standard/tests/general_functions/strval.phpt index b92be41ef49e1..372ac6701e09e 100644 --- a/ext/standard/tests/general_functions/strval.phpt +++ b/ext/standard/tests/general_functions/strval.phpt @@ -279,9 +279,9 @@ string(0) "" -- Iteration 1 -- string(6) "Object" -- Iteration 2 -- -string(14) "Resource id #5" +string(14) "Resource id #%d" -- Iteration 3 -- -string(14) "Resource id #6" +string(14) "Resource id #%d" -- Iteration 4 -- Notice: Array to string conversion in %sstrval.php on line %d diff --git a/ext/standard/tests/general_functions/type.phpt b/ext/standard/tests/general_functions/type.phpt index 98eccbbda79e7..51654b1859a1f 100644 --- a/ext/standard/tests/general_functions/type.phpt +++ b/ext/standard/tests/general_functions/type.phpt @@ -105,9 +105,9 @@ int(0) bool(true) int(0) bool(true) -int(5) +int(%d) bool(true) -int(6) +int(%d) string(54) "Object of class stdClass could not be converted to int" bool(true) int(%d) @@ -128,9 +128,9 @@ float(0) bool(true) float(0) bool(true) -float(5) +float(%d) bool(true) -float(6) +float(%d) string(57) "Object of class stdClass could not be converted to double" bool(true) float(%d) diff --git a/ext/standard/tests/general_functions/var_dump.phpt b/ext/standard/tests/general_functions/var_dump.phpt index 09e9f3b99ed15..c47227141b02c 100644 --- a/ext/standard/tests/general_functions/var_dump.phpt +++ b/ext/standard/tests/general_functions/var_dump.phpt @@ -844,9 +844,9 @@ object(object_class)#13 (8) { *** Testing var_dump() on resources *** -- Iteration 1 -- -resource(5) of type (stream) +resource(%d) of type (stream) -- Iteration 2 -- -resource(6) of type (stream) +resource(%d) of type (stream) *** Testing var_dump() on different combinations of scalar and non-scalar variables *** @@ -1227,9 +1227,9 @@ array(4) { } array(2) { [0]=> - resource(5) of type (stream) + resource(%d) of type (stream) [1]=> - resource(6) of type (stream) + resource(%d) of type (stream) } array(9) { [0]=> diff --git a/ext/standard/tests/general_functions/var_export-locale.phpt b/ext/standard/tests/general_functions/var_export-locale.phpt index 37142cf34c75a..b6f87c431c550 100644 --- a/ext/standard/tests/general_functions/var_export-locale.phpt +++ b/ext/standard/tests/general_functions/var_export-locale.phpt @@ -1,7 +1,7 @@ --TEST-- Test var_export() function with locale --INI-- -precision=14 +serialize_precision=17 --SKIPIF-- 10.5, - 1 => 5.6, + 1 => 5.5999999999999996, ) array ( 0 => 10.5, - 1 => 5.6, + 1 => 5.5999999999999996, ) -string(34) "array ( +string(49) "array ( 0 => 10.5, - 1 => 5.6, + 1 => 5.5999999999999996, )" diff --git a/ext/standard/tests/general_functions/var_export_basic3.phpt b/ext/standard/tests/general_functions/var_export_basic3.phpt index 299721591071b..58c04481679c7 100644 --- a/ext/standard/tests/general_functions/var_export_basic3.phpt +++ b/ext/standard/tests/general_functions/var_export_basic3.phpt @@ -1,7 +1,7 @@ --TEST-- Test var_export() function with valid float values --INI-- -precision=14 +serialize_precision=17 --FILE-- 10.5, - 1 => 5.6, + 1 => 5.5999999999999996, ) array ( 0 => 10.5, - 1 => 5.6, + 1 => 5.5999999999999996, ) -string(34) "array ( +string(49) "array ( 0 => 10.5, - 1 => 5.6, + 1 => 5.5999999999999996, )" @@ -274,4 +276,4 @@ string(41) "array ( 1 => 'test', )" -===DONE=== \ No newline at end of file +===DONE=== diff --git a/ext/standard/tests/http/bug61548.phpt b/ext/standard/tests/http/bug61548.phpt new file mode 100644 index 0000000000000..138b15a338c06 --- /dev/null +++ b/ext/standard/tests/http/bug61548.phpt @@ -0,0 +1,118 @@ +--TEST-- +Bug #61548 (content-type must appear at the end of headers) +--INI-- +allow_url_fopen=1 +--SKIPIF-- + +--FILE-- + [ + 'method' => 'POST', + 'header' => $header, + 'follow_location' => true, + ], + ]; + + $ctx = stream_context_create($options); + + $responses = [ + "data://text/plain,HTTP/1.1 201\r\nLocation: /foo\r\n\r\n", + "data://text/plain,HTTP/1.1 200\r\nConnection: close\r\n\r\n", + ]; + $pid = http_server('tcp://127.0.0.1:12342', $responses, $output); + + $fd = fopen('http://127.0.0.1:12342/', 'rb', false, $ctx); + fseek($output, 0, SEEK_SET); + echo stream_get_contents($output); + + http_server_kill($pid); +} + +do_test("First:1\nSecond:2\nContent-type: text/plain"); +do_test("First:1\nSecond:2\nContent-type: text/plain\n"); +do_test("First:1\nSecond:2\nContent-type: text/plain\nThird:"); +do_test("First:1\nContent-type:text/plain\nSecond:2"); +do_test("First:1\nContent-type:text/plain\nSecond:2\n"); +do_test("First:1\nContent-type:text/plain\nSecond:2\nThird:"); + +?> +Done +--EXPECT-- +POST / HTTP/1.0 +Host: 127.0.0.1:12342 +First:1 +Second:2 +Content-type: text/plain + +GET /foo HTTP/1.0 +Host: 127.0.0.1:12342 +First:1 +Second:2 + + +POST / HTTP/1.0 +Host: 127.0.0.1:12342 +First:1 +Second:2 +Content-type: text/plain + +GET /foo HTTP/1.0 +Host: 127.0.0.1:12342 +First:1 +Second:2 + + +POST / HTTP/1.0 +Host: 127.0.0.1:12342 +First:1 +Second:2 +Content-type: text/plain +Third: + +GET /foo HTTP/1.0 +Host: 127.0.0.1:12342 +First:1 +Second:2 +Third: + +POST / HTTP/1.0 +Host: 127.0.0.1:12342 +First:1 +Content-type:text/plain +Second:2 + +GET /foo HTTP/1.0 +Host: 127.0.0.1:12342 +First:1 +Second:2 + +POST / HTTP/1.0 +Host: 127.0.0.1:12342 +First:1 +Content-type:text/plain +Second:2 + +GET /foo HTTP/1.0 +Host: 127.0.0.1:12342 +First:1 +Second:2 + +POST / HTTP/1.0 +Host: 127.0.0.1:12342 +First:1 +Content-type:text/plain +Second:2 +Third: + +GET /foo HTTP/1.0 +Host: 127.0.0.1:12342 +First:1 +Second:2 +Third: + +Done + diff --git a/ext/standard/tests/mail/bug51604.phpt b/ext/standard/tests/mail/bug51604.phpt index a65702102508b..988849c4e1e55 100644 --- a/ext/standard/tests/mail/bug51604.phpt +++ b/ext/standard/tests/mail/bug51604.phpt @@ -11,7 +11,7 @@ if(substr(PHP_OS, 0, 3) == "WIN") --FILE-- --FILE-- --EXPECTF-- diff --git a/ext/standard/tests/network/tcp4loop.phpt b/ext/standard/tests/network/tcp4loop.phpt index afd955918e8fb..a163cd9b35816 100644 --- a/ext/standard/tests/network/tcp4loop.phpt +++ b/ext/standard/tests/network/tcp4loop.phpt @@ -2,14 +2,21 @@ Streams Based IPv4 TCP Loopback test --FILE-- --FILE-- --FILE-- a[] = new B(1); + $this->a[] = new B(2); + } +} + +class B implements Serializable +{ + public $b; + + public function __construct($c) + { + $this->b = new C($c); + } + + public function serialize() + { + return serialize(clone $this->b); + } + + public function unserialize($data) + { + $this->b = unserialize($data); + } +} + +class C +{ + public $c; + + public function __construct($c) + { + $this->c = $c; + } +} + +$a = unserialize(serialize(new A())); + +print $a->a[0]->b->c . "\n"; +print $a->a[1]->b->c . "\n"; + +?> +Done +--EXPECT-- +Test +1 +2 +Done diff --git a/ext/standard/tests/serialize/bug65806.phpt b/ext/standard/tests/serialize/bug65806.phpt new file mode 100644 index 0000000000000..19fab95c6430d --- /dev/null +++ b/ext/standard/tests/serialize/bug65806.phpt @@ -0,0 +1,83 @@ +--TEST-- +Bug #65806 (unserialize fails with object which is referenced multiple times) +--FILE-- +_obj = $obj; + $this->_serialized = serialize($this->_obj); + } + public function get() + { + return $this->_obj; + } + public function __sleep() + { + $this->_serialized = serialize($this->_obj); + return array( + "\0" . __CLASS__ . "\0_serialized", + ); + } + public function __wakeup() + { + $this->_obj = unserialize($this->_serialized); + } +} + +echo "SCRIPT START" . PHP_EOL; + +$objA = new myObjA(); +$objB = new myObjB(); +$objC = new myObjC(); + +$objB->attrA = new ArrayIterator(); +$objB->attrB = $objA; + +$objC->attrC = $objB; +$objC->attrD = $objA; + +$list = new myList($objC); + +echo 'check ' . check($list->get()) . PHP_EOL; + +echo "start serialize/unserialize" . PHP_EOL; +$newList = unserialize(serialize($list)); +echo "finish serialize/unserialize" . PHP_EOL; + +//after unserialize the property myObjC::attrD is null instead of expected object +echo 'check ' . check($newList->get()) . PHP_EOL; + +echo "SCRIPT END" . PHP_EOL ; + +function check(myObjC $obj) { + + if (!is_object($obj->attrC)) { + return 'failed (myObjC::attrC => ' . var_export($obj->attrC, true) . ')'; + } + if (!is_object($obj->attrD)) { + return 'failed (myObjC::attrD => ' . var_export($obj->attrD, true) . ')'; + } + return 'successful'; +} +?> +--EXPECT-- +SCRIPT START +check successful +start serialize/unserialize +finish serialize/unserialize +check successful +SCRIPT END + diff --git a/ext/standard/tests/serialize/serialization_error_002.phpt b/ext/standard/tests/serialize/serialization_error_002.phpt new file mode 100644 index 0000000000000..70f35e4f3b866 --- /dev/null +++ b/ext/standard/tests/serialize/serialization_error_002.phpt @@ -0,0 +1,52 @@ +--TEST-- +Test unserialize(): error is indistinguishable from deserialized boolean +--FILE-- + +--EXPECTF-- +*** Testing unserialize() error/boolean distinction *** +string(4) "b:0;" + +Notice: unserialize(): Error at offset 0 of 27 bytes in %s%eserialization_error_002.php on line 20 +bool(false) +bool(false) +unserialize error and deserialized false are identical? 1 +bool(false) +bool(true) +Done diff --git a/ext/standard/tests/streams/stream_set_timeout_error.phpt b/ext/standard/tests/streams/stream_set_timeout_error.phpt index c1d4d1406f5a0..814257dd93700 100644 --- a/ext/standard/tests/streams/stream_set_timeout_error.phpt +++ b/ext/standard/tests/streams/stream_set_timeout_error.phpt @@ -13,10 +13,16 @@ echo "*** Testing stream_set_timeout() : error conditions ***\n"; //Test stream_set_timeout with one more than the expected number of arguments echo "\n-- Testing stream_set_timeout() function with more than expected no. of arguments --\n"; -/* Setup socket server */ -$server = stream_socket_server('tcp://127.0.0.1:31337'); +for ($i=0; $i<100; $i++) { + $port = rand(10000, 65000); + /* Setup socket server */ + $server = @stream_socket_server("tcp://127.0.0.1:$port"); + if ($server) { + break; + } +} /* Connect to it */ -$client = fsockopen('tcp://127.0.0.1:31337'); +$client = fsockopen("tcp://127.0.0.1:$port"); $seconds = 10; $microseconds = 10; diff --git a/ext/standard/tests/strings/bug65947.phpt b/ext/standard/tests/strings/bug65947.phpt new file mode 100644 index 0000000000000..956aa6049a247 --- /dev/null +++ b/ext/standard/tests/strings/bug65947.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #65947 (basename is no more working after fgetcsv in certain situation) +--SKIPIF-- + int(182) ["unparsed"]=> - string(3) "GMT" + string(4) " GMT" } array(9) { ["tm_sec"]=> diff --git a/ext/standard/type.c b/ext/standard/type.c index 5d93f66f5b725..ec6630d9ed4ce 100644 --- a/ext/standard/type.c +++ b/ext/standard/type.c @@ -186,7 +186,7 @@ PHP_FUNCTION(boolval) return; } - RETURN_BOOL(zend_is_true(*val)); + RETURN_BOOL(zend_is_true(*val TSRMLS_CC)); } /* }}} */ diff --git a/ext/standard/var.c b/ext/standard/var.c index c1e7c2f3ee346..a7ece7fb5c34f 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -436,7 +436,7 @@ PHPAPI void php_var_export_ex(zval **struc, int level, smart_str *buf TSRMLS_DC) smart_str_append_long(buf, Z_LVAL_PP(struc)); break; case IS_DOUBLE: - tmp_len = spprintf(&tmp_str, 0,"%.*H", (int) EG(precision), Z_DVAL_PP(struc)); + tmp_len = spprintf(&tmp_str, 0,"%.*H", PG(serialize_precision), Z_DVAL_PP(struc)); smart_str_appendl(buf, tmp_str, tmp_len); efree(tmp_str); break; @@ -453,7 +453,7 @@ PHPAPI void php_var_export_ex(zval **struc, int level, smart_str *buf TSRMLS_DC) break; case IS_ARRAY: myht = Z_ARRVAL_PP(struc); - if(myht && myht->nApplyCount > 0){ + if (myht->nApplyCount > 0){ smart_str_appendl(buf, "NULL", 4); zend_error(E_WARNING, "var_export does not handle circular references"); return; @@ -549,11 +549,9 @@ static inline int php_add_var_hash(HashTable *var_hash, zval *var, void *var_old char id[32], *p; register int len; - /* relies on "(long)" being a perfect hash function for data pointers, - * however the actual identity of an object has had to be determined - * by its object handle since 5.0. */ if ((Z_TYPE_P(var) == IS_OBJECT) && Z_OBJ_HT_P(var)->get_class_entry) { - p = smart_str_print_long(id + sizeof(id) - 1, (long) Z_OBJ_HANDLE_P(var)); + p = smart_str_print_long(id + sizeof(id) - 1, + (long) zend_objects_get_address(var TSRMLS_CC)); *(--p) = 'O'; len = id + sizeof(id) - 1 - p; } else { diff --git a/ext/tokenizer/tokenizer_data.c b/ext/tokenizer/tokenizer_data.c index 57b29e1dd7006..8c4786575effc 100644 --- a/ext/tokenizer/tokenizer_data.c +++ b/ext/tokenizer/tokenizer_data.c @@ -38,6 +38,7 @@ void tokenizer_register_constants(INIT_FUNC_ARGS) { REGISTER_LONG_CONSTANT("T_LOGICAL_XOR", T_LOGICAL_XOR, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_LOGICAL_AND", T_LOGICAL_AND, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_PRINT", T_PRINT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("T_YIELD", T_YIELD, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_SR_EQUAL", T_SR_EQUAL, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_SL_EQUAL", T_SL_EQUAL, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_XOR_EQUAL", T_XOR_EQUAL, CONST_CS | CONST_PERSISTENT); @@ -108,7 +109,6 @@ void tokenizer_register_constants(INIT_FUNC_ARGS) { REGISTER_LONG_CONSTANT("T_FUNCTION", T_FUNCTION, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_CONST", T_CONST, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_RETURN", T_RETURN, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("T_YIELD", T_YIELD, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_TRY", T_TRY, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_CATCH", T_CATCH, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_FINALLY", T_FINALLY, CONST_CS | CONST_PERSISTENT); @@ -158,6 +158,7 @@ void tokenizer_register_constants(INIT_FUNC_ARGS) { REGISTER_LONG_CONSTANT("T_NS_C", T_NS_C, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_DIR", T_DIR, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_NS_SEPARATOR", T_NS_SEPARATOR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("T_ELLIPSIS", T_ELLIPSIS, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("T_DOUBLE_COLON", T_PAAMAYIM_NEKUDOTAYIM, CONST_CS | CONST_PERSISTENT); } @@ -174,6 +175,7 @@ char *get_token_type_name(int token_type) case T_LOGICAL_XOR: return "T_LOGICAL_XOR"; case T_LOGICAL_AND: return "T_LOGICAL_AND"; case T_PRINT: return "T_PRINT"; + case T_YIELD: return "T_YIELD"; case T_SR_EQUAL: return "T_SR_EQUAL"; case T_SL_EQUAL: return "T_SL_EQUAL"; case T_XOR_EQUAL: return "T_XOR_EQUAL"; @@ -244,7 +246,6 @@ char *get_token_type_name(int token_type) case T_FUNCTION: return "T_FUNCTION"; case T_CONST: return "T_CONST"; case T_RETURN: return "T_RETURN"; - case T_YIELD: return "T_YIELD"; case T_TRY: return "T_TRY"; case T_CATCH: return "T_CATCH"; case T_FINALLY: return "T_FINALLY"; @@ -294,6 +295,7 @@ char *get_token_type_name(int token_type) case T_NS_C: return "T_NS_C"; case T_DIR: return "T_DIR"; case T_NS_SEPARATOR: return "T_NS_SEPARATOR"; + case T_ELLIPSIS: return "T_ELLIPSIS"; } return "UNKNOWN"; diff --git a/ext/xmlreader/php_xmlreader.c b/ext/xmlreader/php_xmlreader.c index 02ebc7738ef8e..76cd56f144ed7 100644 --- a/ext/xmlreader/php_xmlreader.c +++ b/ext/xmlreader/php_xmlreader.c @@ -588,9 +588,6 @@ PHP_METHOD(xmlreader, getAttributeNo) if (retchar) { RETVAL_STRING(retchar, 1); xmlFree(retchar); - return; - } else { - RETURN_EMPTY_STRING(); } } /* }}} */ @@ -622,9 +619,6 @@ PHP_METHOD(xmlreader, getAttributeNs) if (retchar) { RETVAL_STRING(retchar, 1); xmlFree(retchar); - return; - } else { - RETURN_EMPTY_STRING(); } } /* }}} */ @@ -805,7 +799,6 @@ PHP_METHOD(xmlreader, read) if (intern != NULL && intern->ptr != NULL) { retval = xmlTextReaderRead(intern->ptr); if (retval == -1) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "An Error Occurred while reading"); RETURN_FALSE; } else { RETURN_BOOL(retval); @@ -847,7 +840,6 @@ PHP_METHOD(xmlreader, next) retval = xmlTextReaderNext(intern->ptr); } if (retval == -1) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "An Error Occurred while reading"); RETURN_FALSE; } else { RETURN_BOOL(retval); @@ -1320,6 +1312,7 @@ PHP_MINIT_FUNCTION(xmlreader) xmlreader_object_handlers.read_property = xmlreader_read_property; xmlreader_object_handlers.write_property = xmlreader_write_property; xmlreader_object_handlers.get_property_ptr_ptr = xmlreader_get_property_ptr_ptr; + xmlreader_object_handlers.clone_obj = NULL; INIT_CLASS_ENTRY(ce, "XMLReader", xmlreader_functions); ce.create_object = xmlreader_objects_new; diff --git a/ext/xmlreader/tests/bug51936.phpt b/ext/xmlreader/tests/bug51936.phpt new file mode 100644 index 0000000000000..4b5f1012e79c0 --- /dev/null +++ b/ext/xmlreader/tests/bug51936.phpt @@ -0,0 +1,22 @@ +--TEST-- +Bug #51936 (Crash with clone XMLReader) +--SKIPIF-- + +--FILE-- +xml(""); + +$xmlreader->next(); +$xmlreader2 = clone $xmlreader; +$xmlreader2->next(); +?> +Done +--EXPECTF-- +Test + +Fatal error: Trying to clone an uncloneable object of class XMLReader in %s on line %d diff --git a/ext/xmlreader/tests/bug64230.phpt b/ext/xmlreader/tests/bug64230.phpt new file mode 100644 index 0000000000000..0b070925f30d3 --- /dev/null +++ b/ext/xmlreader/tests/bug64230.phpt @@ -0,0 +1,50 @@ +--TEST-- +Bug #64230 (XMLReader does not suppress errors) +--SKIPIF-- + +--FILE-- +message); + } + libxml_clear_errors(); +} + +echo "Internal errors TRUE\n"; +libxml_use_internal_errors(true); + +$x = new XMLReader; +$x->xml(""); +$x->read(); + +show_internal_errors(); + +echo "Internal errors FALSE\n"; +libxml_use_internal_errors(false); + +$x = new XMLReader; +$x->xml(""); +$x->read(); + +show_internal_errors(); + +?> +Done +--EXPECTF-- +Test +Internal errors TRUE +Internal: Specification mandate value for attribute att + +Internal errors FALSE + +Warning: XMLReader::read(): %s: parser error : Specification mandate value for attribute att in %s on line %d + +Warning: XMLReader::read(): in %s on line %d + +Warning: XMLReader::read(): ^ in %s on line %d +Done diff --git a/ext/xsl/php_xsl.c b/ext/xsl/php_xsl.c index 41e1b9fa236bb..c3b901e320a87 100644 --- a/ext/xsl/php_xsl.c +++ b/ext/xsl/php_xsl.c @@ -57,8 +57,8 @@ zend_module_entry xsl_module_entry = { xsl_functions, PHP_MINIT(xsl), PHP_MSHUTDOWN(xsl), - PHP_RINIT(xsl), /* Replace with NULL if there's nothing to do at request start */ - PHP_RSHUTDOWN(xsl), /* Replace with NULL if there's nothing to do at request end */ + NULL, + NULL, PHP_MINFO(xsl), #if ZEND_MODULE_API_NO >= 20010901 "0.1", /* Replace with version number for your extension */ @@ -170,6 +170,7 @@ PHP_MINIT_FUNCTION(xsl) xsltRegisterExtModuleFunction ((const xmlChar *) "function", (const xmlChar *) "http://php.net/xsl", xsl_ext_function_object_php); + xsltSetGenericErrorFunc(NULL, php_libxml_error_handler); REGISTER_LONG_CONSTANT("XSL_CLONE_AUTO", 0, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("XSL_CLONE_NEVER", -1, CONST_CS | CONST_PERSISTENT); @@ -273,7 +274,7 @@ PHP_MSHUTDOWN_FUNCTION(xsl) (const xmlChar *) "http://php.net/xsl"); xsltUnregisterExtModuleFunction ((const xmlChar *) "function", (const xmlChar *) "http://php.net/xsl"); - + xsltSetGenericErrorFunc(NULL, NULL); xsltCleanupGlobals(); UNREGISTER_INI_ENTRIES(); @@ -282,24 +283,6 @@ PHP_MSHUTDOWN_FUNCTION(xsl) } /* }}} */ -/* {{{ PHP_RINIT_FUNCTION - */ -PHP_RINIT_FUNCTION(xsl) -{ - xsltSetGenericErrorFunc(NULL, php_libxml_error_handler); - return SUCCESS; -} -/* }}} */ - -/* {{{ PHP_RSHUTDOWN_FUNCTION - */ -PHP_RSHUTDOWN_FUNCTION(xsl) -{ - xsltSetGenericErrorFunc(NULL, NULL); - return SUCCESS; -} -/* }}} */ - /* {{{ PHP_MINFO_FUNCTION */ PHP_MINFO_FUNCTION(xsl) diff --git a/ext/xsl/tests/bug49634.phpt b/ext/xsl/tests/bug49634.phpt new file mode 100644 index 0000000000000..b009fd5fb8604 --- /dev/null +++ b/ext/xsl/tests/bug49634.phpt @@ -0,0 +1,105 @@ +--TEST-- +bug #49634 (Segfault throwing an exception in a XSL registered function) +--SKIPIF-- + +--FILE-- + + + test + +XML; + +$cDIR = __DIR__; +$sXsl = << + + + + + +XSL; + +function testFunction($a) +{ + throw new Exception('Test exception.'); +} + +$domXml = new DOMDocument; +$domXml->loadXML($sXml); +$domXsl = new DOMDocument; +$domXsl->loadXML($sXsl); + +for ($i = 0; $i < 10; $i++) +{ + $xsltProcessor = new XSLTProcessor(); + $xsltProcessor->registerPHPFunctions(array('testFunction')); + $xsltProcessor->importStyleSheet($domXsl); + try { + @$xsltProcessor->transformToDoc($domXml); + } catch (Exception $e) { + echo $e,"\n"; + } +} +?> +===DONE=== +--EXPECTF-- +exception 'Exception' with message 'Test exception.' in %s:%d +Stack trace: +#0 [internal function]: testFunction(Array) +#1 %s(%d): XSLTProcessor->transformToDoc(Object(DOMDocument)) +#2 {main} +exception 'Exception' with message 'Test exception.' in %s:%d +Stack trace: +#0 [internal function]: testFunction(Array) +#1 %s(%d): XSLTProcessor->transformToDoc(Object(DOMDocument)) +#2 {main} +exception 'Exception' with message 'Test exception.' in %s:%d +Stack trace: +#0 [internal function]: testFunction(Array) +#1 %s(%d): XSLTProcessor->transformToDoc(Object(DOMDocument)) +#2 {main} +exception 'Exception' with message 'Test exception.' in %s:%d +Stack trace: +#0 [internal function]: testFunction(Array) +#1 %s(%d): XSLTProcessor->transformToDoc(Object(DOMDocument)) +#2 {main} +exception 'Exception' with message 'Test exception.' in %s:%d +Stack trace: +#0 [internal function]: testFunction(Array) +#1 %s(%d): XSLTProcessor->transformToDoc(Object(DOMDocument)) +#2 {main} +exception 'Exception' with message 'Test exception.' in %s:%d +Stack trace: +#0 [internal function]: testFunction(Array) +#1 %s(%d): XSLTProcessor->transformToDoc(Object(DOMDocument)) +#2 {main} +exception 'Exception' with message 'Test exception.' in %s:%d +Stack trace: +#0 [internal function]: testFunction(Array) +#1 %s(%d): XSLTProcessor->transformToDoc(Object(DOMDocument)) +#2 {main} +exception 'Exception' with message 'Test exception.' in %s:%d +Stack trace: +#0 [internal function]: testFunction(Array) +#1 %s(%d): XSLTProcessor->transformToDoc(Object(DOMDocument)) +#2 {main} +exception 'Exception' with message 'Test exception.' in %s:%d +Stack trace: +#0 [internal function]: testFunction(Array) +#1 %s(%d): XSLTProcessor->transformToDoc(Object(DOMDocument)) +#2 {main} +exception 'Exception' with message 'Test exception.' in %s:%d +Stack trace: +#0 [internal function]: testFunction(Array) +#1 %s(%d): XSLTProcessor->transformToDoc(Object(DOMDocument)) +#2 {main} +===DONE=== diff --git a/ext/xsl/tests/bug49634.xml b/ext/xsl/tests/bug49634.xml new file mode 100644 index 0000000000000..f3f286eafc9c7 --- /dev/null +++ b/ext/xsl/tests/bug49634.xml @@ -0,0 +1 @@ + diff --git a/ext/xsl/xsltprocessor.c b/ext/xsl/xsltprocessor.c index af11104a2e82b..f5acc14bbbb53 100644 --- a/ext/xsl/xsltprocessor.c +++ b/ext/xsl/xsltprocessor.c @@ -279,7 +279,10 @@ static void xsl_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int t node->type = XML_NAMESPACE_DECL; node->parent = nsparent; node->ns = curns; + } else { + node = xmlDocCopyNodeList(domintern->document->ptr, node); } + child = php_dom_create_object(node, &ret, child, domintern TSRMLS_CC); add_next_index_zval(args[i], child); } diff --git a/ext/zip/CREDITS b/ext/zip/CREDITS index 6c7e42d417160..59b7ef097e531 100644 --- a/ext/zip/CREDITS +++ b/ext/zip/CREDITS @@ -1,2 +1,2 @@ Zip -Pierre-Alain Joye +Pierre-Alain Joye, Remi Collet diff --git a/ext/zip/LICENSE_libzip b/ext/zip/LICENSE_libzip new file mode 100644 index 0000000000000..9b2fda07b1054 --- /dev/null +++ b/ext/zip/LICENSE_libzip @@ -0,0 +1,27 @@ +Copyright (C) 1999-2008 Dieter Baron and Thomas Klausner +The authors can be contacted at + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. +3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/ext/zip/config.m4 b/ext/zip/config.m4 index 805d92442e017..56ae6a5b29f51 100644 --- a/ext/zip/config.m4 +++ b/ext/zip/config.m4 @@ -13,8 +13,12 @@ fi PHP_ARG_WITH(pcre-dir, pcre install prefix, [ --with-pcre-dir ZIP: pcre install prefix], no, no) +PHP_ARG_WITH(libzip, libzip, +[ --with-libzip[=DIR] ZIP: use libzip], no, no) + if test "$PHP_ZIP" != "no"; then + dnl libzip, depends on zlib if test "$PHP_ZLIB_DIR" != "no" && test "$PHP_ZLIB_DIR" != "yes"; then if test -f "$PHP_ZLIB_DIR/include/zlib/zlib.h"; then PHP_ZLIB_DIR="$PHP_ZLIB_DIR" @@ -47,61 +51,124 @@ if test "$PHP_ZIP" != "no"; then PHP_ADD_INCLUDE($PHP_ZLIB_INCDIR) fi - dnl This is PECL build, check if bundled PCRE library is used - old_CPPFLAGS=$CPPFLAGS - CPPFLAGS=$INCLUDES - AC_EGREP_CPP(yes,[ -#include
-#if defined(HAVE_BUNDLED_PCRE) && !defined(COMPILE_DL_PCRE) -yes -#endif - ],[ - PHP_PCRE_REGEX=yes - ],[ - AC_EGREP_CPP(yes,[ -#include
-#if defined(HAVE_PCRE) && !defined(COMPILE_DL_PCRE) -yes -#endif - ],[ - PHP_PCRE_REGEX=pecl - ],[ - PHP_PCRE_REGEX=no + if test "$PHP_LIBZIP" != "no"; then + + AC_PATH_PROG(PKG_CONFIG, pkg-config, no) + + dnl system libzip, depends on libzip + AC_MSG_CHECKING(for libzip) + if test -r $PHP_LIBZIP/include/zip.h; then + LIBZIP_CFLAGS="-I$PHP_LIBZIP/include" + LIBZIP_LIBDIR="$PHP_LIBZIP/$PHP_LIBDIR" + AC_MSG_RESULT(from option: found in $PHP_LIBZIP) + + elif test -x "$PKG_CONFIG" && $PKG_CONFIG --exists libzip; then + LIBZIP_CFLAGS=`$PKG_CONFIG libzip --cflags` + LIBZIP_LIBDIR=`$PKG_CONFIG libzip --variable=libdir` + AC_MSG_RESULT(from pkgconfig: found in $LIBZIP_LIBDIR) + + else + for i in /usr/local /usr; do + if test -r $i/include/zip.h; then + LIBZIP_CFLAGS="-I$i/include" + LIBZIP_LIBDIR="$i/$PHP_LIBDIR" + AC_MSG_RESULT(in default path: found in $i) + break + fi + done + fi + + if test -z "$LIBZIP_LIBDIR"; then + AC_MSG_RESULT(not found) + AC_MSG_ERROR(Please reinstall the libzip distribution) + fi + + dnl Could not think of a simple way to check libzip for overwrite support + PHP_CHECK_LIBRARY(zip, zip_open, + [ + PHP_ADD_LIBRARY_WITH_PATH(zip, $LIBZIP_LIBDIR, ZIP_SHARED_LIBADD) + AC_DEFINE(HAVE_LIBZIP,1,[ ]) + ], [ + AC_MSG_ERROR(could not find usable libzip) + ], [ + -L$LIBZIP_LIBDIR ]) - ]) - CPPFLAGS=$old_CPPFLAGS - - PHP_ZIP_SOURCES="$PHP_ZIP_SOURCES lib/zip_add.c lib/zip_error.c lib/zip_fclose.c \ - lib/zip_fread.c lib/zip_open.c lib/zip_source_filep.c \ - lib/zip_strerror.c lib/zip_close.c lib/zip_error_get.c \ - lib/zip_file_error_get.c lib/zip_free.c lib/zip_rename.c \ - lib/zip_source_free.c lib/zip_unchange_all.c lib/zip_delete.c \ - lib/zip_error_get_sys_type.c lib/zip_file_get_offset.c \ - lib/zip_get_name.c lib/zip_replace.c lib/zip_source_function.c \ - lib/zip_unchange.c lib/zip_dirent.c lib/zip_error_strerror.c \ - lib/zip_filerange_crc.c lib/zip_file_strerror.c lib/zip_get_num_files.c \ - lib/zip_get_archive_flag.c lib/zip_set_archive_flag.c \ - lib/zip_set_name.c lib/zip_source_zip.c lib/zip_unchange_data.c \ - lib/zip_entry_free.c lib/zip_error_to_str.c lib/zip_fopen.c \ - lib/zip_name_locate.c lib/zip_source_buffer.c lib/zip_stat.c \ - lib/zip_entry_new.c lib/zip_err_str.c lib/zip_fopen_index.c \ - lib/zip_get_archive_comment.c lib/zip_get_file_comment.c \ - lib/zip_new.c lib/zip_source_file.c lib/zip_stat_index.c \ - lib/zip_set_archive_comment.c lib/zip_set_file_comment.c \ - lib/zip_unchange_archive.c lib/zip_memdup.c lib/zip_stat_init.c lib/zip_add_dir.c \ - lib/zip_error_clear.c lib/zip_file_error_clear.c \ - lib/zip_fdopen.c lib/zip_fopen_encrypted.c lib/zip_fopen_index_encrypted.c \ - lib/zip_get_compression_implementation.c lib/zip_get_encryption_implementation.c \ - lib/zip_get_file_extra.c lib/zip_get_num_entries.c lib/zip_set_default_password.c \ - lib/zip_set_file_extra.c lib/zip_source_close.c lib/zip_source_crc.c \ - lib/zip_source_deflate.c lib/zip_source_error.c lib/zip_source_layered.c \ - lib/zip_source_open.c lib/zip_source_pkware.c lib/zip_source_pop.c \ - lib/zip_source_read.c lib/zip_source_stat.c" + + AC_DEFINE(HAVE_ZIP,1,[ ]) + PHP_NEW_EXTENSION(zip, php_zip.c zip_stream.c, $ext_shared,, $LIBZIP_CFLAGS) + PHP_SUBST(ZIP_SHARED_LIBADD) + else + + + PHP_ZIP_SOURCES="$PHP_ZIP_SOURCES lib/zip_add.c lib/zip_add_dir.c lib/zip_add_entry.c\ + lib/zip_close.c lib/zip_delete.c lib/zip_dir_add.c lib/zip_dirent.c lib/zip_discard.c lib/zip_entry.c\ + lib/zip_err_str.c lib/zip_error.c lib/zip_error_clear.c lib/zip_error_get.c lib/zip_error_get_sys_type.c\ + lib/zip_error_strerror.c lib/zip_error_to_str.c lib/zip_extra_field.c lib/zip_extra_field_api.c\ + lib/zip_fclose.c lib/zip_fdopen.c lib/zip_file_add.c lib/zip_file_error_clear.c lib/zip_file_error_get.c\ + lib/zip_file_get_comment.c lib/zip_file_get_offset.c lib/zip_file_rename.c lib/zip_file_replace.c\ + lib/zip_file_set_comment.c lib/zip_file_strerror.c lib/zip_filerange_crc.c lib/zip_fopen.c\ + lib/zip_fopen_encrypted.c lib/zip_fopen_index.c lib/zip_fopen_index_encrypted.c lib/zip_fread.c\ + lib/zip_get_archive_comment.c lib/zip_get_archive_flag.c lib/zip_get_compression_implementation.c\ + lib/zip_get_encryption_implementation.c lib/zip_get_file_comment.c lib/zip_get_name.c lib/zip_get_num_entries.c \ + lib/zip_get_num_files.c lib/zip_memdup.c lib/zip_name_locate.c lib/zip_new.c lib/zip_open.c lib/zip_rename.c lib/zip_replace.c\ + lib/zip_set_archive_comment.c lib/zip_set_archive_flag.c lib/zip_set_default_password.c lib/zip_set_file_comment.c\ + lib/zip_set_file_compression.c lib/zip_set_name.c lib/zip_source_buffer.c lib/zip_source_close.c lib/zip_source_crc.c\ + lib/zip_source_deflate.c lib/zip_source_error.c lib/zip_source_file.c lib/zip_source_filep.c lib/zip_source_free.c\ + lib/zip_source_function.c lib/zip_source_layered.c lib/zip_source_open.c lib/zip_source_pkware.c lib/zip_source_pop.c\ + lib/zip_source_read.c lib/zip_source_stat.c lib/zip_source_window.c lib/zip_source_zip.c lib/zip_source_zip_new.c\ + lib/zip_stat.c lib/zip_stat_index.c lib/zip_stat_init.c lib/zip_strerror.c lib/zip_string.c lib/zip_unchange.c lib/zip_unchange_all.c\ + lib/zip_unchange_archive.c lib/zip_unchange_data.c lib/zip_utf-8.c lib/mkstemp.c" AC_DEFINE(HAVE_ZIP,1,[ ]) PHP_NEW_EXTENSION(zip, php_zip.c zip_stream.c $PHP_ZIP_SOURCES, $ext_shared) PHP_ADD_BUILD_DIR($ext_builddir/lib, 1) PHP_SUBST(ZIP_SHARED_LIBADD) +fi + + +AC_CHECK_TYPES([int8_t]) +AC_CHECK_TYPES([int16_t]) +AC_CHECK_TYPES([int32_t]) +AC_CHECK_TYPES([int64_t]) +AC_CHECK_TYPES([uint8_t]) +AC_CHECK_TYPES([uint16_t]) +AC_CHECK_TYPES([uint32_t]) +AC_CHECK_TYPES([uint64_t]) +AC_CHECK_TYPES([ssize_t]) + +AC_CHECK_SIZEOF([short]) +AC_CHECK_SIZEOF([int]) +AC_CHECK_SIZEOF([long]) +AC_CHECK_SIZEOF([long long]) +AC_CHECK_SIZEOF([off_t]) +AC_CHECK_SIZEOF([size_t]) + +AC_PATH_PROG([TOUCH], [touch]) +AC_PATH_PROG([UNZIP], [unzip]) + +AC_STRUCT_TIMEZONE + +case $host_os +in + *bsd*) MANFMT=mdoc;; + *) MANFMT=man;; +esac +AC_SUBST([MANFMT]) + +AH_BOTTOM([ +#ifndef HAVE_SSIZE_T +# if SIZEOF_SIZE_T == SIZEOF_INT +typedef int ssize_t; +# elif SIZEOF_SIZE_T == SIZEOF_LONG +typedef long ssize_t; +# elif SIZEOF_SIZE_T == SIZEOF_LONG_LONG +typedef long long ssize_t; +# else +#error no suitable type for ssize_t found +# endif +#endif +]) + dnl so we always include the known-good working hack. PHP_ADD_MAKEFILE_FRAGMENT diff --git a/ext/zip/config.w32 b/ext/zip/config.w32 index fa0a5180df5ce..5b9f09575a769 100644 --- a/ext/zip/config.w32 +++ b/ext/zip/config.w32 @@ -9,36 +9,28 @@ if (PHP_ZIP != "no") { (PHP_ZLIB_SHARED && CHECK_LIB("zlib.lib", "zip", PHP_ZIP)) || (PHP_ZLIB == "yes" && (!PHP_ZLIB_SHARED))) ) { EXTENSION('zip', 'php_zip.c zip_stream.c'); - ADD_SOURCES(configure_module_dirname + "/lib", "zip_add.c zip_error.c zip_fclose.c \ - zip_fread.c zip_open.c zip_source_filep.c \ - zip_strerror.c zip_close.c zip_error_get.c \ - zip_file_error_get.c zip_free.c zip_rename.c \ - zip_source_free.c zip_unchange_all.c zip_delete.c \ - zip_error_get_sys_type.c zip_file_get_offset.c \ - zip_get_name.c zip_replace.c zip_source_function.c \ - zip_unchange.c zip_dirent.c zip_error_strerror.c \ - zip_filerange_crc.c zip_file_strerror.c zip_get_num_files.c \ - zip_get_archive_flag.c zip_set_archive_flag.c \ - zip_set_name.c zip_source_zip.c zip_unchange_data.c \ - zip_entry_free.c zip_error_to_str.c zip_fopen.c \ - zip_name_locate.c zip_source_buffer.c zip_stat.c \ - zip_entry_new.c zip_err_str.c zip_fopen_index.c \ - zip_new.c zip_source_file.c zip_stat_index.c \ - zip_get_archive_comment.c zip_get_file_comment.c \ - zip_set_archive_comment.c zip_set_file_comment.c \ - zip_unchange_archive.c zip_memdup.c zip_stat_init.c \ - zip_add_dir.c zip_file_error_clear.c zip_error_clear.c \ - zip_fdopen.c zip_fopen_encrypted.c zip_fopen_index_encrypted.c \ - zip_get_compression_implementation.c zip_get_encryption_implementation.c \ - zip_get_file_extra.c zip_get_num_entries.c zip_set_default_password.c \ - zip_set_file_extra.c zip_source_close.c zip_source_crc.c \ - zip_source_deflate.c zip_source_error.c zip_source_layered.c \ - zip_source_open.c zip_source_pkware.c zip_source_pop.c \ - zip_source_read.c zip_source_stat.c", "zip"); + ADD_SOURCES(configure_module_dirname + "/lib", "zip_add.c zip_add_dir.c zip_add_entry.c\ + zip_close.c zip_delete.c zip_dir_add.c zip_dirent.c zip_discard.c zip_entry.c\ + zip_err_str.c zip_error.c zip_error_clear.c zip_error_get.c zip_error_get_sys_type.c\ + zip_error_strerror.c zip_error_to_str.c zip_extra_field.c zip_extra_field_api.c\ + zip_fclose.c zip_fdopen.c zip_file_add.c zip_file_error_clear.c zip_file_error_get.c\ + zip_file_get_comment.c zip_file_get_offset.c zip_file_rename.c zip_file_replace.c\ + zip_file_set_comment.c zip_file_strerror.c zip_filerange_crc.c zip_fopen.c\ + zip_fopen_encrypted.c zip_fopen_index.c zip_fopen_index_encrypted.c zip_fread.c\ + zip_get_archive_comment.c zip_get_archive_flag.c zip_get_compression_implementation.c\ + zip_get_encryption_implementation.c zip_get_file_comment.c zip_get_name.c zip_get_num_entries.c \ + zip_get_num_files.c zip_memdup.c zip_name_locate.c zip_new.c zip_open.c zip_rename.c zip_replace.c\ + zip_set_archive_comment.c zip_set_archive_flag.c zip_set_default_password.c zip_set_file_comment.c\ + zip_set_file_compression.c zip_set_name.c zip_source_buffer.c zip_source_close.c zip_source_crc.c\ + zip_source_deflate.c zip_source_error.c zip_source_file.c zip_source_filep.c zip_source_free.c\ + zip_source_function.c zip_source_layered.c zip_source_open.c zip_source_pkware.c zip_source_pop.c\ + zip_source_read.c zip_source_stat.c zip_source_window.c zip_source_zip.c zip_source_zip_new.c\ + zip_stat.c zip_stat_index.c zip_stat_init.c zip_strerror.c zip_string.c zip_unchange.c zip_unchange_all.c\ + zip_unchange_archive.c zip_unchange_data.c zip_utf-8.c mkstemp.c", "zip"); AC_DEFINE('HAVE_ZIP', 1); + ADD_FLAG("CFLAGS_ZIP", "/D _WIN32"); } else { WARNING("zip not enabled; libraries and headers not found"); } } - diff --git a/ext/zip/examples/addglob.php b/ext/zip/examples/addglob.php new file mode 100644 index 0000000000000..790312b4d586a --- /dev/null +++ b/ext/zip/examples/addglob.php @@ -0,0 +1,14 @@ +open('a.zip', ZIPARCHIVE::CREATE); + +/* or 'remove_all_path' => 0*/ +$options = array( + 'remove_path' => '/home/francis/myimages', + 'add_path' => 'images/', +); +$found = $z->addGlob("/home/pierre/cvs/gd/libgd/tests/*.png", 0, $options); +var_dump($found); +$z->close(); + diff --git a/ext/zip/examples/addpattern.php b/ext/zip/examples/addpattern.php new file mode 100644 index 0000000000000..a1a9b122914e5 --- /dev/null +++ b/ext/zip/examples/addpattern.php @@ -0,0 +1,13 @@ +open('a.zip', ZIPARCHIVE::CREATE); + +/* or 'remove_all_path' => 0*/ +$options = array('remove_path' => '/home/pierre/cvs/gd/libgd/tests', +'add_path' => 'images/', +); + +$found = $z->addPattern("/(\.png)$/i", "/home/pierre/cvs/gd/libgd/tests", $options); +var_dump($found); +$z->close(); + diff --git a/ext/zip/lib/config.h b/ext/zip/lib/config.h new file mode 100644 index 0000000000000..f9132ba439c41 --- /dev/null +++ b/ext/zip/lib/config.h @@ -0,0 +1,25 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt. | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Pierre-Alain Joye | + +----------------------------------------------------------------------+ +*/ +#ifdef HAVE_CONFIG_H +/* Building in PECL */ +#include "../config.h" + +#else +/* Building in PHP tree */ +#include "php_config.h" +#endif diff --git a/ext/zip/lib/mkstemp.c b/ext/zip/lib/mkstemp.c new file mode 100644 index 0000000000000..843d5e3613143 --- /dev/null +++ b/ext/zip/lib/mkstemp.c @@ -0,0 +1,151 @@ +/* Adapted from NetBSB libc by Dieter Baron */ + +/* NetBSD: gettemp.c,v 1.13 2003/12/05 00:57:36 uebayasi Exp */ + +/* + * Copyright (c) 1987, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include + +#include +#include +#include +#include +#ifdef _WIN32 +#include +#endif +#include +#include + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + + + +int +_zip_mkstemp(char *path) +{ +#ifdef _WIN32 + int ret; + ret = _creat(_mktemp(path), _S_IREAD|_S_IWRITE); + if (ret == -1) { + return 0; + } else { + return ret; + } +#else + int fd; + char *start, *trv; + struct stat sbuf; + pid_t pid; + + /* To guarantee multiple calls generate unique names even if + the file is not created. 676 different possibilities with 7 + or more X's, 26 with 6 or less. */ + static char xtra[2] = "aa"; + int xcnt = 0; + + pid = getpid(); + + /* Move to end of path and count trailing X's. */ + for (trv = path; *trv; ++trv) + if (*trv == 'X') + xcnt++; + else + xcnt = 0; + + /* Use at least one from xtra. Use 2 if more than 6 X's. */ + if (*(trv - 1) == 'X') + *--trv = xtra[0]; + if (xcnt > 6 && *(trv - 1) == 'X') + *--trv = xtra[1]; + + /* Set remaining X's to pid digits with 0's to the left. */ + while (*--trv == 'X') { + *trv = (pid % 10) + '0'; + pid /= 10; + } + + /* update xtra for next call. */ + if (xtra[0] != 'z') + xtra[0]++; + else { + xtra[0] = 'a'; + if (xtra[1] != 'z') + xtra[1]++; + else + xtra[1] = 'a'; + } + + /* + * check the target directory; if you have six X's and it + * doesn't exist this runs for a *very* long time. + */ + for (start = trv + 1;; --trv) { + if (trv <= path) + break; + if (*trv == '/') { + *trv = '\0'; + if (stat(path, &sbuf)) + return (0); + if (!S_ISDIR(sbuf.st_mode)) { + errno = ENOTDIR; + return (0); + } + *trv = '/'; + break; + } + } + + for (;;) { + if ((fd=open(path, O_CREAT|O_EXCL|O_RDWR|O_BINARY, 0600)) >= 0) + return (fd); + if (errno != EEXIST) + return (0); + + /* tricky little algorithm for backward compatibility */ + for (trv = start;;) { + if (!*trv) + return (0); + if (*trv == 'z') + *trv++ = 'a'; + else { + if (isdigit((unsigned char)*trv)) + *trv = 'a'; + else + ++*trv; + break; + } + } + } + /*NOTREACHED*/ +#endif +} diff --git a/ext/zip/lib/php_zip_config.w32.h b/ext/zip/lib/php_zip_config.w32.h new file mode 100644 index 0000000000000..8956839c62c32 --- /dev/null +++ b/ext/zip/lib/php_zip_config.w32.h @@ -0,0 +1,57 @@ +#ifndef HAD_CONFIG_H +#define HAD_CONFIG_H +#define HAVE__CLOSE +#define HAVE__DUP +#define HAVE__FDOPEN +#define HAVE__FILENO +#define HAVE__OPEN +#define HAVE__SNPRINTF +/* #undef HAVE__STRCMPI */ +#define HAVE__STRDUP +#define HAVE__STRICMP +/* #undef HAVE_FSEEKO */ +/* #undef HAVE_FTELLO */ +/* #undef HAVE_MKSTEMP */ +#define HAVE_MOVEFILEEXA +/* #undef HAVE_SNPRINTF */ +/* #undef HAVE_STRCASECMP */ +/* #undef HAVE_STRINGS_H */ +/* #undef HAVE_STRUCT_TM_TM_ZONE */ +/* #undef HAVE_UNISTD_H */ +#define PACKAGE "libzip" +#define VERSION "0.10.b" + +/* #undef HAVE_SSIZE_T */ + +#ifndef HAVE_SSIZE_T + +#ifndef SIZE_T_LIBZIP +#define SIZE_T_LIBZIP 4 +#endif +#ifndef INT_LIBZIP +#define INT_LIBZIP 4 +#endif +#ifndef LONG_LIBZIP +#define LONG_LIBZIP 4 +#endif +#ifndef LONG_LONG_LIBZIP +#define LONG_LONG_LIBZIP 8 +#endif +#ifndef SIZEOF_OFF_T +#define SIZEOF_OFF_T 4 +#endif + +# if SIZE_T_LIBZIP == INT_LIBZIP +# ifndef ssize_t +typedef int ssize_t; +# endif +# elif SIZE_T_LIBZIP == LONG_LIBZIP +typedef long ssize_t; +# elif SIZE_T_LIBZIP == LONG_LONG_LIBZIP +typedef long long ssize_t; +# else +#error no suitable type for ssize_t found +# endif +#endif + +#endif /* HAD_CONFIG_H */ diff --git a/ext/zip/lib/zip.h b/ext/zip/lib/zip.h index f11c9aba7f99c..1fb1dbf5e0f5b 100644 --- a/ext/zip/lib/zip.h +++ b/ext/zip/lib/zip.h @@ -3,7 +3,7 @@ /* zip.h -- exported declarations. - Copyright (C) 1999-2011 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2012 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -38,18 +38,30 @@ #include "main/php.h" #ifdef PHP_WIN32 -# include "zip_win32.h" -# ifdef PHP_ZIP_EXPORTS -# define ZIP_EXTERN(rt) __declspec(dllexport)rt _stdcall -# else -# define ZIP_EXTERN(rt) rt -# endif +#ifdef PHP_ZIP_EXPORTS +# define ZIP_EXTERN __declspec(dllexport) _stdcall +# else +# define ZIP_EXTERN +# endif #elif defined(__GNUC__) && __GNUC__ >= 4 -# define ZIP_EXTERN(rt) __attribute__ ((visibility("default"))) rt +# define ZIP_EXTERN __attribute__ ((visibility("default"))) #else -# define ZIP_EXTERN(rt) rt +# define ZIP_EXTERN #endif + +#ifndef ZIP_EXTERN +#ifdef _WIN32 +#define ZIP_EXTERN __declspec(dllimport) +#elif defined(__GNUC__) && __GNUC__ >= 4 +#define ZIP_EXTERN __attribute__ ((visibility ("default"))) +#else +#define ZIP_EXTERN +#endif +#endif + + + BEGIN_EXTERN_C() #include "zipconf.h" @@ -63,27 +75,40 @@ BEGIN_EXTERN_C() #define ZIP_CREATE 1 #define ZIP_EXCL 2 #define ZIP_CHECKCONS 4 -#define ZIP_OVERWRITE 8 - +#define ZIP_TRUNCATE 8 /* flags for zip_name_locate, zip_fopen, zip_stat, ... */ -#define ZIP_FL_NOCASE 1 /* ignore case on name lookup */ -#define ZIP_FL_NODIR 2 /* ignore directory component */ -#define ZIP_FL_COMPRESSED 4 /* read compressed data */ -#define ZIP_FL_UNCHANGED 8 /* use original data, ignoring changes */ -#define ZIP_FL_RECOMPRESS 16 /* force recompression of data */ -#define ZIP_FL_ENCRYPTED 32 /* read encrypted data - (implies ZIP_FL_COMPRESSED) */ +#define ZIP_FL_NOCASE 1u /* ignore case on name lookup */ +#define ZIP_FL_NODIR 2u /* ignore directory component */ +#define ZIP_FL_COMPRESSED 4u /* read compressed data */ +#define ZIP_FL_UNCHANGED 8u /* use original data, ignoring changes */ +#define ZIP_FL_RECOMPRESS 16u /* force recompression of data */ +#define ZIP_FL_ENCRYPTED 32u /* read encrypted data (implies ZIP_FL_COMPRESSED) */ +#define ZIP_FL_ENC_GUESS 0u /* guess string encoding (is default) */ +#define ZIP_FL_ENC_RAW 64u /* get unmodified string */ +#define ZIP_FL_ENC_STRICT 128u /* follow specification strictly */ +#define ZIP_FL_LOCAL 256u /* in local header */ +#define ZIP_FL_CENTRAL 512u /* in central directory */ +/* 1024u reserved for internal use */ +#define ZIP_FL_ENC_UTF_8 2048u /* string is UTF-8 encoded */ +#define ZIP_FL_ENC_CP437 4096u /* string is CP437 encoded */ +#define ZIP_FL_OVERWRITE 8192u /* zip_file_add: if file with name exists, overwrite (replace) it */ /* archive global flags flags */ -#define ZIP_AFL_TORRENT 1 /* torrent zipped */ -#define ZIP_AFL_RDONLY 2 /* read only -- cannot be cleared */ +#define ZIP_AFL_TORRENT 1u /* torrent zipped */ +#define ZIP_AFL_RDONLY 2u /* read only -- cannot be cleared */ + +/* create a new extra field */ + +#define ZIP_EXTRA_FIELD_ALL ZIP_UINT16_MAX +#define ZIP_EXTRA_FIELD_NEW ZIP_UINT16_MAX /* flags for compression and encryption sources */ +#define ZIP_CODEC_DECODE 0 /* decompress/decrypt (encode flag not set) */ #define ZIP_CODEC_ENCODE 1 /* compress/encrypt */ @@ -178,15 +203,15 @@ enum zip_source_cmd { #define ZIP_SOURCE_ERR_LOWER -2 -#define ZIP_STAT_NAME 0x0001 -#define ZIP_STAT_INDEX 0x0002 -#define ZIP_STAT_SIZE 0x0004 -#define ZIP_STAT_COMP_SIZE 0x0008 -#define ZIP_STAT_MTIME 0x0010 -#define ZIP_STAT_CRC 0x0020 -#define ZIP_STAT_COMP_METHOD 0x0040 -#define ZIP_STAT_ENCRYPTION_METHOD 0x0080 -#define ZIP_STAT_FLAGS 0x0100 +#define ZIP_STAT_NAME 0x0001u +#define ZIP_STAT_INDEX 0x0002u +#define ZIP_STAT_SIZE 0x0004u +#define ZIP_STAT_COMP_SIZE 0x0008u +#define ZIP_STAT_MTIME 0x0010u +#define ZIP_STAT_CRC 0x0020u +#define ZIP_STAT_COMP_METHOD 0x0040u +#define ZIP_STAT_ENCRYPTION_METHOD 0x0080u +#define ZIP_STAT_FLAGS 0x0100u struct zip_stat { zip_uint64_t valid; /* which fields have valid values */ @@ -205,72 +230,78 @@ struct zip; struct zip_file; struct zip_source; +typedef zip_uint32_t zip_flags_t; + typedef zip_int64_t (*zip_source_callback)(void *, void *, zip_uint64_t, enum zip_source_cmd); -ZIP_EXTERN(zip_int64_t) zip_add(struct zip *, const char *, struct zip_source *); -ZIP_EXTERN(zip_int64_t) zip_add_dir(struct zip *, const char *); -ZIP_EXTERN(int) zip_close(struct zip *); -ZIP_EXTERN(int) zip_delete(struct zip *, zip_uint64_t); -ZIP_EXTERN(void) zip_error_clear(struct zip *); -ZIP_EXTERN(void) zip_error_get(struct zip *, int *, int *); -ZIP_EXTERN(int) zip_error_get_sys_type(int); -ZIP_EXTERN(int) zip_error_to_str(char *, zip_uint64_t, int, int); -ZIP_EXTERN(int) zip_fclose(struct zip_file *); -ZIP_EXTERN(struct zip *)zip_fdopen(int, int, int *); -ZIP_EXTERN(void) zip_file_error_clear(struct zip_file *); -ZIP_EXTERN(void) zip_file_error_get(struct zip_file *, int *, int *); -ZIP_EXTERN(const char *)zip_file_strerror(struct zip_file *); -ZIP_EXTERN(struct) zip_file *zip_fopen(struct zip *, const char *, int); -ZIP_EXTERN(struct) zip_file *zip_fopen_encrypted(struct zip *, const char *, - int, const char *); -ZIP_EXTERN(struct zip_file *)zip_fopen_index(struct zip *, zip_uint64_t, int); -ZIP_EXTERN(struct zip_file *)zip_fopen_index_encrypted(struct zip *, - zip_uint64_t, int, - const char *); -ZIP_EXTERN(zip_int64_t) zip_fread(struct zip_file *, void *, zip_uint64_t); -ZIP_EXTERN(const char *)zip_get_archive_comment(struct zip *, int *, int); -ZIP_EXTERN(int) zip_get_archive_flag(struct zip *, int, int); -ZIP_EXTERN(const char *)zip_get_file_comment(struct zip *, zip_uint64_t, - int *, int); -ZIP_EXTERN(const char *)zip_get_file_extra(struct zip *, zip_uint64_t, - int *, int); -ZIP_EXTERN(const char *)zip_get_name(struct zip *, zip_uint64_t, int); -ZIP_EXTERN(zip_uint64_t) zip_get_num_entries(struct zip *, int); -ZIP_EXTERN(int) zip_get_num_files(struct zip *); /* deprecated, use zip_get_num_entries instead */ -ZIP_EXTERN(int) zip_name_locate(struct zip *, const char *, int); -ZIP_EXTERN(struct zip *)zip_open(const char *, int, int *); -ZIP_EXTERN(int) zip_rename(struct zip *, zip_uint64_t, const char *); -ZIP_EXTERN(int) zip_replace(struct zip *, zip_uint64_t, struct zip_source *); -ZIP_EXTERN(int) zip_set_archive_comment(struct zip *, const char *, int); -ZIP_EXTERN(int) zip_set_archive_flag(struct zip *, int, int); -ZIP_EXTERN(int) zip_set_default_password(struct zip *, const char *); -ZIP_EXTERN(int) zip_set_file_comment(struct zip *, zip_uint64_t, - const char *, int); -ZIP_EXTERN(int) zip_set_file_extra(struct zip *, zip_uint64_t, - const char *, int); -ZIP_EXTERN(struct) zip_source *zip_source_buffer(struct zip *, const void *, - zip_uint64_t, int); -ZIP_EXTERN(struct) zip_source *zip_source_file(struct zip *, const char *, - zip_uint64_t, zip_int64_t); -ZIP_EXTERN(struct) zip_source *zip_source_filep(struct zip *, FILE *, - zip_uint64_t, zip_int64_t); -ZIP_EXTERN(void) zip_source_free(struct zip_source *); -ZIP_EXTERN(struct zip_source *)zip_source_function(struct zip *, - zip_source_callback, void *); -ZIP_EXTERN(struct zip_source *)zip_source_zip(struct zip *, struct zip *, - zip_uint64_t, int, - zip_uint64_t, zip_int64_t); -ZIP_EXTERN(int) zip_stat(struct zip *, const char *, int, struct zip_stat *); -ZIP_EXTERN(int) zip_stat_index(struct zip *, zip_uint64_t, int, - struct zip_stat *); -ZIP_EXTERN(void) zip_stat_init(struct zip_stat *); -ZIP_EXTERN(const char *)zip_strerror(struct zip *); -ZIP_EXTERN(int) zip_unchange(struct zip *, zip_uint64_t); -ZIP_EXTERN(int) zip_unchange_all(struct zip *); -ZIP_EXTERN(int) zip_unchange_archive(struct zip *); +#ifndef ZIP_DISABLE_DEPRECATED +ZIP_EXTERN zip_int64_t zip_add(struct zip *, const char *, struct zip_source *); /* use zip_file_add */ +ZIP_EXTERN zip_int64_t zip_add_dir(struct zip *, const char *); /* use zip_dir_add */ +ZIP_EXTERN const char *zip_get_file_comment(struct zip *, zip_uint64_t, int *, int); /* use zip_file_get_comment */ +ZIP_EXTERN int zip_get_num_files(struct zip *); /* use zip_get_num_entries instead */ +ZIP_EXTERN int zip_rename(struct zip *, zip_uint64_t, const char *); /* use zip_file_rename */ +ZIP_EXTERN int zip_replace(struct zip *, zip_uint64_t, struct zip_source *); /* use zip_file_replace */ +ZIP_EXTERN int zip_set_file_comment(struct zip *, zip_uint64_t, const char *, int); /* use zip_file_set_comment */ +#endif + +ZIP_EXTERN int zip_archive_set_tempdir(struct zip *, const char *); +ZIP_EXTERN zip_int64_t zip_file_add(struct zip *, const char *, struct zip_source *, zip_flags_t); +ZIP_EXTERN zip_int64_t zip_dir_add(struct zip *, const char *, zip_flags_t); +ZIP_EXTERN int zip_close(struct zip *); +ZIP_EXTERN void zip_discard(struct zip *); +ZIP_EXTERN int zip_delete(struct zip *, zip_uint64_t); +ZIP_EXTERN int zip_file_extra_field_delete(struct zip *, zip_uint64_t, zip_uint16_t, zip_flags_t); +ZIP_EXTERN int zip_file_extra_field_delete_by_id(struct zip *, zip_uint64_t, zip_uint16_t, zip_uint16_t, zip_flags_t); +ZIP_EXTERN void zip_error_clear(struct zip *); +ZIP_EXTERN void zip_error_get(struct zip *, int *, int *); +ZIP_EXTERN int zip_error_get_sys_type(int); +ZIP_EXTERN int zip_error_to_str(char *, zip_uint64_t, int, int); +ZIP_EXTERN int zip_fclose(struct zip_file *); +ZIP_EXTERN struct zip *zip_fdopen(int, int, int *); +ZIP_EXTERN void zip_file_error_clear(struct zip_file *); +ZIP_EXTERN void zip_file_error_get(struct zip_file *, int *, int *); +ZIP_EXTERN const char *zip_file_strerror(struct zip_file *); +ZIP_EXTERN struct zip_file *zip_fopen(struct zip *, const char *, zip_flags_t); +ZIP_EXTERN struct zip_file *zip_fopen_encrypted(struct zip *, const char *, zip_flags_t, const char *); +ZIP_EXTERN struct zip_file *zip_fopen_index(struct zip *, zip_uint64_t, zip_flags_t); +ZIP_EXTERN struct zip_file *zip_fopen_index_encrypted(struct zip *, zip_uint64_t, zip_flags_t, const char *); +ZIP_EXTERN zip_int64_t zip_fread(struct zip_file *, void *, zip_uint64_t); +ZIP_EXTERN const char *zip_get_archive_comment(struct zip *, int *, zip_flags_t); +ZIP_EXTERN int zip_get_archive_flag(struct zip *, zip_flags_t, zip_flags_t); +ZIP_EXTERN const char *zip_file_get_comment(struct zip *, zip_uint64_t, zip_uint32_t *, zip_flags_t); +ZIP_EXTERN const zip_uint8_t *zip_file_extra_field_get(struct zip *, zip_uint64_t, zip_uint16_t, zip_uint16_t *, zip_uint16_t *, zip_flags_t); +ZIP_EXTERN const zip_uint8_t *zip_file_extra_field_get_by_id(struct zip *, zip_uint64_t, zip_uint16_t, zip_uint16_t, zip_uint16_t *, zip_flags_t); +ZIP_EXTERN zip_int16_t zip_file_extra_fields_count(struct zip *, zip_uint64_t, zip_flags_t); +ZIP_EXTERN zip_int16_t zip_file_extra_fields_count_by_id(struct zip *, zip_uint64_t, zip_uint16_t, zip_flags_t); +ZIP_EXTERN const char *zip_get_name(struct zip *, zip_uint64_t, zip_flags_t); +ZIP_EXTERN zip_int64_t zip_get_num_entries(struct zip *, zip_flags_t); +ZIP_EXTERN zip_int64_t zip_name_locate(struct zip *, const char *, zip_flags_t); +ZIP_EXTERN struct zip *zip_open(const char *, int, int *); +ZIP_EXTERN int zip_file_rename(struct zip *, zip_uint64_t, const char *, zip_flags_t); +ZIP_EXTERN int zip_file_replace(struct zip *, zip_uint64_t, struct zip_source *, zip_flags_t); +ZIP_EXTERN int zip_set_archive_comment(struct zip *, const char *, zip_uint16_t); +ZIP_EXTERN int zip_set_archive_flag(struct zip *, zip_flags_t, int); +ZIP_EXTERN int zip_set_default_password(struct zip *, const char *); +ZIP_EXTERN int zip_file_set_comment(struct zip *, zip_uint64_t, const char *, zip_uint16_t, zip_flags_t); +ZIP_EXTERN int zip_set_file_compression(struct zip *, zip_uint64_t, zip_int32_t, zip_uint32_t); +ZIP_EXTERN int zip_file_extra_field_set(struct zip *, zip_uint64_t, zip_uint16_t, zip_uint16_t, const zip_uint8_t *, zip_uint16_t, zip_flags_t); +ZIP_EXTERN struct zip_source *zip_source_buffer(struct zip *, const void *, zip_uint64_t, int); +ZIP_EXTERN struct zip_source *zip_source_file(struct zip *, const char *, zip_uint64_t, zip_int64_t); +ZIP_EXTERN struct zip_source *zip_source_filep(struct zip *, FILE *, zip_uint64_t, zip_int64_t); +ZIP_EXTERN void zip_source_free(struct zip_source *); +ZIP_EXTERN struct zip_source *zip_source_function(struct zip *, zip_source_callback, void *); +ZIP_EXTERN struct zip_source *zip_source_zip(struct zip *, struct zip *, zip_uint64_t, zip_flags_t, zip_uint64_t, zip_int64_t); +ZIP_EXTERN int zip_stat(struct zip *, const char *, zip_flags_t, struct zip_stat *); +ZIP_EXTERN int zip_stat_index(struct zip *, zip_uint64_t, zip_flags_t, struct zip_stat *); +ZIP_EXTERN void zip_stat_init(struct zip_stat *); +ZIP_EXTERN const char *zip_strerror(struct zip *); +ZIP_EXTERN int zip_unchange(struct zip *, zip_uint64_t); +ZIP_EXTERN int zip_unchange_all(struct zip *); +ZIP_EXTERN int zip_unchange_archive(struct zip *); + END_EXTERN_C(); #endif /* _HAD_ZIP_H */ diff --git a/ext/zip/lib/zip_add.c b/ext/zip/lib/zip_add.c index 6067abbac491f..4bce3fd4af274 100644 --- a/ext/zip/lib/zip_add.c +++ b/ext/zip/lib/zip_add.c @@ -1,6 +1,6 @@ /* zip_add.c -- add file via callback function - Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2012 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -33,6 +33,7 @@ +#define _ZIP_COMPILING_DEPRECATED #include "zipint.h" @@ -44,13 +45,8 @@ ZIP_UINT64_MAX, and each entry is larger than 2 bytes. */ -ZIP_EXTERN(zip_int64_t) +ZIP_EXTERN zip_int64_t zip_add(struct zip *za, const char *name, struct zip_source *source) { - if (name == NULL || source == NULL) { - _zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return -1; - } - - return _zip_replace(za, ZIP_UINT64_MAX, name, source); + return zip_file_add(za, name, source, 0); } diff --git a/ext/zip/lib/zip_add_dir.c b/ext/zip/lib/zip_add_dir.c index 0a9d7f4863011..22a28bd856253 100644 --- a/ext/zip/lib/zip_add_dir.c +++ b/ext/zip/lib/zip_add_dir.c @@ -1,6 +1,6 @@ /* zip_add_dir.c -- add directory - Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2013 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -33,56 +33,15 @@ -#include -#include - +#define _ZIP_COMPILING_DEPRECATED #include "zipint.h" /* NOTE: Signed due to -1 on error. See zip_add.c for more details. */ -ZIP_EXTERN(zip_int64_t) +ZIP_EXTERN zip_int64_t zip_add_dir(struct zip *za, const char *name) { - int len; - zip_int64_t ret; - char *s; - struct zip_source *source; - - if (ZIP_IS_RDONLY(za)) { - _zip_error_set(&za->error, ZIP_ER_RDONLY, 0); - return -1; - } - - if (name == NULL) { - _zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return -1; - } - - s = NULL; - len = strlen(name); - - if (name[len-1] != '/') { - if ((s=(char *)malloc(len+2)) == NULL) { - _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return -1; - } - strcpy(s, name); - s[len] = '/'; - s[len+1] = '\0'; - } - - if ((source=zip_source_buffer(za, NULL, 0, 0)) == NULL) { - free(s); - return -1; - } - - ret = _zip_replace(za, -1, s ? s : name, source); - - free(s); - if (ret < 0) - zip_source_free(source); - - return ret; + return zip_dir_add(za, name, 0); } diff --git a/ext/zip/lib/zip_add_entry.c b/ext/zip/lib/zip_add_entry.c new file mode 100644 index 0000000000000..3a7e2ccbe920f --- /dev/null +++ b/ext/zip/lib/zip_add_entry.c @@ -0,0 +1,66 @@ +/* + zip_add_entry.c -- create and init struct zip_entry + Copyright (C) 1999-2012 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include + +#include "zipint.h" + + + +/* NOTE: Signed due to -1 on error. See zip_add.c for more details. */ + +zip_int64_t +_zip_add_entry(struct zip *za) +{ + zip_uint64_t idx; + + if (za->nentry+1 >= za->nentry_alloc) { + struct zip_entry *rentries; + zip_uint64_t nalloc = za->nentry_alloc + 16; + rentries = (struct zip_entry *)realloc(za->entry, sizeof(struct zip_entry) * nalloc); + if (!rentries) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return -1; + } + za->entry = rentries; + za->nentry_alloc = nalloc; + } + + idx = za->nentry++; + + _zip_entry_init(za->entry+idx); + + return (zip_int64_t)idx; +} diff --git a/ext/zip/lib/zip_close.c b/ext/zip/lib/zip_close.c index 576be3b3536fb..c9c7e58088644 100644 --- a/ext/zip/lib/zip_close.c +++ b/ext/zip/lib/zip_close.c @@ -38,6 +38,9 @@ #include #include #include +#ifdef HAVE_STRINGS_H +#include +#endif #include #ifdef HAVE_UNISTD_H #include @@ -49,110 +52,106 @@ #include #endif -static int add_data(struct zip *, struct zip_source *, struct zip_dirent *, - FILE *); -static int copy_data(FILE *, off_t, FILE *, struct zip_error *); + + +/* max deflate size increase: size + ceil(size/16k)*5+6 */ +#define MAX_DEFLATE_SIZE_32 4293656963u + +static int add_data(struct zip *, struct zip_source *, struct zip_dirent *, FILE *); +static int copy_data(FILE *, zip_uint64_t, FILE *, struct zip_error *); static int copy_source(struct zip *, struct zip_source *, FILE *); -static int write_cdir(struct zip *, struct zip_cdir *, FILE *); -static int _zip_cdir_set_comment(struct zip_cdir *, struct zip *); +static int write_cdir(struct zip *, const struct zip_filelist *, zip_uint64_t, FILE *); static char *_zip_create_temp_output(struct zip *, FILE **); static int _zip_torrentzip_cmp(const void *, const void *); -struct filelist { - int idx; - const char *name; -}; - - - -ZIP_EXTERN(int) +ZIP_EXTERN int zip_close(struct zip *za) { - int survivors; - int i, j, error; + zip_uint64_t i, j, survivors; + int error; char *temp; FILE *out; #ifndef PHP_WIN32 mode_t mask; #endif - struct zip_cdir *cd; - struct zip_dirent de; - struct filelist *filelist; + struct zip_filelist *filelist; int reopen_on_error; int new_torrentzip; + int changed; reopen_on_error = 0; if (za == NULL) return -1; - if (!_zip_changed(za, &survivors)) { - _zip_free(za); - return 0; - } + changed = _zip_changed(za, &survivors); /* don't create zip files with no entries */ if (survivors == 0) { - if (za->zn && za->zp) { + if (za->zn && ((za->open_flags & ZIP_TRUNCATE) || (changed && za->zp))) { if (remove(za->zn) != 0) { _zip_error_set(&za->error, ZIP_ER_REMOVE, errno); return -1; } } - _zip_free(za); + zip_discard(za); return 0; } - if ((filelist=(struct filelist *)malloc(sizeof(filelist[0])*survivors)) - == NULL) - return -1; - - if ((cd=_zip_cdir_new(survivors, &za->error)) == NULL) { - free(filelist); - return -1; + if (!changed) { + zip_discard(za); + return 0; } - for (i=0; ientry[i]); + if (survivors > za->nentry) { + _zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); + return -1; + } + + if ((filelist=(struct zip_filelist *)malloc(sizeof(filelist[0])*survivors)) == NULL) + return -1; /* archive comment is special for torrentzip */ if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0)) { - cd->comment = _zip_memdup(TORRENT_SIG "XXXXXXXX", - TORRENT_SIG_LEN + TORRENT_CRC_LEN, - &za->error); - if (cd->comment == NULL) { - _zip_cdir_free(cd); - free(filelist); - return -1; - } - cd->comment_len = TORRENT_SIG_LEN + TORRENT_CRC_LEN; - } - else if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, ZIP_FL_UNCHANGED) == 0) { - if (_zip_cdir_set_comment(cd, za) == -1) { - _zip_cdir_free(cd); + /* XXX: use internal function when zip_set_archive_comment clears TORRENT flag */ + if (zip_set_archive_comment(za, TORRENT_SIG "XXXXXXXX", TORRENT_SIG_LEN + TORRENT_CRC_LEN) < 0) { free(filelist); return -1; } } - - if ((temp=_zip_create_temp_output(za, &out)) == NULL) { - _zip_cdir_free(cd); - free(filelist); - return -1; - } + /* XXX: if no longer torrentzip and archive comment not changed by user, delete it */ /* create list of files with index into original archive */ for (i=j=0; inentry; i++) { - if (za->entry[i].state == ZIP_ST_DELETED) + if (za->entry[i].deleted) continue; + if (j >= survivors) { + free(filelist); + _zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); + return -1; + } + filelist[j].idx = i; filelist[j].name = zip_get_name(za, i, 0); j++; } + if (j < survivors) { + free(filelist); + _zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); + return -1; + } + + + if ((temp=_zip_create_temp_output(za, &out)) == NULL) { + free(filelist); + return -1; + } + + if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0)) qsort(filelist, survivors, sizeof(filelist[0]), _zip_torrentzip_cmp); @@ -162,106 +161,49 @@ zip_close(struct zip *za) ZIP_FL_UNCHANGED) == 0); error = 0; for (j=0; jentry+i; - _zip_dirent_init(&de); + new_data = (ZIP_ENTRY_DATA_CHANGED(entry) || new_torrentzip || ZIP_ENTRY_CHANGED(entry, ZIP_DIRENT_COMP_METHOD)); /* create new local directory entry */ - if (ZIP_ENTRY_DATA_CHANGED(za->entry+i) || new_torrentzip) { - - if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0)) - _zip_dirent_torrent_normalize(&de); - - /* use it as central directory entry */ - memcpy(cd->entry+j, &de, sizeof(cd->entry[j])); - - /* set/update file name */ - if (za->entry[i].ch_filename == NULL) { - if (za->entry[i].state == ZIP_ST_ADDED) { - de.filename = strdup("-"); - de.filename_len = 1; - cd->entry[j].filename = "-"; - cd->entry[j].filename_len = 1; - } - else { - de.filename = strdup(za->cdir->entry[i].filename); - de.filename_len = strlen(de.filename); - cd->entry[j].filename = za->cdir->entry[i].filename; - cd->entry[j].filename_len = de.filename_len; - } + if (entry->changes == NULL) { + if ((entry->changes=_zip_dirent_clone(entry->orig)) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + error = 1; + break; } } - else { - /* copy existing directory entries */ - if ((NULL == za->zp) || (fseeko(za->zp, za->cdir->entry[i].offset, SEEK_SET) != 0)) { - _zip_error_set(&za->error, ZIP_ER_SEEK, errno); - error = 1; - break; - } - if (_zip_dirent_read(&de, za->zp, NULL, NULL, 1, - &za->error) != 0) { - error = 1; - break; - } - memcpy(cd->entry+j, za->cdir->entry+i, sizeof(cd->entry[j])); - if (de.bitflags & ZIP_GPBF_DATA_DESCRIPTOR) { - de.crc = za->cdir->entry[i].crc; - de.comp_size = za->cdir->entry[i].comp_size; - de.uncomp_size = za->cdir->entry[i].uncomp_size; - de.bitflags &= ~ZIP_GPBF_DATA_DESCRIPTOR; - cd->entry[j].bitflags &= ~ZIP_GPBF_DATA_DESCRIPTOR; - } - } + de = entry->changes; - if (za->entry[i].ch_filename) { - free(de.filename); - if ((de.filename=strdup(za->entry[i].ch_filename)) == NULL) { - error = 1; - break; - } - de.filename_len = strlen(de.filename); - cd->entry[j].filename = za->entry[i].ch_filename; - cd->entry[j].filename_len = de.filename_len; + if (_zip_read_local_ef(za, i) < 0) { + error = 1; + break; } - if (za->entry[i].ch_extra_len != -1) { - free(de.extrafield); - if ((de.extrafield=malloc(za->entry[i].ch_extra_len)) == NULL) { - error = 1; - break; - } - memcpy(de.extrafield, za->entry[i].ch_extra, za->entry[i].ch_extra_len); - de.extrafield_len = za->entry[i].ch_extra_len; - /* as the rest of cd entries, its malloc/free is done by za */ - /* TODO unsure if this should also be set in the CD -- - * not done for now - cd->entry[j].extrafield = za->entry[i].ch_extra; - cd->entry[j].extrafield_len = za->entry[i].ch_extra_len; - */ - } + if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0)) + _zip_dirent_torrent_normalize(entry->changes); - if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0) == 0 - && za->entry[i].ch_comment_len != -1) { - /* as the rest of cd entries, its malloc/free is done by za */ - cd->entry[j].comment = za->entry[i].ch_comment; - cd->entry[j].comment_len = za->entry[i].ch_comment_len; - } - cd->entry[j].offset = ftello(out); + de->offset = (zip_uint64_t)ftello(out); /* XXX: check for errors */ - if (ZIP_ENTRY_DATA_CHANGED(za->entry+i) || new_torrentzip) { + if (new_data) { struct zip_source *zs; zs = NULL; - if (!ZIP_ENTRY_DATA_CHANGED(za->entry+i)) { - if ((zs=zip_source_zip(za, za, i, ZIP_FL_RECOMPRESS, 0, -1)) - == NULL) { + if (!ZIP_ENTRY_DATA_CHANGED(entry)) { + if ((zs=_zip_source_zip_new(za, za, i, ZIP_FL_UNCHANGED, 0, 0, NULL)) == NULL) { error = 1; break; } } - if (add_data(za, zs ? zs : za->entry[i].source, &de, out) < 0) { + /* add_data writes dirent */ + if (add_data(za, zs ? zs : entry->source, de, out) < 0) { error = 1; if (zs) zip_source_free(zs); @@ -269,51 +211,49 @@ zip_close(struct zip *za) } if (zs) zip_source_free(zs); - - cd->entry[j].last_mod = de.last_mod; - cd->entry[j].comp_method = de.comp_method; - cd->entry[j].comp_size = de.comp_size; - cd->entry[j].uncomp_size = de.uncomp_size; - cd->entry[j].crc = de.crc; } else { - if (_zip_dirent_write(&de, out, 1, &za->error) < 0) { + zip_uint64_t offset; + + /* when copying data, all sizes are known -> no data descriptor needed */ + de->bitflags &= ~ZIP_GPBF_DATA_DESCRIPTOR; + if (_zip_dirent_write(de, out, ZIP_FL_LOCAL, &za->error) < 0) { error = 1; break; } - /* we just read the local dirent, file is at correct position */ - if (copy_data(za->zp, cd->entry[j].comp_size, out, - &za->error) < 0) { + if ((offset=_zip_file_get_offset(za, i, &za->error)) == 0) { + error = 1; + break; + } + if ((fseek(za->zp, (off_t)offset, SEEK_SET) < 0)) { + _zip_error_set(&za->error, ZIP_ER_SEEK, errno); + error = 1; + break; + } + if (copy_data(za->zp, de->comp_size, out, &za->error) < 0) { error = 1; break; } } - - _zip_dirent_finalize(&de); } - free(filelist); - if (!error) { - if (write_cdir(za, cd, out) < 0) + if (write_cdir(za, filelist, survivors, out) < 0) error = 1; } - /* pointers in cd entries are owned by za */ - cd->nentry = 0; - _zip_cdir_free(cd); + free(filelist); if (error) { - _zip_dirent_finalize(&de); fclose(out); - remove(temp); + (void)remove(temp); free(temp); return -1; } if (fclose(out) != 0) { _zip_error_set(&za->error, ZIP_ER_CLOSE, errno); - remove(temp); + (void)remove(temp); free(temp); return -1; } @@ -325,7 +265,7 @@ zip_close(struct zip *za) } if (_zip_rename(temp, za->zn) != 0) { _zip_error_set(&za->error, ZIP_ER_RENAME, errno); - remove(temp); + (void)remove(temp); free(temp); if (reopen_on_error) { /* ignore errors, since we're already in an error case */ @@ -339,56 +279,112 @@ zip_close(struct zip *za) chmod(za->zn, 0666&~mask); #endif - _zip_free(za); - free(temp); - + zip_discard(za); + free(temp); + return 0; } static int -add_data(struct zip *za, struct zip_source *src, struct zip_dirent *de, - FILE *ft) +add_data(struct zip *za, struct zip_source *src, struct zip_dirent *de, FILE *ft) { off_t offstart, offdata, offend; struct zip_stat st; struct zip_source *s2; - zip_compression_implementation comp_impl; int ret; + int is_zip64; + zip_flags_t flags; if (zip_source_stat(src, &st) < 0) { _zip_error_set_from_source(&za->error, src); return -1; } + if ((st.valid & ZIP_STAT_COMP_METHOD) == 0) { + st.valid |= ZIP_STAT_COMP_METHOD; + st.comp_method = ZIP_CM_STORE; + } + + if (ZIP_CM_IS_DEFAULT(de->comp_method) && st.comp_method != ZIP_CM_STORE) + de->comp_method = st.comp_method; + else if (de->comp_method == ZIP_CM_STORE && (st.valid & ZIP_STAT_SIZE)) { + st.valid |= ZIP_STAT_COMP_SIZE; + st.comp_size = st.size; + } + else { + /* we'll recompress */ + st.valid &= ~ZIP_STAT_COMP_SIZE; + } + + + flags = ZIP_EF_LOCAL; + + if ((st.valid & ZIP_STAT_SIZE) == 0) + flags |= ZIP_FL_FORCE_ZIP64; + else { + de->uncomp_size = st.size; + + if ((st.valid & ZIP_STAT_COMP_SIZE) == 0) { + if (( ((de->comp_method == ZIP_CM_DEFLATE || ZIP_CM_IS_DEFAULT(de->comp_method)) && st.size > MAX_DEFLATE_SIZE_32) + || (de->comp_method != ZIP_CM_STORE && de->comp_method != ZIP_CM_DEFLATE && !ZIP_CM_IS_DEFAULT(de->comp_method)))) + flags |= ZIP_FL_FORCE_ZIP64; + } + else + de->comp_size = st.comp_size; + } + + offstart = ftello(ft); - if (_zip_dirent_write(de, ft, 1, &za->error) < 0) + /* as long as we don't support non-seekable output, clear data descriptor bit */ + de->bitflags &= ~ZIP_GPBF_DATA_DESCRIPTOR; + if ((is_zip64=_zip_dirent_write(de, ft, flags, &za->error)) < 0) return -1; - if ((s2=zip_source_crc(za, src, 0)) == NULL) { - zip_source_pop(s2); - return -1; - } - - /* XXX: deflate 0-byte files for torrentzip? */ - if (((st.valid & ZIP_STAT_COMP_METHOD) == 0 - || st.comp_method == ZIP_CM_STORE) - && ((st.valid & ZIP_STAT_SIZE) == 0 || st.size != 0)) { - comp_impl = NULL; - if ((comp_impl=zip_get_compression_implementation(ZIP_CM_DEFLATE)) - == NULL) { - _zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0); - zip_source_pop(s2); - return -1; + + if (st.comp_method == ZIP_CM_STORE || (ZIP_CM_IS_DEFAULT(de->comp_method) && st.comp_method != de->comp_method)) { + struct zip_source *s_store, *s_crc; + zip_compression_implementation comp_impl; + + if (st.comp_method != ZIP_CM_STORE) { + if ((comp_impl=_zip_get_compression_implementation(st.comp_method)) == NULL) { + _zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0); + return -1; + } + if ((s_store=comp_impl(za, src, st.comp_method, ZIP_CODEC_DECODE)) == NULL) { + /* error set by comp_impl */ + return -1; + } } - if ((s2=comp_impl(za, s2, ZIP_CM_DEFLATE, ZIP_CODEC_ENCODE)) - == NULL) { - /* XXX: set error? */ - zip_source_pop(s2); + else + s_store = src; + + if ((s_crc=zip_source_crc(za, s_store, 0)) == NULL) { + if (s_store != src) + zip_source_pop(s_store); return -1; } + + /* XXX: deflate 0-byte files for torrentzip? */ + if (de->comp_method != ZIP_CM_STORE && ((st.valid & ZIP_STAT_SIZE) == 0 || st.size != 0)) { + if ((comp_impl=_zip_get_compression_implementation(de->comp_method)) == NULL) { + _zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0); + zip_source_pop(s_crc); + if (s_store != src) + zip_source_pop(s_store); + return -1; + } + if ((s2=comp_impl(za, s_crc, de->comp_method, ZIP_CODEC_ENCODE)) == NULL) { + zip_source_pop(s_crc); + if (s_store != src) + zip_source_pop(s_store); + return -1; + } + } + else + s2 = s_crc; } else s2 = src; @@ -418,18 +414,33 @@ add_data(struct zip *za, struct zip_source *src, struct zip_dirent *de, return -1; } - de->last_mod = st.mtime; + if ((st.valid & (ZIP_STAT_COMP_METHOD|ZIP_STAT_CRC|ZIP_STAT_SIZE)) != (ZIP_STAT_COMP_METHOD|ZIP_STAT_CRC|ZIP_STAT_SIZE)) { + _zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); + return -1; + } + + if (st.valid & ZIP_STAT_MTIME) + de->last_mod = st.mtime; + else + time(&de->last_mod); de->comp_method = st.comp_method; de->crc = st.crc; de->uncomp_size = st.size; - de->comp_size = offend - offdata; + de->comp_size = (zip_uint64_t)(offend - offdata); if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0)) _zip_dirent_torrent_normalize(de); - if (_zip_dirent_write(de, ft, 1, &za->error) < 0) + if ((ret=_zip_dirent_write(de, ft, flags, &za->error)) < 0) return -1; - + + if (is_zip64 != ret) { + /* Zip64 mismatch between preliminary file header written before data and final file header written afterwards */ + _zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); + return -1; + } + + if (fseeko(ft, offend, SEEK_SET) < 0) { _zip_error_set(&za->error, ZIP_ER_SEEK, errno); return -1; @@ -441,24 +452,26 @@ add_data(struct zip *za, struct zip_source *src, struct zip_dirent *de, static int -copy_data(FILE *fs, off_t len, FILE *ft, struct zip_error *error) +copy_data(FILE *fs, zip_uint64_t len, FILE *ft, struct zip_error *error) { char buf[BUFSIZE]; - int n, nn; + size_t n, nn; if (len == 0) return 0; while (len > 0) { nn = len > sizeof(buf) ? sizeof(buf) : len; - if ((n=fread(buf, 1, nn, fs)) < 0) { - _zip_error_set(error, ZIP_ER_READ, errno); - return -1; - } - else if (n == 0) { - _zip_error_set(error, ZIP_ER_EOF, 0); - return -1; - } + if ((n=fread(buf, 1, nn, fs)) == 0) { + if (ferror(fs)) { + _zip_error_set(error, ZIP_ER_READ, errno); + return -1; + } + else { + _zip_error_set(error, ZIP_ER_EOF, 0); + return -1; + } + } if (fwrite(buf, 1, n, ft) != (size_t)n) { _zip_error_set(error, ZIP_ER_WRITE, errno); @@ -487,7 +500,7 @@ copy_source(struct zip *za, struct zip_source *src, FILE *ft) ret = 0; while ((n=zip_source_read(src, buf, sizeof(buf))) > 0) { - if (fwrite(buf, 1, n, ft) != (size_t)n) { + if (fwrite(buf, 1, (size_t)n, ft) != (size_t)n) { _zip_error_set(&za->error, ZIP_ER_WRITE, errno); ret = -1; break; @@ -508,29 +521,32 @@ copy_source(struct zip *za, struct zip_source *src, FILE *ft) static int -write_cdir(struct zip *za, struct zip_cdir *cd, FILE *out) +write_cdir(struct zip *za, const struct zip_filelist *filelist, zip_uint64_t survivors, FILE *out) { - off_t offset; + off_t cd_start, end; + zip_int64_t size; uLong crc; char buf[TORRENT_CRC_LEN+1]; - if (_zip_cdir_write(cd, out, &za->error) < 0) + cd_start = ftello(out); + + if ((size=_zip_cdir_write(za, filelist, survivors, out)) < 0) return -1; + end = ftello(out); + if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0) == 0) return 0; /* fix up torrentzip comment */ - offset = ftello(out); - - if (_zip_filerange_crc(out, cd->offset, cd->size, &crc, &za->error) < 0) + if (_zip_filerange_crc(out, cd_start, size, &crc, &za->error) < 0) return -1; snprintf(buf, sizeof(buf), "%08lX", (long)crc); - if (fseeko(out, offset-TORRENT_CRC_LEN, SEEK_SET) < 0) { + if (fseeko(out, end-TORRENT_CRC_LEN, SEEK_SET) < 0) { _zip_error_set(&za->error, ZIP_ER_SEEK, errno); return -1; } @@ -545,47 +561,22 @@ write_cdir(struct zip *za, struct zip_cdir *cd, FILE *out) -static int -_zip_cdir_set_comment(struct zip_cdir *dest, struct zip *src) -{ - if (src->ch_comment_len != -1) { - dest->comment = _zip_memdup(src->ch_comment, - src->ch_comment_len, &src->error); - if (dest->comment == NULL) - return -1; - dest->comment_len = src->ch_comment_len; - } else { - if (src->cdir && src->cdir->comment) { - dest->comment = _zip_memdup(src->cdir->comment, - src->cdir->comment_len, &src->error); - if (dest->comment == NULL) - return -1; - dest->comment_len = src->cdir->comment_len; - } - } - - return 0; -} - - - int -_zip_changed(struct zip *za, int *survivorsp) +_zip_changed(const struct zip *za, zip_uint64_t *survivorsp) { - int changed, i, survivors; + int changed; + zip_uint64_t i, survivors; - changed = survivors = 0; + changed = 0; + survivors = 0; - if (za->ch_comment_len != -1 - || za->ch_flags != za->flags) + if (za->comment_changed || za->ch_flags != za->flags) changed = 1; for (i=0; inentry; i++) { - if ((za->entry[i].state != ZIP_ST_UNCHANGED) - || (za->entry[i].ch_extra_len != -1) - || (za->entry[i].ch_comment_len != -1)) + if (za->entry[i].deleted || za->entry[i].source || (za->entry[i].changes && za->entry[i].changes->changed != 0)) changed = 1; - if (za->entry[i].state != ZIP_ST_DELETED) + if (!za->entry[i].deleted) survivors++; } @@ -603,14 +594,21 @@ _zip_create_temp_output(struct zip *za, FILE **outp) char *temp; int tfd; FILE *tfp; - int len = strlen(za->zn) + 8; - - if ((temp=(char *)malloc(len)) == NULL) { - _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return NULL; + + if (za->tempdir) { + if ((temp=(char *)malloc(strlen(za->tempdir)+13)) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return NULL; + } + sprintf(temp, "%s/.zip.XXXXXX", za->tempdir); + } + else { + if ((temp=(char *)malloc(strlen(za->zn)+8)) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return NULL; + } + sprintf(temp, "%s.XXXXXX", za->zn); } - - snprintf(temp, len, "%s.XXXXXX", za->zn); if ((tfd=mkstemp(temp)) == -1) { _zip_error_set(&za->error, ZIP_ER_TMPOPEN, errno); @@ -621,7 +619,7 @@ _zip_create_temp_output(struct zip *za, FILE **outp) if ((tfp=fdopen(tfd, "r+b")) == NULL) { _zip_error_set(&za->error, ZIP_ER_TMPOPEN, errno); close(tfd); - remove(temp); + (void)remove(temp); free(temp); return NULL; } @@ -630,7 +628,7 @@ _zip_create_temp_output(struct zip *za, FILE **outp) According to Pierre Joye, Windows in some environments per default creates text files, so force binary mode. */ - _setmode(_fileno(tfp), _O_BINARY ); + _setmode(_fileno(tfp), _O_BINARY ); #endif *outp = tfp; @@ -642,6 +640,13 @@ _zip_create_temp_output(struct zip *za, FILE **outp) static int _zip_torrentzip_cmp(const void *a, const void *b) { - return strcasecmp(((const struct filelist *)a)->name, - ((const struct filelist *)b)->name); + const char *aname = ((const struct zip_filelist *)a)->name; + const char *bname = ((const struct zip_filelist *)b)->name; + + if (aname == NULL) + return (bname != NULL) * -1; + else if (bname == NULL) + return 1; + + return strcasecmp(aname, bname); } diff --git a/ext/zip/lib/zip_delete.c b/ext/zip/lib/zip_delete.c index 131d444124c4b..cb769367cc6f6 100644 --- a/ext/zip/lib/zip_delete.c +++ b/ext/zip/lib/zip_delete.c @@ -37,7 +37,7 @@ -ZIP_EXTERN(int) +ZIP_EXTERN int zip_delete(struct zip *za, zip_uint64_t idx) { if (idx >= za->nentry) { @@ -55,7 +55,7 @@ zip_delete(struct zip *za, zip_uint64_t idx) if (_zip_unchange(za, idx, 1) != 0) return -1; - za->entry[idx].state = ZIP_ST_DELETED; + za->entry[idx].deleted = 1; return 0; } diff --git a/ext/zip/lib/zip_entry_new.c b/ext/zip/lib/zip_dir_add.c similarity index 61% rename from ext/zip/lib/zip_entry_new.c rename to ext/zip/lib/zip_dir_add.c index ad5d59975a927..0a74bd608764e 100644 --- a/ext/zip/lib/zip_entry_new.c +++ b/ext/zip/lib/zip_dir_add.c @@ -1,6 +1,6 @@ /* - zip_entry_new.c -- create and init struct zip_entry - Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner + zip_dir_add.c -- add directory + Copyright (C) 1999-2012 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -34,48 +34,55 @@ #include +#include #include "zipint.h" -struct zip_entry * -_zip_entry_new(struct zip *za) +/* NOTE: Signed due to -1 on error. See zip_add.c for more details. */ + +ZIP_EXTERN zip_int64_t +zip_dir_add(struct zip *za, const char *name, zip_flags_t flags) { - struct zip_entry *ze; - if (!za) { - ze = (struct zip_entry *)malloc(sizeof(struct zip_entry)); - if (!ze) { - return NULL; - } + size_t len; + zip_int64_t ret; + char *s; + struct zip_source *source; + + if (ZIP_IS_RDONLY(za)) { + _zip_error_set(&za->error, ZIP_ER_RDONLY, 0); + return -1; } - else { - if (za->nentry+1 >= za->nentry_alloc) { - struct zip_entry *rentries; - za->nentry_alloc += 16; - rentries = (struct zip_entry *)realloc(za->entry, - sizeof(struct zip_entry) - * za->nentry_alloc); - if (!rentries) { - _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return NULL; - } - za->entry = rentries; - } - ze = za->entry+za->nentry; + + if (name == NULL) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; } - ze->state = ZIP_ST_UNCHANGED; + s = NULL; + len = strlen(name); - ze->ch_filename = NULL; - ze->ch_extra = NULL; - ze->ch_extra_len = -1; - ze->ch_comment = NULL; - ze->ch_comment_len = -1; - ze->source = NULL; + if (name[len-1] != '/') { + if ((s=(char *)malloc(len+2)) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return -1; + } + strcpy(s, name); + s[len] = '/'; + s[len+1] = '\0'; + } + + if ((source=zip_source_buffer(za, NULL, 0, 0)) == NULL) { + free(s); + return -1; + } + + ret = _zip_file_replace(za, ZIP_UINT64_MAX, s ? s : name, source, flags); - if (za) - za->nentry++; + free(s); + if (ret < 0) + zip_source_free(source); - return ze; + return ret; } diff --git a/ext/zip/lib/zip_dirent.c b/ext/zip/lib/zip_dirent.c index b9dac5c989e32..f4f2deb6fc5b9 100644 --- a/ext/zip/lib/zip_dirent.c +++ b/ext/zip/lib/zip_dirent.c @@ -1,6 +1,6 @@ /* zip_dirent.c -- read directory entry (local or central), clean dirent - Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2013 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -42,48 +42,54 @@ #include "zipint.h" -static time_t _zip_d2u_time(int, int); -static char *_zip_readfpstr(FILE *, unsigned int, int, struct zip_error *); -static char *_zip_readstr(unsigned char **, int, int, struct zip_error *); -static void _zip_write2(unsigned short, FILE *); -static void _zip_write4(unsigned int, FILE *); +static time_t _zip_d2u_time(zip_uint16_t, zip_uint16_t); +static struct zip_string *_zip_read_string(const unsigned char **, FILE *, zip_uint16_t, int, struct zip_error *); +static struct zip_string *_zip_dirent_process_ef_utf_8(const struct zip_dirent *, zip_uint16_t, struct zip_string *); +static struct zip_extra_field *_zip_ef_utf8(zip_uint16_t, struct zip_string *, struct zip_error *); void _zip_cdir_free(struct zip_cdir *cd) { - int i; + zip_uint64_t i; if (!cd) return; for (i=0; inentry; i++) - _zip_dirent_finalize(cd->entry+i); - free(cd->comment); + _zip_entry_finalize(cd->entry+i); free(cd->entry); + _zip_string_free(cd->comment); free(cd); } int -_zip_cdir_grow(struct zip_cdir *cd, int nentry, struct zip_error *error) +_zip_cdir_grow(struct zip_cdir *cd, zip_uint64_t nentry, struct zip_error *error) { - struct zip_dirent *entry; + struct zip_entry *entry; + zip_uint64_t i; - if (nentry < cd->nentry) { + if (nentry < cd->nentry_alloc) { _zip_error_set(error, ZIP_ER_INTERNAL, 0); return -1; } - if ((entry=((struct zip_dirent *) + if (nentry == cd->nentry_alloc) + return 0; + + if ((entry=((struct zip_entry *) realloc(cd->entry, sizeof(*(cd->entry))*nentry))) == NULL) { _zip_error_set(error, ZIP_ER_MEMORY, 0); return -1; } + + for (i=cd->nentry_alloc; inentry = nentry; + cd->nentry_alloc = nentry; cd->entry = entry; return 0; @@ -92,64 +98,132 @@ _zip_cdir_grow(struct zip_cdir *cd, int nentry, struct zip_error *error) struct zip_cdir * -_zip_cdir_new(int nentry, struct zip_error *error) +_zip_cdir_new(zip_uint64_t nentry, struct zip_error *error) { struct zip_cdir *cd; + zip_uint64_t i; if ((cd=(struct zip_cdir *)malloc(sizeof(*cd))) == NULL) { _zip_error_set(error, ZIP_ER_MEMORY, 0); return NULL; } - if ((cd->entry=(struct zip_dirent *)malloc(sizeof(*(cd->entry))*nentry)) - == NULL) { + if (nentry == 0) + cd->entry = NULL; + else if ((cd->entry=(struct zip_entry *)malloc(sizeof(*(cd->entry))*nentry)) == NULL) { _zip_error_set(error, ZIP_ER_MEMORY, 0); free(cd); return NULL; } - /* entries must be initialized by caller */ + for (i=0; ientry+i); - cd->nentry = nentry; + cd->nentry = cd->nentry_alloc = nentry; cd->size = cd->offset = 0; cd->comment = NULL; - cd->comment_len = 0; return cd; } -int -_zip_cdir_write(struct zip_cdir *cd, FILE *fp, struct zip_error *error) +zip_int64_t +_zip_cdir_write(struct zip *za, const struct zip_filelist *filelist, zip_uint64_t survivors, FILE *fp) { - int i; + off_t off; + zip_uint64_t offset, size; + struct zip_string *comment; + zip_uint64_t i; + int is_zip64; + int ret; + + if ((off=ftello(fp)) < 0) { + _zip_error_set(&za->error, ZIP_ER_READ, errno); + return -1; + } + offset = (zip_uint64_t)off; - cd->offset = ftello(fp); + is_zip64 = 0; - for (i=0; inentry; i++) { - if (_zip_dirent_write(cd->entry+i, fp, 0, error) != 0) + for (i=0; ientry+filelist[i].idx; + + if ((ret=_zip_dirent_write(entry->changes ? entry->changes : entry->orig, fp, ZIP_FL_CENTRAL, &za->error)) < 0) return -1; + if (ret) + is_zip64 = 1; + } + + if ((off=ftello(fp)) < 0) { + _zip_error_set(&za->error, ZIP_ER_READ, errno); + return -1; + } + size = (zip_uint64_t)off - offset; + + if (offset > ZIP_UINT32_MAX || survivors > ZIP_UINT16_MAX) + is_zip64 = 1; + + if (is_zip64) { + fwrite(EOCD64_MAGIC, 1, 4, fp); + _zip_write8(EOCD64LEN-12, fp); + _zip_write2(45, fp); + _zip_write2(45, fp); + _zip_write4(0, fp); + _zip_write4(0, fp); + _zip_write8(survivors, fp); + _zip_write8(survivors, fp); + _zip_write8(size, fp); + _zip_write8(offset, fp); + + fwrite(EOCD64LOC_MAGIC, 1, 4, fp); + _zip_write4(0, fp); + _zip_write8(offset+size, fp); + _zip_write4(1, fp); + } - cd->size = ftello(fp) - cd->offset; - /* clearerr(fp); */ fwrite(EOCD_MAGIC, 1, 4, fp); _zip_write4(0, fp); - _zip_write2((unsigned short)cd->nentry, fp); - _zip_write2((unsigned short)cd->nentry, fp); - _zip_write4(cd->size, fp); - _zip_write4(cd->offset, fp); - _zip_write2(cd->comment_len, fp); - fwrite(cd->comment, 1, cd->comment_len, fp); + _zip_write2(survivors >= ZIP_UINT16_MAX ? ZIP_UINT16_MAX : (zip_uint16_t)survivors, fp); + _zip_write2(survivors >= ZIP_UINT16_MAX ? ZIP_UINT16_MAX : (zip_uint16_t)survivors, fp); + _zip_write4(size >= ZIP_UINT32_MAX ? ZIP_UINT32_MAX : (zip_uint32_t)size, fp); + _zip_write4(offset >= ZIP_UINT32_MAX ? ZIP_UINT32_MAX : (zip_uint32_t)offset, fp); + + comment = za->comment_changed ? za->comment_changes : za->comment_orig; + + _zip_write2(comment ? comment->length : 0, fp); + if (comment) + fwrite(comment->raw, 1, comment->length, fp); if (ferror(fp)) { - _zip_error_set(error, ZIP_ER_WRITE, errno); + _zip_error_set(&za->error, ZIP_ER_WRITE, errno); return -1; } - return 0; + return (zip_int64_t)size; +} + + + +struct zip_dirent * +_zip_dirent_clone(const struct zip_dirent *sde) +{ + struct zip_dirent *tde; + + if ((tde=(struct zip_dirent *)malloc(sizeof(*tde))) == NULL) + return NULL; + + if (sde) + memcpy(tde, sde, sizeof(*sde)); + else + _zip_dirent_init(tde); + + tde->changed = 0; + tde->cloned = 1; + + return tde; } @@ -157,18 +231,24 @@ _zip_cdir_write(struct zip_cdir *cd, FILE *fp, struct zip_error *error) void _zip_dirent_finalize(struct zip_dirent *zde) { - if (zde->filename_len > 0) { - free(zde->filename); - } - zde->filename = NULL; - if (zde->extrafield_len > 0) { - free(zde->extrafield); - } - zde->extrafield = NULL; - if (zde->comment_len > 0) { - free(zde->comment); - } - zde->comment = NULL; + if (!zde->cloned || zde->changed & ZIP_DIRENT_FILENAME) + _zip_string_free(zde->filename); + if (!zde->cloned || zde->changed & ZIP_DIRENT_EXTRA_FIELD) + _zip_ef_free(zde->extra_fields); + if (!zde->cloned || zde->changed & ZIP_DIRENT_COMMENT) + _zip_string_free(zde->comment); +} + + + +void +_zip_dirent_free(struct zip_dirent *zde) +{ + if (zde == NULL) + return; + + _zip_dirent_finalize(zde); + free(zde); } @@ -176,20 +256,21 @@ _zip_dirent_finalize(struct zip_dirent *zde) void _zip_dirent_init(struct zip_dirent *de) { - de->version_madeby = 0; + de->changed = 0; + de->local_extra_fields_read = 0; + de->cloned = 0; + + de->version_madeby = 20; de->version_needed = 20; /* 2.0 */ de->bitflags = 0; - de->comp_method = 0; + de->comp_method = ZIP_CM_DEFAULT; de->last_mod = 0; de->crc = 0; de->comp_size = 0; de->uncomp_size = 0; de->filename = NULL; - de->filename_len = 0; - de->extrafield = NULL; - de->extrafield_len = 0; + de->extra_fields = NULL; de->comment = NULL; - de->comment_len = 0; de->disk_number = 0; de->int_attrib = 0; de->ext_attrib = 0; @@ -198,6 +279,32 @@ _zip_dirent_init(struct zip_dirent *de) +int +_zip_dirent_needs_zip64(const struct zip_dirent *de, zip_flags_t flags) +{ + if (de->uncomp_size >= ZIP_UINT32_MAX || de->comp_size >= ZIP_UINT32_MAX + || ((flags & ZIP_FL_CENTRAL) && de->offset >= ZIP_UINT32_MAX)) + return 1; + + return 0; +} + + + +struct zip_dirent * +_zip_dirent_new(void) +{ + struct zip_dirent *de; + + if ((de=(struct zip_dirent *)malloc(sizeof(*de))) == NULL) + return NULL; + + _zip_dirent_init(de); + return de; +} + + + /* _zip_dirent_read(zde, fp, bufp, left, localp, error): Fills the zip directory entry zde. @@ -218,13 +325,14 @@ _zip_dirent_init(struct zip_dirent *de) int _zip_dirent_read(struct zip_dirent *zde, FILE *fp, - unsigned char **bufp, zip_uint32_t *leftp, int local, + const unsigned char **bufp, zip_uint64_t *leftp, int local, struct zip_error *error) { unsigned char buf[CDENTRYSIZE]; - unsigned char *cur; - unsigned short dostime, dosdate; + const unsigned char *cur; + zip_uint16_t dostime, dosdate; zip_uint32_t size; + zip_uint16_t filename_len, comment_len, ef_len; if (local) size = LENTRYSIZE; @@ -255,9 +363,10 @@ _zip_dirent_read(struct zip_dirent *zde, FILE *fp, } cur += 4; - + /* convert buffercontents to zip_dirent */ - + + _zip_dirent_init(zde); if (!local) zde->version_madeby = _zip_read2(&cur); else @@ -275,17 +384,17 @@ _zip_dirent_read(struct zip_dirent *zde, FILE *fp, zde->comp_size = _zip_read4(&cur); zde->uncomp_size = _zip_read4(&cur); - zde->filename_len = _zip_read2(&cur); - zde->extrafield_len = _zip_read2(&cur); + filename_len = _zip_read2(&cur); + ef_len = _zip_read2(&cur); if (local) { - zde->comment_len = 0; + comment_len = 0; zde->disk_number = 0; zde->int_attrib = 0; zde->ext_attrib = 0; zde->offset = 0; } else { - zde->comment_len = _zip_read2(&cur); + comment_len = _zip_read2(&cur); zde->disk_number = _zip_read2(&cur); zde->int_attrib = _zip_read2(&cur); zde->ext_attrib = _zip_read4(&cur); @@ -293,56 +402,102 @@ _zip_dirent_read(struct zip_dirent *zde, FILE *fp, } zde->filename = NULL; - zde->extrafield = NULL; + zde->extra_fields = NULL; zde->comment = NULL; - size += zde->filename_len+zde->extrafield_len+zde->comment_len; + size += filename_len+ef_len+comment_len; if (leftp && (*leftp < size)) { - _zip_error_set(error, ZIP_ER_NOZIP, 0); + _zip_error_set(error, ZIP_ER_INCONS, 0); return -1; } - if (bufp) { - if (zde->filename_len) { - zde->filename = _zip_readstr(&cur, zde->filename_len, 1, error); - if (!zde->filename) - return -1; - } + if (filename_len) { + zde->filename = _zip_read_string(bufp ? &cur : NULL, fp, filename_len, 1, error); + if (!zde->filename) + return -1; - if (zde->extrafield_len) { - zde->extrafield = _zip_readstr(&cur, zde->extrafield_len, 0, - error); - if (!zde->extrafield) + if (zde->bitflags & ZIP_GPBF_ENCODING_UTF_8) { + if (_zip_guess_encoding(zde->filename, ZIP_ENCODING_UTF8_KNOWN) == ZIP_ENCODING_ERROR) { + _zip_error_set(error, ZIP_ER_INCONS, 0); return -1; + } } + } - if (zde->comment_len) { - zde->comment = _zip_readstr(&cur, zde->comment_len, 0, error); - if (!zde->comment) - return -1; + if (ef_len) { + zip_uint8_t *ef = _zip_read_data(bufp ? &cur : NULL, fp, ef_len, 0, error); + + if (ef == NULL) + return -1; + if ((zde->extra_fields=_zip_ef_parse(ef, ef_len, local ? ZIP_EF_LOCAL : ZIP_EF_CENTRAL, error)) == NULL) { + free(ef); + return -1; } + free(ef); + if (local) + zde->local_extra_fields_read = 1; } - else { - if (zde->filename_len) { - zde->filename = _zip_readfpstr(fp, zde->filename_len, 1, error); - if (!zde->filename) - return -1; - } - if (zde->extrafield_len) { - zde->extrafield = _zip_readfpstr(fp, zde->extrafield_len, 0, - error); - if (!zde->extrafield) + if (comment_len) { + zde->comment = _zip_read_string(bufp ? &cur : NULL, fp, comment_len, 0, error); + if (!zde->comment) + return -1; + + if (zde->bitflags & ZIP_GPBF_ENCODING_UTF_8) { + if (_zip_guess_encoding(zde->comment, ZIP_ENCODING_UTF8_KNOWN) == ZIP_ENCODING_ERROR) { + _zip_error_set(error, ZIP_ER_INCONS, 0); return -1; + } } + } - if (zde->comment_len) { - zde->comment = _zip_readfpstr(fp, zde->comment_len, 0, error); - if (!zde->comment) - return -1; + zde->filename = _zip_dirent_process_ef_utf_8(zde, ZIP_EF_UTF_8_NAME, zde->filename); + zde->comment = _zip_dirent_process_ef_utf_8(zde, ZIP_EF_UTF_8_COMMENT, zde->comment); + + /* Zip64 */ + + if (zde->uncomp_size == ZIP_UINT32_MAX || zde->comp_size == ZIP_UINT32_MAX || zde->offset == ZIP_UINT32_MAX) { + zip_uint16_t got_len, needed_len; + const zip_uint8_t *ef = _zip_ef_get_by_id(zde->extra_fields, &got_len, ZIP_EF_ZIP64, 0, local ? ZIP_EF_LOCAL : ZIP_EF_CENTRAL, error); + /* XXX: if got_len == 0 && !ZIP64_EOCD: no error, 0xffffffff is valid value */ + if (ef == NULL) + return -1; + + + if (local) + needed_len = 16; + else + needed_len = ((zde->uncomp_size == ZIP_UINT32_MAX) + (zde->comp_size == ZIP_UINT32_MAX) + (zde->offset == ZIP_UINT32_MAX)) * 8 + + (zde->disk_number == ZIP_UINT16_MAX) * 4; + + if (got_len != needed_len) { + _zip_error_set(error, ZIP_ER_INCONS, 0); + return -1; } + + if (zde->uncomp_size == ZIP_UINT32_MAX) + zde->uncomp_size = _zip_read8(&ef); + else if (local) + ef += 8; + if (zde->comp_size == ZIP_UINT32_MAX) + zde->comp_size = _zip_read8(&ef); + if (!local) { + if (zde->offset == ZIP_UINT32_MAX) + zde->offset = _zip_read8(&ef); + if (zde->disk_number == ZIP_UINT16_MAX) + zde->disk_number = _zip_read4(&ef); + } + } + + if (!local) { + if (zde->offset > ZIP_OFF_MAX) { + _zip_error_set(error, ZIP_ER_SEEK, EFBIG); + return -1; + } } + + zde->extra_fields = _zip_ef_remove_internal(zde->extra_fields); if (bufp) *bufp = cur; @@ -354,6 +509,65 @@ _zip_dirent_read(struct zip_dirent *zde, FILE *fp, +static struct zip_string * +_zip_dirent_process_ef_utf_8(const struct zip_dirent *de, zip_uint16_t id, struct zip_string *str) +{ + zip_uint16_t ef_len; + zip_uint32_t ef_crc; + + const zip_uint8_t *ef = _zip_ef_get_by_id(de->extra_fields, &ef_len, id, 0, ZIP_EF_BOTH, NULL); + + if (ef == NULL || ef_len < 5 || ef[0] != 1) + return str; + + ef++; + ef_crc = _zip_read4(&ef); + + if (_zip_string_crc32(str) == ef_crc) { + struct zip_string *ef_str = _zip_string_new(ef, ef_len-5, ZIP_ENCODING_UTF8_KNOWN, NULL); + + if (ef_str != NULL) { + _zip_string_free(str); + str = ef_str; + } + } + + return str; +} + + + +zip_int32_t +_zip_dirent_size(FILE *f, zip_uint16_t flags, struct zip_error *error) +{ + zip_int32_t size; + int local = (flags & ZIP_EF_LOCAL); + int i; + unsigned char b[6]; + const unsigned char *p; + + size = local ? LENTRYSIZE : CDENTRYSIZE; + + if (fseek(f, local ? 26 : 28, SEEK_CUR) < 0) { + _zip_error_set(error, ZIP_ER_SEEK, errno); + return -1; + } + + if (fread(b, (local ? 4 : 6), 1, f) != 1) { + _zip_error_set(error, ZIP_ER_READ, errno); + return -1; + } + + p = b; + for (i=0; i<(local ? 2 : 3); i++) { + size += _zip_read2(&p); + } + + return size; +} + + + /* _zip_dirent_torrent_normalize(de); Set values suitable for torrentzip. */ @@ -399,84 +613,157 @@ _zip_dirent_torrent_normalize(struct zip_dirent *de) de->disk_number = 0; de->int_attrib = 0; de->ext_attrib = 0; - de->offset = 0; - free(de->extrafield); - de->extrafield = NULL; - de->extrafield_len = 0; - free(de->comment); + _zip_ef_free(de->extra_fields); + de->extra_fields = NULL; + _zip_string_free(de->comment); de->comment = NULL; - de->comment_len = 0; } -/* _zip_dirent_write(zde, fp, localp, error): +/* _zip_dirent_write(zde, fp, flags, error): Writes zip directory entry zde to file fp. - If localp != 0, it writes a local header instead of a central - directory entry. + If flags & ZIP_EF_LOCAL, it writes a local header instead of a central + directory entry. If flags & ZIP_EF_FORCE_ZIP64, a ZIP64 extra field is written, even if not needed. - Returns 0 if successful. On error, error is filled in and -1 is + Returns 0 if successful, 1 if successful and wrote ZIP64 extra field. On error, error is filled in and -1 is returned. */ int -_zip_dirent_write(struct zip_dirent *zde, FILE *fp, int localp, - struct zip_error *error) +_zip_dirent_write(struct zip_dirent *de, FILE *fp, zip_flags_t flags, struct zip_error *error) { unsigned short dostime, dosdate; + enum zip_encoding_type com_enc, name_enc; + struct zip_extra_field *ef; + zip_uint8_t ef_zip64[24], *ef_zip64_p; + int is_zip64; + int is_really_zip64; + + ef = NULL; - fwrite(localp ? LOCAL_MAGIC : CENTRAL_MAGIC, 1, 4, fp); + is_zip64 = 0; - if (!localp) - _zip_write2(zde->version_madeby, fp); - _zip_write2(zde->version_needed, fp); - _zip_write2(zde->bitflags, fp); - _zip_write2(zde->comp_method, fp); + fwrite((flags & ZIP_FL_LOCAL) ? LOCAL_MAGIC : CENTRAL_MAGIC, 1, 4, fp); - _zip_u2d_time(zde->last_mod, &dostime, &dosdate); + name_enc = _zip_guess_encoding(de->filename, ZIP_ENCODING_UNKNOWN); + com_enc = _zip_guess_encoding(de->comment, ZIP_ENCODING_UNKNOWN); + + if ((name_enc == ZIP_ENCODING_UTF8_KNOWN && com_enc == ZIP_ENCODING_ASCII) || + (name_enc == ZIP_ENCODING_ASCII && com_enc == ZIP_ENCODING_UTF8_KNOWN) || + (name_enc == ZIP_ENCODING_UTF8_KNOWN && com_enc == ZIP_ENCODING_UTF8_KNOWN)) + de->bitflags |= ZIP_GPBF_ENCODING_UTF_8; + else { + de->bitflags &= ~ZIP_GPBF_ENCODING_UTF_8; + if (name_enc == ZIP_ENCODING_UTF8_KNOWN) { + ef = _zip_ef_utf8(ZIP_EF_UTF_8_NAME, de->filename, error); + if (ef == NULL) + return -1; + } + if ((flags & ZIP_FL_LOCAL) == 0 && com_enc == ZIP_ENCODING_UTF8_KNOWN){ + struct zip_extra_field *ef2 = _zip_ef_utf8(ZIP_EF_UTF_8_COMMENT, de->comment, error); + if (ef2 == NULL) { + _zip_ef_free(ef); + return -1; + } + ef2->next = ef; + ef = ef2; + } + } + + ef_zip64_p = ef_zip64; + if (flags & ZIP_FL_LOCAL) { + if ((flags & ZIP_FL_FORCE_ZIP64) || de->comp_size > ZIP_UINT32_MAX || de->uncomp_size > ZIP_UINT32_MAX) { + _zip_poke8(de->comp_size, &ef_zip64_p); + _zip_poke8(de->uncomp_size, &ef_zip64_p); + } + } + else { + if ((flags & ZIP_FL_FORCE_ZIP64) || de->comp_size > ZIP_UINT32_MAX || de->uncomp_size > ZIP_UINT32_MAX || de->offset > ZIP_UINT32_MAX) { + if (de->comp_size >= ZIP_UINT32_MAX) + _zip_poke8(de->comp_size, &ef_zip64_p); + if (de->uncomp_size >= ZIP_UINT32_MAX) + _zip_poke8(de->uncomp_size, &ef_zip64_p); + if (de->offset >= ZIP_UINT32_MAX) + _zip_poke8(de->offset, &ef_zip64_p); + } + } + + if (ef_zip64_p != ef_zip64) { + struct zip_extra_field *ef64 = _zip_ef_new(ZIP_EF_ZIP64, (zip_uint16_t)(ef_zip64_p-ef_zip64), ef_zip64, ZIP_EF_BOTH); + ef64->next = ef; + ef = ef64; + is_zip64 = 1; + } + + if ((flags & (ZIP_FL_LOCAL|ZIP_FL_FORCE_ZIP64)) == (ZIP_FL_LOCAL|ZIP_FL_FORCE_ZIP64)) + is_really_zip64 = _zip_dirent_needs_zip64(de, flags); + else + is_really_zip64 = is_zip64; + + if ((flags & ZIP_FL_LOCAL) == 0) + _zip_write2(is_really_zip64 ? 45 : de->version_madeby, fp); + _zip_write2(is_really_zip64 ? 45 : de->version_needed, fp); + _zip_write2(de->bitflags&0xfff9, fp); /* clear compression method specific flags */ + _zip_write2((zip_uint16_t)de->comp_method, fp); /* XXX: can it be ZIP_CM_DEFAULT? */ + + _zip_u2d_time(de->last_mod, &dostime, &dosdate); _zip_write2(dostime, fp); _zip_write2(dosdate, fp); + + _zip_write4(de->crc, fp); + if (de->comp_size < ZIP_UINT32_MAX) + _zip_write4((zip_uint32_t)de->comp_size, fp); + else + _zip_write4(ZIP_UINT32_MAX, fp); + if (de->uncomp_size < ZIP_UINT32_MAX) + _zip_write4((zip_uint32_t)de->uncomp_size, fp); + else + _zip_write4(ZIP_UINT32_MAX, fp); + + _zip_write2(_zip_string_length(de->filename), fp); + _zip_write2(_zip_ef_size(de->extra_fields, flags) + _zip_ef_size(ef, ZIP_EF_BOTH), fp); - _zip_write4(zde->crc, fp); - _zip_write4(zde->comp_size, fp); - _zip_write4(zde->uncomp_size, fp); - - _zip_write2(zde->filename_len, fp); - _zip_write2(zde->extrafield_len, fp); - - if (!localp) { - _zip_write2(zde->comment_len, fp); - _zip_write2(zde->disk_number, fp); - _zip_write2(zde->int_attrib, fp); - _zip_write4(zde->ext_attrib, fp); - _zip_write4(zde->offset, fp); + if ((flags & ZIP_FL_LOCAL) == 0) { + _zip_write2(_zip_string_length(de->comment), fp); + _zip_write2((zip_uint16_t)de->disk_number, fp); + _zip_write2(de->int_attrib, fp); + _zip_write4(de->ext_attrib, fp); + if (de->offset < ZIP_UINT32_MAX) + _zip_write4((zip_uint32_t)de->offset, fp); + else + _zip_write4(ZIP_UINT32_MAX, fp); } - if (zde->filename_len) - fwrite(zde->filename, 1, zde->filename_len, fp); + if (de->filename) + _zip_string_write(de->filename, fp); - if (zde->extrafield_len) - fwrite(zde->extrafield, 1, zde->extrafield_len, fp); + if (ef) + _zip_ef_write(ef, ZIP_EF_BOTH, fp); + if (de->extra_fields) + _zip_ef_write(de->extra_fields, flags, fp); - if (!localp) { - if (zde->comment_len) - fwrite(zde->comment, 1, zde->comment_len, fp); + if ((flags & ZIP_FL_LOCAL) == 0) { + if (de->comment) + _zip_string_write(de->comment, fp); } + _zip_ef_free(ef); + if (ferror(fp)) { _zip_error_set(error, ZIP_ER_WRITE, errno); return -1; } - return 0; + return is_zip64; } static time_t -_zip_d2u_time(int dtime, int ddate) +_zip_d2u_time(zip_uint16_t dtime, zip_uint16_t ddate) { struct tm tm; @@ -498,12 +785,72 @@ _zip_d2u_time(int dtime, int ddate) -unsigned short -_zip_read2(unsigned char **a) +static struct zip_extra_field * +_zip_ef_utf8(zip_uint16_t id, struct zip_string *str, struct zip_error *error) { - unsigned short ret; + const zip_uint8_t *raw; + zip_uint8_t *data, *p; + zip_uint32_t len; + struct zip_extra_field *ef; + + raw = _zip_string_get(str, &len, ZIP_FL_ENC_RAW, NULL); + + if (len+5 > ZIP_UINT16_MAX) { + /* XXX: error */ + } + + if ((data=(zip_uint8_t *)malloc(len+5)) == NULL) { + _zip_error_set(error, ZIP_ER_MEMORY, 0); + return NULL; + } + + p = data; + *(p++) = 1; + _zip_poke4(_zip_string_crc32(str), &p); + memcpy(p, raw, len); + p += len; + + ef = _zip_ef_new(id, (zip_uint16_t)(p-data), data, ZIP_EF_BOTH); + free(data); + return ef; +} + + + +struct zip_dirent * +_zip_get_dirent(struct zip *za, zip_uint64_t idx, zip_flags_t flags, struct zip_error *error) +{ + if (error == NULL) + error = &za->error; + + if (idx >= za->nentry) { + _zip_error_set(error, ZIP_ER_INVAL, 0); + return NULL; + } + + if ((flags & ZIP_FL_UNCHANGED) || za->entry[idx].changes == NULL) { + if (za->entry[idx].orig == NULL) { + _zip_error_set(error, ZIP_ER_INVAL, 0); + return NULL; + } + if (za->entry[idx].deleted && (flags & ZIP_FL_UNCHANGED) == 0) { + _zip_error_set(error, ZIP_ER_DELETED, 0); + return NULL; + } + return za->entry[idx].orig; + } + else + return za->entry[idx].changes; +} + + - ret = (*a)[0]+((*a)[1]<<8); +zip_uint16_t +_zip_read2(const zip_uint8_t **a) +{ + zip_uint16_t ret; + + ret = (zip_uint16_t)((*a)[0]+((*a)[1]<<8)); *a += 2; return ret; @@ -511,12 +858,12 @@ _zip_read2(unsigned char **a) -unsigned int -_zip_read4(unsigned char **a) +zip_uint32_t +_zip_read4(const zip_uint8_t **a) { - unsigned int ret; + zip_uint32_t ret; - ret = ((((((*a)[3]<<8)+(*a)[2])<<8)+(*a)[1])<<8)+(*a)[0]; + ret = ((((((zip_uint32_t)(*a)[3]<<8)+(*a)[2])<<8)+(*a)[1])<<8)+(*a)[0]; *a += 4; return ret; @@ -524,65 +871,108 @@ _zip_read4(unsigned char **a) -static char * -_zip_readfpstr(FILE *fp, unsigned int len, int nulp, struct zip_error *error) +zip_uint64_t +_zip_read8(const zip_uint8_t **a) { - char *r, *o; + zip_uint64_t x, y; + + x = ((((((zip_uint64_t)(*a)[3]<<8)+(*a)[2])<<8)+(*a)[1])<<8)+(*a)[0]; + *a += 4; + y = ((((((zip_uint64_t)(*a)[3]<<8)+(*a)[2])<<8)+(*a)[1])<<8)+(*a)[0]; + *a += 4; + + return x+(y<<32); +} - r = (char *)malloc(nulp ? len+1 : len); + + +zip_uint8_t * +_zip_read_data(const zip_uint8_t **buf, FILE *fp, size_t len, int nulp, struct zip_error *error) +{ + zip_uint8_t *r; + + if (len == 0 && nulp == 0) + return NULL; + + r = (zip_uint8_t *)malloc(nulp ? len+1 : len); if (!r) { _zip_error_set(error, ZIP_ER_MEMORY, 0); return NULL; } - if (fread(r, 1, len, fp)>8)&0xff; + *((*p)++) = (i>>16)&0xff; + *((*p)++) = (i>>24)&0xff; +} + + + +void +_zip_poke8(zip_uint64_t i, zip_uint8_t **p) +{ + *((*p)++) = i&0xff; + *((*p)++) = (i>>8)&0xff; + *((*p)++) = (i>>16)&0xff; + *((*p)++) = (i>>24)&0xff; + *((*p)++) = (i>>32)&0xff; + *((*p)++) = (i>>40)&0xff; + *((*p)++) = (i>>48)&0xff; + *((*p)++) = (i>>56)&0xff; } -static void -_zip_write2(unsigned short i, FILE *fp) +void +_zip_write2(zip_uint16_t i, FILE *fp) { putc(i&0xff, fp); putc((i>>8)&0xff, fp); @@ -592,13 +982,30 @@ _zip_write2(unsigned short i, FILE *fp) -static void -_zip_write4(unsigned int i, FILE *fp) +void +_zip_write4(zip_uint32_t i, FILE *fp) +{ + putc(i&0xff, fp); + putc((i>>8)&0xff, fp); + putc((i>>16)&0xff, fp); + putc((i>>24)&0xff, fp); + + return; +} + + + +void +_zip_write8(zip_uint64_t i, FILE *fp) { putc(i&0xff, fp); putc((i>>8)&0xff, fp); putc((i>>16)&0xff, fp); putc((i>>24)&0xff, fp); + putc((i>>32)&0xff, fp); + putc((i>>40)&0xff, fp); + putc((i>>48)&0xff, fp); + putc((i>>56)&0xff, fp); return; } @@ -606,15 +1013,13 @@ _zip_write4(unsigned int i, FILE *fp) void -_zip_u2d_time(time_t time, unsigned short *dtime, unsigned short *ddate) +_zip_u2d_time(time_t time, zip_uint16_t *dtime, zip_uint16_t *ddate) { struct tm *tm; tm = localtime(&time); - *ddate = ((tm->tm_year+1900-1980)<<9) + ((tm->tm_mon+1)<<5) - + tm->tm_mday; - *dtime = ((tm->tm_hour)<<11) + ((tm->tm_min)<<5) - + ((tm->tm_sec)>>1); + *ddate = (zip_uint16_t)(((tm->tm_year+1900-1980)<<9) + ((tm->tm_mon+1)<<5) + tm->tm_mday); + *dtime = (zip_uint16_t)(((tm->tm_hour)<<11) + ((tm->tm_min)<<5) + ((tm->tm_sec)>>1)); return; } diff --git a/ext/zip/lib/zip_free.c b/ext/zip/lib/zip_discard.c similarity index 86% rename from ext/zip/lib/zip_free.c rename to ext/zip/lib/zip_discard.c index 9932c14fec9a2..37ba8c2ea64de 100644 --- a/ext/zip/lib/zip_free.c +++ b/ext/zip/lib/zip_discard.c @@ -1,6 +1,6 @@ /* - zip_free.c -- free struct zip - Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + zip_discard.c -- discard and free struct zip + Copyright (C) 1999-2012 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -39,14 +39,14 @@ -/* _zip_free: +/* zip_discard: frees the space allocated to a zipfile struct, and closes the corresponding file. */ void -_zip_free(struct zip *za) +zip_discard(struct zip *za) { - int i; + zip_uint64_t i; if (za == NULL) return; @@ -58,13 +58,12 @@ _zip_free(struct zip *za) fclose(za->zp); free(za->default_password); - _zip_cdir_free(za->cdir); - free(za->ch_comment); + _zip_string_free(za->comment_orig); + _zip_string_free(za->comment_changes); if (za->entry) { - for (i=0; inentry; i++) { - _zip_entry_free(za->entry+i); - } + for (i=0; inentry; i++) + _zip_entry_finalize(za->entry+i); free(za->entry); } diff --git a/ext/zip/lib/zip_entry_free.c b/ext/zip/lib/zip_entry.c similarity index 79% rename from ext/zip/lib/zip_entry_free.c rename to ext/zip/lib/zip_entry.c index e8a77707f0bfa..58663e8d0c88e 100644 --- a/ext/zip/lib/zip_entry_free.c +++ b/ext/zip/lib/zip_entry.c @@ -1,6 +1,6 @@ /* - zip_entry_free.c -- free struct zip_entry - Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + zip_entry.c -- struct zip_entry helper functions + Copyright (C) 1999-2012 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -33,23 +33,23 @@ -#include - #include "zipint.h" +void +_zip_entry_finalize(struct zip_entry *e) +{ + _zip_unchange_data(e); + _zip_dirent_free(e->orig); + _zip_dirent_free(e->changes); +} + void -_zip_entry_free(struct zip_entry *ze) +_zip_entry_init(struct zip_entry *e) { - free(ze->ch_filename); - ze->ch_filename = NULL; - free(ze->ch_extra); - ze->ch_extra = NULL; - ze->ch_extra_len = -1; - free(ze->ch_comment); - ze->ch_comment = NULL; - ze->ch_comment_len = -1; - - _zip_unchange_data(ze); + e->orig = NULL; + e->changes = NULL; + e->source = NULL; + e->deleted = 0; } diff --git a/ext/zip/lib/zip_error.c b/ext/zip/lib/zip_error.c index b8d907abf4d9a..4b1f27921a256 100644 --- a/ext/zip/lib/zip_error.c +++ b/ext/zip/lib/zip_error.c @@ -1,6 +1,6 @@ /* zip_error.c -- struct zip_error helper functions - Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2013 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -42,6 +42,9 @@ void _zip_error_clear(struct zip_error *err) { + if (err == NULL) + return; + err->zip_err = ZIP_ER_OK; err->sys_err = 0; } @@ -49,7 +52,7 @@ _zip_error_clear(struct zip_error *err) void -_zip_error_copy(struct zip_error *dst, struct zip_error *src) +_zip_error_copy(struct zip_error *dst, const struct zip_error *src) { dst->zip_err = src->zip_err; dst->sys_err = src->sys_err; @@ -67,7 +70,7 @@ _zip_error_fini(struct zip_error *err) void -_zip_error_get(struct zip_error *err, int *zep, int *sep) +_zip_error_get(const struct zip_error *err, int *zep, int *sep) { if (zep) *zep = err->zip_err; diff --git a/ext/zip/lib/zip_error_clear.c b/ext/zip/lib/zip_error_clear.c index 34e7dea48ebba..b4ff10391290a 100644 --- a/ext/zip/lib/zip_error_clear.c +++ b/ext/zip/lib/zip_error_clear.c @@ -37,8 +37,11 @@ -ZIP_EXTERN(void) +ZIP_EXTERN void zip_error_clear(struct zip *za) { + if (za == NULL) + return; + _zip_error_clear(&za->error); } diff --git a/ext/zip/lib/zip_error_get.c b/ext/zip/lib/zip_error_get.c index c15705e32fccd..6d1c958c17766 100644 --- a/ext/zip/lib/zip_error_get.c +++ b/ext/zip/lib/zip_error_get.c @@ -37,7 +37,7 @@ -ZIP_EXTERN(void) +ZIP_EXTERN void zip_error_get(struct zip *za, int *zep, int *sep) { _zip_error_get(&za->error, zep, sep); diff --git a/ext/zip/lib/zip_error_get_sys_type.c b/ext/zip/lib/zip_error_get_sys_type.c index 47aa93e69b927..6c6f38074040e 100644 --- a/ext/zip/lib/zip_error_get_sys_type.c +++ b/ext/zip/lib/zip_error_get_sys_type.c @@ -37,7 +37,7 @@ -ZIP_EXTERN(int) +ZIP_EXTERN int zip_error_get_sys_type(int ze) { if (ze < 0 || ze >= _zip_nerr_str) diff --git a/ext/zip/lib/zip_error_to_str.c b/ext/zip/lib/zip_error_to_str.c index bafe74335a049..11a0cd2bb0e6d 100644 --- a/ext/zip/lib/zip_error_to_str.c +++ b/ext/zip/lib/zip_error_to_str.c @@ -42,7 +42,7 @@ -ZIP_EXTERN(int) +ZIP_EXTERN int zip_error_to_str(char *buf, zip_uint64_t len, int ze, int se) { const char *zs, *ss; diff --git a/ext/zip/lib/zip_extra_field.c b/ext/zip/lib/zip_extra_field.c new file mode 100644 index 0000000000000..41fd2b1d901af --- /dev/null +++ b/ext/zip/lib/zip_extra_field.c @@ -0,0 +1,386 @@ +/* + zip_extra_field.c -- manipulate extra fields + Copyright (C) 2012-2013 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include "zipint.h" + +#include +#include +#include + + + +struct zip_extra_field * +_zip_ef_clone(const struct zip_extra_field *ef, struct zip_error *error) +{ + struct zip_extra_field *head, *prev, *def; + + head = prev = NULL; + + while (ef) { + if ((def=_zip_ef_new(ef->id, ef->size, ef->data, ef->flags)) == NULL) { + _zip_error_set(error, ZIP_ER_MEMORY, 0); + _zip_ef_free(head); + return NULL; + } + + if (head == NULL) + head = def; + if (prev) + prev->next = def; + prev = def; + + ef = ef->next; + } + + return head; +} + + +struct zip_extra_field * +_zip_ef_delete_by_id(struct zip_extra_field *ef, zip_uint16_t id, zip_uint16_t id_idx, zip_flags_t flags) +{ + struct zip_extra_field *head, *prev; + int i; + + i = 0; + head = ef; + prev = NULL; + for (; ef; ef=(prev ? prev->next : head)) { + if ((ef->flags & flags & ZIP_EF_BOTH) && ef->id == id) { + if (id_idx == ZIP_EXTRA_FIELD_ALL || i == id_idx) { + ef->flags &= ~(flags & ZIP_EF_BOTH); + if ((ef->flags & ZIP_EF_BOTH) == 0) { + if (prev) + prev->next = ef->next; + else + head = ef->next; + ef->next = NULL; + _zip_ef_free(ef); + + if (id_idx == ZIP_EXTRA_FIELD_ALL) + continue; + } + } + + i++; + if (i > id_idx) + break; + } + prev = ef; + } + + return head; +} + + + + +void +_zip_ef_free(struct zip_extra_field *ef) +{ + struct zip_extra_field *ef2; + + while (ef) { + ef2 = ef->next; + free(ef->data); + free(ef); + ef = ef2; + } +} + + + +const zip_uint8_t * +_zip_ef_get_by_id(const struct zip_extra_field *ef, zip_uint16_t *lenp, zip_uint16_t id, zip_uint16_t id_idx, zip_flags_t flags, struct zip_error *error) +{ + static const zip_uint8_t empty[1] = { '\0' }; + + int i; + + i = 0; + for (; ef; ef=ef->next) { + if (ef->id == id && (ef->flags & flags & ZIP_EF_BOTH)) { + if (i < id_idx) { + i++; + continue; + } + + if (lenp) + *lenp = ef->size; + if (ef->size > 0) + return ef->data; + else + return empty; + } + } + + _zip_error_set(error, ZIP_ER_NOENT, 0); + return NULL; +} + + + +struct zip_extra_field * +_zip_ef_merge(struct zip_extra_field *to, struct zip_extra_field *from) +{ + struct zip_extra_field *ef2, *tt, *tail; + int duplicate; + + if (to == NULL) + return from; + + for (tail=to; tail->next; tail=tail->next) + ; + + for (; from; from=ef2) { + ef2 = from->next; + + duplicate = 0; + for (tt=to; tt; tt=tt->next) { + if (tt->id == from->id && tt->size == from->size && memcmp(tt->data, from->data, tt->size) == 0) { + tt->flags |= (from->flags & ZIP_EF_BOTH); + duplicate = 1; + break; + } + } + + from->next = NULL; + if (duplicate) + _zip_ef_free(from); + else + tail = tail->next = from; + } + + return to; +} + + + +struct zip_extra_field * +_zip_ef_new(zip_uint16_t id, zip_uint16_t size, const zip_uint8_t *data, zip_flags_t flags) +{ + struct zip_extra_field *ef; + + if ((ef=(struct zip_extra_field *)malloc(sizeof(*ef))) == NULL) + return NULL; + + ef->next = NULL; + ef->flags = flags; + ef->id = id; + ef->size = size; + if (size > 0) { + if ((ef->data=(zip_uint8_t *)_zip_memdup(data, size, NULL)) == NULL) { + free(ef); + return NULL; + } + } + else + ef->data = NULL; + + return ef; +} + + + +struct zip_extra_field * +_zip_ef_parse(const zip_uint8_t *data, zip_uint16_t len, zip_flags_t flags, struct zip_error *error) +{ + struct zip_extra_field *ef, *ef2, *ef_head; + const zip_uint8_t *p; + zip_uint16_t fid, flen; + + ef_head = NULL; + for (p=data; p data+len) { + _zip_error_set(error, ZIP_ER_INCONS, 0); + _zip_ef_free(ef_head); + return NULL; + } + + fid = _zip_read2(&p); + flen = _zip_read2(&p); + + if (p+flen > data+len) { + _zip_error_set(error, ZIP_ER_INCONS, 0); + _zip_ef_free(ef_head); + return NULL; + } + + if ((ef2=_zip_ef_new(fid, flen, p, flags)) == NULL) { + _zip_error_set(error, ZIP_ER_MEMORY, 0); + _zip_ef_free(ef_head); + return NULL; + } + + if (ef_head) { + ef->next = ef2; + ef = ef2; + } + else + ef_head = ef = ef2; + } + + return ef_head; +} + + + +struct zip_extra_field * +_zip_ef_remove_internal(struct zip_extra_field *ef) +{ + struct zip_extra_field *ef_head; + struct zip_extra_field *prev, *next; + + ef_head = ef; + prev = NULL; + + while (ef) { + if (ZIP_EF_IS_INTERNAL(ef->id)) { + next = ef->next; + if (ef_head == ef) + ef_head = next; + ef->next = NULL; + _zip_ef_free(ef); + if (prev) + prev->next = next; + ef = next; + } + else { + prev = ef; + ef = ef->next; + } + } + + return ef_head; +} + + +zip_uint16_t +_zip_ef_size(const struct zip_extra_field *ef, zip_flags_t flags) +{ + zip_uint16_t size; + + size = 0; + for (; ef; ef=ef->next) { + if (ef->flags & flags & ZIP_EF_BOTH) + size += 4+ef->size; + } + + return size; +} + + + +void +_zip_ef_write(const struct zip_extra_field *ef, zip_flags_t flags, FILE *f) +{ + for (; ef; ef=ef->next) { + if (ef->flags & flags & ZIP_EF_BOTH) { + _zip_write2(ef->id, f); + _zip_write2(ef->size, f); + if (ef->size > 0) + fwrite(ef->data, ef->size, 1, f); + } + } +} + + + +int +_zip_read_local_ef(struct zip *za, zip_uint64_t idx) +{ + struct zip_entry *e; + unsigned char b[4]; + const unsigned char *p; + zip_uint16_t fname_len, ef_len; + + if (idx >= za->nentry) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + e = za->entry+idx; + + if (e->orig == NULL || e->orig->local_extra_fields_read) + return 0; + + + if (fseeko(za->zp, (off_t)(e->orig->offset + 26), SEEK_SET) < 0) { + _zip_error_set(&za->error, ZIP_ER_SEEK, errno); + return -1; + } + + if (fread(b, sizeof(b), 1, za->zp) != 1) { + _zip_error_set(&za->error, ZIP_ER_READ, errno); + return -1; + } + + p = b; + fname_len = _zip_read2(&p); + ef_len = _zip_read2(&p); + + if (ef_len > 0) { + struct zip_extra_field *ef; + zip_uint8_t *ef_raw; + + if (fseek(za->zp, fname_len, SEEK_CUR) < 0) { + _zip_error_set(&za->error, ZIP_ER_SEEK, errno); + return -1; + } + + ef_raw = _zip_read_data(NULL, za->zp, ef_len, 0, &za->error); + + if (ef_raw == NULL) + return -1; + + if ((ef=_zip_ef_parse(ef_raw, ef_len, ZIP_EF_LOCAL, &za->error)) == NULL) { + free(ef_raw); + return -1; + } + free(ef_raw); + + ef = _zip_ef_remove_internal(ef); + e->orig->extra_fields = _zip_ef_merge(e->orig->extra_fields, ef); + } + + e->orig->local_extra_fields_read = 1; + + if (e->changes && e->changes->local_extra_fields_read == 0) { + e->changes->extra_fields = e->orig->extra_fields; + e->changes->local_extra_fields_read = 1; + } + + return 0; +} diff --git a/ext/zip/lib/zip_extra_field_api.c b/ext/zip/lib/zip_extra_field_api.c new file mode 100644 index 0000000000000..02ed4555e0c0d --- /dev/null +++ b/ext/zip/lib/zip_extra_field_api.c @@ -0,0 +1,364 @@ +/* + zip_extra_field_api.c -- public extra fields API functions + Copyright (C) 2012-2013 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include "zipint.h" + + + +ZIP_EXTERN int +zip_file_extra_field_delete(struct zip *za, zip_uint64_t idx, zip_uint16_t ef_idx, zip_flags_t flags) +{ + struct zip_dirent *de; + + if ((flags & ZIP_EF_BOTH) == 0) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + if (_zip_get_dirent(za, idx, 0, NULL) == NULL) + return -1; + + if (ZIP_IS_RDONLY(za)) { + _zip_error_set(&za->error, ZIP_ER_RDONLY, 0); + return -1; + } + + if (_zip_file_extra_field_prepare_for_change(za, idx) < 0) + return -1; + + de = za->entry[idx].changes; + + de->extra_fields = _zip_ef_delete_by_id(de->extra_fields, ZIP_EXTRA_FIELD_ALL, ef_idx, flags); + return 0; +} + + + +ZIP_EXTERN int +zip_file_extra_field_delete_by_id(struct zip *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_uint16_t ef_idx, zip_flags_t flags) +{ + struct zip_dirent *de; + + if ((flags & ZIP_EF_BOTH) == 0) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + if (_zip_get_dirent(za, idx, 0, NULL) == NULL) + return -1; + + if (ZIP_IS_RDONLY(za)) { + _zip_error_set(&za->error, ZIP_ER_RDONLY, 0); + return -1; + } + + if (_zip_file_extra_field_prepare_for_change(za, idx) < 0) + return -1; + + de = za->entry[idx].changes; + + de->extra_fields = _zip_ef_delete_by_id(de->extra_fields, ef_id, ef_idx, flags); + return 0; +} + + + +ZIP_EXTERN const zip_uint8_t * +zip_file_extra_field_get(struct zip *za, zip_uint64_t idx, zip_uint16_t ef_idx, zip_uint16_t *idp, zip_uint16_t *lenp, zip_flags_t flags) +{ + static const zip_uint8_t empty[1] = { '\0' }; + + struct zip_dirent *de; + struct zip_extra_field *ef; + int i; + + if ((flags & ZIP_EF_BOTH) == 0) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return NULL; + } + + if ((de=_zip_get_dirent(za, idx, flags, &za->error)) == NULL) + return NULL; + + if (flags & ZIP_FL_LOCAL) + if (_zip_read_local_ef(za, idx) < 0) + return NULL; + + i = 0; + for (ef=de->extra_fields; ef; ef=ef->next) { + if (ef->flags & flags & ZIP_EF_BOTH) { + if (i < ef_idx) { + i++; + continue; + } + + if (idp) + *idp = ef->id; + if (lenp) + *lenp = ef->size; + if (ef->size > 0) + return ef->data; + else + return empty; + } + } + + _zip_error_set(&za->error, ZIP_ER_NOENT, 0); + return NULL; + +} + + + +ZIP_EXTERN const zip_uint8_t * +zip_file_extra_field_get_by_id(struct zip *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_uint16_t ef_idx, zip_uint16_t *lenp, zip_flags_t flags) +{ + struct zip_dirent *de; + + if ((flags & ZIP_EF_BOTH) == 0) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return NULL; + } + + if ((de=_zip_get_dirent(za, idx, flags, &za->error)) == NULL) + return NULL; + + if (flags & ZIP_FL_LOCAL) + if (_zip_read_local_ef(za, idx) < 0) + return NULL; + + return _zip_ef_get_by_id(de->extra_fields, lenp, ef_id, ef_idx, flags, &za->error); +} + + + +ZIP_EXTERN zip_int16_t +zip_file_extra_fields_count(struct zip *za, zip_uint64_t idx, zip_flags_t flags) +{ + struct zip_dirent *de; + struct zip_extra_field *ef; + zip_uint16_t n; + + if ((flags & ZIP_EF_BOTH) == 0) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + if ((de=_zip_get_dirent(za, idx, flags, &za->error)) == NULL) + return -1; + + if (flags & ZIP_FL_LOCAL) + if (_zip_read_local_ef(za, idx) < 0) + return -1; + + n = 0; + for (ef=de->extra_fields; ef; ef=ef->next) + if (ef->flags & flags & ZIP_EF_BOTH) + n++; + + return (zip_int16_t)n; +} + + + +ZIP_EXTERN zip_int16_t +zip_file_extra_fields_count_by_id(struct zip *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_flags_t flags) +{ + struct zip_dirent *de; + struct zip_extra_field *ef; + zip_uint16_t n; + + if ((flags & ZIP_EF_BOTH) == 0) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + if ((de=_zip_get_dirent(za, idx, flags, &za->error)) == NULL) + return -1; + + if (flags & ZIP_FL_LOCAL) + if (_zip_read_local_ef(za, idx) < 0) + return -1; + + n = 0; + for (ef=de->extra_fields; ef; ef=ef->next) + if (ef->id == ef_id && (ef->flags & flags & ZIP_EF_BOTH)) + n++; + + return (zip_int16_t)n; +} + + + +ZIP_EXTERN int +zip_file_extra_field_set(struct zip *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_uint16_t ef_idx, const zip_uint8_t *data, zip_uint16_t len, zip_flags_t flags) +{ + struct zip_dirent *de; + zip_uint16_t ls, cs; + struct zip_extra_field *ef, *ef_prev, *ef_new; + int i, found, new_len; + + if ((flags & ZIP_EF_BOTH) == 0) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + if (_zip_get_dirent(za, idx, 0, NULL) == NULL) + return -1; + + if (ZIP_IS_RDONLY(za)) { + _zip_error_set(&za->error, ZIP_ER_RDONLY, 0); + return -1; + } + + if (ZIP_EF_IS_INTERNAL(ef_id)) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + if (_zip_file_extra_field_prepare_for_change(za, idx) < 0) + return -1; + + de = za->entry[idx].changes; + + ef = de->extra_fields; + ef_prev = NULL; + i = 0; + found = 0; + + for (; ef; ef=ef->next) { + if (ef->id == ef_id && (ef->flags & flags & ZIP_EF_BOTH)) { + if (i == ef_idx) { + found = 1; + break; + } + i++; + } + ef_prev = ef; + } + + if (i < ef_idx && ef_idx != ZIP_EXTRA_FIELD_NEW) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + if (flags & ZIP_EF_LOCAL) + ls = _zip_ef_size(de->extra_fields, ZIP_EF_LOCAL); + else + ls = 0; + if (flags & ZIP_EF_CENTRAL) + cs = _zip_ef_size(de->extra_fields, ZIP_EF_CENTRAL); + else + cs = 0; + + new_len = ls > cs ? ls : cs; + if (found) + new_len -= ef->size + 4; + new_len += len + 4; + + if (new_len > ZIP_UINT16_MAX) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + if ((ef_new=_zip_ef_new(ef_id, len, data, flags)) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return -1; + } + + if (found) { + if ((ef->flags & ZIP_EF_BOTH) == (flags & ZIP_EF_BOTH)) { + ef_new->next = ef->next; + ef->next = NULL; + _zip_ef_free(ef); + if (ef_prev) + ef_prev->next = ef_new; + else + de->extra_fields = ef_new; + } + else { + ef->flags &= ~(flags & ZIP_EF_BOTH); + ef_new->next = ef->next; + ef->next = ef_new; + } + } + else if (ef_prev) { + ef_new->next = ef_prev->next; + ef_prev->next = ef_new; + } + else + de->extra_fields = ef_new; + + return 0; +} + + + +int +_zip_file_extra_field_prepare_for_change(struct zip *za, zip_uint64_t idx) +{ + struct zip_entry *e; + + if (idx >= za->nentry) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + e = za->entry+idx; + + if (e->changes && (e->changes->changed & ZIP_DIRENT_EXTRA_FIELD)) + return 0; + + if (e->orig) { + if (_zip_read_local_ef(za, idx) < 0) + return -1; + } + + if (e->changes == NULL) { + if ((e->changes=_zip_dirent_clone(e->orig)) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return -1; + } + } + + if (e->orig && e->orig->extra_fields) { + if ((e->changes->extra_fields=_zip_ef_clone(e->orig->extra_fields, &za->error)) == NULL) + return -1; + } + e->changes->changed |= ZIP_DIRENT_EXTRA_FIELD; + + return 0; +} + diff --git a/ext/zip/lib/zip_fclose.c b/ext/zip/lib/zip_fclose.c index eb55ddbcea455..093c30eada9f1 100644 --- a/ext/zip/lib/zip_fclose.c +++ b/ext/zip/lib/zip_fclose.c @@ -39,20 +39,23 @@ -ZIP_EXTERN(int) +ZIP_EXTERN int zip_fclose(struct zip_file *zf) { - int i, ret; + int ret; + unsigned int i; if (zf->src) zip_source_free(zf->src); - for (i=0; iza->nfile; i++) { - if (zf->za->file[i] == zf) { - zf->za->file[i] = zf->za->file[zf->za->nfile-1]; - zf->za->nfile--; - break; - } + if (zf->za) { + for (i=0; iza->nfile; i++) { + if (zf->za->file[i] == zf) { + zf->za->file[i] = zf->za->file[zf->za->nfile-1]; + zf->za->nfile--; + break; + } + } } ret = 0; diff --git a/ext/zip/lib/zip_fdopen.c b/ext/zip/lib/zip_fdopen.c index df70f27561ace..bda9aabac4915 100644 --- a/ext/zip/lib/zip_fdopen.c +++ b/ext/zip/lib/zip_fdopen.c @@ -37,11 +37,24 @@ -ZIP_EXTERN(struct zip *) -zip_fdopen(int fd_orig, int flags, int *zep) +ZIP_EXTERN struct zip * +zip_fdopen(int fd_orig, int _flags, int *zep) { int fd; FILE *fp; + unsigned int flags; + + if (_flags < 0) { + if (zep) + *zep = ZIP_ER_INVAL; + return NULL; + } + flags = (unsigned int)_flags; + + if (flags & ZIP_TRUNCATE) { + *zep = ZIP_ER_INVAL; + return NULL; + } /* We dup() here to avoid messing with the passed in fd. We could not restore it to the original state in case of error. */ @@ -58,5 +71,5 @@ zip_fdopen(int fd_orig, int flags, int *zep) } close(fd_orig); - return _zip_open(NULL, fp, flags, ZIP_AFL_RDONLY, zep); + return _zip_open(NULL, fp, flags, zep); } diff --git a/ext/zip/lib/zip_file_add.c b/ext/zip/lib/zip_file_add.c new file mode 100644 index 0000000000000..995cb91c1a287 --- /dev/null +++ b/ext/zip/lib/zip_file_add.c @@ -0,0 +1,55 @@ +/* + zip_file_add.c -- add file via callback function + Copyright (C) 1999-2012 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include "zipint.h" + + +/* + NOTE: Return type is signed so we can return -1 on error. + The index can not be larger than ZIP_INT64_MAX since the size + of the central directory cannot be larger than + ZIP_UINT64_MAX, and each entry is larger than 2 bytes. +*/ + +ZIP_EXTERN zip_int64_t +zip_file_add(struct zip *za, const char *name, struct zip_source *source, zip_flags_t flags) +{ + if (name == NULL || source == NULL) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + return _zip_file_replace(za, ZIP_UINT64_MAX, name, source, flags); +} diff --git a/ext/zip/lib/zip_file_error_clear.c b/ext/zip/lib/zip_file_error_clear.c index 6c9c2a02b3f0f..ce8b6cbd9403a 100644 --- a/ext/zip/lib/zip_file_error_clear.c +++ b/ext/zip/lib/zip_file_error_clear.c @@ -37,8 +37,11 @@ -ZIP_EXTERN(void) +ZIP_EXTERN void zip_file_error_clear(struct zip_file *zf) { + if (zf == NULL) + return; + _zip_error_clear(&zf->error); } diff --git a/ext/zip/lib/zip_file_error_get.c b/ext/zip/lib/zip_file_error_get.c index a53fa7e003324..f20e011fc747e 100644 --- a/ext/zip/lib/zip_file_error_get.c +++ b/ext/zip/lib/zip_file_error_get.c @@ -37,7 +37,7 @@ -ZIP_EXTERN(void) +ZIP_EXTERN void zip_file_error_get(struct zip_file *zf, int *zep, int *sep) { _zip_error_get(&zf->error, zep, sep); diff --git a/ext/zip/lib/zip_get_file_extra.c b/ext/zip/lib/zip_file_get_comment.c similarity index 72% rename from ext/zip/lib/zip_get_file_extra.c rename to ext/zip/lib/zip_file_get_comment.c index a27edd8ee9452..766731ea268ef 100644 --- a/ext/zip/lib/zip_get_file_extra.c +++ b/ext/zip/lib/zip_file_get_comment.c @@ -1,6 +1,6 @@ /* - zip_get_file_extra.c -- get file extra field - Copyright (C) 2006-2010 Dieter Baron and Thomas Klausner + zip_file_get_comment.c -- get file comment + Copyright (C) 2006-2012 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -17,7 +17,7 @@ 3. The names of the authors may not be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -31,28 +31,28 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - + #include "zipint.h" + +/* lenp is 32 bit because converted comment can be longer than ZIP_UINT16_MAX */ - -ZIP_EXTERN(const char *) -zip_get_file_extra(struct zip *za, zip_uint64_t idx, int *lenp, int flags) +ZIP_EXTERN const char * +zip_file_get_comment(struct zip *za, zip_uint64_t idx, zip_uint32_t *lenp, zip_flags_t flags) { - if (idx >= za->nentry) { - _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + struct zip_dirent *de; + zip_uint32_t len; + const zip_uint8_t *str; + + if ((de=_zip_get_dirent(za, idx, flags, NULL)) == NULL) return NULL; - } - - if ((flags & ZIP_FL_UNCHANGED) - || (za->entry[idx].ch_extra_len == -1)) { - if (lenp != NULL) - *lenp = za->cdir->entry[idx].extrafield_len; - return za->cdir->entry[idx].extrafield; - } - - if (lenp != NULL) - *lenp = za->entry[idx].ch_extra_len; - return za->entry[idx].ch_extra; + + if ((str=_zip_string_get(de->comment, &len, flags, &za->error)) == NULL) + return NULL; + + if (lenp) + *lenp = len; + + return (const char *)str; } diff --git a/ext/zip/lib/zip_file_get_offset.c b/ext/zip/lib/zip_file_get_offset.c index b96fd5e480907..65a011fc077c3 100644 --- a/ext/zip/lib/zip_file_get_offset.c +++ b/ext/zip/lib/zip_file_get_offset.c @@ -50,25 +50,27 @@ On error, fills in za->error and returns 0. */ -unsigned int -_zip_file_get_offset(struct zip *za, int idx) +zip_uint64_t +_zip_file_get_offset(const struct zip *za, zip_uint64_t idx, struct zip_error *error) { - struct zip_dirent de; - unsigned int offset; + zip_uint64_t offset; + zip_int32_t size; - offset = za->cdir->entry[idx].offset; + offset = za->entry[idx].orig->offset; - if (fseeko(za->zp, offset, SEEK_SET) != 0) { - _zip_error_set(&za->error, ZIP_ER_SEEK, errno); + if (fseeko(za->zp, (off_t)offset, SEEK_SET) != 0) { + _zip_error_set(error, ZIP_ER_SEEK, errno); return 0; } - if (_zip_dirent_read(&de, za->zp, NULL, NULL, 1, &za->error) != 0) + /* XXX: cache? */ + if ((size=_zip_dirent_size(za->zp, ZIP_EF_LOCAL, error)) < 0) return 0; - offset += LENTRYSIZE + de.filename_len + de.extrafield_len; - - _zip_dirent_finalize(&de); - - return offset; + if (offset+(zip_uint32_t)size > ZIP_OFF_MAX) { + _zip_error_set(error, ZIP_ER_SEEK, EFBIG); + return 0; + } + + return offset + (zip_uint32_t)size; } diff --git a/ext/zip/lib/zip_set_file_extra.c b/ext/zip/lib/zip_file_rename.c similarity index 70% rename from ext/zip/lib/zip_set_file_extra.c rename to ext/zip/lib/zip_file_rename.c index db829e2e0a842..383a52adae714 100644 --- a/ext/zip/lib/zip_set_file_extra.c +++ b/ext/zip/lib/zip_file_rename.c @@ -1,6 +1,6 @@ /* - zip_set_file_extra.c -- set extra field for file in archive - Copyright (C) 2006-2010 Dieter Baron and Thomas Klausner + zip_file_rename.c -- rename file in zip archive + Copyright (C) 1999-2012 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -17,7 +17,7 @@ 3. The names of the authors may not be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -31,23 +31,21 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + - -#include +#include #include "zipint.h" + - -ZIP_EXTERN(int) -zip_set_file_extra(struct zip *za, zip_uint64_t idx, - const char *extra, int len) +ZIP_EXTERN int +zip_file_rename(struct zip *za, zip_uint64_t idx, const char *name, zip_flags_t flags) { - char *tmpext; - - if (idx >= za->nentry - || len < 0 || len > MAXEXTLEN - || (len > 0 && extra == NULL)) { + const char *old_name; + int old_is_dir, new_is_dir; + + if (idx >= za->nentry || (name != NULL && strlen(name) > ZIP_UINT16_MAX)) { _zip_error_set(&za->error, ZIP_ER_INVAL, 0); return -1; } @@ -57,16 +55,16 @@ zip_set_file_extra(struct zip *za, zip_uint64_t idx, return -1; } - if (len > 0) { - if ((tmpext=(char *)_zip_memdup(extra, len, &za->error)) == NULL) - return -1; - } - else - tmpext = NULL; + if ((old_name=zip_get_name(za, idx, 0)) == NULL) + return -1; + + new_is_dir = (name != NULL && name[strlen(name)-1] == '/'); + old_is_dir = (old_name[strlen(old_name)-1] == '/'); - free(za->entry[idx].ch_extra); - za->entry[idx].ch_extra = tmpext; - za->entry[idx].ch_extra_len = len; + if (new_is_dir != old_is_dir) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } - return 0; + return _zip_set_name(za, idx, name, flags); } diff --git a/ext/zip/lib/zip_file_replace.c b/ext/zip/lib/zip_file_replace.c new file mode 100644 index 0000000000000..7e7e942168478 --- /dev/null +++ b/ext/zip/lib/zip_file_replace.c @@ -0,0 +1,111 @@ +/* + zip_file_replace.c -- replace file via callback function + Copyright (C) 1999-2012 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include "zipint.h" + + + +ZIP_EXTERN int +zip_file_replace(struct zip *za, zip_uint64_t idx, struct zip_source *source, zip_flags_t flags) +{ + if (idx >= za->nentry || source == NULL) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + if (_zip_file_replace(za, idx, NULL, source, flags) == -1) + return -1; + + return 0; +} + + + + +/* NOTE: Signed due to -1 on error. See zip_add.c for more details. */ + +zip_int64_t +_zip_file_replace(struct zip *za, zip_uint64_t idx, const char *name, struct zip_source *source, zip_flags_t flags) +{ + zip_uint64_t za_nentry_prev; + + if (ZIP_IS_RDONLY(za)) { + _zip_error_set(&za->error, ZIP_ER_RDONLY, 0); + return -1; + } + + za_nentry_prev = za->nentry; + if (idx == ZIP_UINT64_MAX) { + zip_int64_t i = -1; + + if (flags & ZIP_FL_OVERWRITE) + i = _zip_name_locate(za, name, flags, NULL); + + if (i == -1) { + /* create and use new entry, used by zip_add */ + if ((i=_zip_add_entry(za)) < 0) + return -1; + } + idx = (zip_uint64_t)i; + } + + if (name && _zip_set_name(za, idx, name, flags) != 0) { + if (za->nentry != za_nentry_prev) { + _zip_entry_finalize(za->entry+idx); + za->nentry = za_nentry_prev; + } + return -1; + } + + /* does not change any name related data, so we can do it here; + * needed for a double add of the same file name */ + _zip_unchange_data(za->entry+idx); + + if (za->entry[idx].orig != NULL && (za->entry[idx].changes == NULL || (za->entry[idx].changes->changed & ZIP_DIRENT_COMP_METHOD) == 0)) { + if (za->entry[idx].changes == NULL) { + if ((za->entry[idx].changes=_zip_dirent_clone(za->entry[idx].orig)) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return -1; + } + } + + za->entry[idx].changes->comp_method = ZIP_CM_REPLACED_DEFAULT; + za->entry[idx].changes->changed |= ZIP_DIRENT_COMP_METHOD; + } + + za->entry[idx].source = source; + + return (zip_int64_t)idx; +} diff --git a/ext/zip/lib/zip_file_set_comment.c b/ext/zip/lib/zip_file_set_comment.c new file mode 100644 index 0000000000000..722f3d43cc3d3 --- /dev/null +++ b/ext/zip/lib/zip_file_set_comment.c @@ -0,0 +1,105 @@ +/* + zip_file_set_comment.c -- set comment for file in archive + Copyright (C) 2006-2012 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include + +#include "zipint.h" + + + +ZIP_EXTERN int +zip_file_set_comment(struct zip *za, zip_uint64_t idx, + const char *comment, zip_uint16_t len, zip_flags_t flags) +{ + struct zip_entry *e; + struct zip_string *cstr; + int changed; + + if (_zip_get_dirent(za, idx, 0, NULL) == NULL) + return -1; + + if (ZIP_IS_RDONLY(za)) { + _zip_error_set(&za->error, ZIP_ER_RDONLY, 0); + return -1; + } + + if (len > 0 && comment == NULL) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + if (len > 0) { + if ((cstr=_zip_string_new((const zip_uint8_t *)comment, len, flags, &za->error)) == NULL) + return -1; + if ((flags & ZIP_FL_ENCODING_ALL) == ZIP_FL_ENC_GUESS && _zip_guess_encoding(cstr, ZIP_ENCODING_UNKNOWN) == ZIP_ENCODING_UTF8_GUESSED) + cstr->encoding = ZIP_ENCODING_UTF8_KNOWN; + } + else + cstr = NULL; + + e = za->entry+idx; + + if (e->changes) { + _zip_string_free(e->changes->comment); + e->changes->comment = NULL; + e->changes->changed &= ~ZIP_DIRENT_COMMENT; + } + + if (e->orig && e->orig->comment) + changed = !_zip_string_equal(e->orig->comment, cstr); + else + changed = (cstr != NULL); + + if (changed) { + if (e->changes == NULL) { + if ((e->changes=_zip_dirent_clone(e->orig)) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + _zip_string_free(cstr); + return -1; + } + } + e->changes->comment = cstr; + e->changes->changed |= ZIP_DIRENT_COMMENT; + } + else { + _zip_string_free(cstr); + if (e->changes && e->changes->changed == 0) { + _zip_dirent_free(e->changes); + e->changes = NULL; + } + } + + return 0; +} diff --git a/ext/zip/lib/zip_file_strerror.c b/ext/zip/lib/zip_file_strerror.c index c2864f2ba1aaf..9ba70f14ff52b 100644 --- a/ext/zip/lib/zip_file_strerror.c +++ b/ext/zip/lib/zip_file_strerror.c @@ -37,7 +37,7 @@ -ZIP_EXTERN(const char *) +ZIP_EXTERN const char * zip_file_strerror(struct zip_file *zf) { return _zip_error_strerror(&zf->error); diff --git a/ext/zip/lib/zip_filerange_crc.c b/ext/zip/lib/zip_filerange_crc.c index 4d1ad566929f8..3b1c868407ef9 100644 --- a/ext/zip/lib/zip_filerange_crc.c +++ b/ext/zip/lib/zip_filerange_crc.c @@ -1,6 +1,6 @@ /* zip_filerange_crc.c -- compute CRC32 for a range of a file - Copyright (C) 2008 Dieter Baron and Thomas Klausner + Copyright (C) 2008-2013 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -56,13 +56,13 @@ _zip_filerange_crc(FILE *fp, off_t start, off_t len, uLong *crcp, } while (len > 0) { - n = len > BUFSIZE ? BUFSIZE : len; - if ((n=fread(buf, 1, n, fp)) <= 0) { + n = len > BUFSIZE ? BUFSIZE : (size_t)len; + if ((n=fread(buf, 1, n, fp)) == 0) { _zip_error_set(errp, ZIP_ER_READ, errno); return -1; } - *crcp = crc32(*crcp, buf, n); + *crcp = crc32(*crcp, buf, (uInt)n); len-= n; } diff --git a/ext/zip/lib/zip_fopen.c b/ext/zip/lib/zip_fopen.c index f62adbbf92692..331f79ea36149 100644 --- a/ext/zip/lib/zip_fopen.c +++ b/ext/zip/lib/zip_fopen.c @@ -37,13 +37,13 @@ -ZIP_EXTERN(struct zip_file *) -zip_fopen(struct zip *za, const char *fname, int flags) +ZIP_EXTERN struct zip_file * +zip_fopen(struct zip *za, const char *fname, zip_flags_t flags) { - int idx; + zip_int64_t idx; if ((idx=zip_name_locate(za, fname, flags)) < 0) return NULL; - return zip_fopen_index_encrypted(za, idx, flags, za->default_password); + return zip_fopen_index_encrypted(za, (zip_uint64_t)idx, flags, za->default_password); } diff --git a/ext/zip/lib/zip_fopen_encrypted.c b/ext/zip/lib/zip_fopen_encrypted.c index 8aba0625672bc..34230f00d7c0a 100644 --- a/ext/zip/lib/zip_fopen_encrypted.c +++ b/ext/zip/lib/zip_fopen_encrypted.c @@ -37,14 +37,13 @@ -ZIP_EXTERN(struct zip_file *) -zip_fopen_encrypted(struct zip *za, const char *fname, int flags, - const char *password) +ZIP_EXTERN struct zip_file * +zip_fopen_encrypted(struct zip *za, const char *fname, zip_flags_t flags, const char *password) { - int idx; + zip_int64_t idx; if ((idx=zip_name_locate(za, fname, flags)) < 0) return NULL; - return zip_fopen_index_encrypted(za, idx, flags, password); + return zip_fopen_index_encrypted(za, (zip_uint64_t)idx, flags, password); } diff --git a/ext/zip/lib/zip_fopen_index.c b/ext/zip/lib/zip_fopen_index.c index b60fd33e8f53e..30466ffa19a59 100644 --- a/ext/zip/lib/zip_fopen_index.c +++ b/ext/zip/lib/zip_fopen_index.c @@ -1,6 +1,6 @@ /* zip_fopen_index.c -- open file in zip archive for reading by index - Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2013 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -41,8 +41,8 @@ -ZIP_EXTERN(struct zip_file *) -zip_fopen_index(struct zip *za, zip_uint64_t fileno, int flags) +ZIP_EXTERN struct zip_file * +zip_fopen_index(struct zip *za, zip_uint64_t index, zip_flags_t flags) { - return zip_fopen_index_encrypted(za, fileno, flags, za->default_password); + return zip_fopen_index_encrypted(za, index, flags, za->default_password); } diff --git a/ext/zip/lib/zip_fopen_index_encrypted.c b/ext/zip/lib/zip_fopen_index_encrypted.c index 988a78fe03f9a..cc81ca7f53b67 100644 --- a/ext/zip/lib/zip_fopen_index_encrypted.c +++ b/ext/zip/lib/zip_fopen_index_encrypted.c @@ -1,6 +1,6 @@ /* zip_fopen_index_encrypted.c -- open file for reading by index w/ password - Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2013 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -43,103 +43,15 @@ static struct zip_file *_zip_file_new(struct zip *za); -ZIP_EXTERN(struct zip_file *) -zip_fopen_index_encrypted(struct zip *za, zip_uint64_t fileno, int flags, +ZIP_EXTERN struct zip_file * +zip_fopen_index_encrypted(struct zip *za, zip_uint64_t index, zip_flags_t flags, const char *password) { struct zip_file *zf; - zip_compression_implementation comp_impl; - zip_encryption_implementation enc_impl; - struct zip_source *src, *s2; - zip_uint64_t start; - struct zip_stat st; - - if (fileno >= za->nentry) { - _zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return NULL; - } + struct zip_source *src; - if ((flags & ZIP_FL_UNCHANGED) == 0 - && ZIP_ENTRY_DATA_CHANGED(za->entry+fileno)) { - _zip_error_set(&za->error, ZIP_ER_CHANGED, 0); + if ((src=_zip_source_zip_new(za, za, index, flags, 0, 0, password)) == NULL) return NULL; - } - - if (fileno >= za->cdir->nentry) { - _zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return NULL; - } - - if (flags & ZIP_FL_ENCRYPTED) - flags |= ZIP_FL_COMPRESSED; - - zip_stat_index(za, fileno, flags, &st); - - enc_impl = NULL; - if ((flags & ZIP_FL_ENCRYPTED) == 0) { - if (st.encryption_method != ZIP_EM_NONE) { - if (password == NULL) { - _zip_error_set(&za->error, ZIP_ER_NOPASSWD, 0); - return NULL; - } - if ((enc_impl=zip_get_encryption_implementation( - st.encryption_method)) == NULL) { - _zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0); - return NULL; - } - } - } - - comp_impl = NULL; - if ((flags & ZIP_FL_COMPRESSED) == 0) { - if (st.comp_method != ZIP_CM_STORE) { - if ((comp_impl=zip_get_compression_implementation( - st.comp_method)) == NULL) { - _zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0); - return NULL; - } - } - } - - if ((start=_zip_file_get_offset(za, fileno)) == 0) - return NULL; - - if (st.comp_size == 0) { - if ((src=zip_source_buffer(za, NULL, 0, 0)) == NULL) - return NULL; - } - else { - if ((src=_zip_source_file_or_p(za, NULL, za->zp, start, st.comp_size, - 0, &st)) == NULL) - return NULL; - if (enc_impl) { - if ((s2=enc_impl(za, src, ZIP_EM_TRAD_PKWARE, 0, - password)) == NULL) { - zip_source_free(src); - /* XXX: set error (how?) */ - return NULL; - } - src = s2; - } - if (comp_impl) { - if ((s2=comp_impl(za, src, za->cdir->entry[fileno].comp_method, - 0)) == NULL) { - zip_source_free(src); - /* XXX: set error (how?) */ - return NULL; - } - src = s2; - } - if ((flags & ZIP_FL_COMPRESSED) == 0 - || st.comp_method == ZIP_CM_STORE ) { - if ((s2=zip_source_crc(za, src, 1)) == NULL) { - zip_source_free(src); - /* XXX: set error (how?) */ - return NULL; - } - src = s2; - } - } if (zip_source_open(src) < 0) { _zip_error_set_from_source(&za->error, src); @@ -147,7 +59,10 @@ zip_fopen_index_encrypted(struct zip *za, zip_uint64_t fileno, int flags, return NULL; } - zf = _zip_file_new(za); + if ((zf=_zip_file_new(za)) == NULL) { + zip_source_free(src); + return NULL; + } zf->src = src; @@ -160,14 +75,14 @@ static struct zip_file * _zip_file_new(struct zip *za) { struct zip_file *zf, **file; - int n; if ((zf=(struct zip_file *)malloc(sizeof(struct zip_file))) == NULL) { _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); return NULL; } - if (za->nfile >= za->nfile_alloc-1) { + if (za->nfile+1 >= za->nfile_alloc) { + unsigned int n; n = za->nfile_alloc + 10; file = (struct zip_file **)realloc(za->file, n*sizeof(struct zip_file *)); diff --git a/ext/zip/lib/zip_fread.c b/ext/zip/lib/zip_fread.c index a6c0851b0aaac..8235c6dfacf80 100644 --- a/ext/zip/lib/zip_fread.c +++ b/ext/zip/lib/zip_fread.c @@ -37,7 +37,7 @@ -ZIP_EXTERN(zip_int64_t) +ZIP_EXTERN zip_int64_t zip_fread(struct zip_file *zf, void *outbuf, zip_uint64_t toread) { zip_int64_t n; diff --git a/ext/zip/lib/zip_get_archive_comment.c b/ext/zip/lib/zip_get_archive_comment.c index fe97e6e8c18a1..202f761f4e852 100644 --- a/ext/zip/lib/zip_get_archive_comment.c +++ b/ext/zip/lib/zip_get_archive_comment.c @@ -1,6 +1,6 @@ /* zip_get_archive_comment.c -- get archive comment - Copyright (C) 2006-2007 Dieter Baron and Thomas Klausner + Copyright (C) 2006-2012 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -33,28 +33,29 @@ +#include + #include "zipint.h" -ZIP_EXTERN(const char *) -zip_get_archive_comment(struct zip *za, int *lenp, int flags) +ZIP_EXTERN const char * +zip_get_archive_comment(struct zip *za, int *lenp, zip_flags_t flags) { - if ((flags & ZIP_FL_UNCHANGED) - || (za->ch_comment_len == -1)) { - if (za->cdir) { - if (lenp != NULL) - *lenp = za->cdir->comment_len; - return za->cdir->comment; - } - else { - if (lenp != NULL) - *lenp = -1; - return NULL; - } - } - - if (lenp != NULL) - *lenp = za->ch_comment_len; - return za->ch_comment; + struct zip_string *comment; + zip_uint32_t len; + const zip_uint8_t *str; + + if ((flags & ZIP_FL_UNCHANGED) || (za->comment_changes == NULL)) + comment = za->comment_orig; + else + comment = za->comment_changes; + + if ((str=_zip_string_get(comment, &len, flags, &za->error)) == NULL) + return NULL; + + if (lenp) + *lenp = (int)len; + + return (const char *)str; } diff --git a/ext/zip/lib/zip_get_archive_flag.c b/ext/zip/lib/zip_get_archive_flag.c index 2d46aa39ffbb4..c3be5c14fec38 100644 --- a/ext/zip/lib/zip_get_archive_flag.c +++ b/ext/zip/lib/zip_get_archive_flag.c @@ -37,10 +37,10 @@ -ZIP_EXTERN(int) -zip_get_archive_flag(struct zip *za, int flag, int flags) +ZIP_EXTERN int +zip_get_archive_flag(struct zip *za, unsigned int flag, zip_flags_t flags) { - int fl; + unsigned int fl; fl = (flags & ZIP_FL_UNCHANGED) ? za->flags : za->ch_flags; diff --git a/ext/zip/lib/zip_get_compression_implementation.c b/ext/zip/lib/zip_get_compression_implementation.c index 197cd49635d41..aa4a1605c0f36 100644 --- a/ext/zip/lib/zip_get_compression_implementation.c +++ b/ext/zip/lib/zip_get_compression_implementation.c @@ -37,10 +37,10 @@ -ZIP_EXTERN(zip_compression_implementation) -zip_get_compression_implementation(zip_uint16_t cm) +zip_compression_implementation +_zip_get_compression_implementation(zip_int32_t cm) { - if (cm == ZIP_CM_DEFLATE) + if (cm == ZIP_CM_DEFLATE || ZIP_CM_IS_DEFAULT(cm)) return zip_source_deflate; return NULL; } diff --git a/ext/zip/lib/zip_get_encryption_implementation.c b/ext/zip/lib/zip_get_encryption_implementation.c index 783d538d3f6ff..7dcb99210d498 100644 --- a/ext/zip/lib/zip_get_encryption_implementation.c +++ b/ext/zip/lib/zip_get_encryption_implementation.c @@ -37,8 +37,8 @@ -ZIP_EXTERN(zip_encryption_implementation) -zip_get_encryption_implementation(zip_uint16_t em) +zip_encryption_implementation +_zip_get_encryption_implementation(zip_uint16_t em) { if (em == ZIP_EM_TRAD_PKWARE) return zip_source_pkware; diff --git a/ext/zip/lib/zip_get_file_comment.c b/ext/zip/lib/zip_get_file_comment.c index 43c1520e1d438..3be459d4da6b0 100644 --- a/ext/zip/lib/zip_get_file_comment.c +++ b/ext/zip/lib/zip_get_file_comment.c @@ -1,6 +1,6 @@ /* zip_get_file_comment.c -- get file comment - Copyright (C) 2006-2007 Dieter Baron and Thomas Klausner + Copyright (C) 2006-2012 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -33,26 +33,21 @@ +#define _ZIP_COMPILING_DEPRECATED #include "zipint.h" -ZIP_EXTERN(const char *) +ZIP_EXTERN const char * zip_get_file_comment(struct zip *za, zip_uint64_t idx, int *lenp, int flags) { - if (idx >= za->nentry) { - _zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return NULL; - } + zip_uint32_t len; + const char *s; - if ((flags & ZIP_FL_UNCHANGED) - || (za->entry[idx].ch_comment_len == -1)) { - if (lenp != NULL) - *lenp = za->cdir->entry[idx].comment_len; - return za->cdir->entry[idx].comment; + if ((s=zip_file_get_comment(za, idx, &len, (zip_flags_t)flags)) != NULL) { + if (lenp) + *lenp = (int)len; } - - if (lenp != NULL) - *lenp = za->entry[idx].ch_comment_len; - return za->entry[idx].ch_comment; + + return s; } diff --git a/ext/zip/lib/zip_get_name.c b/ext/zip/lib/zip_get_name.c index 945e24e1501d5..f67c7caf4305f 100644 --- a/ext/zip/lib/zip_get_name.c +++ b/ext/zip/lib/zip_get_name.c @@ -1,6 +1,6 @@ /* zip_get_name.c -- get filename for a file in zip file - Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2012 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -33,12 +33,14 @@ +#include + #include "zipint.h" -ZIP_EXTERN(const char *) -zip_get_name(struct zip *za, zip_uint64_t idx, int flags) +ZIP_EXTERN const char * +zip_get_name(struct zip *za, zip_uint64_t idx, zip_flags_t flags) { return _zip_get_name(za, idx, flags, &za->error); } @@ -46,27 +48,16 @@ zip_get_name(struct zip *za, zip_uint64_t idx, int flags) const char * -_zip_get_name(struct zip *za, zip_uint64_t idx, int flags, - struct zip_error *error) +_zip_get_name(struct zip *za, zip_uint64_t idx, zip_flags_t flags, struct zip_error *error) { - if (idx >= za->nentry) { - _zip_error_set(error, ZIP_ER_INVAL, 0); - return NULL; - } + struct zip_dirent *de; + const zip_uint8_t *str; - if ((flags & ZIP_FL_UNCHANGED) == 0) { - if (za->entry[idx].state == ZIP_ST_DELETED) { - _zip_error_set(error, ZIP_ER_DELETED, 0); - return NULL; - } - if (za->entry[idx].ch_filename) - return za->entry[idx].ch_filename; - } + if ((de=_zip_get_dirent(za, idx, flags, error)) == NULL) + return NULL; - if (za->cdir == NULL || idx >= za->cdir->nentry) { - _zip_error_set(error, ZIP_ER_INVAL, 0); + if ((str=_zip_string_get(de->filename, NULL, flags, error)) == NULL) return NULL; - } - - return za->cdir->entry[idx].filename; + + return (const char *)str; } diff --git a/ext/zip/lib/zip_get_num_entries.c b/ext/zip/lib/zip_get_num_entries.c index dd392e909592e..26484baff22a6 100644 --- a/ext/zip/lib/zip_get_num_entries.c +++ b/ext/zip/lib/zip_get_num_entries.c @@ -37,16 +37,19 @@ -ZIP_EXTERN(zip_uint64_t) -zip_get_num_entries(struct zip *za, int flags) +ZIP_EXTERN zip_int64_t +zip_get_num_entries(struct zip *za, zip_flags_t flags) { + zip_uint64_t n; + if (za == NULL) return -1; if (flags & ZIP_FL_UNCHANGED) { - if (za->cdir == NULL) - return 0; - return za->cdir->nentry; + n = za->nentry; + while (n>0 && za->entry[n-1].orig == NULL) + --n; + return (zip_int64_t)n; } - return za->nentry; + return (zip_int64_t)za->nentry; } diff --git a/ext/zip/lib/zip_get_num_files.c b/ext/zip/lib/zip_get_num_files.c index a442f293ec350..29b06dc8193ff 100644 --- a/ext/zip/lib/zip_get_num_files.c +++ b/ext/zip/lib/zip_get_num_files.c @@ -33,15 +33,17 @@ +#define _ZIP_COMPILING_DEPRECATED #include "zipint.h" -ZIP_EXTERN(int) +ZIP_EXTERN int zip_get_num_files(struct zip *za) { if (za == NULL) return -1; - return za->nentry; + /* XXX: check for overflow */ + return (int)za->nentry; } diff --git a/ext/zip/lib/zip_memdup.c b/ext/zip/lib/zip_memdup.c index 641125ed2d1b2..06af2dabd36c7 100644 --- a/ext/zip/lib/zip_memdup.c +++ b/ext/zip/lib/zip_memdup.c @@ -1,6 +1,6 @@ /* zip_memdup.c -- internal zip function, "strdup" with len - Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2012 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -43,6 +43,9 @@ _zip_memdup(const void *mem, size_t len, struct zip_error *error) { void *ret; + if (len == 0) + return NULL; + ret = malloc(len); if (!ret) { _zip_error_set(error, ZIP_ER_MEMORY, 0); diff --git a/ext/zip/lib/zip_name_locate.c b/ext/zip/lib/zip_name_locate.c index 8cdd2c4d7ea0b..3cac110543672 100644 --- a/ext/zip/lib/zip_name_locate.c +++ b/ext/zip/lib/zip_name_locate.c @@ -34,26 +34,28 @@ #include +#ifdef HAVE_STRINGS_H +#include +#endif #include "zipint.h" -ZIP_EXTERN(int) -zip_name_locate(struct zip *za, const char *fname, int flags) +ZIP_EXTERN zip_int64_t +zip_name_locate(struct zip *za, const char *fname, zip_flags_t flags) { return _zip_name_locate(za, fname, flags, &za->error); } -int -_zip_name_locate(struct zip *za, const char *fname, int flags, - struct zip_error *error) +zip_int64_t +_zip_name_locate(struct zip *za, const char *fname, zip_flags_t flags, struct zip_error *error) { int (*cmp)(const char *, const char *); const char *fn, *p; - int i, n; + zip_uint64_t i; if (za == NULL) return -1; @@ -63,21 +65,12 @@ _zip_name_locate(struct zip *za, const char *fname, int flags, return -1; } - if ((flags & ZIP_FL_UNCHANGED) && za->cdir == NULL) { - _zip_error_set(error, ZIP_ER_NOENT, 0); - return -1; - } - - cmp = (flags & ZIP_FL_NOCASE) ? strcmpi : strcmp; + cmp = (flags & ZIP_FL_NOCASE) ? strcasecmp : strcmp; - n = (flags & ZIP_FL_UNCHANGED) ? za->cdir->nentry : za->nentry; - for (i=0; icdir->entry[i].filename; - else - fn = _zip_get_name(za, i, flags, error); + for (i=0; inentry; i++) { + fn = _zip_get_name(za, i, flags, error); - /* newly added (partially filled) entry */ + /* newly added (partially filled) entry or error */ if (fn == NULL) continue; @@ -87,11 +80,12 @@ _zip_name_locate(struct zip *za, const char *fname, int flags, fn = p+1; } - if (cmp(fname, fn) == 0) - return i; + if (cmp(fname, fn) == 0) { + _zip_error_clear(error); + return (zip_int64_t)i; + } } -/* Look for an entry should not raise an error */ -/* _zip_error_set(error, ZIP_ER_NOENT, 0);*/ + _zip_error_set(error, ZIP_ER_NOENT, 0); return -1; } diff --git a/ext/zip/lib/zip_new.c b/ext/zip/lib/zip_new.c index 7ce1237cdbabd..f77634a389f36 100644 --- a/ext/zip/lib/zip_new.c +++ b/ext/zip/lib/zip_new.c @@ -1,6 +1,6 @@ /* zip_new.c -- create and init struct zip - Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2012 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -56,16 +56,17 @@ _zip_new(struct zip_error *error) za->zn = NULL; za->zp = NULL; + za->open_flags = 0; _zip_error_init(&za->error); - za->cdir = NULL; - za->ch_comment = NULL; - za->ch_comment_len = -1; + za->flags = za->ch_flags = 0; + za->default_password = NULL; + za->comment_orig = za->comment_changes = NULL; + za->comment_changed = 0; za->nentry = za->nentry_alloc = 0; za->entry = NULL; za->nfile = za->nfile_alloc = 0; za->file = NULL; - za->flags = za->ch_flags = 0; - za->default_password = NULL; + za->tempdir = NULL; return za; } diff --git a/ext/zip/lib/zip_open.c b/ext/zip/lib/zip_open.c index 5ce1c1070ae03..e6a30d5ae7066 100644 --- a/ext/zip/lib/zip_open.c +++ b/ext/zip/lib/zip_open.c @@ -1,6 +1,6 @@ /* zip_open.c -- open zip archive by name - Copyright (C) 1999-2011 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2012 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -42,38 +42,53 @@ #include "zipint.h" -static void set_error(int *, struct zip_error *, int); -static struct zip *_zip_allocate_new(const char *, int *); -static int _zip_checkcons(FILE *, struct zip_cdir *, struct zip_error *); -static void _zip_check_torrentzip(struct zip *); -static struct zip_cdir *_zip_find_central_dir(FILE *, int, int *, off_t); -static int _zip_file_exists(const char *, int, int *); -static int _zip_headercomp(struct zip_dirent *, int, - struct zip_dirent *, int); -static unsigned char *_zip_memmem(const unsigned char *, int, - const unsigned char *, int); -static struct zip_cdir *_zip_readcdir(FILE *, off_t, unsigned char *, unsigned char *, - int, int, struct zip_error *); +static void set_error(int *, const struct zip_error *, int); +static struct zip *_zip_allocate_new(const char *, unsigned int, int *); +static zip_int64_t _zip_checkcons(FILE *, struct zip_cdir *, struct zip_error *); +static void _zip_check_torrentzip(struct zip *, const struct zip_cdir *); +static struct zip_cdir *_zip_find_central_dir(FILE *, unsigned int, int *, off_t); +static int _zip_file_exists(const char *, unsigned int, int *); +static int _zip_headercomp(const struct zip_dirent *, const struct zip_dirent *); +static unsigned char *_zip_memmem(const unsigned char *, size_t, + const unsigned char *, size_t); +static struct zip_cdir *_zip_readcdir(FILE *, off_t, unsigned char *, const unsigned char *, + size_t, unsigned int, struct zip_error *); +static struct zip_cdir *_zip_read_eocd(const unsigned char *, const unsigned char *, off_t, + size_t, unsigned int, struct zip_error *); +static struct zip_cdir *_zip_read_eocd64(FILE *, const unsigned char *, const unsigned char *, + off_t, size_t, unsigned int, struct zip_error *); -ZIP_EXTERN(struct zip *) -zip_open(const char *fn, int flags, int *zep) +ZIP_EXTERN struct zip * +zip_open(const char *fn, int _flags, int *zep) { FILE *fp; - - if (flags & ZIP_OVERWRITE) { - return _zip_allocate_new(fn, zep); + unsigned int flags; + + if (_flags < 0) { + if (zep) + *zep = ZIP_ER_INVAL; + return NULL; } - + flags = (unsigned int)_flags; + switch (_zip_file_exists(fn, flags, zep)) { case -1: - if (!(flags & ZIP_OVERWRITE)) { - return NULL; - } + return NULL; case 0: - return _zip_allocate_new(fn, zep); + return _zip_allocate_new(fn, flags, zep); default: + if (flags & ZIP_TRUNCATE) { + FILE *f; + + if ((f = fopen(fn, "rb")) == NULL) { + set_error(zep, NULL, ZIP_ER_OPEN); + return NULL; + } + fclose(f); + return _zip_allocate_new(fn, flags, zep); + } break; } @@ -82,17 +97,36 @@ zip_open(const char *fn, int flags, int *zep) return NULL; } - return _zip_open(fn, fp, flags, 0, zep); + return _zip_open(fn, fp, flags, zep); } + +ZIP_EXTERN int +zip_archive_set_tempdir(struct zip *za, const char *tempdir) +{ + char *new_tempdir; + + if (tempdir) { + if ((new_tempdir = strdup(tempdir)) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, errno); + return -1; + } + } + else + new_tempdir = NULL; + + free(za->tempdir); + za->tempdir = new_tempdir; + + return 0; +} struct zip * -_zip_open(const char *fn, FILE *fp, int flags, int aflags, int *zep) +_zip_open(const char *fn, FILE *fp, unsigned int flags, int *zep) { struct zip *za; struct zip_cdir *cdir; - int i; off_t len; if (fseeko(fp, 0, SEEK_END) < 0) { @@ -103,7 +137,7 @@ _zip_open(const char *fn, FILE *fp, int flags, int aflags, int *zep) /* treat empty files as empty archives */ if (len == 0) { - if ((za=_zip_allocate_new(fn, zep)) == NULL) + if ((za=_zip_allocate_new(fn, flags, zep)) == NULL) fclose(fp); else za->zp = fp; @@ -116,34 +150,32 @@ _zip_open(const char *fn, FILE *fp, int flags, int aflags, int *zep) return NULL; } - if ((za=_zip_allocate_new(fn, zep)) == NULL) { + if ((za=_zip_allocate_new(fn, flags, zep)) == NULL) { _zip_cdir_free(cdir); fclose(fp); return NULL; } - za->cdir = cdir; + za->entry = cdir->entry; + za->nentry = cdir->nentry; + za->nentry_alloc = cdir->nentry_alloc; + za->comment_orig = cdir->comment; + za->zp = fp; - if ((za->entry=(struct zip_entry *)malloc(sizeof(*(za->entry)) - * cdir->nentry)) == NULL) { - set_error(zep, NULL, ZIP_ER_MEMORY); - _zip_free(za); - return NULL; - } - for (i=0; inentry; i++) - _zip_entry_new(za); + _zip_check_torrentzip(za, cdir); - _zip_check_torrentzip(za); za->ch_flags = za->flags; + free(cdir); + return za; } static void -set_error(int *zep, struct zip_error *err, int ze) +set_error(int *zep, const struct zip_error *err, int ze) { int se; @@ -166,16 +198,17 @@ set_error(int *zep, struct zip_error *err, int ze) entries, or NULL if unsuccessful. */ static struct zip_cdir * -_zip_readcdir(FILE *fp, off_t buf_offset, unsigned char *buf, unsigned char *eocd, int buflen, - int flags, struct zip_error *error) +_zip_readcdir(FILE *fp, off_t buf_offset, unsigned char *buf, const unsigned char *eocd, size_t buflen, + unsigned int flags, struct zip_error *error) { struct zip_cdir *cd; - unsigned char *cdp, **bufp; - int i, comlen, nentry; - zip_uint32_t left; + const unsigned char *cdp; + const unsigned char **bufp; + zip_int64_t tail_len, comment_len; + zip_uint64_t i, left; - comlen = buf + buflen - eocd - EOCDLEN; - if (comlen < 0) { + tail_len = buf + buflen - eocd - EOCDLEN; + if (tail_len < 0) { /* not enough bytes left for comment */ _zip_error_set(error, ZIP_ER_NOZIP, 0); return NULL; @@ -192,46 +225,32 @@ _zip_readcdir(FILE *fp, off_t buf_offset, unsigned char *buf, unsigned char *eoc return NULL; } - cdp = eocd + 8; - /* number of cdir-entries on this disk */ - i = _zip_read2(&cdp); - /* number of cdir-entries */ - nentry = _zip_read2(&cdp); + if (eocd-EOCD64LOCLEN >= buf && memcmp(eocd-EOCD64LOCLEN, EOCD64LOC_MAGIC, 4) == 0) + cd = _zip_read_eocd64(fp, eocd-EOCD64LOCLEN, buf, buf_offset, buflen, flags, error); + else + cd = _zip_read_eocd(eocd, buf, buf_offset, buflen, flags, error); - if ((cd=_zip_cdir_new(nentry, error)) == NULL) + if (cd == NULL) return NULL; - cd->size = _zip_read4(&cdp); - cd->offset = _zip_read4(&cdp); - cd->comment = NULL; - cd->comment_len = _zip_read2(&cdp); + cdp = eocd + 20; + comment_len = _zip_read2(&cdp); - if (((zip_uint64_t)cd->offset)+cd->size > buf_offset + (eocd-buf)) { + if ((zip_uint64_t)cd->offset+(zip_uint64_t)cd->size > (zip_uint64_t)buf_offset + (zip_uint64_t)(eocd-buf)) { /* cdir spans past EOCD record */ _zip_error_set(error, ZIP_ER_INCONS, 0); - cd->nentry = 0; _zip_cdir_free(cd); return NULL; } - if ((comlen < cd->comment_len) || (cd->nentry != i)) { - _zip_error_set(error, ZIP_ER_NOZIP, 0); - cd->nentry = 0; - _zip_cdir_free(cd); - return NULL; - } - if ((flags & ZIP_CHECKCONS) && comlen != cd->comment_len) { + if (tail_len < comment_len || ((flags & ZIP_CHECKCONS) && tail_len != comment_len)) { _zip_error_set(error, ZIP_ER_INCONS, 0); - cd->nentry = 0; _zip_cdir_free(cd); return NULL; } - if (cd->comment_len) { - if ((cd->comment=(char *)_zip_memdup(eocd+EOCDLEN, - cd->comment_len, error)) - == NULL) { - cd->nentry = 0; + if (comment_len) { + if ((cd->comment=_zip_string_new(eocd+EOCDLEN, (zip_uint16_t)comment_len, ZIP_FL_ENC_GUESS, error)) == NULL) { _zip_cdir_free(cd); return NULL; } @@ -249,40 +268,32 @@ _zip_readcdir(FILE *fp, off_t buf_offset, unsigned char *buf, unsigned char *eoc fseeko(fp, cd->offset, SEEK_SET); /* possible consistency check: cd->offset = len-(cd->size+cd->comment_len+EOCDLEN) ? */ - if (ferror(fp) || ((unsigned long)ftello(fp) != cd->offset)) { + if (ferror(fp) || (ftello(fp) != cd->offset)) { /* seek error or offset of cdir wrong */ if (ferror(fp)) _zip_error_set(error, ZIP_ER_SEEK, errno); else _zip_error_set(error, ZIP_ER_NOZIP, 0); - cd->nentry = 0; _zip_cdir_free(cd); return NULL; } } - left = cd->size; + left = (zip_uint64_t)cd->size; i=0; while (inentry && left > 0) { - if ((_zip_dirent_read(cd->entry+i, fp, bufp, &left, 0, error)) < 0) { - cd->nentry = i; + if ((cd->entry[i].orig=_zip_dirent_new()) == NULL + || (_zip_dirent_read(cd->entry[i].orig, fp, bufp, &left, 0, error)) < 0) { _zip_cdir_free(cd); return NULL; } i++; - - if (i == cd->nentry && left > 0) { - /* Infozip extension for more than 64k entries: - nentries wraps around, size indicates correct EOCD */ - if (_zip_cdir_grow(cd, cd->nentry+ZIP_UINT16_MAX, error) < 0) { - cd->nentry = i; - _zip_cdir_free(cd); - return NULL; - } - } } - - cd->nentry = i; + if (i != cd->nentry || ((flags & ZIP_CHECKCONS) && left != 0)) { + _zip_error_set(error, ZIP_ER_INCONS, 0); + _zip_cdir_free(cd); + return NULL; + } return cd; } @@ -295,84 +306,88 @@ _zip_readcdir(FILE *fp, off_t buf_offset, unsigned char *buf, unsigned char *eoc file and header offsets. Returns -1 if not plausible, else the difference between the lowest and the highest fileposition reached */ -static int +static zip_int64_t _zip_checkcons(FILE *fp, struct zip_cdir *cd, struct zip_error *error) { - int i; - unsigned int min, max, j; + zip_uint64_t i; + zip_uint64_t min, max, j; struct zip_dirent temp; if (cd->nentry) { - max = cd->entry[0].offset; - min = cd->entry[0].offset; + max = cd->entry[0].orig->offset; + min = cd->entry[0].orig->offset; } else min = max = 0; for (i=0; inentry; i++) { - if (cd->entry[i].offset < min) - min = cd->entry[i].offset; - if (min > cd->offset) { + if (cd->entry[i].orig->offset < min) + min = cd->entry[i].orig->offset; + if (min > (zip_uint64_t)cd->offset) { _zip_error_set(error, ZIP_ER_NOZIP, 0); return -1; } - j = cd->entry[i].offset + cd->entry[i].comp_size - + cd->entry[i].filename_len + LENTRYSIZE; + j = cd->entry[i].orig->offset + cd->entry[i].orig->comp_size + + _zip_string_length(cd->entry[i].orig->filename) + LENTRYSIZE; if (j > max) max = j; - if (max > cd->offset) { + if (max > (zip_uint64_t)cd->offset) { _zip_error_set(error, ZIP_ER_NOZIP, 0); return -1; } - if (fseeko(fp, cd->entry[i].offset, SEEK_SET) != 0) { - _zip_error_set(error, ZIP_ER_SEEK, 0); + if (fseeko(fp, (off_t)cd->entry[i].orig->offset, SEEK_SET) != 0) { + _zip_error_set(error, ZIP_ER_SEEK, errno); return -1; } if (_zip_dirent_read(&temp, fp, NULL, NULL, 1, error) == -1) return -1; - if (_zip_headercomp(cd->entry+i, 0, &temp, 1) != 0) { + if (_zip_headercomp(cd->entry[i].orig, &temp) != 0) { _zip_error_set(error, ZIP_ER_INCONS, 0); _zip_dirent_finalize(&temp); return -1; } + + cd->entry[i].orig->extra_fields = _zip_ef_merge(cd->entry[i].orig->extra_fields, temp.extra_fields); + cd->entry[i].orig->local_extra_fields_read = 1; + temp.extra_fields = NULL; + _zip_dirent_finalize(&temp); } - return max - min; + return (max-min) < ZIP_INT64_MAX ? (zip_int64_t)(max-min) : ZIP_INT64_MAX; } /* _zip_check_torrentzip: - check whether ZA has a valid TORRENTZIP comment, i.e. is torrentzipped */ + check wether ZA has a valid TORRENTZIP comment, i.e. is torrentzipped */ static void -_zip_check_torrentzip(struct zip *za) +_zip_check_torrentzip(struct zip *za, const struct zip_cdir *cdir) { uLong crc_got, crc_should; char buf[8+1]; char *end; - if (za->zp == NULL || za->cdir == NULL) + if (za->zp == NULL || cdir == NULL) return; - if (za->cdir->comment_len != TORRENT_SIG_LEN+8 - || strncmp(za->cdir->comment, TORRENT_SIG, TORRENT_SIG_LEN) != 0) + if (_zip_string_length(cdir->comment) != TORRENT_SIG_LEN+8 + || strncmp((const char *)cdir->comment->raw, TORRENT_SIG, TORRENT_SIG_LEN) != 0) return; - memcpy(buf, za->cdir->comment+TORRENT_SIG_LEN, 8); + memcpy(buf, cdir->comment->raw+TORRENT_SIG_LEN, 8); buf[8] = '\0'; errno = 0; crc_should = strtoul(buf, &end, 16); if ((crc_should == UINT_MAX && errno != 0) || (end && *end)) return; - if (_zip_filerange_crc(za->zp, za->cdir->offset, za->cdir->size, - &crc_got, NULL) < 0) + if (_zip_filerange_crc(za->zp, cdir->offset, cdir->size, &crc_got, NULL) < 0) return; if (crc_got == crc_should) @@ -383,68 +398,32 @@ _zip_check_torrentzip(struct zip *za) /* _zip_headercomp: - compares two headers h1 and h2; if they are local headers, set - local1p or local2p respectively to 1, else 0. Return 0 if they - are identical, -1 if not. */ + compares a central directory entry and a local file header + Return 0 if they are consistent, -1 if not. */ static int -_zip_headercomp(struct zip_dirent *h1, int local1p, struct zip_dirent *h2, - int local2p) +_zip_headercomp(const struct zip_dirent *central, const struct zip_dirent *local) { - if ((h1->version_needed != h2->version_needed) + if ((central->version_needed != local->version_needed) #if 0 /* some zip-files have different values in local and global headers for the bitflags */ - || (h1->bitflags != h2->bitflags) + || (central->bitflags != local->bitflags) #endif - || (h1->comp_method != h2->comp_method) - || (h1->last_mod != h2->last_mod) - || (h1->filename_len != h2->filename_len) - || !h1->filename || !h2->filename - || strcmp(h1->filename, h2->filename)) + || (central->comp_method != local->comp_method) + || (central->last_mod != local->last_mod) + || !_zip_string_equal(central->filename, local->filename)) return -1; - /* check that CRC and sizes are zero if data descriptor is used */ - if ((h1->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) && local1p - && (h1->crc != 0 - || h1->comp_size != 0 - || h1->uncomp_size != 0)) - return -1; - if ((h2->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) && local2p - && (h2->crc != 0 - || h2->comp_size != 0 - || h2->uncomp_size != 0)) - return -1; - - /* check that CRC and sizes are equal if no data descriptor is used */ - if (((h1->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) == 0 || local1p == 0) - && ((h2->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) == 0 || local2p == 0)) { - if ((h1->crc != h2->crc) - || (h1->comp_size != h2->comp_size) - || (h1->uncomp_size != h2->uncomp_size)) + + if ((central->crc != local->crc) || (central->comp_size != local->comp_size) + || (central->uncomp_size != local->uncomp_size)) { + /* InfoZip stores valid values in local header even when data descriptor is used. + This is in violation of the appnote. */ + if (((local->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) == 0 + || local->crc != 0 || local->comp_size != 0 || local->uncomp_size != 0)) return -1; } - - if ((local1p == local2p) - && ((h1->extrafield_len != h2->extrafield_len) - || (h1->extrafield_len && h2->extrafield - && memcmp(h1->extrafield, h2->extrafield, - h1->extrafield_len)))) - return -1; - - /* if either is local, nothing more to check */ - if (local1p || local2p) - return 0; - - if ((h1->version_madeby != h2->version_madeby) - || (h1->disk_number != h2->disk_number) - || (h1->int_attrib != h2->int_attrib) - || (h1->ext_attrib != h2->ext_attrib) - || (h1->offset != h2->offset) - || (h1->comment_len != h2->comment_len) - || (h1->comment_len && h2->comment - && memcmp(h1->comment, h2->comment, h1->comment_len))) - return -1; return 0; } @@ -452,7 +431,7 @@ _zip_headercomp(struct zip_dirent *h1, int local1p, struct zip_dirent *h2, static struct zip * -_zip_allocate_new(const char *fn, int *zep) +_zip_allocate_new(const char *fn, unsigned int flags, int *zep) { struct zip *za; struct zip_error error; @@ -467,18 +446,19 @@ _zip_allocate_new(const char *fn, int *zep) else { za->zn = strdup(fn); if (!za->zn) { - _zip_free(za); + zip_discard(za); set_error(zep, NULL, ZIP_ER_MEMORY); return NULL; } } + za->open_flags = flags; return za; } static int -_zip_file_exists(const char *fn, int flags, int *zep) +_zip_file_exists(const char *fn, unsigned int flags, int *zep) { struct stat st; @@ -488,7 +468,7 @@ _zip_file_exists(const char *fn, int flags, int *zep) } if (stat(fn, &st) != 0) { - if (flags & ZIP_CREATE || flags & ZIP_OVERWRITE) + if (flags & ZIP_CREATE) return 0; else { set_error(zep, NULL, ZIP_ER_OPEN); @@ -508,12 +488,14 @@ _zip_file_exists(const char *fn, int flags, int *zep) static struct zip_cdir * -_zip_find_central_dir(FILE *fp, int flags, int *zep, off_t len) +_zip_find_central_dir(FILE *fp, unsigned int flags, int *zep, off_t len) { struct zip_cdir *cdir, *cdirnew; unsigned char *buf, *match; off_t buf_offset; - int a, best, buflen, i; + size_t buflen; + zip_int64_t a, i; + zip_int64_t best; struct zip_error zerr; i = fseeko(fp, -(len < CDBUFSIZE ? len : CDBUFSIZE), SEEK_END); @@ -541,10 +523,10 @@ _zip_find_central_dir(FILE *fp, int flags, int *zep, off_t len) best = -1; cdir = NULL; - match = buf; + match = buf+ (buflen < CDBUFSIZE ? 0 : EOCD64LOCLEN); _zip_error_set(&zerr, ZIP_ER_NOZIP, 0); - while ((match=_zip_memmem(match, buflen-(match-buf)-18, + while ((match=_zip_memmem(match, buflen-(size_t)(match-buf)-(EOCDLEN-4), (const unsigned char *)EOCD_MAGIC, 4))!=NULL) { /* found match -- check, if good */ /* to avoid finding the same match all over again */ @@ -589,8 +571,7 @@ _zip_find_central_dir(FILE *fp, int flags, int *zep, off_t len) static unsigned char * -_zip_memmem(const unsigned char *big, int biglen, const unsigned char *little, - int littlelen) +_zip_memmem(const unsigned char *big, size_t biglen, const unsigned char *little, size_t littlelen) { const unsigned char *p; @@ -598,11 +579,159 @@ _zip_memmem(const unsigned char *big, int biglen, const unsigned char *little, return NULL; p = big-1; while ((p=(const unsigned char *) - memchr(p+1, little[0], (size_t)(big-(p+1)+biglen-littlelen+1))) - != NULL) { + memchr(p+1, little[0], (size_t)(big-(p+1))+(size_t)(biglen-littlelen)+1)) != NULL) { if (memcmp(p+1, little+1, littlelen-1)==0) return (unsigned char *)p; } return NULL; } + + + +static struct zip_cdir * +_zip_read_eocd(const unsigned char *eocd, const unsigned char *buf, off_t buf_offset, size_t buflen, + unsigned int flags, struct zip_error *error) +{ + struct zip_cdir *cd; + const unsigned char *cdp; + zip_uint64_t i, nentry, size, offset; + + if (eocd+EOCDLEN > buf+buflen) { + _zip_error_set(error, ZIP_ER_INCONS, 0); + return NULL; + } + + cdp = eocd + 8; + + /* number of cdir-entries on this disk */ + i = _zip_read2(&cdp); + /* number of cdir-entries */ + nentry = _zip_read2(&cdp); + + if (nentry != i) { + _zip_error_set(error, ZIP_ER_NOZIP, 0); + return NULL; + } + + size = _zip_read4(&cdp); + offset = _zip_read4(&cdp); + + if (size > ZIP_OFF_MAX || offset > ZIP_OFF_MAX || offset+size > ZIP_OFF_MAX) { + _zip_error_set(error, ZIP_ER_SEEK, EFBIG); + return NULL; + } + + if (offset+size > (zip_uint64_t)(buf_offset + (eocd-buf))) { + /* cdir spans past EOCD record */ + _zip_error_set(error, ZIP_ER_INCONS, 0); + return NULL; + } + + if ((flags & ZIP_CHECKCONS) && offset+size != (zip_uint64_t)(buf_offset + (eocd-buf))) { + _zip_error_set(error, ZIP_ER_INCONS, 0); + return NULL; + } + + if ((cd=_zip_cdir_new(nentry, error)) == NULL) + return NULL; + + cd->size = (off_t)size; + cd->offset = (off_t)offset; + + return cd; +} + + + +static struct zip_cdir * +_zip_read_eocd64(FILE *f, const zip_uint8_t *eocd64loc, const zip_uint8_t *buf, + off_t buf_offset, size_t buflen, unsigned int flags, struct zip_error *error) +{ + struct zip_cdir *cd; + zip_uint64_t offset; + const zip_uint8_t *cdp; + zip_uint8_t eocd[EOCD64LEN]; + zip_uint64_t eocd_offset; + zip_uint64_t size, nentry, i; + + cdp = eocd64loc+8; + eocd_offset = _zip_read8(&cdp); + + if (eocd_offset > ZIP_OFF_MAX || eocd_offset + EOCD64LEN > ZIP_OFF_MAX) { + _zip_error_set(error, ZIP_ER_SEEK, EFBIG); + return NULL; + } + + if (eocd64loc < buf || (off_t)eocd_offset+EOCD64LEN > (buf_offset+(eocd64loc-buf))) { + _zip_error_set(error, ZIP_ER_INCONS, 0); + return NULL; + } + + if ((off_t)eocd_offset >= buf_offset && (off_t)eocd_offset+EOCD64LEN <= buf_offset+(ssize_t)buflen) + cdp = buf+((off_t)eocd_offset-buf_offset); + else { + if (fseeko(f, (off_t)eocd_offset, SEEK_SET) != 0) { + _zip_error_set(error, ZIP_ER_SEEK, errno); + return NULL; + } + + clearerr(f); + if (fread(eocd, 1, EOCD64LEN, f) < EOCD64LEN) { + _zip_error_set(error, ZIP_ER_READ, errno); + return NULL; + } + + if (ferror(f)) { + _zip_error_set(error, ZIP_ER_READ, errno); + return NULL; + } + + cdp = eocd; + } + + if (memcmp(cdp, EOCD64_MAGIC, 4) != 0) { + _zip_error_set(error, ZIP_ER_INCONS, 0); + return NULL; + } + cdp += 4; + + size = _zip_read8(&cdp); + + if ((flags & ZIP_CHECKCONS) && size+eocd_offset+12 != (zip_uint64_t)(buf_offset+(eocd64loc-buf))) { + _zip_error_set(error, ZIP_ER_INCONS, 0); + return NULL; + } + + cdp += 4; /* skip version made by/needed */ + cdp += 8; /* skip num disks */ + + nentry = _zip_read8(&cdp); + i = _zip_read8(&cdp); + + if (nentry != i) { + _zip_error_set(error, ZIP_ER_MULTIDISK, 0); + return NULL; + } + + size = _zip_read8(&cdp); + offset = _zip_read8(&cdp); + + if (size > ZIP_OFF_MAX || offset > ZIP_OFF_MAX || offset+size > ZIP_OFF_MAX) { + _zip_error_set(error, ZIP_ER_SEEK, EFBIG); + return NULL; + } + if ((flags & ZIP_CHECKCONS) && offset+size != eocd_offset) { + _zip_error_set(error, ZIP_ER_INCONS, 0); + return NULL; + } + + if ((cd=_zip_cdir_new(nentry, error)) == NULL) + return NULL; + + + cd->size = (off_t)size; + cd->offset = (off_t)offset; + + return cd; +} diff --git a/ext/zip/lib/zip_rename.c b/ext/zip/lib/zip_rename.c index 6b5a0359172da..8841caeca9a9e 100644 --- a/ext/zip/lib/zip_rename.c +++ b/ext/zip/lib/zip_rename.c @@ -1,6 +1,6 @@ /* zip_rename.c -- rename file in zip archive - Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2012 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -35,36 +35,13 @@ #include +#define _ZIP_COMPILING_DEPRECATED #include "zipint.h" -ZIP_EXTERN(int) +ZIP_EXTERN int zip_rename(struct zip *za, zip_uint64_t idx, const char *name) { - const char *old_name; - int old_is_dir, new_is_dir; - - if (idx >= za->nentry || name[0] == '\0') { - _zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return -1; - } - - if (ZIP_IS_RDONLY(za)) { - _zip_error_set(&za->error, ZIP_ER_RDONLY, 0); - return -1; - } - - if ((old_name=zip_get_name(za, idx, 0)) == NULL) - return -1; - - new_is_dir = (name[strlen(name)-1] == '/'); - old_is_dir = (old_name[strlen(old_name)-1] == '/'); - - if (new_is_dir != old_is_dir) { - _zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return -1; - } - - return _zip_set_name(za, idx, name); + return zip_file_rename(za, idx, name, 0); } diff --git a/ext/zip/lib/zip_replace.c b/ext/zip/lib/zip_replace.c index 6dc3dd5ab508f..de717afec7dd1 100644 --- a/ext/zip/lib/zip_replace.c +++ b/ext/zip/lib/zip_replace.c @@ -1,6 +1,6 @@ /* zip_replace.c -- replace file via callback function - Copyright (C) 1999-2009 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2012 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -33,53 +33,13 @@ +#define _ZIP_COMPILING_DEPRECATED #include "zipint.h" -ZIP_EXTERN(int) +ZIP_EXTERN int zip_replace(struct zip *za, zip_uint64_t idx, struct zip_source *source) { - if (idx >= za->nentry || source == NULL) { - _zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return -1; - } - - if (_zip_replace(za, idx, NULL, source) == -1) - return -1; - - return 0; -} - - - - -/* NOTE: Signed due to -1 on error. See zip_add.c for more details. */ - -zip_int64_t -_zip_replace(struct zip *za, zip_uint64_t idx, const char *name, - struct zip_source *source) -{ - if (ZIP_IS_RDONLY(za)) { - _zip_error_set(&za->error, ZIP_ER_RDONLY, 0); - return -1; - } - - if (idx == ZIP_UINT64_MAX) { - if (_zip_entry_new(za) == NULL) - return -1; - - idx = za->nentry - 1; - } - - _zip_unchange_data(za->entry+idx); - - if (name && _zip_set_name(za, idx, name) != 0) - return -1; - - za->entry[idx].state = ((za->cdir == NULL || idx >= za->cdir->nentry) - ? ZIP_ST_ADDED : ZIP_ST_REPLACED); - za->entry[idx].source = source; - - return idx; + return zip_file_replace(za, idx, source, 0); } diff --git a/ext/zip/lib/zip_set_archive_comment.c b/ext/zip/lib/zip_set_archive_comment.c index 3cd069c7577c9..df1caee06b116 100644 --- a/ext/zip/lib/zip_set_archive_comment.c +++ b/ext/zip/lib/zip_set_archive_comment.c @@ -1,6 +1,6 @@ /* zip_set_archive_comment.c -- set archive comment - Copyright (C) 2006-2009 Dieter Baron and Thomas Klausner + Copyright (C) 2006-2013 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -39,32 +39,46 @@ -ZIP_EXTERN(int) -zip_set_archive_comment(struct zip *za, const char *comment, int len) +ZIP_EXTERN int +zip_set_archive_comment(struct zip *za, const char *comment, zip_uint16_t len) { - char *tmpcom; + struct zip_string *cstr; - if (len < 0 || len > MAXCOMLEN - || (len > 0 && comment == NULL)) { - _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + if (ZIP_IS_RDONLY(za)) { + _zip_error_set(&za->error, ZIP_ER_RDONLY, 0); return -1; } - if (ZIP_IS_RDONLY(za)) { - _zip_error_set(&za->error, ZIP_ER_RDONLY, 0); + if (len > 0 && comment == NULL) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); return -1; } if (len > 0) { - if ((tmpcom=(char *)_zip_memdup(comment, len, &za->error)) == NULL) + if ((cstr=_zip_string_new((const zip_uint8_t *)comment, len, ZIP_FL_ENC_GUESS, &za->error)) == NULL) return -1; + + if (_zip_guess_encoding(cstr, ZIP_ENCODING_UNKNOWN) == ZIP_ENCODING_CP437) { + _zip_string_free(cstr); + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } } else - tmpcom = NULL; + cstr = NULL; + + _zip_string_free(za->comment_changes); + za->comment_changes = NULL; - free(za->ch_comment); - za->ch_comment = tmpcom; - za->ch_comment_len = len; + if (((za->comment_orig && _zip_string_equal(za->comment_orig, cstr)) + || (za->comment_orig == NULL && cstr == NULL))) { + _zip_string_free(cstr); + za->comment_changed = 0; + } + else { + za->comment_changes = cstr; + za->comment_changed = 1; + } return 0; } diff --git a/ext/zip/lib/zip_set_archive_flag.c b/ext/zip/lib/zip_set_archive_flag.c index 07bcfbe304d85..b6cdab120ddb2 100644 --- a/ext/zip/lib/zip_set_archive_flag.c +++ b/ext/zip/lib/zip_set_archive_flag.c @@ -37,8 +37,8 @@ -ZIP_EXTERN(int) -zip_set_archive_flag(struct zip *za, int flag, int value) +ZIP_EXTERN int +zip_set_archive_flag(struct zip *za, unsigned int flag, int value) { unsigned int new_flags; diff --git a/ext/zip/lib/zip_set_default_password.c b/ext/zip/lib/zip_set_default_password.c index c274d1100bb3a..b9aa80acffc25 100644 --- a/ext/zip/lib/zip_set_default_password.c +++ b/ext/zip/lib/zip_set_default_password.c @@ -40,7 +40,7 @@ -ZIP_EXTERN(int) +ZIP_EXTERN int zip_set_default_password(struct zip *za, const char *passwd) { if (za == NULL) diff --git a/ext/zip/lib/zip_set_file_comment.c b/ext/zip/lib/zip_set_file_comment.c index 5e63dc2730ad4..7acd0eb36de29 100644 --- a/ext/zip/lib/zip_set_file_comment.c +++ b/ext/zip/lib/zip_set_file_comment.c @@ -1,6 +1,6 @@ /* zip_set_file_comment.c -- set comment for file in archive - Copyright (C) 2006-2009 Dieter Baron and Thomas Klausner + Copyright (C) 2006-2012 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -35,38 +35,17 @@ #include +#define _ZIP_COMPILING_DEPRECATED #include "zipint.h" -ZIP_EXTERN(int) -zip_set_file_comment(struct zip *za, zip_uint64_t idx, - const char *comment, int len) +ZIP_EXTERN int +zip_set_file_comment(struct zip *za, zip_uint64_t idx, const char *comment, int len) { - char *tmpcom; - - if (idx >= za->nentry - || len < 0 || len > MAXCOMLEN - || (len > 0 && comment == NULL)) { - _zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return -1; - } - - if (ZIP_IS_RDONLY(za)) { - _zip_error_set(&za->error, ZIP_ER_RDONLY, 0); - return -1; + if (len < 0 || len > ZIP_UINT16_MAX) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; } - - if (len > 0) { - if ((tmpcom=(char *)_zip_memdup(comment, len, &za->error)) == NULL) - return -1; - } - else - tmpcom = NULL; - - free(za->entry[idx].ch_comment); - za->entry[idx].ch_comment = tmpcom; - za->entry[idx].ch_comment_len = len; - - return 0; + return zip_file_set_comment(za, idx, comment, (zip_uint16_t)len, 0); } diff --git a/ext/zip/lib/zip_set_file_compression.c b/ext/zip/lib/zip_set_file_compression.c new file mode 100644 index 0000000000000..ea8517d70e602 --- /dev/null +++ b/ext/zip/lib/zip_set_file_compression.c @@ -0,0 +1,90 @@ +/* + zip_set_file_compression.c -- set compression for file in archive + Copyright (C) 2012 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include "zipint.h" + + + +ZIP_EXTERN int +zip_set_file_compression(struct zip *za, zip_uint64_t idx, + zip_int32_t method, zip_uint32_t flags) +{ + struct zip_entry *e; + zip_int32_t old_method; + + if (idx >= za->nentry) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return -1; + } + + if (ZIP_IS_RDONLY(za)) { + _zip_error_set(&za->error, ZIP_ER_RDONLY, 0); + return -1; + } + + if (method != ZIP_CM_DEFAULT && method != ZIP_CM_STORE && method != ZIP_CM_DEFLATE) { + _zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0); + return -1; + } + + e = za->entry+idx; + + old_method = (e->orig == NULL ? ZIP_CM_DEFAULT : e->orig->comp_method); + + /* XXX: revisit this when flags are supported, since they may require a recompression */ + + if (method == old_method) { + if (e->changes) { + e->changes->changed &= ~ZIP_DIRENT_COMP_METHOD; + if (e->changes->changed == 0) { + _zip_dirent_free(e->changes); + e->changes = NULL; + } + } + } + else { + if (e->changes == NULL) { + if ((e->changes=_zip_dirent_clone(e->orig)) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return -1; + } + } + + e->changes->comp_method = method; + e->changes->changed |= ZIP_DIRENT_COMP_METHOD; + } + + return 0; +} diff --git a/ext/zip/lib/zip_set_name.c b/ext/zip/lib/zip_set_name.c index 2a90601bfec35..60c9e7d5bf59a 100644 --- a/ext/zip/lib/zip_set_name.c +++ b/ext/zip/lib/zip_set_name.c @@ -1,6 +1,6 @@ /* zip_set_name.c -- rename helper function - Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2012 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -41,35 +41,77 @@ int -_zip_set_name(struct zip *za, zip_uint64_t idx, const char *name) +_zip_set_name(struct zip *za, zip_uint64_t idx, const char *name, zip_flags_t flags) { - char *s; + struct zip_entry *e; + struct zip_string *str; + int changed; zip_int64_t i; - - if (idx >= za->nentry || name == NULL) { + + if (idx >= za->nentry) { _zip_error_set(&za->error, ZIP_ER_INVAL, 0); return -1; } - if ((i=_zip_name_locate(za, name, 0, NULL)) != -1 && i != idx) { + if (ZIP_IS_RDONLY(za)) { + _zip_error_set(&za->error, ZIP_ER_RDONLY, 0); + return -1; + } + + if (name && strlen(name) > 0) { + /* XXX: check for string too long */ + if ((str=_zip_string_new((const zip_uint8_t *)name, (zip_uint16_t)strlen(name), flags, &za->error)) == NULL) + return -1; + if ((flags & ZIP_FL_ENCODING_ALL) == ZIP_FL_ENC_GUESS && _zip_guess_encoding(str, ZIP_ENCODING_UNKNOWN) == ZIP_ENCODING_UTF8_GUESSED) + str->encoding = ZIP_ENCODING_UTF8_KNOWN; + } + else + str = NULL; + + /* XXX: encoding flags needed for CP437? */ + if ((i=_zip_name_locate(za, name, 0, NULL)) >= 0 && (zip_uint64_t)i != idx) { + _zip_string_free(str); _zip_error_set(&za->error, ZIP_ER_EXISTS, 0); return -1; } /* no effective name change */ - if (i == idx) + if (i>=0 && (zip_uint64_t)i == idx) { + _zip_string_free(str); return 0; - - if ((s=strdup(name)) == NULL) { - _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return -1; } - - if (za->entry[idx].state == ZIP_ST_UNCHANGED) - za->entry[idx].state = ZIP_ST_RENAMED; - free(za->entry[idx].ch_filename); - za->entry[idx].ch_filename = s; + e = za->entry+idx; + + if (e->changes) { + _zip_string_free(e->changes->filename); + e->changes->filename = NULL; + e->changes->changed &= ~ZIP_DIRENT_FILENAME; + } + + if (e->orig) + changed = !_zip_string_equal(e->orig->filename, str); + else + changed = 1; + + if (changed) { + if (e->changes == NULL) { + if ((e->changes=_zip_dirent_clone(e->orig)) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + _zip_string_free(str); + return -1; + } + } + e->changes->filename = str; + e->changes->changed |= ZIP_DIRENT_FILENAME; + } + else { + _zip_string_free(str); + if (e->changes && e->changes->changed == 0) { + _zip_dirent_free(e->changes); + e->changes = NULL; + } + } return 0; } diff --git a/ext/zip/lib/zip_source_buffer.c b/ext/zip/lib/zip_source_buffer.c index 8c9154ce3c5ba..8a13e7602d195 100644 --- a/ext/zip/lib/zip_source_buffer.c +++ b/ext/zip/lib/zip_source_buffer.c @@ -48,7 +48,7 @@ static zip_int64_t read_data(void *, void *, zip_uint64_t, enum zip_source_cmd); -ZIP_EXTERN(struct zip_source *) +ZIP_EXTERN struct zip_source * zip_source_buffer(struct zip *za, const void *data, zip_uint64_t len, int freep) { struct read_data *f; @@ -98,9 +98,7 @@ read_data(void *state, void *data, zip_uint64_t len, enum zip_source_cmd cmd) return 0; case ZIP_SOURCE_READ: - /* XXX: return error if (len > ZIP_INT64_MAX) */ - - n = z->end - z->buf; + n = (zip_uint64_t)(z->end - z->buf); if (n > len) n = len; @@ -109,7 +107,7 @@ read_data(void *state, void *data, zip_uint64_t len, enum zip_source_cmd cmd) z->buf += n; } - return n; + return (zip_int64_t)n; case ZIP_SOURCE_CLOSE: return 0; @@ -125,7 +123,7 @@ read_data(void *state, void *data, zip_uint64_t len, enum zip_source_cmd cmd) zip_stat_init(st); st->mtime = z->mtime; - st->size = z->end - z->data; + st->size = (zip_uint64_t)(z->end - z->data); st->comp_size = st->size; st->comp_method = ZIP_CM_STORE; st->encryption_method = ZIP_EM_NONE; diff --git a/ext/zip/lib/zip_source_close.c b/ext/zip/lib/zip_source_close.c index a3bf7e5e1d9bd..7b89d5fc15f68 100644 --- a/ext/zip/lib/zip_source_close.c +++ b/ext/zip/lib/zip_source_close.c @@ -37,7 +37,7 @@ -ZIP_EXTERN(void) +void zip_source_close(struct zip_source *src) { if (!src->is_open) diff --git a/ext/zip/lib/zip_source_crc.c b/ext/zip/lib/zip_source_crc.c index 7fd78f56970cf..99bc965228898 100644 --- a/ext/zip/lib/zip_source_crc.c +++ b/ext/zip/lib/zip_source_crc.c @@ -38,7 +38,7 @@ #include "zipint.h" -struct crc { +struct crc_context { int eof; int validate; int e[2]; @@ -51,23 +51,27 @@ static zip_int64_t crc_read(struct zip_source *, void *, void * -ZIP_EXTERN(struct zip_source *) +struct zip_source * zip_source_crc(struct zip *za, struct zip_source *src, int validate) { - struct crc *ctx; + struct crc_context *ctx; if (src == NULL) { _zip_error_set(&za->error, ZIP_ER_INVAL, 0); return NULL; } - if ((ctx=(struct crc *)malloc(sizeof(*ctx))) == NULL) { + if ((ctx=(struct crc_context *)malloc(sizeof(*ctx))) == NULL) { _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); return NULL; } + ctx->eof = 0; ctx->validate = validate; - + ctx->e[0] = ctx->e[1] = 0; + ctx->size = 0; + ctx->crc = 0; + return zip_source_layered(za, src, crc_read, ctx); } @@ -77,15 +81,15 @@ static zip_int64_t crc_read(struct zip_source *src, void *_ctx, void *data, zip_uint64_t len, enum zip_source_cmd cmd) { - struct crc *ctx; + struct crc_context *ctx; zip_int64_t n; - ctx = (struct crc *)_ctx; + ctx = (struct crc_context *)_ctx; switch (cmd) { case ZIP_SOURCE_OPEN: ctx->eof = 0; - ctx->crc = crc32(0, NULL, 0); + ctx->crc = (zip_uint32_t)crc32(0, NULL, 0); ctx->size = 0; return 0; @@ -120,8 +124,8 @@ crc_read(struct zip_source *src, void *_ctx, void *data, } } else { - ctx->size += n; - ctx->crc = crc32(ctx->crc, data, n); + ctx->size += (zip_uint64_t)n; + ctx->crc = (zip_uint32_t)crc32(ctx->crc, (const Bytef *)data, (uInt)n); /* XXX: check for overflow, use multiple crc calls if needed */ } return n; @@ -139,7 +143,10 @@ crc_read(struct zip_source *src, void *_ctx, void *data, After all, this only works for uncompressed data. */ st->size = ctx->size; st->crc = ctx->crc; - st->valid |= ZIP_STAT_SIZE|ZIP_STAT_CRC; + st->comp_size = ctx->size; + st->comp_method = ZIP_CM_STORE; + st->encryption_method = ZIP_EM_NONE; + st->valid |= ZIP_STAT_SIZE|ZIP_STAT_CRC|ZIP_STAT_COMP_SIZE|ZIP_STAT_COMP_METHOD|ZIP_STAT_ENCRYPTION_METHOD;; } } return 0; diff --git a/ext/zip/lib/zip_source_deflate.c b/ext/zip/lib/zip_source_deflate.c index 5d9c5e67bb605..879953144ce56 100644 --- a/ext/zip/lib/zip_source_deflate.c +++ b/ext/zip/lib/zip_source_deflate.c @@ -60,14 +60,14 @@ static void deflate_free(struct deflate *); -ZIP_EXTERN(struct zip_source *) +struct zip_source * zip_source_deflate(struct zip *za, struct zip_source *src, - zip_uint16_t cm, int flags) + zip_int32_t cm, int flags) { struct deflate *ctx; struct zip_source *s2; - if (src == NULL || cm != ZIP_CM_DEFLATE) { + if (src == NULL || (cm != ZIP_CM_DEFLATE && !ZIP_CM_IS_DEFAULT(cm))) { _zip_error_set(&za->error, ZIP_ER_INVAL, 0); return NULL; } @@ -113,7 +113,7 @@ compress_read(struct zip_source *src, struct deflate *ctx, return 0; ctx->zstr.next_out = (Bytef *)data; - ctx->zstr.avail_out = len; + ctx->zstr.avail_out = (uInt)len; /* XXX: check for overflow */ end = 0; while (!end) { @@ -136,8 +136,7 @@ compress_read(struct zip_source *src, struct deflate *ctx, break; } - if ((n=zip_source_read(src, ctx->buffer, - sizeof(ctx->buffer))) < 0) { + if ((n=zip_source_read(src, ctx->buffer, sizeof(ctx->buffer))) < 0) { zip_source_error(src, ctx->e, ctx->e+1); end = 1; break; @@ -149,7 +148,7 @@ compress_read(struct zip_source *src, struct deflate *ctx, } else { ctx->zstr.next_in = (Bytef *)ctx->buffer; - ctx->zstr.avail_in = n; + ctx->zstr.avail_in = (uInt)n; } continue; } @@ -167,7 +166,7 @@ compress_read(struct zip_source *src, struct deflate *ctx, } if (ctx->zstr.avail_out < len) - return len - ctx->zstr.avail_out; + return (zip_int64_t)(len - ctx->zstr.avail_out); return (ctx->e[0] == 0) ? 0 : -1; } @@ -188,7 +187,7 @@ decompress_read(struct zip_source *src, struct deflate *ctx, return 0; ctx->zstr.next_out = (Bytef *)data; - ctx->zstr.avail_out = len; + ctx->zstr.avail_out = (uInt)len; /* XXX: check for overflow */ end = 0; while (!end && ctx->zstr.avail_out) { @@ -210,8 +209,7 @@ decompress_read(struct zip_source *src, struct deflate *ctx, break; } - if ((n=zip_source_read(src, ctx->buffer, - sizeof(ctx->buffer))) < 0) { + if ((n=zip_source_read(src, ctx->buffer, sizeof(ctx->buffer))) < 0) { zip_source_error(src, ctx->e, ctx->e+1); end = 1; break; @@ -220,7 +218,7 @@ decompress_read(struct zip_source *src, struct deflate *ctx, ctx->eof = 1; else { ctx->zstr.next_in = (Bytef *)ctx->buffer; - ctx->zstr.avail_in = n; + ctx->zstr.avail_in = (uInt)n; } continue; } @@ -237,7 +235,7 @@ decompress_read(struct zip_source *src, struct deflate *ctx, } if (ctx->zstr.avail_out < len) - return len - ctx->zstr.avail_out; + return (zip_int64_t)(len - ctx->zstr.avail_out); return (ctx->e[0] == 0) ? 0 : -1; } @@ -334,7 +332,7 @@ deflate_decompress(struct zip_source *src, void *ud, void *data, ctx->zstr.zfree = Z_NULL; ctx->zstr.opaque = NULL; ctx->zstr.next_in = (Bytef *)ctx->buffer; - ctx->zstr.avail_in = n; + ctx->zstr.avail_in = (uInt)n /* XXX: check for overflow */; /* negative value to tell zlib that there is no header */ if ((ret=inflateInit2(&ctx->zstr, -MAX_WBITS)) != Z_OK) { diff --git a/ext/zip/lib/zip_source_error.c b/ext/zip/lib/zip_source_error.c index ffb4652d33621..a1efd551ea3dd 100644 --- a/ext/zip/lib/zip_source_error.c +++ b/ext/zip/lib/zip_source_error.c @@ -1,6 +1,6 @@ /* zip_source_error.c -- get last error from zip_source - Copyright (C) 2009 Dieter Baron and Thomas Klausner + Copyright (C) 2009-2013 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -37,24 +37,21 @@ -ZIP_EXTERN(void) +void zip_source_error(struct zip_source *src, int *ze, int *se) { int e[2]; if (src->src == NULL) { + if (src->cb.f(src->ud, e, sizeof(e), ZIP_SOURCE_ERROR) < 0) { + e[0] = ZIP_ER_INTERNAL; + e[1] = 0; + } } else { switch (src->error_source) { case ZIP_LES_NONE: - if (src->src == NULL) { - if (src->cb.f(src->ud, e, sizeof(e), ZIP_SOURCE_ERROR) < 0) { - e[0] = ZIP_ER_INTERNAL; - e[1] = 0; - } - } - else - e[0] = e[1] = 0; + e[0] = e[1] = 0; break; case ZIP_LES_INVAL: @@ -67,8 +64,7 @@ zip_source_error(struct zip_source *src, int *ze, int *se) return; case ZIP_LES_UPPER: - if (src->cb.l(src->src, src->ud, e, sizeof(e), - ZIP_SOURCE_ERROR) < 0) { + if (src->cb.l(src->src, src->ud, e, sizeof(e), ZIP_SOURCE_ERROR) < 0) { e[0] = ZIP_ER_INTERNAL; e[1] = 0; } @@ -77,6 +73,7 @@ zip_source_error(struct zip_source *src, int *ze, int *se) default: e[0] = ZIP_ER_INTERNAL; e[1] = 0; + break; } } diff --git a/ext/zip/lib/zip_source_file.c b/ext/zip/lib/zip_source_file.c index 681cc2f3ea643..79c8ee5aca22b 100644 --- a/ext/zip/lib/zip_source_file.c +++ b/ext/zip/lib/zip_source_file.c @@ -40,7 +40,7 @@ -ZIP_EXTERN(struct zip_source *) +ZIP_EXTERN struct zip_source * zip_source_file(struct zip *za, const char *fname, zip_uint64_t start, zip_int64_t len) { diff --git a/ext/zip/lib/zip_source_filep.c b/ext/zip/lib/zip_source_filep.c index 4d896a4c01bfc..0bd2d6846e5a3 100644 --- a/ext/zip/lib/zip_source_filep.c +++ b/ext/zip/lib/zip_source_filep.c @@ -58,14 +58,14 @@ static zip_int64_t read_file(void *state, void *data, zip_uint64_t len, -ZIP_EXTERN(struct zip_source *) +ZIP_EXTERN struct zip_source * zip_source_filep(struct zip *za, FILE *file, zip_uint64_t start, zip_int64_t len) { if (za == NULL) return NULL; - if (file == NULL || start < 0 || len < -1) { + if (file == NULL || len < -1) { _zip_error_set(&za->error, ZIP_ER_INVAL, 0); return NULL; } @@ -125,7 +125,7 @@ read_file(void *state, void *data, zip_uint64_t len, enum zip_source_cmd cmd) { struct read_file *z; char *buf; - int i, n; + size_t i, n; z = (struct read_file *)state; buf = (char *)data; @@ -140,7 +140,7 @@ read_file(void *state, void *data, zip_uint64_t len, enum zip_source_cmd cmd) } } - if (z->closep) { + if (z->closep && z->off > 0) { if (fseeko(z->f, (off_t)z->off, SEEK_SET) < 0) { z->e[0] = ZIP_ER_SEEK; z->e[1] = errno; @@ -153,30 +153,31 @@ read_file(void *state, void *data, zip_uint64_t len, enum zip_source_cmd cmd) case ZIP_SOURCE_READ: /* XXX: return INVAL if len > size_t max */ if (z->remain != -1) - n = len > z->remain ? z->remain : len; + n = len > (zip_uint64_t)z->remain ? (zip_uint64_t)z->remain : len; else n = len; if (!z->closep) { /* we might share this file with others, so let's be safe */ - if (fseeko(z->f, (off_t)(z->off + z->len-z->remain), - SEEK_SET) < 0) { + if (fseeko(z->f, (off_t)(z->off + (zip_uint64_t)(z->len-z->remain)), SEEK_SET) < 0) { z->e[0] = ZIP_ER_SEEK; z->e[1] = errno; return -1; } } - if ((i=fread(buf, 1, n, z->f)) < 0) { - z->e[0] = ZIP_ER_READ; - z->e[1] = errno; - return -1; + if ((i=fread(buf, 1, n, z->f)) == 0) { + if (ferror(z->f)) { + z->e[0] = ZIP_ER_READ; + z->e[1] = errno; + return -1; + } } if (z->remain != -1) z->remain -= i; - return i; + return (zip_int64_t)i; case ZIP_SOURCE_CLOSE: if (z->fname) { @@ -214,11 +215,11 @@ read_file(void *state, void *data, zip_uint64_t len, enum zip_source_cmd cmd) st->mtime = fst.st_mtime; st->valid |= ZIP_STAT_MTIME; if (z->len != -1) { - st->size = z->len; + st->size = (zip_uint64_t)z->len; st->valid |= ZIP_STAT_SIZE; } else if ((fst.st_mode&S_IFMT) == S_IFREG) { - st->size = fst.st_size; + st->size = (zip_uint64_t)fst.st_size; st->valid |= ZIP_STAT_SIZE; } } diff --git a/ext/zip/lib/zip_source_free.c b/ext/zip/lib/zip_source_free.c index f71c71ed6c577..b1e78404965c2 100644 --- a/ext/zip/lib/zip_source_free.c +++ b/ext/zip/lib/zip_source_free.c @@ -39,7 +39,7 @@ -ZIP_EXTERN(void) +ZIP_EXTERN void zip_source_free(struct zip_source *src) { if (src == NULL) diff --git a/ext/zip/lib/zip_source_function.c b/ext/zip/lib/zip_source_function.c index 984b107f7baa6..cb92e339b4bb2 100644 --- a/ext/zip/lib/zip_source_function.c +++ b/ext/zip/lib/zip_source_function.c @@ -39,7 +39,7 @@ -ZIP_EXTERN(struct zip_source *) +ZIP_EXTERN struct zip_source * zip_source_function(struct zip *za, zip_source_callback zcb, void *ud) { struct zip_source *zs; diff --git a/ext/zip/lib/zip_source_layered.c b/ext/zip/lib/zip_source_layered.c index 86ed420407071..ad2870333cdee 100644 --- a/ext/zip/lib/zip_source_layered.c +++ b/ext/zip/lib/zip_source_layered.c @@ -39,7 +39,7 @@ -ZIP_EXTERN(struct zip_source *) +struct zip_source * zip_source_layered(struct zip *za, struct zip_source *src, zip_source_layered_callback cb, void *ud) { diff --git a/ext/zip/lib/zip_source_open.c b/ext/zip/lib/zip_source_open.c index 2c768f7f3a4e5..a5010393e7b9c 100644 --- a/ext/zip/lib/zip_source_open.c +++ b/ext/zip/lib/zip_source_open.c @@ -1,6 +1,6 @@ /* zip_source_open.c -- open zip_source (prepare for reading) - Copyright (C) 2009 Dieter Baron and Thomas Klausner + Copyright (C) 2009-2013 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -37,7 +37,7 @@ -ZIP_EXTERN(int) +int zip_source_open(struct zip_source *src) { zip_int64_t ret; @@ -60,7 +60,7 @@ zip_source_open(struct zip_source *src) ret = src->cb.l(src->src, src->ud, NULL, 0, ZIP_SOURCE_OPEN); if (ret < 0) { - (void)zip_source_close(src->src); + zip_source_close(src->src); if (ret == ZIP_SOURCE_ERR_LOWER) src->error_source = ZIP_LES_LOWER; diff --git a/ext/zip/lib/zip_source_pkware.c b/ext/zip/lib/zip_source_pkware.c index 83b5cc5ad5b22..ec53dfeef0468 100644 --- a/ext/zip/lib/zip_source_pkware.c +++ b/ext/zip/lib/zip_source_pkware.c @@ -49,10 +49,6 @@ struct trad_pkware { #define KEY1 591751049 #define KEY2 878082192 -static const uLongf *crc = NULL; - -#define CRC32(c, b) (crc[((c) ^ (b)) & 0xff] ^ ((c) >> 8)) - static void decrypt(struct trad_pkware *, zip_uint8_t *, @@ -64,7 +60,7 @@ static void pkware_free(struct trad_pkware *); -ZIP_EXTERN(struct zip_source *) +struct zip_source * zip_source_pkware(struct zip *za, struct zip_source *src, zip_uint16_t em, int flags, const char *password) { @@ -80,9 +76,6 @@ zip_source_pkware(struct zip *za, struct zip_source *src, return NULL; } - if (crc == NULL) - crc = get_crc_table(); - if ((ctx=(struct trad_pkware *)malloc(sizeof(*ctx))) == NULL) { _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); return NULL; @@ -118,7 +111,7 @@ decrypt(struct trad_pkware *ctx, zip_uint8_t *out, const zip_uint8_t *in, if (!update_only) { /* decrypt next byte */ - tmp = ctx->key[2] | 2; + tmp = (zip_uint16_t)(ctx->key[2] | 2); tmp = (tmp * (tmp ^ 1)) >> 8; b ^= tmp; } @@ -128,10 +121,10 @@ decrypt(struct trad_pkware *ctx, zip_uint8_t *out, const zip_uint8_t *in, out[i] = b; /* update keys */ - ctx->key[0] = CRC32(ctx->key[0], b); + ctx->key[0] = (zip_uint32_t)crc32(ctx->key[0] ^ 0xffffffffUL, &b, 1) ^ 0xffffffffUL; ctx->key[1] = (ctx->key[1] + (ctx->key[0] & 0xff)) * 134775813 + 1; b = ctx->key[1] >> 24; - ctx->key[2] = CRC32(ctx->key[2], b); + ctx->key[2] = (zip_uint32_t)crc32(ctx->key[2] ^ 0xffffffffUL, &b, 1) ^ 0xffffffffUL; } } @@ -196,7 +189,7 @@ pkware_decrypt(struct zip_source *src, void *ud, void *data, if ((n=zip_source_read(src, data, len)) < 0) return ZIP_SOURCE_ERR_LOWER; - decrypt(ud, (zip_uint8_t *)data, (zip_uint8_t *)data, (zip_uint64_t)n, + decrypt((struct trad_pkware *)ud, (zip_uint8_t *)data, (zip_uint8_t *)data, (zip_uint64_t)n, 0); return n; diff --git a/ext/zip/lib/zip_source_pop.c b/ext/zip/lib/zip_source_pop.c index 406093869b962..cd9cb529b5cc7 100644 --- a/ext/zip/lib/zip_source_pop.c +++ b/ext/zip/lib/zip_source_pop.c @@ -39,7 +39,7 @@ -ZIP_EXTERN(struct zip_source *) +struct zip_source * zip_source_pop(struct zip_source *src) { struct zip_source *lower; diff --git a/ext/zip/lib/zip_source_read.c b/ext/zip/lib/zip_source_read.c index 7246f9ccb5367..81b90ba42de35 100644 --- a/ext/zip/lib/zip_source_read.c +++ b/ext/zip/lib/zip_source_read.c @@ -37,7 +37,7 @@ -ZIP_EXTERN(zip_int64_t) +zip_int64_t zip_source_read(struct zip_source *src, void *data, zip_uint64_t len) { zip_int64_t ret; diff --git a/ext/zip/lib/zip_source_stat.c b/ext/zip/lib/zip_source_stat.c index 662779eb6cfba..85ae6a2fd6a26 100644 --- a/ext/zip/lib/zip_source_stat.c +++ b/ext/zip/lib/zip_source_stat.c @@ -37,7 +37,7 @@ -ZIP_EXTERN(int) +int zip_source_stat(struct zip_source *src, struct zip_stat *st) { zip_int64_t ret; diff --git a/ext/zip/lib/zip_source_window.c b/ext/zip/lib/zip_source_window.c new file mode 100644 index 0000000000000..fd202099b5aa8 --- /dev/null +++ b/ext/zip/lib/zip_source_window.c @@ -0,0 +1,150 @@ +/* + zip_source_window.c -- return part of lower source + Copyright (C) 2012-2013 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include +#include + +#include "zipint.h" + +struct window { + zip_uint64_t skip; + zip_uint64_t len; + zip_uint64_t left; + int e[2]; +}; + +static zip_int64_t window_read(struct zip_source *, void *, void *, + zip_uint64_t, enum zip_source_cmd); + + + +struct zip_source * +zip_source_window(struct zip *za, struct zip_source *src, zip_uint64_t start, zip_uint64_t len) +{ + struct window *ctx; + + if (src == NULL) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return NULL; + } + + if ((ctx=(struct window *)malloc(sizeof(*ctx))) == NULL) { + _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return NULL; + } + + ctx->skip = start; + ctx->len = len; + ctx->left = len; + + return zip_source_layered(za, src, window_read, ctx); +} + + + +static zip_int64_t +window_read(struct zip_source *src, void *_ctx, void *data, + zip_uint64_t len, enum zip_source_cmd cmd) +{ + struct window *ctx; + zip_int64_t ret; + zip_uint64_t n, i; + char b[8192]; + + ctx = (struct window *)_ctx; + + switch (cmd) { + case ZIP_SOURCE_OPEN: + for (n=0; nskip; n+=(zip_uint64_t)ret) { + i = (ctx->skip-n > sizeof(b) ? sizeof(b) : ctx->skip-n); + if ((ret=zip_source_read(src, b, i)) < 0) + return ZIP_SOURCE_ERR_LOWER; + if (ret==0) { + ctx->e[0] = ZIP_ER_EOF; + ctx->e[1] = 0; + return -1; + } + } + return 0; + + case ZIP_SOURCE_READ: + if (len > ctx->left) + len = ctx->left; + + if (len == 0) + return 0; + + if ((ret=zip_source_read(src, data, len)) < 0) + return ZIP_SOURCE_ERR_LOWER; + + ctx->left -= (zip_uint64_t)ret; + + if (ret == 0) { + if (ctx->left > 0) { + ctx->e[0] = ZIP_ER_EOF; + ctx->e[1] = 0; + return -1; + } + } + return ret; + + case ZIP_SOURCE_CLOSE: + return 0; + + case ZIP_SOURCE_STAT: + { + struct zip_stat *st; + + st = (struct zip_stat *)data; + + st->size = ctx->len; + st->valid |= ZIP_STAT_SIZE; + st->valid &= ~(ZIP_STAT_CRC|ZIP_STAT_COMP_SIZE); + } + return 0; + + case ZIP_SOURCE_ERROR: + memcpy(data, ctx->e, sizeof(ctx->e)); + return 0; + + case ZIP_SOURCE_FREE: + free(ctx); + return 0; + + default: + return -1; + } + +} diff --git a/ext/zip/lib/zip_source_zip.c b/ext/zip/lib/zip_source_zip.c index 228803c717f6a..e4fc2229f782c 100644 --- a/ext/zip/lib/zip_source_zip.c +++ b/ext/zip/lib/zip_source_zip.c @@ -38,153 +38,24 @@ #include "zipint.h" -struct read_zip { - struct zip_file *zf; - struct zip_stat st; - zip_uint64_t off; - zip_int64_t len; -}; - -static zip_int64_t read_zip(void *st, void *data, zip_uint64_t len, - enum zip_source_cmd cmd); - -ZIP_EXTERN(struct zip_source *) +ZIP_EXTERN struct zip_source * zip_source_zip(struct zip *za, struct zip *srcza, zip_uint64_t srcidx, - int flags, zip_uint64_t start, zip_int64_t len) + zip_flags_t flags, zip_uint64_t start, zip_int64_t len) { - struct zip_error error; - struct zip_source *zs; - struct read_zip *p; - - /* XXX: ZIP_FL_RECOMPRESS */ - - if (za == NULL) - return NULL; - - if (srcza == NULL || len < -1 || srcidx < 0 || srcidx >= srcza->nentry) { - _zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return NULL; + if (len < -1) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return NULL; } - - if ((flags & ZIP_FL_UNCHANGED) == 0 - && ZIP_ENTRY_DATA_CHANGED(srcza->entry+srcidx)) { - _zip_error_set(&za->error, ZIP_ER_CHANGED, 0); - return NULL; - } - - if (len == 0) - len = -1; - - if (start == 0 && len == -1 && (flags & ZIP_FL_RECOMPRESS) == 0) + + if (len == -1) + len = 0; + + if (start == 0 && len == 0) flags |= ZIP_FL_COMPRESSED; else flags &= ~ZIP_FL_COMPRESSED; - if ((p=(struct read_zip *)malloc(sizeof(*p))) == NULL) { - _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return NULL; - } - - _zip_error_copy(&error, &srcza->error); - - if (zip_stat_index(srcza, srcidx, flags, &p->st) < 0 - || (p->zf=zip_fopen_index(srcza, srcidx, flags)) == NULL) { - free(p); - _zip_error_copy(&za->error, &srcza->error); - _zip_error_copy(&srcza->error, &error); - - return NULL; - } - p->off = start; - p->len = len; - - if ((flags & ZIP_FL_COMPRESSED) == 0) { - p->st.size = p->st.comp_size = len; - p->st.comp_method = ZIP_CM_STORE; - p->st.crc = 0; - } - - if ((zs=zip_source_function(za, read_zip, p)) == NULL) { - free(p); - return NULL; - } - - return zs; -} - - - -static zip_int64_t -read_zip(void *state, void *data, zip_uint64_t len, enum zip_source_cmd cmd) -{ - struct read_zip *z; - char b[8192], *buf; - int i; - zip_uint64_t n; - - z = (struct read_zip *)state; - buf = (char *)data; - - switch (cmd) { - case ZIP_SOURCE_OPEN: - for (n=0; noff; n+= i) { - i = (z->off-n > sizeof(b) ? sizeof(b) : z->off-n); - if ((i=zip_fread(z->zf, b, i)) < 0) { - zip_fclose(z->zf); - z->zf = NULL; - return -1; - } - } - return 0; - - case ZIP_SOURCE_READ: - if (z->len != -1) - n = len > z->len ? z->len : len; - else - n = len; - - - if ((i=zip_fread(z->zf, buf, n)) < 0) - return -1; - - if (z->len != -1) - z->len -= i; - - return i; - - case ZIP_SOURCE_CLOSE: - return 0; - - case ZIP_SOURCE_STAT: - if (len < sizeof(z->st)) - return -1; - len = sizeof(z->st); - - memcpy(data, &z->st, len); - return len; - - case ZIP_SOURCE_ERROR: - { - int *e; - - if (len < sizeof(int)*2) - return -1; - - e = (int *)data; - zip_file_error_get(z->zf, e, e+1); - } - return sizeof(int)*2; - - case ZIP_SOURCE_FREE: - zip_fclose(z->zf); - free(z); - return 0; - - default: - ; - } - - return -1; + return _zip_source_zip_new(za, srcza, srcidx, flags, start, (zip_uint64_t)len, NULL); } diff --git a/ext/zip/lib/zip_source_zip_new.c b/ext/zip/lib/zip_source_zip_new.c new file mode 100644 index 0000000000000..8e48f6f3faa0c --- /dev/null +++ b/ext/zip/lib/zip_source_zip_new.c @@ -0,0 +1,172 @@ +/* + zip_source_zip_new.c -- prepare data structures for zip_fopen/zip_source_zip + Copyright (C) 2012 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include + +#include "zipint.h" + + + +struct zip_source * +_zip_source_zip_new(struct zip *za, struct zip *srcza, zip_uint64_t srcidx, zip_flags_t flags, + zip_uint64_t start, zip_uint64_t len, const char *password) +{ + zip_compression_implementation comp_impl; + zip_encryption_implementation enc_impl; + struct zip_source *src, *s2; + zip_uint64_t offset; + struct zip_stat st; + + if (za == NULL) + return NULL; + + if (srcza == NULL || srcidx >= srcza->nentry) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return NULL; + } + + if ((flags & ZIP_FL_UNCHANGED) == 0 + && (ZIP_ENTRY_DATA_CHANGED(srcza->entry+srcidx) || srcza->entry[srcidx].deleted)) { + _zip_error_set(&za->error, ZIP_ER_CHANGED, 0); + return NULL; + } + + if (zip_stat_index(srcza, srcidx, flags|ZIP_FL_UNCHANGED, &st) < 0) { + _zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); + return NULL; + } + + if (flags & ZIP_FL_ENCRYPTED) + flags |= ZIP_FL_COMPRESSED; + + if ((start > 0 || len > 0) && (flags & ZIP_FL_COMPRESSED)) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return NULL; + } + + /* overflow or past end of file */ + if ((start > 0 || len > 0) && (start+len < start || start+len > st.size)) { + _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + return NULL; + } + + enc_impl = NULL; + if (((flags & ZIP_FL_ENCRYPTED) == 0) && (st.encryption_method != ZIP_EM_NONE)) { + if (password == NULL) { + _zip_error_set(&za->error, ZIP_ER_NOPASSWD, 0); + return NULL; + } + if ((enc_impl=_zip_get_encryption_implementation(st.encryption_method)) == NULL) { + _zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0); + return NULL; + } + } + + comp_impl = NULL; + if ((flags & ZIP_FL_COMPRESSED) == 0) { + if (st.comp_method != ZIP_CM_STORE) { + if ((comp_impl=_zip_get_compression_implementation(st.comp_method)) == NULL) { + _zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0); + return NULL; + } + } + } + + if ((offset=_zip_file_get_offset(srcza, srcidx, &za->error)) == 0) + return NULL; + + if (st.comp_size == 0) { + if ((src=zip_source_buffer(za, NULL, 0, 0)) == NULL) + return NULL; + } + else { + if (start+len > 0 && enc_impl == NULL && comp_impl == NULL) { + struct zip_stat st2; + + st2.size = len ? len : st.size-start; + st2.comp_size = st2.size; + st2.comp_method = ZIP_CM_STORE; + st2.mtime = st.mtime; + st2.valid = ZIP_STAT_SIZE|ZIP_STAT_COMP_SIZE|ZIP_STAT_COMP_METHOD|ZIP_STAT_MTIME; + + /* XXX: check for overflow of st2.size */ + if ((src=_zip_source_file_or_p(za, NULL, srcza->zp, offset+start, (zip_int64_t)st2.size, 0, &st2)) == NULL) + return NULL; + } + else { + /* XXX: check for overflow of st.comp_size */ + if ((src=_zip_source_file_or_p(za, NULL, srcza->zp, offset, (zip_int64_t)st.comp_size, 0, &st)) == NULL) + return NULL; + } + + if (enc_impl) { + if ((s2=enc_impl(za, src, st.encryption_method, 0, password)) == NULL) { + zip_source_free(src); + /* XXX: set error (how?) */ + return NULL; + } + src = s2; + } + if (comp_impl) { + if ((s2=comp_impl(za, src, st.comp_method, 0)) == NULL) { + zip_source_free(src); + /* XXX: set error (how?) */ + return NULL; + } + src = s2; + } + if (((flags & ZIP_FL_COMPRESSED) == 0 || st.comp_method == ZIP_CM_STORE) + && (len == 0 || len == st.comp_size)) { + /* when reading the whole file, check for crc errors */ + if ((s2=zip_source_crc(za, src, 1)) == NULL) { + zip_source_free(src); + /* XXX: set error (how?) */ + return NULL; + } + src = s2; + } + + if (start+len > 0 && (comp_impl || enc_impl)) { + if ((s2=zip_source_window(za, src, start, len ? len : st.size-start)) == NULL) { + zip_source_free(src); + /* XXX: set error (how?) (why?) */ + return NULL; + } + src = s2; + } + } + + return src; +} diff --git a/ext/zip/lib/zip_stat.c b/ext/zip/lib/zip_stat.c index c8a25e1d84ac3..8254627d929f4 100644 --- a/ext/zip/lib/zip_stat.c +++ b/ext/zip/lib/zip_stat.c @@ -37,13 +37,13 @@ -ZIP_EXTERN(int) -zip_stat(struct zip *za, const char *fname, int flags, struct zip_stat *st) +ZIP_EXTERN int +zip_stat(struct zip *za, const char *fname, zip_flags_t flags, struct zip_stat *st) { - int idx; + zip_int64_t idx; if ((idx=zip_name_locate(za, fname, flags)) < 0) return -1; - return zip_stat_index(za, idx, flags, st); + return zip_stat_index(za, (zip_uint64_t)idx, flags, st); } diff --git a/ext/zip/lib/zip_stat_index.c b/ext/zip/lib/zip_stat_index.c index 8faa8cc394972..f4ce72aaa82d8 100644 --- a/ext/zip/lib/zip_stat_index.c +++ b/ext/zip/lib/zip_stat_index.c @@ -37,16 +37,15 @@ -ZIP_EXTERN(int) -zip_stat_index(struct zip *za, zip_uint64_t index, int flags, +ZIP_EXTERN int +zip_stat_index(struct zip *za, zip_uint64_t index, zip_flags_t flags, struct zip_stat *st) { const char *name; - - if (index >= za->nentry) { - _zip_error_set(&za->error, ZIP_ER_INVAL, 0); + struct zip_dirent *de; + + if ((de=_zip_get_dirent(za, index, flags, NULL)) == NULL) return -1; - } if ((name=zip_get_name(za, index, flags)) == NULL) return -1; @@ -60,20 +59,15 @@ zip_stat_index(struct zip *za, zip_uint64_t index, int flags, } } else { - if (za->cdir == NULL || index >= za->cdir->nentry) { - _zip_error_set(&za->error, ZIP_ER_INVAL, 0); - return -1; - } - zip_stat_init(st); - st->crc = za->cdir->entry[index].crc; - st->size = za->cdir->entry[index].uncomp_size; - st->mtime = za->cdir->entry[index].last_mod; - st->comp_size = za->cdir->entry[index].comp_size; - st->comp_method = za->cdir->entry[index].comp_method; - if (za->cdir->entry[index].bitflags & ZIP_GPBF_ENCRYPTED) { - if (za->cdir->entry[index].bitflags & ZIP_GPBF_STRONG_ENCRYPTION) { + st->crc = de->crc; + st->size = de->uncomp_size; + st->mtime = de->last_mod; + st->comp_size = de->comp_size; + st->comp_method = (zip_uint16_t)de->comp_method; + if (de->bitflags & ZIP_GPBF_ENCRYPTED) { + if (de->bitflags & ZIP_GPBF_STRONG_ENCRYPTION) { /* XXX */ st->encryption_method = ZIP_EM_UNKNOWN; } diff --git a/ext/zip/lib/zip_stat_init.c b/ext/zip/lib/zip_stat_init.c index 74e1ffd0b0dce..d17613bf5e7e8 100644 --- a/ext/zip/lib/zip_stat_init.c +++ b/ext/zip/lib/zip_stat_init.c @@ -37,7 +37,7 @@ -ZIP_EXTERN(void) +ZIP_EXTERN void zip_stat_init(struct zip_stat *st) { st->valid = 0; diff --git a/ext/zip/lib/zip_strerror.c b/ext/zip/lib/zip_strerror.c index ad23bafed6c62..9ebee144f908a 100644 --- a/ext/zip/lib/zip_strerror.c +++ b/ext/zip/lib/zip_strerror.c @@ -36,7 +36,8 @@ #include "zipint.h" -ZIP_EXTERN(const char *) + +ZIP_EXTERN const char * zip_strerror(struct zip *za) { return _zip_error_strerror(&za->error); diff --git a/ext/zip/lib/zip_string.c b/ext/zip/lib/zip_string.c new file mode 100644 index 0000000000000..a2d5eb5d3fdae --- /dev/null +++ b/ext/zip/lib/zip_string.c @@ -0,0 +1,196 @@ +/* + zip_string.c -- string handling (with encoding) + Copyright (C) 2012 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include +#include + +#include "zipint.h" + + + +zip_uint32_t +_zip_string_crc32(const struct zip_string *s) +{ + zip_uint32_t crc; + + crc = (zip_uint32_t)crc32(0L, Z_NULL, 0); + + if (s != NULL) + crc = (zip_uint32_t)crc32(crc, s->raw, s->length); + + return crc; +} + + + +int +_zip_string_equal(const struct zip_string *a, const struct zip_string *b) +{ + if (a == NULL || b == NULL) + return a == b; + + if (a->length != b->length) + return 0; + + /* XXX: encoding */ + + return (memcmp(a->raw, b->raw, a->length) == 0); +} + + + +void +_zip_string_free(struct zip_string *s) +{ + if (s == NULL) + return; + + free(s->raw); + free(s->converted); + free(s); +} + + + +const zip_uint8_t * +_zip_string_get(struct zip_string *string, zip_uint32_t *lenp, zip_flags_t flags, struct zip_error *error) +{ + static const zip_uint8_t empty[1] = ""; + + if (string == NULL) { + if (lenp) + *lenp = 0; + return empty; + } + + if ((flags & ZIP_FL_ENC_RAW) == 0) { + /* start guessing */ + if (string->encoding == ZIP_ENCODING_UNKNOWN) + _zip_guess_encoding(string, ZIP_ENCODING_UNKNOWN); + + if (((flags & ZIP_FL_ENC_STRICT) + && string->encoding != ZIP_ENCODING_ASCII && string->encoding != ZIP_ENCODING_UTF8_KNOWN) + || (string->encoding == ZIP_ENCODING_CP437)) { + if (string->converted == NULL) { + if ((string->converted=_zip_cp437_to_utf8(string->raw, string->length, + &string->converted_length, error)) == NULL) + return NULL; + } + if (lenp) + *lenp = string->converted_length; + return string->converted; + } + } + + if (lenp) + *lenp = string->length; + return string->raw; +} + + + +zip_uint16_t +_zip_string_length(const struct zip_string *s) +{ + if (s == NULL) + return 0; + + return s->length; +} + + + +struct zip_string * +_zip_string_new(const zip_uint8_t *raw, zip_uint16_t length, zip_flags_t flags, struct zip_error *error) +{ + struct zip_string *s; + enum zip_encoding_type expected_encoding; + + if (length == 0) + return NULL; + + switch (flags & ZIP_FL_ENCODING_ALL) { + case ZIP_FL_ENC_GUESS: + expected_encoding = ZIP_ENCODING_UNKNOWN; + break; + case ZIP_FL_ENC_UTF_8: + expected_encoding = ZIP_ENCODING_UTF8_KNOWN; + break; + case ZIP_FL_ENC_CP437: + expected_encoding = ZIP_ENCODING_CP437; + break; + default: + _zip_error_set(error, ZIP_ER_INVAL, 0); + return NULL; + } + + if ((s=(struct zip_string *)malloc(sizeof(*s))) == NULL) { + _zip_error_set(error, ZIP_ER_MEMORY, 0); + return NULL; + } + + if ((s->raw=(zip_uint8_t *)malloc(length+1)) == NULL) { + free(s); + return NULL; + } + + memcpy(s->raw, raw, length); + s->raw[length] = '\0'; + s->length = length; + s->encoding = ZIP_ENCODING_UNKNOWN; + s->converted = NULL; + s->converted_length = 0; + + if (expected_encoding != ZIP_ENCODING_UNKNOWN) { + if (_zip_guess_encoding(s, expected_encoding) == ZIP_ENCODING_ERROR) { + _zip_string_free(s); + _zip_error_set(error, ZIP_ER_INVAL, 0); + return NULL; + } + } + + return s; +} + + + +void +_zip_string_write(const struct zip_string *s, FILE *f) +{ + if (s == NULL) + return; + + fwrite(s->raw, s->length, 1, f); +} diff --git a/ext/zip/lib/zip_unchange.c b/ext/zip/lib/zip_unchange.c index 550e8b99031f2..5f0e753b78634 100644 --- a/ext/zip/lib/zip_unchange.c +++ b/ext/zip/lib/zip_unchange.c @@ -39,7 +39,7 @@ -ZIP_EXTERN(int) +ZIP_EXTERN int zip_unchange(struct zip *za, zip_uint64_t idx) { return _zip_unchange(za, idx, 0); @@ -50,34 +50,23 @@ zip_unchange(struct zip *za, zip_uint64_t idx) int _zip_unchange(struct zip *za, zip_uint64_t idx, int allow_duplicates) { - int i; + zip_int64_t i; if (idx >= za->nentry) { _zip_error_set(&za->error, ZIP_ER_INVAL, 0); return -1; } - if (za->entry[idx].ch_filename) { - if (!allow_duplicates) { - i = _zip_name_locate(za, - _zip_get_name(za, idx, ZIP_FL_UNCHANGED, NULL), - 0, NULL); - if (i != -1 && i != idx) { - _zip_error_set(&za->error, ZIP_ER_EXISTS, 0); - return -1; - } + if (!allow_duplicates && za->entry[idx].changes && (za->entry[idx].changes->changed & ZIP_DIRENT_FILENAME)) { + i = _zip_name_locate(za, _zip_get_name(za, idx, ZIP_FL_UNCHANGED, NULL), 0, NULL); + if (i >= 0 && (zip_uint64_t)i != idx) { + _zip_error_set(&za->error, ZIP_ER_EXISTS, 0); + return -1; } - - free(za->entry[idx].ch_filename); - za->entry[idx].ch_filename = NULL; } - free(za->entry[idx].ch_extra); - za->entry[idx].ch_extra = NULL; - za->entry[idx].ch_extra_len = -1; - free(za->entry[idx].ch_comment); - za->entry[idx].ch_comment = NULL; - za->entry[idx].ch_comment_len = -1; + _zip_dirent_free(za->entry[idx].changes); + za->entry[idx].changes = NULL; _zip_unchange_data(za->entry+idx); diff --git a/ext/zip/lib/zip_unchange_all.c b/ext/zip/lib/zip_unchange_all.c index 01282f89dbbaf..bbc2825eb6265 100644 --- a/ext/zip/lib/zip_unchange_all.c +++ b/ext/zip/lib/zip_unchange_all.c @@ -39,10 +39,11 @@ -ZIP_EXTERN(int) +ZIP_EXTERN int zip_unchange_all(struct zip *za) { - int ret, i; + int ret; + zip_uint64_t i; ret = 0; for (i=0; inentry; i++) diff --git a/ext/zip/lib/zip_unchange_archive.c b/ext/zip/lib/zip_unchange_archive.c index ca2b67854435a..e24ee21727002 100644 --- a/ext/zip/lib/zip_unchange_archive.c +++ b/ext/zip/lib/zip_unchange_archive.c @@ -39,13 +39,15 @@ -ZIP_EXTERN(int) +ZIP_EXTERN int zip_unchange_archive(struct zip *za) { - free(za->ch_comment); - za->ch_comment = NULL; - za->ch_comment_len = -1; - + if (za->comment_changed) { + _zip_string_free(za->comment_changes); + za->comment_changes = NULL; + za->comment_changed = 0; + } + za->ch_flags = za->flags; return 0; diff --git a/ext/zip/lib/zip_unchange_data.c b/ext/zip/lib/zip_unchange_data.c index 7dd93b768a87a..fa25feb03885f 100644 --- a/ext/zip/lib/zip_unchange_data.c +++ b/ext/zip/lib/zip_unchange_data.c @@ -1,8 +1,6 @@ /* - $NiH: zip_unchange_data.c,v 1.14 2004/11/30 23:02:47 wiz Exp $ - zip_unchange_data.c -- undo helper function - Copyright (C) 1999, 2004 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2012 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -35,8 +33,6 @@ -#include - #include "zipint.h" void @@ -46,7 +42,15 @@ _zip_unchange_data(struct zip_entry *ze) zip_source_free(ze->source); ze->source = NULL; } - - ze->state = ze->ch_filename ? ZIP_ST_RENAMED : ZIP_ST_UNCHANGED; + + if (ze->changes != NULL && (ze->changes->changed & ZIP_DIRENT_COMP_METHOD) && ze->changes->comp_method == ZIP_CM_REPLACED_DEFAULT) { + ze->changes->changed &= ~ZIP_DIRENT_COMP_METHOD; + if (ze->changes->changed == 0) { + _zip_dirent_free(ze->changes); + ze->changes = NULL; + } + } + + ze->deleted = 0; } diff --git a/ext/zip/lib/zip_utf-8.c b/ext/zip/lib/zip_utf-8.c new file mode 100644 index 0000000000000..c36fad13f5f45 --- /dev/null +++ b/ext/zip/lib/zip_utf-8.c @@ -0,0 +1,255 @@ +/* + zip_utf-8.c -- UTF-8 support functions for libzip + Copyright (C) 2011-2012 Dieter Baron and Thomas Klausner + + This file is part of libzip, a library to manipulate ZIP archives. + The authors can be contacted at + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The names of the authors may not be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + + +#include "zipint.h" + +#include + + + +static const zip_uint16_t _cp437_to_unicode[256] = { + /* 0x00 - 0x0F */ + 0x2007, 0x263A, 0x263B, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022, + 0x25D8, 0x25CB, 0x25D9, 0x2642, 0x2640, 0x266A, 0x266B, 0x263C, + + /* 0x10 - 0x1F */ + 0x25BA, 0x25C4, 0x2195, 0x203C, 0x00B6, 0x00A7, 0x25AC, 0x21A8, + 0x2191, 0x2193, 0x2192, 0x2190, 0x221F, 0x2194, 0x25B2, 0x25BC, + + /* 0x20 - 0x2F */ + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, + + /* 0x30 - 0x3F */ + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + + /* 0x40 - 0x4F */ + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + + /* 0x50 - 0x5F */ + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + + /* 0x60 - 0x6F */ + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, + + /* 0x70 - 0x7F */ + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x2302, + + /* 0x80 - 0x8F */ + 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, + 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, + + /* 0x90 - 0x9F */ + 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, + 0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192, + + /* 0xA0 - 0xAF */ + 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, + 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, + + /* 0xB0 - 0xBF */ + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, + + /* 0xC0 - 0xCF */ + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, + + /* 0xD0 - 0xDF */ + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, + 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + + /* 0xE0 - 0xEF */ + 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, + 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, + + /* 0xF0 - 0xFF */ + 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, + 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 +}; + +#define UTF_8_LEN_2_MASK 0xe0 +#define UTF_8_LEN_2_MATCH 0xc0 +#define UTF_8_LEN_3_MASK 0xf0 +#define UTF_8_LEN_3_MATCH 0xe0 +#define UTF_8_LEN_4_MASK 0xf8 +#define UTF_8_LEN_4_MATCH 0xf0 +#define UTF_8_CONTINUE_MASK 0xc0 +#define UTF_8_CONTINUE_MATCH 0x80 + + + +enum zip_encoding_type +_zip_guess_encoding(struct zip_string *str, enum zip_encoding_type expected_encoding) +{ + enum zip_encoding_type enc; + const zip_uint8_t *name; + zip_uint32_t i, j, ulen; + + if (str == NULL) + return ZIP_ENCODING_ASCII; + + name = str->raw; + + if (str->encoding != ZIP_ENCODING_UNKNOWN) + enc = str->encoding; + else { + enc = ZIP_ENCODING_ASCII; + for (i=0; ilength; i++) { + if ((name[i] > 31 && name[i] < 128) || name[i] == '\r' || name[i] == '\n' || name[i] == '\t') + continue; + + enc = ZIP_ENCODING_UTF8_GUESSED; + if ((name[i] & UTF_8_LEN_2_MASK) == UTF_8_LEN_2_MATCH) + ulen = 1; + else if ((name[i] & UTF_8_LEN_3_MASK) == UTF_8_LEN_3_MATCH) + ulen = 2; + else if ((name[i] & UTF_8_LEN_4_MASK) == UTF_8_LEN_4_MATCH) + ulen = 3; + else { + enc = ZIP_ENCODING_CP437; + break; + } + + if (i + ulen >= str->length) { + enc = ZIP_ENCODING_CP437; + break; + } + + for (j=1; j<=ulen; j++) { + if ((name[i+j] & UTF_8_CONTINUE_MASK) != UTF_8_CONTINUE_MATCH) { + enc = ZIP_ENCODING_CP437; + goto done; + } + } + i += ulen; + } + } + +done: + str->encoding = enc; + + if (expected_encoding != ZIP_ENCODING_UNKNOWN) { + if (expected_encoding == ZIP_ENCODING_UTF8_KNOWN && enc == ZIP_ENCODING_UTF8_GUESSED) + str->encoding = enc = ZIP_ENCODING_UTF8_KNOWN; + + if (expected_encoding != enc && enc != ZIP_ENCODING_ASCII) + return ZIP_ENCODING_ERROR; + } + + return enc; +} + + + +static zip_uint32_t +_zip_unicode_to_utf8_len(zip_uint32_t codepoint) +{ + if (codepoint < 0x0080) + return 1; + if (codepoint < 0x0800) + return 2; + if (codepoint < 0x10000) + return 3; + return 4; +} + + + +static zip_uint32_t +_zip_unicode_to_utf8(zip_uint32_t codepoint, zip_uint8_t *buf) +{ + if (codepoint < 0x0080) { + buf[0] = codepoint & 0xff; + return 1; + } + if (codepoint < 0x0800) { + buf[0] = UTF_8_LEN_2_MATCH | ((codepoint >> 6) & 0x1f); + buf[1] = UTF_8_CONTINUE_MATCH | (codepoint & 0x3f); + return 2; + } + if (codepoint < 0x10000) { + buf[0] = UTF_8_LEN_3_MATCH | ((codepoint >> 12) & 0x0f); + buf[1] = UTF_8_CONTINUE_MATCH | ((codepoint >> 6) & 0x3f); + buf[2] = UTF_8_CONTINUE_MATCH | (codepoint & 0x3f); + return 3; + } + buf[0] = UTF_8_LEN_4_MATCH | ((codepoint >> 18) & 0x07); + buf[1] = UTF_8_CONTINUE_MATCH | ((codepoint >> 12) & 0x3f); + buf[2] = UTF_8_CONTINUE_MATCH | ((codepoint >> 6) & 0x3f); + buf[3] = UTF_8_CONTINUE_MATCH | (codepoint & 0x3f); + return 4; +} + + + +zip_uint8_t * +_zip_cp437_to_utf8(const zip_uint8_t * const _cp437buf, zip_uint32_t len, + zip_uint32_t *utf8_lenp, struct zip_error *error) +{ + zip_uint8_t *cp437buf = (zip_uint8_t *)_cp437buf; + zip_uint8_t *utf8buf; + zip_uint32_t buflen, i, offset; + + if (len == 0) { + if (utf8_lenp) + *utf8_lenp = 0; + return NULL; + } + + buflen = 1; + for (i=0; i -#include -#include -#include -#include - -#ifndef strcasecmp -# define strcmpi _strcmpi -#endif - -#ifndef ssize_t -# define ssize_t SSIZE_T -#endif - -#ifndef mode_t -# define mode_t int -#endif - -#ifndef snprintf -# define snprintf _snprintf -#endif - -#ifndef mkstemp -# define mkstemp(t) _creat(_mktemp(t), _S_IREAD|_S_IWRITE) -#endif -/* -#ifndef fseeko -# define fseeko fseek -#endif -*/ diff --git a/ext/zip/lib/zipconf.h b/ext/zip/lib/zipconf.h index 646c0bde53f0e..1cb5c0467aeb8 100644 --- a/ext/zip/lib/zipconf.h +++ b/ext/zip/lib/zipconf.h @@ -1,47 +1,129 @@ -#ifndef _HAD_ZIPCONF_H -#define _HAD_ZIPCONF_H - -/* - zipconf.h -- platform specific include file - - This file was generated automatically by ./make_zipconf.sh - based on ../config.h. - */ - -#define LIBZIP_VERSION "0.10.1" -#define LIBZIP_VERSION_MAJOR 0 -#define LIBZIP_VERSION_MINOR 10 -#define LIBZIP_VERSION_MICRO 0 - -#include - -typedef int8_t zip_int8_t; -#define ZIP_INT8_MIN INT8_MIN -#define ZIP_INT8_MAX INT8_MAX - -typedef uint8_t zip_uint8_t; -#define ZIP_UINT8_MAX UINT8_MAX - -typedef int16_t zip_int16_t; -#define ZIP_INT16_MIN INT16_MIN -#define ZIP_INT16_MAX INT16_MAX - -typedef uint16_t zip_uint16_t; -#define ZIP_UINT16_MAX UINT16_MAX - -typedef int32_t zip_int32_t; -#define ZIP_INT32_MIN INT32_MIN -#define ZIP_INT32_MAX INT32_MAX - -typedef uint32_t zip_uint32_t; -#define ZIP_UINT32_MAX UINT32_MAX - -typedef int64_t zip_int64_t; -#define ZIP_INT64_MIN INT64_MIN -#define ZIP_INT64_MAX INT64_MAX - -typedef uint64_t zip_uint64_t; -#define ZIP_UINT64_MAX UINT64_MAX - - -#endif /* zipconf.h */ +#ifndef _HAD_ZIPCONF_H +#define _HAD_ZIPCONF_H + +/* + zipconf.h -- platform specific include file + + This file was generated automatically by CMake + based on ../cmake-zipconf.h.in. + */ +#define LIBZIP_VERSION "0.11.1" +/* #undef HAVE_INTTYPES_H_LIBZIP */ + +#if defined(_WIN32) +# if _MSC_VER > 1500 +# define HAVE_STDINT_H_LIBZIP +# else +# include "win32/php_stdint.h" +# endif +#else +# include +#endif +#define HAVE_SYS_TYPES_H_LIBZIP +#define HAVE___INT8_LIBZIP +#define HAVE_INT8_T_LIBZIP +#define HAVE_UINT8_T_LIBZIP +#define HAVE___INT16_LIBZIP +#define HAVE_INT16_T_LIBZIP +#define HAVE_UINT16_T_LIBZIP +#define HAVE___INT32_LIBZIP +#define HAVE_INT32_T_LIBZIP +#define HAVE_UINT32_T_LIBZIP +#define HAVE___INT64_LIBZIP +#define HAVE_INT64_T_LIBZIP +#define HAVE_UINT64_T_LIBZIP +#define SHORT_LIBZIP 2 +#define INT_LIBZIP 4 +#define LONG_LIBZIP 4 +#define LONG_LONG_LIBZIP 8 + +#if defined(HAVE_STDINT_H_LIBZIP) +#include +#elif defined(HAVE_INTTYPES_H_LIBZIP) +#include +#elif defined(HAVE_SYS_TYPES_H_LIBZIP) +#include +#endif + +#if defined(HAVE_INT8_T_LIBZIP) +typedef int8_t zip_int8_t; +#elif defined(HAVE___INT8_LIBZIP) +typedef __int8 zip_int8_t; +#else +typedef signed char zip_int8_t; +#endif +#if defined(HAVE_UINT8_T_LIBZIP) +typedef uint8_t zip_uint8_t; +#elif defined(HAVE___INT8_LIBZIP) +typedef unsigned __int8 zip_uint8_t; +#else +typedef unsigned char zip_uint8_t; +#endif +#if defined(HAVE_INT16_T_LIBZIP) +typedef int16_t zip_int16_t; +#elif defined(HAVE___INT16_LIBZIP) +typedef __int16 zip_int16_t; +#elif defined(SHORT_LIBZIP) && SHORT_LIBZIP == 2 +typedef signed short zip_int16_t; +#endif +#if defined(HAVE_UINT16_T_LIBZIP) +typedef uint16_t zip_uint16_t; +#elif defined(HAVE___INT16_LIBZIP) +typedef unsigned __int16 zip_uint16_t; +#elif defined(SHORT_LIBZIP) && SHORT_LIBZIP == 2 +typedef unsigned short zip_uint16_t; +#endif +#if defined(HAVE_INT32_T_LIBZIP) +typedef int32_t zip_int32_t; +#elif defined(HAVE___INT32_LIBZIP) +typedef __int32 zip_int32_t; +#elif defined(INT_LIBZIP) && INT_LIBZIP == 4 +typedef signed int zip_int32_t; +#elif defined(LONG_LIBZIP) && LONG_LIBZIP == 4 +typedef signed long zip_int32_t; +#endif +#if defined(HAVE_UINT32_T_LIBZIP) +typedef uint32_t zip_uint32_t; +#elif defined(HAVE___INT32_LIBZIP) +typedef unsigned __int32 zip_uint32_t; +#elif defined(INT_LIBZIP) && INT_LIBZIP == 4 +typedef unsigned int zip_uint32_t; +#elif defined(LONG_LIBZIP) && LONG_LIBZIP == 4 +typedef unsigned long zip_uint32_t; +#endif +#if defined(HAVE_INT64_T_LIBZIP) +typedef int64_t zip_int64_t; +#elif defined(HAVE___INT64_LIBZIP) +typedef __int64 zip_int64_t; +#elif defined(LONG_LIBZIP) && LONG_LIBZIP == 8 +typedef signed long zip_int64_t; +#elif defined(LONG_LONG_LIBZIP) && LONG_LONG_LIBZIP == 8 +typedef signed long long zip_int64_t; +#endif +#if defined(HAVE_UINT64_T_LIBZIP) +typedef uint64_t zip_uint64_t; +#elif defined(HAVE___INT64_LIBZIP) +typedef unsigned __int64 zip_uint64_t; +#elif defined(LONG_LIBZIP) && LONG_LONG_LIBZIP == 8 +typedef unsigned long zip_uint64_t; +#elif defined(LONG_LONG_LIBZIP) && LONG_LONG_LIBZIP == 8 +typedef unsigned long long zip_uint64_t; +#endif + +#define ZIP_INT8_MIN -0x80 +#define ZIP_INT8_MAX 0x7f +#define ZIP_UINT8_MAX 0xff + +#define ZIP_INT16_MIN -0x8000 +#define ZIP_INT16_MAX 0x7fff +#define ZIP_UINT16_MAX 0xffff + +#define ZIP_INT32_MIN -0x80000000L +#define ZIP_INT32_MAX 0x7fffffffL +#define ZIP_UINT32_MAX 0xffffffffLU + +#define ZIP_INT64_MIN -0x8000000000000000LL +#define ZIP_INT64_MAX 0x7fffffffffffffffLL +#define ZIP_UINT64_MAX 0xffffffffffffffffULL + +#endif /* zipconf.h */ diff --git a/ext/zip/lib/zipint.h b/ext/zip/lib/zipint.h index ea21dddcd4257..e8765c5b6619f 100644 --- a/ext/zip/lib/zipint.h +++ b/ext/zip/lib/zipint.h @@ -3,7 +3,7 @@ /* zipint.h -- internal declarations. - Copyright (C) 1999-2011 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2013 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. The authors can be contacted at @@ -20,7 +20,7 @@ 3. The names of the authors may not be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -34,69 +34,123 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +/* to have *_MAX definitions for all types when compiling with g++ */ +#define __STDC_LIMIT_MACROS -#include "zip.h" +#include -#ifndef HAVE_FSEEKO -#define fseeko(s, o, w) (fseek((s), (long int)(o), (w))) +#ifdef PHP_WIN32 +/* for dup(), close(), etc. */ +#include +#include "config.w32.h" #endif -#ifndef HAVE_FTELLO -#define ftello(s) ((long)ftell((s))) +#ifndef _ZIP_COMPILING_DEPRECATED +#define ZIP_DISABLE_DEPRECATED #endif -#ifndef PHP_WIN32 -#ifndef HAVE_MKSTEMP -int _zip_mkstemp(char *); -#define mkstemp _zip_mkstemp -#endif +#include "zip.h" +#ifdef PHP_WIN32 +# include "php_zip_config.w32.h" +#else +# include "config.h" #endif -#ifdef PHP_WIN32 +#if defined(HAVE_MOVEFILEEXA) && defined(_WIN32) #include -#include #define _zip_rename(s, t) \ - (!MoveFileExA((s), (t), \ - MOVEFILE_COPY_ALLOWED|MOVEFILE_REPLACE_EXISTING)) + (!MoveFileExA((s), (t), MOVEFILE_COPY_ALLOWED|MOVEFILE_REPLACE_EXISTING)) +#else +#define _zip_rename rename +#endif -/* for dup(), close(), etc. */ -#include +#ifdef _WIN32 +#undef strcasecmp +# define strcasecmp _strcmpi +#endif -#if !defined(HAVE_OPEN) +#if defined(HAVE__CLOSE) +#define close _close +#endif +#if defined(HAVE__DUP) +#define dup _dup +#endif +/* crashes reported when using fdopen instead of _fdopen on Windows/Visual Studio 10/Win64 */ +#if defined(HAVE__FDOPEN) +#define fdopen _fdopen +#endif +#if defined(HAVE__FILENO) +#define fileno _fileno +#endif +/* Windows' open() doesn't understand Unix permissions */ #if defined(HAVE__OPEN) #define open(a, b, c) _open((a), (b)) #endif +#if defined(HAVE__SNPRINTF) +#define snprintf _snprintf +#endif +#if defined(HAVE__STRDUP) && !defined(strdup) +#define strdup _strdup #endif -#else -#define _zip_rename rename +#ifndef HAVE_FSEEKO +#define fseeko(s, o, w) (fseek((s), (long int)(o), (w))) #endif -#ifndef strcasecmp -# define strcmpi strcasecmp +#ifndef HAVE_FTELLO +#define ftello(s) ((long)ftell((s))) #endif +#ifndef HAVE_MKSTEMP +int _zip_mkstemp(char *); +#define mkstemp _zip_mkstemp +#endif - +#if !defined(HAVE_STRCASECMP) +#if defined(HAVE__STRICMP) +#define strcasecmp _stricmp +#endif +#endif + +#if SIZEOF_OFF_T == 8 +#define ZIP_OFF_MAX ZIP_INT64_MAX +#elif SIZEOF_OFF_T == 4 +#define ZIP_OFF_MAX ZIP_INT32_MAX +#elif SIZEOF_OFF_T == 2 +#define ZIP_OFF_MAX ZIP_INT16_MAX +#else +#error unsupported size of off_t +#endif #define CENTRAL_MAGIC "PK\1\2" #define LOCAL_MAGIC "PK\3\4" #define EOCD_MAGIC "PK\5\6" #define DATADES_MAGIC "PK\7\8" +#define EOCD64LOC_MAGIC "PK\6\7" +#define EOCD64_MAGIC "PK\6\6" #define TORRENT_SIG "TORRENTZIPPED-" #define TORRENT_SIG_LEN 14 #define TORRENT_CRC_LEN 8 #define TORRENT_MEM_LEVEL 8 #define CDENTRYSIZE 46u #define LENTRYSIZE 30 -#undef MAXCOMLEN /* defined as 19 on BSD for max command name */ #define MAXCOMLEN 65536 #define MAXEXTLEN 65536 #define EOCDLEN 22 -#define CDBUFSIZE (MAXCOMLEN+EOCDLEN) +#define EOCD64LOCLEN 20 +#define EOCD64LEN 56 +#define CDBUFSIZE (MAXCOMLEN+EOCDLEN+EOCD64LOCLEN) #define BUFSIZE 8192 +#define ZIP_CM_REPLACED_DEFAULT (-2) + +#define ZIP_CM_IS_DEFAULT(x) ((x) == ZIP_CM_DEFAULT || (x) == ZIP_CM_REPLACED_DEFAULT) + +#define ZIP_EF_UTF_8_COMMENT 0x6375 +#define ZIP_EF_UTF_8_NAME 0x7075 +#define ZIP_EF_ZIP64 0x0001 + +#define ZIP_EF_IS_INTERNAL(id) ((id) == ZIP_EF_UTF_8_COMMENT || (id) == ZIP_EF_UTF_8_NAME || (id) == ZIP_EF_ZIP64) /* This section contains API that won't materialize like this. It's @@ -104,20 +158,22 @@ int _zip_mkstemp(char *); typedef struct zip_source *(*zip_compression_implementation)(struct zip *, struct zip_source *, - zip_uint16_t, int); + zip_int32_t, int); typedef struct zip_source *(*zip_encryption_implementation)(struct zip *, struct zip_source *, zip_uint16_t, int, const char *); -ZIP_EXTERN(zip_compression_implementation) zip_get_compression_implementation( - zip_uint16_t); -ZIP_EXTERN(zip_encryption_implementation) zip_get_encryption_implementation( - zip_uint16_t); +zip_compression_implementation _zip_get_compression_implementation(zip_int32_t); +zip_encryption_implementation _zip_get_encryption_implementation(zip_uint16_t); +/* This API is not final yet, but we need it internally, so it's private for now. */ + +const zip_uint8_t *zip_get_extra_field_by_id(struct zip *, int, int, zip_uint16_t, int, zip_uint16_t *); + /* This section contains API that is of limited use until support for user-supplied compression/encryption implementation is finished. Thus we will keep it private for now. */ @@ -126,40 +182,37 @@ typedef zip_int64_t (*zip_source_layered_callback)(struct zip_source *, void *, void *, zip_uint64_t, enum zip_source_cmd); -ZIP_EXTERN(void) zip_source_close(struct zip_source *); -ZIP_EXTERN(struct zip_source *)zip_source_crc(struct zip *, struct zip_source *, - int); -ZIP_EXTERN(struct zip_source *)zip_source_deflate(struct zip *, - struct zip_source *, - zip_uint16_t, int); -ZIP_EXTERN(void) zip_source_error(struct zip_source *, int *, int *); -ZIP_EXTERN(struct zip_source *)zip_source_layered(struct zip *, - struct zip_source *, - zip_source_layered_callback, - void *); -ZIP_EXTERN(int) zip_source_open(struct zip_source *); -ZIP_EXTERN(struct zip_source *)zip_source_pkware(struct zip *, - struct zip_source *, - zip_uint16_t, int, - const char *); -ZIP_EXTERN(zip_int64_t) zip_source_read(struct zip_source *, void *, - zip_uint64_t); -ZIP_EXTERN(int) zip_source_stat(struct zip_source *, struct zip_stat *); +void zip_source_close(struct zip_source *); +struct zip_source *zip_source_crc(struct zip *, struct zip_source *, + int); +struct zip_source *zip_source_deflate(struct zip *, + struct zip_source *, + zip_int32_t, int); +void zip_source_error(struct zip_source *, int *, int *); +struct zip_source *zip_source_layered(struct zip *, + struct zip_source *, + zip_source_layered_callback, + void *); +int zip_source_open(struct zip_source *); +struct zip_source *zip_source_pkware(struct zip *, + struct zip_source *, + zip_uint16_t, int, + const char *); +zip_int64_t zip_source_read(struct zip_source *, void *, + zip_uint64_t); +int zip_source_stat(struct zip_source *, struct zip_stat *); +struct zip_source *zip_source_window(struct zip *, struct zip_source *, + zip_uint64_t, zip_uint64_t); /* This function will probably remain private. It is not needed to implement compression/encryption routines. (We should probably rename it to _zip_source_pop.) */ -ZIP_EXTERN(struct zip_source *)zip_source_pop(struct zip_source *); +struct zip_source *zip_source_pop(struct zip_source *); -/* state of change of a file in zip archive */ - -enum zip_state { ZIP_ST_UNCHANGED, ZIP_ST_DELETED, ZIP_ST_REPLACED, - ZIP_ST_ADDED, ZIP_ST_RENAMED }; - /* error source for layered sources */ enum zip_les { ZIP_LES_NONE, ZIP_LES_UPPER, ZIP_LES_LOWER, ZIP_LES_INVAL }; @@ -169,6 +222,28 @@ enum zip_les { ZIP_LES_NONE, ZIP_LES_UPPER, ZIP_LES_LOWER, ZIP_LES_INVAL }; #define ZIP_GPBF_ENCRYPTED 0x0001 /* is encrypted */ #define ZIP_GPBF_DATA_DESCRIPTOR 0x0008 /* crc/size after file data */ #define ZIP_GPBF_STRONG_ENCRYPTION 0x0040 /* uses strong encryption */ +#define ZIP_GPBF_ENCODING_UTF_8 0x0800 /* file name encoding is UTF-8 */ + + +/* extra fields */ +#define ZIP_EF_LOCAL ZIP_FL_LOCAL /* include in local header */ +#define ZIP_EF_CENTRAL ZIP_FL_CENTRAL /* include in central directory */ +#define ZIP_EF_BOTH (ZIP_EF_LOCAL|ZIP_EF_CENTRAL) /* include in both */ + +#define ZIP_FL_FORCE_ZIP64 1024 /* force zip64 extra field (_zip_dirent_write) */ + +#define ZIP_FL_ENCODING_ALL (ZIP_FL_ENC_GUESS|ZIP_FL_ENC_CP437|ZIP_FL_ENC_UTF_8) + + +/* encoding type */ +enum zip_encoding_type { + ZIP_ENCODING_UNKNOWN, /* not yet analyzed */ + ZIP_ENCODING_ASCII, /* plain ASCII */ + ZIP_ENCODING_UTF8_KNOWN, /* is UTF-8 */ + ZIP_ENCODING_UTF8_GUESSED, /* possibly UTF-8 */ + ZIP_ENCODING_CP437, /* Code Page 437 */ + ZIP_ENCODING_ERROR /* should be UTF-8 but isn't */ +}; /* error information */ @@ -181,25 +256,29 @@ struct zip_error { /* zip archive, part of API */ struct zip { - char *zn; /* file name */ - FILE *zp; /* file */ - struct zip_error error; /* error information */ + char *zn; /* file name */ + FILE *zp; /* file */ + unsigned int open_flags; /* flags passed to zip_open */ + struct zip_error error; /* error information */ - unsigned int flags; /* archive global flags */ - unsigned int ch_flags; /* changed archive global flags */ - - char *default_password; /* password used when no other supplied */ - - struct zip_cdir *cdir; /* central directory */ - char *ch_comment; /* changed archive comment */ - int ch_comment_len; /* length of changed zip archive - * comment, -1 if unchanged */ - zip_uint64_t nentry; /* number of entries */ - zip_uint64_t nentry_alloc; /* number of entries allocated */ - struct zip_entry *entry; /* entries */ - int nfile; /* number of opened files within archive */ - int nfile_alloc; /* number of files allocated */ - struct zip_file **file; /* opened files within archive */ + unsigned int flags; /* archive global flags */ + unsigned int ch_flags; /* changed archive global flags */ + + char *default_password; /* password used when no other supplied */ + + struct zip_string *comment_orig; /* archive comment */ + struct zip_string *comment_changes; /* changed archive comment */ + int comment_changed; /* whether archive comment was changed */ + + zip_uint64_t nentry; /* number of entries */ + zip_uint64_t nentry_alloc; /* number of entries allocated */ + struct zip_entry *entry; /* entries */ + + unsigned int nfile; /* number of opened files within archive */ + unsigned int nfile_alloc; /* number of files allocated */ + struct zip_file **file; /* opened files within archive */ + + char *tempdir; /* custom temp dir (needed e.g. for OS X sandboxing) */ }; /* file in zip archive, part of API */ @@ -213,37 +292,52 @@ struct zip_file { /* zip archive directory entry (central or local) */ +#define ZIP_DIRENT_COMP_METHOD 0x0001u +#define ZIP_DIRENT_FILENAME 0x0002u +#define ZIP_DIRENT_COMMENT 0x0004u +#define ZIP_DIRENT_EXTRA_FIELD 0x0008u +#define ZIP_DIRENT_ALL 0xffffu + struct zip_dirent { - unsigned short version_madeby; /* (c) version of creator */ - unsigned short version_needed; /* (cl) version needed to extract */ - unsigned short bitflags; /* (cl) general purpose bit flag */ - unsigned short comp_method; /* (cl) compression method used */ - time_t last_mod; /* (cl) time of last modification */ - unsigned int crc; /* (cl) CRC-32 of uncompressed data */ - unsigned int comp_size; /* (cl) size of commpressed data */ - unsigned int uncomp_size; /* (cl) size of uncommpressed data */ - char *filename; /* (cl) file name (NUL-terminated) */ - unsigned short filename_len; /* (cl) length of filename (w/o NUL) */ - char *extrafield; /* (cl) extra field */ - unsigned short extrafield_len; /* (cl) length of extra field */ - char *comment; /* (c) file comment */ - unsigned short comment_len; /* (c) length of file comment */ - unsigned short disk_number; /* (c) disk number start */ - unsigned short int_attrib; /* (c) internal file attributes */ - unsigned int ext_attrib; /* (c) external file attributes */ - unsigned int offset; /* (c) offset of local header */ + zip_uint32_t changed; + int local_extra_fields_read; /* whether we already read in local header extra fields */ + int cloned; /* wether this instance is cloned, and thus shares non-changed strings */ + + zip_uint16_t version_madeby; /* (c) version of creator */ + zip_uint16_t version_needed; /* (cl) version needed to extract */ + zip_uint16_t bitflags; /* (cl) general purpose bit flag */ + zip_int32_t comp_method; /* (cl) compression method used (uint16 and ZIP_CM_DEFAULT (-1)) */ + time_t last_mod; /* (cl) time of last modification */ + zip_uint32_t crc; /* (cl) CRC-32 of uncompressed data */ + zip_uint64_t comp_size; /* (cl) size of compressed data */ + zip_uint64_t uncomp_size; /* (cl) size of uncompressed data */ + struct zip_string *filename; /* (cl) file name (NUL-terminated) */ + struct zip_extra_field *extra_fields; /* (cl) extra fields, parsed */ + struct zip_string *comment; /* (c) file comment */ + zip_uint32_t disk_number; /* (c) disk number start */ + zip_uint16_t int_attrib; /* (c) internal file attributes */ + zip_uint32_t ext_attrib; /* (c) external file attributes */ + zip_uint64_t offset; /* (c) offset of local header */ }; /* zip archive central directory */ struct zip_cdir { - struct zip_dirent *entry; /* directory entries */ - int nentry; /* number of entries */ + struct zip_entry *entry; /* directory entries */ + zip_uint64_t nentry; /* number of entries */ + zip_uint64_t nentry_alloc; /* number of entries allocated */ - unsigned int size; /* size of central direcotry */ - unsigned int offset; /* offset of central directory in file */ - char *comment; /* zip archive comment */ - unsigned short comment_len; /* length of zip archive comment */ + off_t size; /* size of central directory */ + off_t offset; /* offset of central directory in file */ + struct zip_string *comment; /* zip archive comment */ +}; + +struct zip_extra_field { + struct zip_extra_field *next; + zip_flags_t flags; /* in local/central header */ + zip_uint16_t id; /* header id */ + zip_uint16_t size; /* data size */ + zip_uint8_t *data; }; @@ -262,13 +356,31 @@ struct zip_source { /* entry in zip archive directory */ struct zip_entry { - enum zip_state state; + struct zip_dirent *orig; + struct zip_dirent *changes; struct zip_source *source; - char *ch_filename; - char *ch_extra; - int ch_extra_len; - char *ch_comment; - int ch_comment_len; + int deleted; +}; + + + +/* file or archive comment, or filename */ + +struct zip_string { + zip_uint8_t *raw; /* raw string */ + zip_uint16_t length; /* length of raw string */ + enum zip_encoding_type encoding; /* autorecognized encoding */ + zip_uint8_t *converted; /* autoconverted string */ + zip_uint32_t converted_length; /* length of converted */ +}; + + + +/* which files to write, and in which order (name is for torrentzip sorting) */ + +struct zip_filelist { + zip_uint64_t idx; + const char *name; }; @@ -279,66 +391,111 @@ extern const int _zip_err_type[]; -#define ZIP_ENTRY_DATA_CHANGED(x) \ - ((x)->state == ZIP_ST_REPLACED \ - || (x)->state == ZIP_ST_ADDED) +#define ZIP_ENTRY_CHANGED(e, f) ((e)->changes && ((e)->changes->changed & (f))) + +#define ZIP_ENTRY_DATA_CHANGED(x) ((x)->source != NULL) #define ZIP_IS_RDONLY(za) ((za)->ch_flags & ZIP_AFL_RDONLY) +zip_int64_t _zip_add_entry(struct zip *); + int _zip_cdir_compute_crc(struct zip *, uLong *); void _zip_cdir_free(struct zip_cdir *); -int _zip_cdir_grow(struct zip_cdir *, int, struct zip_error *); -struct zip_cdir *_zip_cdir_new(int, struct zip_error *); -int _zip_cdir_write(struct zip_cdir *, FILE *, struct zip_error *); +int _zip_cdir_grow(struct zip_cdir *, zip_uint64_t, struct zip_error *); +struct zip_cdir *_zip_cdir_new(zip_uint64_t, struct zip_error *); +zip_int64_t _zip_cdir_write(struct zip *, const struct zip_filelist *, zip_uint64_t, FILE *); +struct zip_dirent *_zip_dirent_clone(const struct zip_dirent *); +void _zip_dirent_free(struct zip_dirent *); void _zip_dirent_finalize(struct zip_dirent *); void _zip_dirent_init(struct zip_dirent *); -int _zip_dirent_read(struct zip_dirent *, FILE *, unsigned char **, - zip_uint32_t *, int, struct zip_error *); +int _zip_dirent_needs_zip64(const struct zip_dirent *, zip_flags_t); +struct zip_dirent *_zip_dirent_new(void); +int _zip_dirent_read(struct zip_dirent *, FILE *, const unsigned char **, + zip_uint64_t *, int, struct zip_error *); +zip_int32_t _zip_dirent_size(FILE *, zip_uint16_t, struct zip_error *); void _zip_dirent_torrent_normalize(struct zip_dirent *); -int _zip_dirent_write(struct zip_dirent *, FILE *, int, struct zip_error *); - -void _zip_entry_free(struct zip_entry *); -void _zip_entry_init(struct zip *, int); -struct zip_entry *_zip_entry_new(struct zip *); +int _zip_dirent_write(struct zip_dirent *, FILE *, zip_flags_t, struct zip_error *); + +struct zip_extra_field *_zip_ef_clone(const struct zip_extra_field *, struct zip_error *); +struct zip_extra_field *_zip_ef_delete_by_id(struct zip_extra_field *, zip_uint16_t, zip_uint16_t, zip_flags_t); +void _zip_ef_free(struct zip_extra_field *); +const zip_uint8_t *_zip_ef_get_by_id(const struct zip_extra_field *, zip_uint16_t *, zip_uint16_t, zip_uint16_t, zip_flags_t, struct zip_error *); +struct zip_extra_field *_zip_ef_merge(struct zip_extra_field *, struct zip_extra_field *); +struct zip_extra_field *_zip_ef_new(zip_uint16_t, zip_uint16_t, const zip_uint8_t *, zip_flags_t); +struct zip_extra_field *_zip_ef_parse(const zip_uint8_t *, zip_uint16_t, zip_flags_t, struct zip_error *); +struct zip_extra_field *_zip_ef_remove_internal(struct zip_extra_field *); +zip_uint16_t _zip_ef_size(const struct zip_extra_field *, zip_flags_t); +void _zip_ef_write(const struct zip_extra_field *, zip_flags_t, FILE *); + +void _zip_entry_finalize(struct zip_entry *); +void _zip_entry_init(struct zip_entry *); void _zip_error_clear(struct zip_error *); -void _zip_error_copy(struct zip_error *, struct zip_error *); +void _zip_error_copy(struct zip_error *, const struct zip_error *); void _zip_error_fini(struct zip_error *); -void _zip_error_get(struct zip_error *, int *, int *); +void _zip_error_get(const struct zip_error *, int *, int *); void _zip_error_init(struct zip_error *); void _zip_error_set(struct zip_error *, int, int); void _zip_error_set_from_source(struct zip_error *, struct zip_source *); const char *_zip_error_strerror(struct zip_error *); +const zip_uint8_t *_zip_extract_extra_field_by_id(struct zip_error *, zip_uint16_t, int, const zip_uint8_t *, zip_uint16_t, zip_uint16_t *); + +int _zip_file_extra_field_prepare_for_change(struct zip *, zip_uint64_t); int _zip_file_fillbuf(void *, size_t, struct zip_file *); -unsigned int _zip_file_get_offset(struct zip *, int); +zip_uint64_t _zip_file_get_offset(const struct zip *, zip_uint64_t, struct zip_error *); int _zip_filerange_crc(FILE *, off_t, off_t, uLong *, struct zip_error *); -struct zip *_zip_open(const char *, FILE *, int, int, int *); +struct zip_dirent *_zip_get_dirent(struct zip *, zip_uint64_t, zip_flags_t, struct zip_error *); + +enum zip_encoding_type _zip_guess_encoding(struct zip_string *, enum zip_encoding_type); +zip_uint8_t *_zip_cp437_to_utf8(const zip_uint8_t * const, zip_uint32_t, + zip_uint32_t *, struct zip_error *error); + +struct zip *_zip_open(const char *, FILE *, unsigned int, int *); + +int _zip_read_local_ef(struct zip *, zip_uint64_t); struct zip_source *_zip_source_file_or_p(struct zip *, const char *, FILE *, zip_uint64_t, zip_int64_t, int, const struct zip_stat *); struct zip_source *_zip_source_new(struct zip *); - -int _zip_changed(struct zip *, int *); -void _zip_free(struct zip *); -const char *_zip_get_name(struct zip *, zip_uint64_t, int, struct zip_error *); +struct zip_source *_zip_source_zip_new(struct zip *, struct zip *, zip_uint64_t, zip_flags_t, + zip_uint64_t, zip_uint64_t, const char *); + +int _zip_string_equal(const struct zip_string *, const struct zip_string *); +void _zip_string_free(struct zip_string *); +zip_uint32_t _zip_string_crc32(const struct zip_string *); +const zip_uint8_t *_zip_string_get(struct zip_string *, zip_uint32_t *, zip_flags_t, struct zip_error *); +zip_uint16_t _zip_string_length(const struct zip_string *); +struct zip_string *_zip_string_new(const zip_uint8_t *, zip_uint16_t, zip_flags_t, struct zip_error *); +void _zip_string_write(const struct zip_string *, FILE *); + +int _zip_changed(const struct zip *, zip_uint64_t *); +const char *_zip_get_name(struct zip *, zip_uint64_t, zip_flags_t, struct zip_error *); int _zip_local_header_read(struct zip *, int); void *_zip_memdup(const void *, size_t, struct zip_error *); -int _zip_name_locate(struct zip *, const char *, int, struct zip_error *); +zip_int64_t _zip_name_locate(struct zip *, const char *, zip_flags_t, struct zip_error *); struct zip *_zip_new(struct zip_error *); -unsigned short _zip_read2(unsigned char **); -unsigned int _zip_read4(unsigned char **); -zip_int64_t _zip_replace(struct zip *, zip_uint64_t, const char *, - struct zip_source *); -int _zip_set_name(struct zip *, zip_uint64_t, const char *); -void _zip_u2d_time(time_t, unsigned short *, unsigned short *); +zip_uint16_t _zip_read2(const zip_uint8_t **); +zip_uint32_t _zip_read4(const zip_uint8_t **); +zip_uint64_t _zip_read8(const zip_uint8_t **); +zip_uint8_t *_zip_read_data(const zip_uint8_t **, FILE *, size_t, int, struct zip_error *); +zip_int64_t _zip_file_replace(struct zip *, zip_uint64_t, const char *, struct zip_source *, zip_flags_t); +int _zip_set_name(struct zip *, zip_uint64_t, const char *, zip_flags_t); +void _zip_u2d_time(time_t, zip_uint16_t *, zip_uint16_t *); int _zip_unchange(struct zip *, zip_uint64_t, int); void _zip_unchange_data(struct zip_entry *); +void _zip_poke4(zip_uint32_t, zip_uint8_t **); +void _zip_poke8(zip_uint64_t, zip_uint8_t **); +void _zip_write2(zip_uint16_t, FILE *); +void _zip_write4(zip_uint32_t, FILE *); +void _zip_write8(zip_uint64_t, FILE *); + + #endif /* zipint.h */ diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c index 969bac1aa6b5d..4367a44c2c7fa 100644 --- a/ext/zip/php_zip.c +++ b/ext/zip/php_zip.c @@ -30,8 +30,6 @@ #include "ext/pcre/php_pcre.h" #include "ext/standard/php_filestat.h" #include "php_zip.h" -#include "lib/zip.h" -#include "lib/zipint.h" /* zip_open is a macro for renaming libzip zipopen, so we need to use PHP_NAMED_FUNCTION */ static PHP_NAMED_FUNCTION(zif_zip_open); @@ -53,6 +51,24 @@ static PHP_NAMED_FUNCTION(zif_zip_entry_close); #endif #endif +#if PHP_VERSION_ID < 50400 +#define ARG_PATH "s" +#define KEY_ARG_DC +#define KEY_ARG_CC +#else +#define ARG_PATH "p" +#define KEY_ARG_DC , const zend_literal *key +#define KEY_ARG_CC , key +#endif + +#if PHP_VERSION_ID < 50500 +#define TYPE_ARG_DC +#define TYPE_ARG_CC +#else +#define TYPE_ARG_DC , int type +#define TYPE_ARG_CC , type +#endif + /* {{{ Resource le */ static int le_zip_dir; #define le_zip_dir_name "Zip Directory" @@ -102,14 +118,14 @@ static char * php_zip_make_relative_path(char *path, int path_len) /* {{{ */ char *path_begin = path; size_t i; - if (IS_SLASH(path[0])) { - return path + 1; - } - if (path_len < 1 || path == NULL) { return NULL; } + if (IS_SLASH(path[0])) { + return path + 1; + } + i = path_len; while (1) { @@ -154,7 +170,7 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil size_t path_cleaned_len; cwd_state new_state; - new_state.cwd = (char*)malloc(1); + new_state.cwd = (char*)emalloc(1); new_state.cwd[0] = '\0'; new_state.cwd_length = 0; @@ -191,7 +207,7 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil if (ZIP_OPENBASEDIR_CHECKPATH(file_dirname_fullpath)) { efree(file_dirname_fullpath); efree(file_basename); - free(new_state.cwd); + efree(new_state.cwd); return 0; } } @@ -215,7 +231,7 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil efree(file_dirname_fullpath); if (!is_dir_only) { efree(file_basename); - free(new_state.cwd); + efree(new_state.cwd); } return 0; } @@ -224,7 +240,7 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil /* it is a standalone directory, job done */ if (is_dir_only) { efree(file_dirname_fullpath); - free(new_state.cwd); + efree(new_state.cwd); return 1; } @@ -232,13 +248,13 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil if (!len) { efree(file_dirname_fullpath); efree(file_basename); - free(new_state.cwd); + efree(new_state.cwd); return 0; } else if (len > MAXPATHLEN) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Full extraction path exceed MAXPATHLEN (%i)", MAXPATHLEN); efree(file_dirname_fullpath); efree(file_basename); - free(new_state.cwd); + efree(new_state.cwd); return 0; } @@ -250,7 +266,7 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil efree(fullpath); efree(file_dirname_fullpath); efree(file_basename); - free(new_state.cwd); + efree(new_state.cwd); return 0; } @@ -285,7 +301,7 @@ static int php_zip_extract_file(struct zip * za, char *dest, char *file, int fil efree(fullpath); efree(file_basename); efree(file_dirname_fullpath); - free(new_state.cwd); + efree(new_state.cwd); if (n<0) { return 0; @@ -299,7 +315,6 @@ static int php_zip_add_file(struct zip *za, const char *filename, size_t filenam char *entry_name, size_t entry_name_len, long offset_start, long offset_len TSRMLS_DC) /* {{{ */ { struct zip_source *zs; - int cur_idx; char resolved_path[MAXPATHLEN]; zval exists_flag; @@ -321,25 +336,11 @@ static int php_zip_add_file(struct zip *za, const char *filename, size_t filenam if (!zs) { return -1; } - - cur_idx = zip_name_locate(za, (const char *)entry_name, 0); - /* TODO: fix _zip_replace */ - if (cur_idx<0) { - /* reset the error */ - if (za->error.str) { - _zip_error_fini(&za->error); - } - _zip_error_init(&za->error); - } else { - if (zip_delete(za, cur_idx) == -1) { - zip_source_free(zs); - return -1; - } - } - - if (zip_add(za, entry_name, zs) == -1) { + if (zip_file_add(za, entry_name, zs, ZIP_FL_OVERWRITE) < 0) { + zip_source_free(zs); return -1; } else { + zip_error_clear(za); return 1; } } @@ -780,7 +781,11 @@ static const zend_function_entry zip_functions[] = { PHP_FE(zip_entry_name, arginfo_zip_entry_name) PHP_FE(zip_entry_compressedsize, arginfo_zip_entry_compressedsize) PHP_FE(zip_entry_compressionmethod, arginfo_zip_entry_compressionmethod) +#ifdef PHP_FE_END PHP_FE_END +#else + {NULL,NULL,NULL} +#endif }; /* }}} */ @@ -869,7 +874,7 @@ static int php_zip_property_reader(ze_zip_object *obj, zip_prop_handler *hnd, zv } /* }}} */ -static zval **php_zip_get_property_ptr_ptr(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) /* {{{ */ +static zval **php_zip_get_property_ptr_ptr(zval *object, zval *member TYPE_ARG_DC KEY_ARG_DC TSRMLS_DC) /* {{{ */ { ze_zip_object *obj; zval tmp_member; @@ -884,24 +889,27 @@ static zval **php_zip_get_property_ptr_ptr(zval *object, zval *member, int type, zval_copy_ctor(&tmp_member); convert_to_string(&tmp_member); member = &tmp_member; +#if PHP_VERSION_ID >= 50400 key = NULL; +#endif } ret = FAILURE; obj = (ze_zip_object *)zend_objects_get_address(object TSRMLS_CC); if (obj->prop_handler != NULL) { +#if PHP_VERSION_ID >= 50400 if (key) { ret = zend_hash_quick_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, key->hash_value, (void **) &hnd); - } else { + } else +#endif ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd); - } } if (ret == FAILURE) { std_hnd = zend_get_std_object_handlers(); - retval = std_hnd->get_property_ptr_ptr(object, member, type, key TSRMLS_CC); + retval = std_hnd->get_property_ptr_ptr(object, member TYPE_ARG_CC KEY_ARG_CC TSRMLS_CC); } if (member == &tmp_member) { @@ -911,7 +919,7 @@ static zval **php_zip_get_property_ptr_ptr(zval *object, zval *member, int type, } /* }}} */ -static zval* php_zip_read_property(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) /* {{{ */ +static zval* php_zip_read_property(zval *object, zval *member, int type KEY_ARG_DC TSRMLS_DC) /* {{{ */ { ze_zip_object *obj; zval tmp_member; @@ -925,18 +933,21 @@ static zval* php_zip_read_property(zval *object, zval *member, int type, const z zval_copy_ctor(&tmp_member); convert_to_string(&tmp_member); member = &tmp_member; +#if PHP_VERSION_ID >= 50400 key = NULL; +#endif } ret = FAILURE; obj = (ze_zip_object *)zend_objects_get_address(object TSRMLS_CC); if (obj->prop_handler != NULL) { +#if PHP_VERSION_ID >= 50400 if (key) { ret = zend_hash_quick_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, key->hash_value, (void **) &hnd); - } else { + } else +#endif ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd); - } } if (ret == SUCCESS) { @@ -949,7 +960,7 @@ static zval* php_zip_read_property(zval *object, zval *member, int type, const z } } else { std_hnd = zend_get_std_object_handlers(); - retval = std_hnd->read_property(object, member, type, key TSRMLS_CC); + retval = std_hnd->read_property(object, member, type KEY_ARG_CC TSRMLS_CC); } if (member == &tmp_member) { @@ -959,7 +970,7 @@ static zval* php_zip_read_property(zval *object, zval *member, int type, const z } /* }}} */ -static int php_zip_has_property(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) /* {{{ */ +static int php_zip_has_property(zval *object, zval *member, int type KEY_ARG_DC TSRMLS_DC) /* {{{ */ { ze_zip_object *obj; zval tmp_member; @@ -972,18 +983,21 @@ static int php_zip_has_property(zval *object, zval *member, int type, const zend zval_copy_ctor(&tmp_member); convert_to_string(&tmp_member); member = &tmp_member; +#if PHP_VERSION_ID >= 50400 key = NULL; +#endif } ret = FAILURE; obj = (ze_zip_object *)zend_objects_get_address(object TSRMLS_CC); if (obj->prop_handler != NULL) { +#if PHP_VERSION_ID >= 50400 if (key) { ret = zend_hash_quick_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, key->hash_value, (void **) &hnd); - } else { + } else +#endif ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd); - } } if (ret == SUCCESS) { @@ -996,7 +1010,11 @@ static int php_zip_has_property(zval *object, zval *member, int type, const zend Z_SET_REFCOUNT_P(tmp, 1); Z_UNSET_ISREF_P(tmp); if (type == 1) { +#if PHP_VERSION_ID >= 50699 + retval = zend_is_true(tmp TSRMLS_CC); +#else retval = zend_is_true(tmp); +#endif } else if (type == 0) { retval = (Z_TYPE_P(tmp) != IS_NULL); } @@ -1005,7 +1023,7 @@ static int php_zip_has_property(zval *object, zval *member, int type, const zend zval_ptr_dtor(&tmp); } else { std_hnd = zend_get_std_object_handlers(); - retval = std_hnd->has_property(object, member, type, key TSRMLS_CC); + retval = std_hnd->has_property(object, member, type KEY_ARG_CC TSRMLS_CC); } if (member == &tmp_member) { @@ -1059,7 +1077,8 @@ static void php_zip_object_free_storage(void *object TSRMLS_DC) /* {{{ */ } if (intern->za) { if (zip_close(intern->za) != 0) { - _zip_free(intern->za); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot destroy the zip context"); + return; } intern->za = NULL; } @@ -1096,6 +1115,9 @@ static void php_zip_object_free_storage(void *object TSRMLS_DC) /* {{{ */ static zend_object_value php_zip_object_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ { +#if PHP_VERSION_ID < 50400 + zval *tmp; +#endif ze_zip_object *intern; zend_object_value retval; @@ -1116,8 +1138,13 @@ static zend_object_value php_zip_object_new(zend_class_entry *class_type TSRMLS_ intern->zo.ce = class_type; #endif - object_properties_init(&intern->zo, class_type); +#if PHP_VERSION_ID < 50400 + zend_hash_copy(intern->zo.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, + (void *) &tmp, sizeof(zval *)); +#else + object_properties_init(&intern->zo, class_type); +#endif retval.handle = zend_objects_store_put(intern, NULL, (zend_objects_free_object_storage_t) php_zip_object_free_storage, @@ -1140,7 +1167,7 @@ static void php_zip_free_dir(zend_rsrc_list_entry *rsrc TSRMLS_DC) if (zip_int) { if (zip_int->za) { if (zip_close(zip_int->za) != 0) { - _zip_free(zip_int->za); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot destroy the zip context"); } zip_int->za = NULL; } @@ -1159,13 +1186,7 @@ static void php_zip_free_entry(zend_rsrc_list_entry *rsrc TSRMLS_DC) if (zr_rsrc) { if (zr_rsrc->zf) { - if (zr_rsrc->zf->za) { - zip_fclose(zr_rsrc->zf); - } else { - if (zr_rsrc->zf->src) - zip_source_free(zr_rsrc->zf->src); - free(zr_rsrc->zf); - } + zip_fclose(zr_rsrc->zf); zr_rsrc->zf = NULL; } efree(zr_rsrc); @@ -1195,7 +1216,7 @@ zend_module_entry zip_module_entry = { NULL, NULL, PHP_MINFO(zip), - PHP_ZIP_VERSION_STRING, + PHP_ZIP_VERSION, STANDARD_MODULE_PROPERTIES }; /* }}} */ @@ -1215,7 +1236,7 @@ static PHP_NAMED_FUNCTION(zif_zip_open) zip_rsrc *rsrc_int; int err = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p", &filename, &filename_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ARG_PATH, &filename, &filename_len) == FAILURE) { return; } @@ -1493,12 +1514,12 @@ static ZIPARCHIVE_METHOD(open) int filename_len; int err = 0; long flags = 0; - char resolved_path[MAXPATHLEN]; + char *resolved_path; zval *this = getThis(); ze_zip_object *ze_obj = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|l", &filename, &filename_len, &flags) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ARG_PATH "|l", &filename, &filename_len, &flags) == FAILURE) { return; } @@ -1516,14 +1537,15 @@ static ZIPARCHIVE_METHOD(open) RETURN_FALSE; } - if (!expand_filepath(filename, resolved_path TSRMLS_CC)) { + if (!(resolved_path = expand_filepath(filename, NULL TSRMLS_CC))) { RETURN_FALSE; } if (ze_obj->za) { /* we already have an opened zip, free it */ if (zip_close(ze_obj->za) != 0) { - _zip_free(ze_obj->za); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty string as source"); + RETURN_FALSE; } ze_obj->za = NULL; } @@ -1536,13 +1558,45 @@ static ZIPARCHIVE_METHOD(open) if (!intern || err) { RETURN_LONG((long)err); } - ze_obj->filename = estrdup(resolved_path); - ze_obj->filename_len = filename_len; + ze_obj->filename = resolved_path; + ze_obj->filename_len = strlen(resolved_path); ze_obj->za = intern; RETURN_TRUE; } /* }}} */ +/* {{{ proto resource ZipArchive::setPassword(string password) +Set the password for the active archive */ +static ZIPARCHIVE_METHOD(setPassword) +{ + struct zip *intern; + zval *this = getThis(); + char *password; + int password_len; + + if (!this) { + RETURN_FALSE; + } + + ZIP_FROM_OBJECT(intern, this); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &password, &password_len) == FAILURE) { + return; + } + + if (password_len < 1) { + RETURN_FALSE; + } else { + int res = zip_set_default_password(intern, (const char *)password); + if (res == 0) { + RETURN_TRUE; + } else { + RETURN_FALSE; + } + } +} +/* }}} */ + /* {{{ proto bool ZipArchive::close() close the zip archive */ static ZIPARCHIVE_METHOD(close) @@ -1552,7 +1606,7 @@ static ZIPARCHIVE_METHOD(close) ze_zip_object *ze_obj; if (!this) { - RETURN_FALSE; + RETURN_FALSE; } ZIP_FROM_OBJECT(intern, this); @@ -1560,7 +1614,7 @@ static ZIPARCHIVE_METHOD(close) ze_obj = (ze_zip_object*) zend_object_store_get_object(this TSRMLS_CC); if (zip_close(intern)) { - RETURN_FALSE; + zip_discard(intern); } efree(ze_obj->filename); @@ -1637,6 +1691,7 @@ static ZIPARCHIVE_METHOD(addEmptyDir) if (zip_add_dir(intern, (const char *)s) == -1) { RETVAL_FALSE; } + zip_error_clear(intern); RETVAL_TRUE; } @@ -1654,7 +1709,7 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /* char *path = NULL; char *remove_path = NULL; char *add_path = NULL; - int pattern_len, add_path_len = 0, remove_path_len = 0, path_len = 0; + int pattern_len, add_path_len, remove_path_len = 0, path_len = 0; long remove_all_path = 0; long flags = 0; zval *options = NULL; @@ -1667,12 +1722,12 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /* ZIP_FROM_OBJECT(intern, this); /* 1 == glob, 2==pcre */ if (type == 1) { - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|la", + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ARG_PATH "|la", &pattern, &pattern_len, &flags, &options) == FAILURE) { return; } } else { - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|sa", + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ARG_PATH "|sa", &pattern, &pattern_len, &path, &path_len, &options) == FAILURE) { return; } @@ -1703,13 +1758,12 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /* zval **zval_file = NULL; for (i = 0; i < found; i++) { - char *file, *file_stripped, *entry_name; + char *file_stripped, *entry_name; size_t entry_name_len, file_stripped_len; char entry_name_buf[MAXPATHLEN]; char *basename = NULL; if (zend_hash_index_find(Z_ARRVAL_P(return_value), i, (void **) &zval_file) == SUCCESS) { - file = Z_STRVAL_PP(zval_file); if (remove_all_path) { php_basename(Z_STRVAL_PP(zval_file), Z_STRLEN_PP(zval_file), NULL, 0, &basename, (size_t *)&file_stripped_len TSRMLS_CC); @@ -1786,7 +1840,7 @@ static ZIPARCHIVE_METHOD(addFile) ZIP_FROM_OBJECT(intern, this); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|sll", + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ARG_PATH "|sll", &filename, &filename_len, &entry_name, &entry_name_len, &offset_start, &offset_len) == FAILURE) { return; } @@ -1856,13 +1910,16 @@ static ZIPARCHIVE_METHOD(addFromString) /* TODO: fix _zip_replace */ if (cur_idx >= 0) { if (zip_delete(intern, cur_idx) == -1) { + zip_source_free(zs); RETURN_FALSE; } } if (zip_add(intern, name, zs) == -1) { + zip_source_free(zs); RETURN_FALSE; } else { + zip_error_clear(intern); RETURN_TRUE; } } @@ -1885,7 +1942,7 @@ static ZIPARCHIVE_METHOD(statName) ZIP_FROM_OBJECT(intern, this); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|l", + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ARG_PATH "|l", &name, &name_len, &flags) == FAILURE) { return; } @@ -1941,7 +1998,7 @@ static ZIPARCHIVE_METHOD(locateName) ZIP_FROM_OBJECT(intern, this); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|l", + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ARG_PATH "|l", &name, &name_len, &flags) == FAILURE) { return; } @@ -2521,7 +2578,7 @@ static void php_zip_get_from(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */ ZIP_FROM_OBJECT(intern, this); if (type == 1) { - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|ll", &filename, &filename_len, &len, &flags) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ARG_PATH "|ll", &filename, &filename_len, &len, &flags) == FAILURE) { return; } PHP_ZIP_STAT_PATH(intern, filename, filename_len, flags, sb); @@ -2597,7 +2654,7 @@ static ZIPARCHIVE_METHOD(getStream) ZIP_FROM_OBJECT(intern, this); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p", &filename, &filename_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, ARG_PATH, &filename, &filename_len) == FAILURE) { return; } @@ -2620,6 +2677,10 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_open, 0, 0, 1) ZEND_ARG_INFO(0, flags) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(arginfo_ziparchive_setpassword, 0, 0, 1) + ZEND_ARG_INFO(0, password) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO(arginfo_ziparchive__void, 0) ZEND_END_ARG_INFO() @@ -2732,6 +2793,7 @@ ZEND_END_ARG_INFO() /* {{{ ze_zip_object_class_functions */ static const zend_function_entry zip_class_functions[] = { ZIPARCHIVE_ME(open, arginfo_ziparchive_open, ZEND_ACC_PUBLIC) + ZIPARCHIVE_ME(setPassword, arginfo_ziparchive_setpassword, ZEND_ACC_PUBLIC) ZIPARCHIVE_ME(close, arginfo_ziparchive__void, ZEND_ACC_PUBLIC) ZIPARCHIVE_ME(getStatusString, arginfo_ziparchive__void, ZEND_ACC_PUBLIC) ZIPARCHIVE_ME(addEmptyDir, arginfo_ziparchive_addemptydir, ZEND_ACC_PUBLIC) @@ -2874,7 +2936,7 @@ static PHP_MINFO_FUNCTION(zip) php_info_print_table_row(2, "Zip", "enabled"); php_info_print_table_row(2, "Extension Version","$Id$"); - php_info_print_table_row(2, "Zip version", PHP_ZIP_VERSION_STRING); + php_info_print_table_row(2, "Zip version", PHP_ZIP_VERSION); php_info_print_table_row(2, "Libzip version", LIBZIP_VERSION); php_info_print_table_end(); diff --git a/ext/zip/php_zip.h b/ext/zip/php_zip.h index dace407d14f31..c8da941b7a82d 100644 --- a/ext/zip/php_zip.h +++ b/ext/zip/php_zip.h @@ -28,9 +28,17 @@ extern zend_module_entry zip_module_entry; #include "TSRM.h" #endif +#if defined(HAVE_LIBZIP) +#include +#else #include "lib/zip.h" +#endif -#define PHP_ZIP_VERSION_STRING "1.11.0" +#ifndef ZIP_OVERWRITE +#define ZIP_OVERWRITE ZIP_TRUNCATE +#endif + +#define PHP_ZIP_VERSION "1.12.3" #if ((PHP_MAJOR_VERSION >= 5 && PHP_MINOR_VERSION >= 2) || PHP_MAJOR_VERSION >= 6) # define PHP_ZIP_USE_OO 1 @@ -67,8 +75,9 @@ typedef struct _ze_zip_read_rsrc { } zip_read_rsrc; #ifdef PHP_ZIP_USE_OO -#define ZIPARCHIVE_ME(name, arg_info, flags) ZEND_FENTRY(name, c_ziparchive_ ##name, arg_info, flags) -#define ZIPARCHIVE_METHOD(name) ZEND_NAMED_FUNCTION(c_ziparchive_##name) +#define ZIPARCHIVE_ME(name, arg_info, flags) {#name, c_ziparchive_ ##name, arg_info,(zend_uint) (sizeof(arg_info)/sizeof(struct _zend_arg_info)-1), flags }, +#define ZIPARCHIVE_METHOD(name) ZEND_NAMED_FUNCTION(c_ziparchive_ ##name) + /* Extends zend object */ typedef struct _ze_zip_object { diff --git a/ext/zip/tests/bug38943.inc b/ext/zip/tests/bug38943.inc new file mode 100644 index 0000000000000..a6f45e8294eff --- /dev/null +++ b/ext/zip/tests/bug38943.inc @@ -0,0 +1,16 @@ +testarray[] = 1; + var_dump($this->testarray); + } +} + +$z = new myZip; +$z->testp = "foobar"; +var_dump($z); + diff --git a/ext/zip/tests/bug38943_2.phpt b/ext/zip/tests/bug38943_2.phpt new file mode 100644 index 0000000000000..bdbad94517cc9 --- /dev/null +++ b/ext/zip/tests/bug38943_2.phpt @@ -0,0 +1,38 @@ +--TEST-- +#38943, properties in extended class cannot be set (5.3) +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +array(1) { + [0]=> + int(1) +} +object(myZip)#1 (%d) { + ["test":"myZip":private]=> + int(0) + ["testp"]=> + string(6) "foobar" + ["testarray":"myZip":private]=> + array(1) { + [0]=> + int(1) + } + ["status"]=> + int(0) + ["statusSys"]=> + int(0) + ["numFiles"]=> + int(0) + ["filename"]=> + string(0) "" + ["comment"]=> + string(0) "" +} diff --git a/ext/zip/tests/doubleclose.phpt b/ext/zip/tests/doubleclose.phpt new file mode 100644 index 0000000000000..abc62c8434789 --- /dev/null +++ b/ext/zip/tests/doubleclose.phpt @@ -0,0 +1,43 @@ +--TEST-- +close() called twice +--SKIPIF-- + +--FILE-- +open(dirname(__FILE__) . '/test.zip')) { + die('Failure'); +} +if ($zip->status == ZIPARCHIVE::ER_OK) { + var_dump($zip->close()); + var_dump($zip->close()); +} else { + die("Failure"); +} + +?> +Done +--EXPECTF-- +Procedural +NULL + +Warning: zip_close(): %i is not a valid Zip Directory resource in %s +bool(false) +Object +bool(true) + +Warning: ZipArchive::close(): Invalid or uninitialized Zip object in %s +bool(false) +Done diff --git a/ext/zip/tests/zip_entry_close.phpt b/ext/zip/tests/zip_entry_close.phpt new file mode 100644 index 0000000000000..82b7819054f49 --- /dev/null +++ b/ext/zip/tests/zip_entry_close.phpt @@ -0,0 +1,24 @@ +--TEST-- +zip_entry_close() function: simple and double call +--SKIPIF-- + +--FILE-- + +Done +--EXPECTF-- +entry_open: bool(true) +entry_close: bool(true) +entry_close: +Warning: zip_entry_close(): %d is not a valid Zip Entry resource in %s +bool(false) +Done diff --git a/ext/zip/zip_stream.c b/ext/zip/zip_stream.c index 79b54cbbb0cdc..02fbc70f85e60 100644 --- a/ext/zip/zip_stream.c +++ b/ext/zip/zip_stream.c @@ -1,3 +1,21 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt. | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Piere-Alain Joye | + +----------------------------------------------------------------------+ +*/ + /* $Id$ */ #ifdef HAVE_CONFIG_H # include "config.h" @@ -6,8 +24,6 @@ #if HAVE_ZIP #ifdef ZEND_ENGINE_2 -#include "lib/zip.h" - #include "php_streams.h" #include "ext/standard/file.h" #include "ext/standard/php_string.h" diff --git a/ext/zlib/tests/gzeof_variation1.phpt b/ext/zlib/tests/gzeof_variation1.phpt index 6d1e0401dff1c..77a1eccb66bb3 100644 --- a/ext/zlib/tests/gzeof_variation1.phpt +++ b/ext/zlib/tests/gzeof_variation1.phpt @@ -9,7 +9,7 @@ if (!extension_loaded("zlib")) { --FILE-- string(17) "for all languages" } -===DONE=== \ No newline at end of file +===DONE=== diff --git a/ext/zlib/tests/gzfile_basic2.phpt b/ext/zlib/tests/gzfile_basic2.phpt index 9f31eb0f87380..2bbf315a1ad71 100644 --- a/ext/zlib/tests/gzfile_basic2.phpt +++ b/ext/zlib/tests/gzfile_basic2.phpt @@ -12,7 +12,7 @@ is a very common test for all languages EOT; $dirname = 'gzfile_temp'; -$filename = $dirname.'/plainfile.txt'; +$filename = $dirname.'/gzfile_basic2.txt'; mkdir($dirname); $h = fopen($filename, 'w'); fwrite($h, $plaintxt); @@ -36,4 +36,4 @@ array(3) { [2]=> string(17) "for all languages" } -===DONE=== \ No newline at end of file +===DONE=== diff --git a/ext/zlib/tests/gzopen_basic2.phpt b/ext/zlib/tests/gzopen_basic2.phpt index 5cc02cd182267..90766b18170cf 100644 --- a/ext/zlib/tests/gzopen_basic2.phpt +++ b/ext/zlib/tests/gzopen_basic2.phpt @@ -18,7 +18,7 @@ echo "*** Testing gzopen() : basic functionality ***\n"; // Initialise all required variables -$filename = "temp.txt.gz"; +$filename = "gzopen_basic2.txt.gz"; $modes = array('w', 'w+'); $data = "This was the information that was written"; diff --git a/ext/zlib/tests/gzputs_basic.phpt b/ext/zlib/tests/gzputs_basic.phpt index 7566e74e72393..6456e4b55f96c 100644 --- a/ext/zlib/tests/gzputs_basic.phpt +++ b/ext/zlib/tests/gzputs_basic.phpt @@ -9,7 +9,7 @@ if (!extension_loaded("zlib")) { --FILE-- --FILE-- = 1400 @@ -2198,7 +2218,7 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod } /* start additional PHP extensions */ - php_register_extensions(&additional_modules, num_additional_modules TSRMLS_CC); + php_register_extensions_bc(additional_modules, num_additional_modules TSRMLS_CC); /* load and startup extensions compiled as shared objects (aka DLLs) as requested by php.ini entries @@ -2243,9 +2263,7 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod } #endif -#ifdef ZTS zend_post_startup(TSRMLS_C); -#endif module_initialized = 1; @@ -2315,6 +2333,7 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod shutdown_memory_manager(1, 0 TSRMLS_CC); zend_interned_strings_snapshot(TSRMLS_C); + virtual_cwd_activate(TSRMLS_C); /* we're done */ return retval; @@ -2624,9 +2643,9 @@ PHPAPI int php_lint_script(zend_file_handle *file TSRMLS_DC) #ifdef PHP_WIN32 /* {{{ dummy_indent just so that this symbol gets exported... */ -PHPAPI void dummy_indent(void) +PHPAPI void dummy_indent(TSRMLS_D) { - zend_indent(); + zend_indent(TSRMLS_C); } /* }}} */ #endif diff --git a/main/php.h b/main/php.h index 17ac8b4fd29d9..bfa148def3342 100644 --- a/main/php.h +++ b/main/php.h @@ -26,7 +26,7 @@ #include #endif -#define PHP_API_VERSION 20121113 +#define PHP_API_VERSION 20131218 #define PHP_HAVE_STREAMS #define YYDEBUG 0 @@ -400,7 +400,7 @@ END_EXTERN_C() /* Virtual current working directory support */ -#include "tsrm_virtual_cwd.h" +#include "zend_virtual_cwd.h" #include "zend_constants.h" diff --git a/main/php_ini.c b/main/php_ini.c index e9529a2d29f2a..2bdd3ae660519 100644 --- a/main/php_ini.c +++ b/main/php_ini.c @@ -361,7 +361,7 @@ static void php_load_zend_extension_cb(void *arg TSRMLS_DC) int length = strlen(filename); if (IS_ABSOLUTE_PATH(filename, length)) { - zend_load_extension(filename); + zend_load_extension(filename TSRMLS_CC); } else { char *libpath; char *extension_dir = INI_STR("extension_dir"); @@ -372,7 +372,7 @@ static void php_load_zend_extension_cb(void *arg TSRMLS_DC) } else { spprintf(&libpath, 0, "%s%c%s", extension_dir, DEFAULT_SLASH, filename); } - zend_load_extension(libpath); + zend_load_extension(libpath TSRMLS_CC); efree(libpath); } } diff --git a/main/php_open_temporary_file.c b/main/php_open_temporary_file.c index 054d497be6d5c..8315297738165 100644 --- a/main/php_open_temporary_file.c +++ b/main/php_open_temporary_file.c @@ -124,11 +124,11 @@ static int php_do_open_temporary_file(const char *path, const char *pfx, char ** cwd[0] = '\0'; } - new_state.cwd = strdup(cwd); + new_state.cwd = estrdup(cwd); new_state.cwd_length = strlen(cwd); if (virtual_file_ex(&new_state, path, NULL, CWD_REALPATH TSRMLS_CC)) { - free(new_state.cwd); + efree(new_state.cwd); return -1; } @@ -140,7 +140,7 @@ static int php_do_open_temporary_file(const char *path, const char *pfx, char ** if (spprintf(&opened_path, 0, "%s%s%sXXXXXX", new_state.cwd, trailing_slash, pfx) >= MAXPATHLEN) { efree(opened_path); - free(new_state.cwd); + efree(new_state.cwd); return -1; } @@ -151,7 +151,7 @@ static int php_do_open_temporary_file(const char *path, const char *pfx, char ** * which means that opening it will fail... */ if (VCWD_CHMOD(opened_path, 0600)) { efree(opened_path); - free(new_state.cwd); + efree(new_state.cwd); return -1; } fd = VCWD_OPEN_MODE(opened_path, open_flags, 0600); @@ -170,7 +170,7 @@ static int php_do_open_temporary_file(const char *path, const char *pfx, char ** } else { *opened_path_p = opened_path; } - free(new_state.cwd); + efree(new_state.cwd); return fd; } /* }}} */ diff --git a/main/php_ticks.c b/main/php_ticks.c index 17ffb9c770fcb..c65fc3246c8d4 100644 --- a/main/php_ticks.c +++ b/main/php_ticks.c @@ -46,17 +46,13 @@ static int php_compare_tick_functions(void *elem1, void *elem2) return (func1 == func2); } -PHPAPI void php_add_tick_function(void (*func)(int)) +PHPAPI void php_add_tick_function(void (*func)(int) TSRMLS_DC) { - TSRMLS_FETCH(); - zend_llist_add_element(&PG(tick_functions), (void *)&func); } -PHPAPI void php_remove_tick_function(void (*func)(int)) +PHPAPI void php_remove_tick_function(void (*func)(int) TSRMLS_DC) { - TSRMLS_FETCH(); - zend_llist_del_element(&PG(tick_functions), (void *)func, (int(*)(void*, void*))php_compare_tick_functions); } @@ -69,10 +65,8 @@ static void php_tick_iterator(void *data, void *arg TSRMLS_DC) func(*((int *)arg)); } -void php_run_ticks(int count) +void php_run_ticks(int count TSRMLS_DC) { - TSRMLS_FETCH(); - zend_llist_apply_with_argument(&PG(tick_functions), (llist_apply_with_arg_func_t) php_tick_iterator, &count TSRMLS_CC); } diff --git a/main/php_ticks.h b/main/php_ticks.h index cc966fa520e7b..9f50af00f5f3a 100644 --- a/main/php_ticks.h +++ b/main/php_ticks.h @@ -24,11 +24,11 @@ int php_startup_ticks(TSRMLS_D); void php_deactivate_ticks(TSRMLS_D); void php_shutdown_ticks(TSRMLS_D); -void php_run_ticks(int count); +void php_run_ticks(int count TSRMLS_DC); BEGIN_EXTERN_C() -PHPAPI void php_add_tick_function(void (*func)(int)); -PHPAPI void php_remove_tick_function(void (*func)(int)); +PHPAPI void php_add_tick_function(void (*func)(int) TSRMLS_DC); +PHPAPI void php_remove_tick_function(void (*func)(int) TSRMLS_DC); END_EXTERN_C() #endif diff --git a/main/php_version.h b/main/php_version.h index d48bf13c6f7ff..87c2e4ac4d8f7 100644 --- a/main/php_version.h +++ b/main/php_version.h @@ -1,8 +1,8 @@ /* automatically generated by configure */ /* edit configure.in to change version number */ #define PHP_MAJOR_VERSION 5 -#define PHP_MINOR_VERSION 6 +#define PHP_MINOR_VERSION 7 #define PHP_RELEASE_VERSION 0 #define PHP_EXTRA_VERSION "-dev" -#define PHP_VERSION "5.6.0-dev" -#define PHP_VERSION_ID 50600 +#define PHP_VERSION "5.7.0-dev" +#define PHP_VERSION_ID 50700 diff --git a/main/streams/php_stream_context.h b/main/streams/php_stream_context.h index 59fa604306d14..6c5c689455585 100644 --- a/main/streams/php_stream_context.h +++ b/main/streams/php_stream_context.h @@ -87,7 +87,7 @@ END_EXTERN_C() BEGIN_EXTERN_C() PHPAPI void php_stream_notification_notify(php_stream_context *context, int notifycode, int severity, char *xmsg, int xcode, size_t bytes_sofar, size_t bytes_max, void * ptr TSRMLS_DC); -PHPAPI php_stream_context *php_stream_context_set(php_stream *stream, php_stream_context *context); +PHPAPI php_stream_context *php_stream_context_set(php_stream *stream, php_stream_context *context TSRMLS_DC); END_EXTERN_C() #define php_stream_notify_info(context, code, xmsg, xcode) do { if ((context) && (context)->notifier) { \ diff --git a/main/streams/php_stream_transport.h b/main/streams/php_stream_transport.h index 52df73d731a44..15ba09430f981 100644 --- a/main/streams/php_stream_transport.h +++ b/main/streams/php_stream_transport.h @@ -170,10 +170,14 @@ typedef enum { STREAM_CRYPTO_METHOD_SSLv3_CLIENT, STREAM_CRYPTO_METHOD_SSLv23_CLIENT, STREAM_CRYPTO_METHOD_TLS_CLIENT, + STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT, + STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT, STREAM_CRYPTO_METHOD_SSLv2_SERVER, STREAM_CRYPTO_METHOD_SSLv3_SERVER, STREAM_CRYPTO_METHOD_SSLv23_SERVER, - STREAM_CRYPTO_METHOD_TLS_SERVER + STREAM_CRYPTO_METHOD_TLS_SERVER, + STREAM_CRYPTO_METHOD_TLSv1_1_SERVER, + STREAM_CRYPTO_METHOD_TLSv1_2_SERVER } php_stream_xport_crypt_method_t; BEGIN_EXTERN_C() diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c index 949b827679ecd..c2ead6da4a01f 100644 --- a/main/streams/plain_wrapper.c +++ b/main/streams/plain_wrapper.c @@ -78,11 +78,7 @@ PHPAPI int php_stream_parse_fopen_modes(const char *mode, int *open_flags) /* unknown mode */ return FAILURE; } -#if defined(O_NONBLOCK) - if (strchr(mode, 'n')) { - flags |= O_NONBLOCK; - } -#endif + if (strchr(mode, '+')) { flags |= O_RDWR; } else if (flags) { @@ -91,6 +87,12 @@ PHPAPI int php_stream_parse_fopen_modes(const char *mode, int *open_flags) flags |= O_RDONLY; } +#if defined(O_NONBLOCK) + if (strchr(mode, 'n')) { + flags |= O_NONBLOCK; + } +#endif + #if defined(_O_TEXT) && defined(O_BINARY) if (strchr(mode, 't')) { flags |= _O_TEXT; @@ -1436,7 +1438,7 @@ PHPAPI php_stream *_php_stream_fopen_with_path(const char *filename, const char php_error_docref(NULL TSRMLS_CC, E_NOTICE, "%s/%s path was truncated to %d", cwd, filename, MAXPATHLEN); } - free(cwd); + efree(cwd); if (((options & STREAM_DISABLE_OPEN_BASEDIR) == 0) && php_check_open_basedir(trypath TSRMLS_CC)) { return NULL; diff --git a/main/streams/streams.c b/main/streams/streams.c index d74f9fd04aa75..8e954c1c0f22e 100644 --- a/main/streams/streams.c +++ b/main/streams/streams.c @@ -2148,10 +2148,9 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mod /* }}} */ /* {{{ context API */ -PHPAPI php_stream_context *php_stream_context_set(php_stream *stream, php_stream_context *context) +PHPAPI php_stream_context *php_stream_context_set(php_stream *stream, php_stream_context *context TSRMLS_DC) { php_stream_context *oldcontext = stream->context; - TSRMLS_FETCH(); stream->context = context; diff --git a/main/streams/transports.c b/main/streams/transports.c index 2d31074ded807..1f87ab3c6c480 100644 --- a/main/streams/transports.c +++ b/main/streams/transports.c @@ -134,7 +134,7 @@ PHPAPI php_stream *_php_stream_xport_create(const char *name, size_t namelen, in context STREAMS_REL_CC TSRMLS_CC); if (stream) { - php_stream_context_set(stream, context); + php_stream_context_set(stream, context TSRMLS_CC); if ((flags & STREAM_XPORT_SERVER) == 0) { /* client */ diff --git a/main/streams/userspace.c b/main/streams/userspace.c index 1e626e4b4c779..d73140f8342b7 100644 --- a/main/streams/userspace.c +++ b/main/streams/userspace.c @@ -1121,7 +1121,7 @@ static int php_userstreamop_set_option(php_stream *stream, int option, int value php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::" USERSTREAM_SET_OPTION " is not implemented!", us->wrapper->classname); ret = PHP_STREAM_OPTION_RETURN_ERR; - } else if (retval && zend_is_true(retval)) { + } else if (retval && zend_is_true(retval TSRMLS_CC)) { ret = PHP_STREAM_OPTION_RETURN_OK; } else { ret = PHP_STREAM_OPTION_RETURN_ERR; @@ -1629,7 +1629,7 @@ static int php_userstreamop_cast(php_stream *stream, int castas, void **retptr T us->wrapper->classname); break; } - if (retval == NULL || !zend_is_true(retval)) { + if (retval == NULL || !zend_is_true(retval TSRMLS_CC)) { break; } php_stream_from_zval_no_verify(intstream, &retval); diff --git a/main/streams/xp_socket.c b/main/streams/xp_socket.c index 4edc68b015f82..0366027c1d770 100644 --- a/main/streams/xp_socket.c +++ b/main/streams/xp_socket.c @@ -426,7 +426,7 @@ static int php_sockop_cast(php_stream *stream, int castas, void **ret TSRMLS_DC) case PHP_STREAM_AS_FD: case PHP_STREAM_AS_SOCKETD: if (ret) - *(int*)ret = sock->socket; + *(php_socket_t *)ret = sock->socket; return SUCCESS; default: return FAILURE; diff --git a/php.ini-development b/php.ini-development index beebabbd24f07..df39e42140800 100644 --- a/php.ini-development +++ b/php.ini-development @@ -692,12 +692,6 @@ default_mimetype = "text/html" ; http://php.net/default-charset ;default_charset = "UTF-8" -; Always populate the $HTTP_RAW_POST_DATA variable. PHP's default behavior is -; to disable this feature. If post reading is disabled through -; enable_post_data_reading, $HTTP_RAW_POST_DATA is *NOT* populated. -; http://php.net/always-populate-raw-post-data -;always_populate_raw_post_data = On - ;;;;;;;;;;;;;;;;;;;;;;;;; ; Paths and Directories ; ;;;;;;;;;;;;;;;;;;;;;;;;; @@ -884,8 +878,7 @@ default_socket_timeout = 60 ;extension=php_exif.dll ; Must be after mbstring as it depends on it ;extension=php_mysql.dll ;extension=php_mysqli.dll -;extension=php_oci8.dll ; Use with Oracle 10gR2 Instant Client -;extension=php_oci8_11g.dll ; Use with Oracle 11gR2 Instant Client +;extension=php_oci8_12c.dll ; Use with Oracle Database 12c Instant Client ;extension=php_openssl.dll ;extension=php_pdo_firebird.dll ;extension=php_pdo_mysql.dll @@ -1907,7 +1900,7 @@ ldap.max_links = -1 ;opcache.revalidate_path=0 ; If disabled, all PHPDoc comments are dropped from the code to reduce the - ;size of the optimized code. +; size of the optimized code. ;opcache.save_comments=1 ; If disabled, PHPDoc comments are not loaded from SHM, so "Doc Comments" diff --git a/php.ini-production b/php.ini-production index 5a95344cb451e..cff1a3bc00d21 100644 --- a/php.ini-production +++ b/php.ini-production @@ -692,12 +692,6 @@ default_mimetype = "text/html" ; http://php.net/default-charset ;default_charset = "UTF-8" -; Always populate the $HTTP_RAW_POST_DATA variable. PHP's default behavior is -; to disable this feature. If post reading is disabled through -; enable_post_data_reading, $HTTP_RAW_POST_DATA is *NOT* populated. -; http://php.net/always-populate-raw-post-data -;always_populate_raw_post_data = On - ;;;;;;;;;;;;;;;;;;;;;;;;; ; Paths and Directories ; ;;;;;;;;;;;;;;;;;;;;;;;;; @@ -884,8 +878,7 @@ default_socket_timeout = 60 ;extension=php_exif.dll ; Must be after mbstring as it depends on it ;extension=php_mysql.dll ;extension=php_mysqli.dll -;extension=php_oci8.dll ; Use with Oracle 10gR2 Instant Client -;extension=php_oci8_11g.dll ; Use with Oracle 11gR2 Instant Client +;extension=php_oci8_12c.dll ; Use with Oracle Database 12c Instant Client ;extension=php_openssl.dll ;extension=php_pdo_firebird.dll ;extension=php_pdo_mysql.dll @@ -1907,7 +1900,7 @@ ldap.max_links = -1 ;opcache.revalidate_path=0 ; If disabled, all PHPDoc comments are dropped from the code to reduce the - ;size of the optimized code. +; size of the optimized code. ;opcache.save_comments=1 ; If disabled, PHPDoc comments are not loaded from SHM, so "Doc Comments" diff --git a/run-tests.php b/run-tests.php index 54a12a177d043..45ea29de519ea 100755 --- a/run-tests.php +++ b/run-tests.php @@ -241,6 +241,7 @@ function verify_config() 'precision=14', 'memory_limit=128M', 'opcache.fast_shutdown=0', + 'opcache.file_update_protection=0', ); function write_information($show_html) @@ -459,7 +460,7 @@ function save_or_mail_results() $compression = 0; $output_file = $CUR_DIR . '/php_test_results_' . date('Ymd_Hi') . '.txt'; -if ($compression) { +if ($compression && in_array("compress.zlib", stream_get_filters())) { $output_file = 'compress.zlib://' . $output_file . '.gz'; } @@ -1090,6 +1091,7 @@ function system_with_timeout($commandline, $env = null, $stdin = null) fwrite($pipes[0], $stdin); } fclose($pipes[0]); + unset($pipes[0]); $timeout = $leak_check ? 300 : (isset($env['TEST_TIMEOUT']) ? $env['TEST_TIMEOUT'] : 60); @@ -1289,16 +1291,20 @@ function run_test($php, $file, $env) unset($section_text['FILEEOF']); } - if (@count($section_text['FILE_EXTERNAL']) == 1) { - // don't allow tests to retrieve files from anywhere but this subdirectory - $section_text['FILE_EXTERNAL'] = dirname($file) . '/' . trim(str_replace('..', '', $section_text['FILE_EXTERNAL'])); + foreach (array( 'FILE', 'EXPECT', 'EXPECTF', 'EXPECTREGEX' ) as $prefix) { + $key = $prefix . '_EXTERNAL'; - if (file_exists($section_text['FILE_EXTERNAL'])) { - $section_text['FILE'] = file_get_contents($section_text['FILE_EXTERNAL'], FILE_BINARY); - unset($section_text['FILE_EXTERNAL']); - } else { - $bork_info = "could not load --FILE_EXTERNAL-- " . dirname($file) . '/' . trim($section_text['FILE_EXTERNAL']); - $borked = true; + if (@count($section_text[$key]) == 1) { + // don't allow tests to retrieve files from anywhere but this subdirectory + $section_text[$key] = dirname($file) . '/' . trim(str_replace('..', '', $section_text[$key])); + + if (file_exists($section_text[$key])) { + $section_text[$prefix] = file_get_contents($section_text[$key], FILE_BINARY); + unset($section_text[$key]); + } else { + $bork_info = "could not load --" . $key . "-- " . dirname($file) . '/' . trim($section_text[$key]); + $borked = true; + } } } @@ -1547,6 +1553,16 @@ function run_test($php, $file, $env) } } } + + if (!extension_loaded("zlib") + && ( array_key_exists("GZIP_POST", $section_text) + || array_key_exists("DEFLATE_POST", $section_text)) + ) { + $message = "ext/zlib required"; + show_result('SKIP', $tested, $tested_file, "reason: $message", $temp_filenames); + junit_mark_test_as('SKIP', $shortname, $tested, null, ""); + return 'SKIPPED'; + } if (@count($section_text['REDIRECTTEST']) == 1) { $test_files = array(); diff --git a/sapi/apache/mod_php5.c b/sapi/apache/mod_php5.c index 8361f7f41060d..28039039a09a1 100644 --- a/sapi/apache/mod_php5.c +++ b/sapi/apache/mod_php5.c @@ -108,7 +108,7 @@ static int sapi_apache_ub_write(const char *str, uint str_length TSRMLS_DC) /* {{{ sapi_apache_flush */ -static void sapi_apache_flush(void *server_context) +static void sapi_apache_flush(void *server_context TSRMLS_DC) { if (server_context) { #if MODULE_MAGIC_NUMBER > 19970110 diff --git a/sapi/apache2filter/sapi_apache2.c b/sapi/apache2filter/sapi_apache2.c index 8ce490ea43da5..c992c1c2d3daf 100644 --- a/sapi/apache2filter/sapi_apache2.c +++ b/sapi/apache2filter/sapi_apache2.c @@ -245,14 +245,13 @@ php_apache_sapi_register_variables(zval *track_vars_array TSRMLS_DC) } static void -php_apache_sapi_flush(void *server_context) +php_apache_sapi_flush(void *server_context TSRMLS_DC) { php_struct *ctx; apr_bucket_brigade *bb; apr_bucket_alloc_t *ba; apr_bucket *b; ap_filter_t *f; /* output filters */ - TSRMLS_FETCH(); ctx = server_context; diff --git a/sapi/apache2handler/sapi_apache2.c b/sapi/apache2handler/sapi_apache2.c index b7f95e0c12729..cf1a83fa533d9 100644 --- a/sapi/apache2handler/sapi_apache2.c +++ b/sapi/apache2handler/sapi_apache2.c @@ -287,11 +287,10 @@ php_apache_sapi_register_variables(zval *track_vars_array TSRMLS_DC) } static void -php_apache_sapi_flush(void *server_context) +php_apache_sapi_flush(void *server_context TSRMLS_DC) { php_struct *ctx; request_rec *r; - TSRMLS_FETCH(); ctx = server_context; diff --git a/sapi/apache_hooks/mod_php5.c b/sapi/apache_hooks/mod_php5.c index 66adb482ed1a0..4827932c7dad5 100644 --- a/sapi/apache_hooks/mod_php5.c +++ b/sapi/apache_hooks/mod_php5.c @@ -253,7 +253,7 @@ static int sapi_apache_ub_write(const char *str, uint str_length TSRMLS_DC) /* {{{ sapi_apache_flush */ -static void sapi_apache_flush(void *server_context) +static void sapi_apache_flush(void *server_context TSRMLS_DC) { if (server_context) { #if MODULE_MAGIC_NUMBER > 19970110 diff --git a/sapi/apache_hooks/php_apache.c b/sapi/apache_hooks/php_apache.c index dde6d88773799..f2a49b711fe54 100644 --- a/sapi/apache_hooks/php_apache.c +++ b/sapi/apache_hooks/php_apache.c @@ -155,15 +155,13 @@ static request_rec *get_apache_request(zval *z TSRMLS_DC) return r; } -/* {{{ php_apache_request_new(request_rec *r) +/* {{{ php_apache_request_new(request_rec *r TSRMLS_DC) * create a new zval-instance for ApacheRequest that wraps request_rec */ -zval *php_apache_request_new(request_rec *r) +zval *php_apache_request_new(request_rec *r TSRMLS_DC) { zval *req; zval *addr; - - TSRMLS_FETCH(); MAKE_STD_ZVAL(addr); Z_TYPE_P(addr) = IS_LONG; @@ -1170,7 +1168,7 @@ PHP_FUNCTION(apache_request_sub_req_lookup_uri) if (!sub_r) { RETURN_FALSE; } - return_value = php_apache_request_new(sub_r); + return_value = php_apache_request_new(sub_r TSRMLS_CC); } /* }}} */ @@ -1196,7 +1194,7 @@ PHP_FUNCTION(apache_request_sub_req_lookup_file) if (!sub_r) { RETURN_FALSE; } - return_value = php_apache_request_new(sub_r); + return_value = php_apache_request_new(sub_r TSRMLS_CC); } /* }}} */ @@ -1222,7 +1220,7 @@ PHP_FUNCTION(apache_request_sub_req_method_uri) if (!sub_r) { RETURN_FALSE; } - return_value = php_apache_request_new(sub_r); + return_value = php_apache_request_new(sub_r TSRMLS_CC); } /* }}} */ diff --git a/sapi/caudium/caudium.c b/sapi/caudium/caudium.c index d3b834fe93ff2..4ab43069ec6d2 100644 --- a/sapi/caudium/caudium.c +++ b/sapi/caudium/caudium.c @@ -395,11 +395,10 @@ php_caudium_sapi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC) * the client. Used for POST/PUT requests. */ -INLINE static int php_caudium_low_read_post(char *buf, uint count_bytes) +INLINE static int php_caudium_low_read_post(char *buf, uint count_bytes TSRMLS_DC) { uint total_read = 0; GET_THIS(); - TSRMLS_FETCH(); if(!MY_FD_OBJ->prog) { @@ -423,7 +422,7 @@ static int php_caudium_sapi_read_post(char *buf, uint count_bytes TSRMLS_DC) { uint total_read = 0; - THREAD_SAFE_RUN(total_read = php_caudium_low_read_post(buf, count_bytes), "read post"); + THREAD_SAFE_RUN(total_read = php_caudium_low_read_post(buf, count_bytes TSRMLS_CC), "read post"); return total_read; } diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c index 221b0021756dc..6b83807cff501 100644 --- a/sapi/cgi/cgi_main.c +++ b/sapi/cgi/cgi_main.c @@ -324,14 +324,14 @@ static int sapi_fcgi_ub_write(const char *str, uint str_length TSRMLS_DC) return str_length; } -static void sapi_cgi_flush(void *server_context) +static void sapi_cgi_flush(void *server_context TSRMLS_DC) { if (fflush(stdout) == EOF) { php_handle_aborted_connection(); } } -static void sapi_fcgi_flush(void *server_context) +static void sapi_fcgi_flush(void *server_context TSRMLS_DC) { fcgi_request *request = (fcgi_request*) server_context; @@ -524,8 +524,11 @@ static int sapi_fcgi_read_post(char *buffer, uint count_bytes TSRMLS_DC) uint read_bytes = 0; int tmp_read_bytes; fcgi_request *request = (fcgi_request*) SG(server_context); + size_t remaining = SG(request_info).content_length - SG(read_post_bytes); - count_bytes = MIN(count_bytes, (uint) SG(request_info).content_length - SG(read_post_bytes)); + if (remaining < count_bytes) { + count_bytes = remaining; + } while (read_bytes < count_bytes) { tmp_read_bytes = fcgi_read(request, buffer + read_bytes, count_bytes - read_bytes); if (tmp_read_bytes <= 0) { @@ -815,7 +818,7 @@ static void php_cgi_ini_activate_user_config(char *path, int path_len, const cha } if (real_path) { - free(real_path); + efree(real_path); } entry->expires = request_time + PG(user_ini_cache_ttl); } @@ -925,7 +928,7 @@ static int sapi_cgi_deactivate(TSRMLS_D) php_handle_aborted_connection(); } } else { - sapi_cgi_flush(SG(server_context)); + sapi_cgi_flush(SG(server_context) TSRMLS_CC); } } return SUCCESS; @@ -1396,7 +1399,7 @@ static void init_request_info(fcgi_request *request TSRMLS_DC) } else { SG(request_info).request_uri = env_script_name; } - free(real_path); + efree(real_path); } } else { /* pre 4.3 behaviour, shouldn't be used but provides BC */ @@ -1688,8 +1691,8 @@ static void add_response_header(sapi_header_struct *h, zval *return_value TSRMLS PHP_FUNCTION(apache_response_headers) /* {{{ */ { - if (ZEND_NUM_ARGS() > 0) { - WRONG_PARAM_COUNT; + if (zend_parse_parameters_none() == FAILURE) { + return; } if (!&SG(sapi_headers).headers) { @@ -2237,7 +2240,7 @@ consult the installation file that came with this distribution, or visit \n\ break; case 'z': /* load extension file */ - zend_load_extension(php_optarg); + zend_load_extension(php_optarg TSRMLS_CC); break; default: @@ -2490,7 +2493,7 @@ consult the installation file that came with this distribution, or visit \n\ /* Zeev might want to do something with this one day */ case PHP_MODE_INDENT: open_file_for_scanning(&file_handle TSRMLS_CC); - zend_indent(); + zend_indent(TSRMLS_C); zend_file_handle_dtor(&file_handle TSRMLS_CC); php_output_teardown(); return SUCCESS; diff --git a/sapi/cli/php_cli.c b/sapi/cli/php_cli.c index 9f3fc4b5b73a9..cb52cd70726e6 100644 --- a/sapi/cli/php_cli.c +++ b/sapi/cli/php_cli.c @@ -320,7 +320,7 @@ static int sapi_cli_ub_write(const char *str, uint str_length TSRMLS_DC) /* {{{ } /* }}} */ -static void sapi_cli_flush(void *server_context) /* {{{ */ +static void sapi_cli_flush(void *server_context TSRMLS_DC) /* {{{ */ { /* Ignore EBADF here, it's caused by the fact that STDIN/STDOUT/STDERR streams * are/could be closed before fflush() is called. @@ -870,7 +870,7 @@ static int do_cli(int argc, char **argv TSRMLS_DC) /* {{{ */ break; case 'z': /* load extension file */ - zend_load_extension(php_optarg); + zend_load_extension(php_optarg TSRMLS_CC); break; case 'H': hide_argv = 1; @@ -1024,7 +1024,7 @@ static int do_cli(int argc, char **argv TSRMLS_DC) /* {{{ */ /* Zeev might want to do something with this one day */ case PHP_MODE_INDENT: open_file_for_scanning(&file_handle TSRMLS_CC); - zend_indent(); + zend_indent(TSRMLS_C); zend_file_handle_dtor(file_handle.handle TSRMLS_CC); goto out; break; diff --git a/sapi/cli/php_cli_server.c b/sapi/cli/php_cli_server.c index 4a9ee3dc6ad33..89f20f63584ac 100644 --- a/sapi/cli/php_cli_server.c +++ b/sapi/cli/php_cli_server.c @@ -133,6 +133,7 @@ typedef struct php_cli_server_request { char *query_string; size_t query_string_len; HashTable headers; + HashTable headers_original_case; char *content; size_t content_len; const char *ext; @@ -275,6 +276,42 @@ static php_cli_server_ext_mime_type_pair mime_type_map[] = { { "webm", "video/webm" }, { "ogv", "video/ogg" }, { "ogg", "audio/ogg" }, + { "3gp", "video/3gpp" }, /* This is standard video format used for MMS in phones */ + { "apk", "application/vnd.android.package-archive" }, + { "avi", "video/x-msvideo" }, + { "bmp", "image/x-ms-bmp" }, + { "csv", "text/comma-separated-values" }, + { "doc", "application/msword" }, + { "docx", "application/msword" }, + { "flac", "audio/flac" }, + { "gz", "application/x-gzip" }, + { "gzip", "application/x-gzip" }, + { "ics", "text/calendar" }, + { "kml", "application/vnd.google-earth.kml+xml" }, + { "kmz", "application/vnd.google-earth.kmz" }, + { "m4a", "audio/mp4" }, + { "mp3", "audio/mpeg" }, + { "mp4", "video/mp4" }, + { "mpg", "video/mpeg" }, + { "mpeg", "video/mpeg" }, + { "mov", "video/quicktime" }, + { "odp", "application/vnd.oasis.opendocument.presentation" }, + { "ods", "application/vnd.oasis.opendocument.spreadsheet" }, + { "odt", "application/vnd.oasis.opendocument.text" }, + { "oga", "audio/ogg" }, + { "pdf", "application/pdf" }, + { "pptx", "application/vnd.ms-powerpoint" }, + { "pps", "application/vnd.ms-powerpoint" }, + { "qt", "video/quicktime" }, + { "swf", "application/x-shockwave-flash" }, + { "tar", "application/x-tar" }, + { "text", "text/plain" }, + { "tif", "image/tiff" }, + { "wav", "audio/wav" }, + { "wmv", "video/x-ms-wmv" }, + { "xls", "application/vnd.ms-excel" }, + { "xlsx", "application/vnd.ms-excel" }, + { "zip", "application/x-zip-compressed" }, { NULL, NULL } }; @@ -435,6 +472,75 @@ static const char *get_mime_type(const char *ext, size_t ext_len) /* {{{ */ return NULL; } /* }}} */ +PHP_FUNCTION(apache_request_headers) /* {{{ */ +{ + php_cli_server_client *client; + HashTable *headers; + char *key; + uint key_len; + char **value_pointer; + HashPosition pos; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + client = SG(server_context); + headers = &client->request.headers_original_case; + + array_init_size(return_value, zend_hash_num_elements(headers)); + + zend_hash_internal_pointer_reset_ex(headers, &pos); + while (zend_hash_get_current_data_ex(headers, (void **)&value_pointer, &pos) == SUCCESS) { + zend_hash_get_current_key_ex(headers, &key, &key_len, NULL, 0, &pos); + add_assoc_string_ex(return_value, key, key_len, *value_pointer, 1); + zend_hash_move_forward_ex(headers, &pos); + } +} +/* }}} */ + +static void add_response_header(sapi_header_struct *h, zval *return_value TSRMLS_DC) /* {{{ */ +{ + char *s, *p; + int len; + ALLOCA_FLAG(use_heap) + + if (h->header_len > 0) { + p = strchr(h->header, ':'); + len = p - h->header; + if (p && (len > 0)) { + while (len > 0 && (h->header[len-1] == ' ' || h->header[len-1] == '\t')) { + len--; + } + if (len) { + s = do_alloca(len + 1, use_heap); + memcpy(s, h->header, len); + s[len] = 0; + do { + p++; + } while (*p == ' ' || *p == '\t'); + add_assoc_stringl_ex(return_value, s, len+1, p, h->header_len - (p - h->header), 1); + free_alloca(s, use_heap); + } + } + } +} +/* }}} */ + +PHP_FUNCTION(apache_response_headers) /* {{{ */ +{ + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + if (!&SG(sapi_headers).headers) { + RETURN_FALSE; + } + array_init(return_value); + zend_llist_apply_with_argument(&SG(sapi_headers).headers, (llist_apply_with_arg_func_t)add_response_header, return_value TSRMLS_CC); +} +/* }}} */ + /* {{{ cli_server module */ @@ -479,9 +585,15 @@ zend_module_entry cli_server_module_entry = { }; /* }}} */ +ZEND_BEGIN_ARG_INFO(arginfo_no_args, 0) +ZEND_END_ARG_INFO() + const zend_function_entry server_additional_functions[] = { PHP_FE(cli_set_process_title, arginfo_cli_set_process_title) PHP_FE(cli_get_process_title, arginfo_cli_get_process_title) + PHP_FE(apache_request_headers, arginfo_no_args) + PHP_FE(apache_response_headers, arginfo_no_args) + PHP_FALIAS(getallheaders, apache_request_headers, arginfo_no_args) {NULL, NULL, NULL} }; @@ -502,10 +614,9 @@ static int sapi_cli_server_ub_write(const char *str, uint str_length TSRMLS_DC) return php_cli_server_client_send_through(client, str, str_length); } /* }}} */ -static void sapi_cli_server_flush(void *server_context) /* {{{ */ +static void sapi_cli_server_flush(void *server_context TSRMLS_DC) /* {{{ */ { php_cli_server_client *client = server_context; - TSRMLS_FETCH(); if (!client) { return; @@ -781,9 +892,11 @@ static void php_cli_server_poller_remove(php_cli_server_poller *poller, int mode static int php_cli_server_poller_poll(php_cli_server_poller *poller, const struct timeval *tv) /* {{{ */ { + struct timeval t = *tv; + memmove(&poller->active.rfds, &poller->rfds, sizeof(poller->rfds)); memmove(&poller->active.wfds, &poller->wfds, sizeof(poller->wfds)); - return php_select(poller->max_fd + 1, &poller->active.rfds, &poller->active.wfds, NULL, (struct timeval *)tv); + return php_select(poller->max_fd + 1, &poller->active.rfds, &poller->active.wfds, NULL, &t); } /* }}} */ static int php_cli_server_poller_iter_on_active(php_cli_server_poller *poller, void *opaque, int(*callback)(void *, int fd, int events)) /* {{{ */ @@ -1030,7 +1143,7 @@ static int php_cli_server_content_sender_send(php_cli_server_content_sender *sen return 0; } /* }}} */ -static int php_cli_server_content_sender_pull(php_cli_server_content_sender *sender, int fd, size_t *nbytes_read) /* {{{ */ +static int php_cli_server_content_sender_pull(php_cli_server_content_sender *sender, int fd, size_t *nbytes_read TSRMLS_DC) /* {{{ */ { ssize_t _nbytes_read; php_cli_server_chunk *chunk = php_cli_server_chunk_heap_new_self_contained(131072); @@ -1038,7 +1151,6 @@ static int php_cli_server_content_sender_pull(php_cli_server_content_sender *sen _nbytes_read = read(fd, chunk->data.heap.p, chunk->data.heap.len); if (_nbytes_read < 0) { char *errstr = get_last_error(); - TSRMLS_FETCH(); php_cli_server_logf("%s" TSRMLS_CC, errstr); pefree(errstr, 1); php_cli_server_chunk_dtor(chunk); @@ -1300,6 +1412,7 @@ static int php_cli_server_request_ctor(php_cli_server_request *req) /* {{{ */ req->query_string = NULL; req->query_string_len = 0; zend_hash_init(&req->headers, 0, NULL, (void(*)(void*))char_ptr_dtor_p, 1); + zend_hash_init(&req->headers_original_case, 0, NULL, NULL, 1); req->content = NULL; req->content_len = 0; req->ext = NULL; @@ -1325,6 +1438,7 @@ static void php_cli_server_request_dtor(php_cli_server_request *req) /* {{{ */ pefree(req->query_string, 1); } zend_hash_destroy(&req->headers); + zend_hash_destroy(&req->headers_original_case); if (req->content) { pefree(req->content, 1); } @@ -1569,6 +1683,7 @@ static int php_cli_server_client_read_request_on_header_value(php_http_parser *p { char *header_name = zend_str_tolower_dup(client->current_header_name, client->current_header_name_len); zend_hash_add(&client->request.headers, header_name, client->current_header_name_len + 1, &value, sizeof(char *), NULL); + zend_hash_add(&client->request.headers_original_case, client->current_header_name, client->current_header_name_len + 1, &value, sizeof(char *), NULL); efree(header_name); } @@ -1600,6 +1715,7 @@ static int php_cli_server_client_read_request_on_body(php_http_parser *parser, c } client->request.content_len = 0; } + client->request.content = perealloc(client->request.content, client->request.content_len + length, 1); memmove(client->request.content + client->request.content_len, at, length); client->request.content_len += length; return 0; @@ -2250,7 +2366,7 @@ static int php_cli_server_send_event(php_cli_server *server, php_cli_server_clie if (client->content_sender_initialized) { if (client->file_fd >= 0 && !client->content_sender.buffer.first) { size_t nbytes_read; - if (php_cli_server_content_sender_pull(&client->content_sender, client->file_fd, &nbytes_read)) { + if (php_cli_server_content_sender_pull(&client->content_sender, client->file_fd, &nbytes_read TSRMLS_CC)) { php_cli_server_close_connection(server, client TSRMLS_CC); return FAILURE; } diff --git a/sapi/cli/tests/php_cli_server_019.phpt b/sapi/cli/tests/php_cli_server_019.phpt new file mode 100644 index 0000000000000..2b983e5c0aee3 --- /dev/null +++ b/sapi/cli/tests/php_cli_server_019.phpt @@ -0,0 +1,68 @@ +--TEST-- +Implement Req #65917 (getallheaders() is not supported by the built-in web server) +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +HTTP/1.1 200 OK +Host: %s +Connection: close +X-Powered-By: %s +Bar-Foo: Foo +Content-type: text/html + +array(2) { + ["Host"]=> + string(9) "localhost" + ["Foo-Bar"]=> + string(3) "Bar" +} +array(2) { + ["Host"]=> + string(9) "localhost" + ["Foo-Bar"]=> + string(3) "Bar" +} +array(3) { + ["X-Powered-By"]=> + string(%d) "P%s" + ["Bar-Foo"]=> + string(3) "Foo" + ["Content-type"]=> + string(9) "text/html" +} diff --git a/sapi/cli/tests/upload_2G.phpt b/sapi/cli/tests/upload_2G.phpt index fe13d90007036..b8416ea730972 100644 --- a/sapi/cli/tests/upload_2G.phpt +++ b/sapi/cli/tests/upload_2G.phpt @@ -89,7 +89,7 @@ array(1) { ["type"]=> string(10) "text/plain" ["tmp_name"]=> - string(14) "/tmp/php%s" + string(%d) "%s" ["error"]=> int(0) ["size"]=> diff --git a/sapi/continuity/capi.c b/sapi/continuity/capi.c index 26762a5a963c1..f75b507ef91a1 100644 --- a/sapi/continuity/capi.c +++ b/sapi/continuity/capi.c @@ -462,7 +462,7 @@ int phpFinit(lstTset * opt) core_globals = ts_resource(core_globals_id); logFmsg(0, "mod/php: PHP Interface v3 (module)"); - logFmsg(0, "mod/php: Copyright (c) 1999-2005 The PHP Group. All rights reserved."); + logFmsg(0, "mod/php: Copyright (c) 1999-2013 The PHP Group. All rights reserved."); sapi_startup(&capi_sapi_module); capi_sapi_module.startup(&capi_sapi_module); diff --git a/sapi/embed/php_embed.c b/sapi/embed/php_embed.c index 414b4dbb022a5..66961ec6ef27a 100644 --- a/sapi/embed/php_embed.c +++ b/sapi/embed/php_embed.c @@ -79,7 +79,7 @@ static int php_embed_ub_write(const char *str, uint str_length TSRMLS_DC) return str_length; } -static void php_embed_flush(void *server_context) +static void php_embed_flush(void *server_context TSRMLS_DC) { if (fflush(stdout)==EOF) { php_handle_aborted_connection(); diff --git a/sapi/fpm/fpm/fastcgi.c b/sapi/fpm/fpm/fastcgi.c index 99905c8b605a6..ec579eadf6ebf 100644 --- a/sapi/fpm/fpm/fastcgi.c +++ b/sapi/fpm/fpm/fastcgi.c @@ -426,8 +426,9 @@ static int fcgi_get_params(fcgi_request *req, unsigned char *p, unsigned char *e char buf[128]; char *tmp = buf; size_t buf_size = sizeof(buf); - int name_len, val_len; - uint eff_name_len; + int name_len = 0; + int val_len = 0; + uint eff_name_len = 0; char *s; int ret = 1; size_t bytes_consumed; diff --git a/sapi/fpm/fpm/fpm_children.c b/sapi/fpm/fpm/fpm_children.c index 84a9474332215..45cc075b42a6c 100644 --- a/sapi/fpm/fpm/fpm_children.c +++ b/sapi/fpm/fpm/fpm_children.c @@ -251,7 +251,7 @@ void fpm_children_bury() /* {{{ */ } zlog(severity, "[pool %s] child %d exited %s after %ld.%06d seconds from start", child->wp->config->name, (int) pid, buf, tv2.tv_sec, (int) tv2.tv_usec); } else { - zlog(ZLOG_DEBUG, "[pool %s] child %d has been killed by the process managment after %ld.%06d seconds from start", child->wp->config->name, (int) pid, tv2.tv_sec, (int) tv2.tv_usec); + zlog(ZLOG_DEBUG, "[pool %s] child %d has been killed by the process management after %ld.%06d seconds from start", child->wp->config->name, (int) pid, tv2.tv_sec, (int) tv2.tv_usec); } fpm_child_close(child, 1 /* in event_loop */); diff --git a/sapi/fpm/fpm/fpm_main.c b/sapi/fpm/fpm/fpm_main.c index 043e0e00a47c0..e1c8ff081a055 100644 --- a/sapi/fpm/fpm/fpm_main.c +++ b/sapi/fpm/fpm/fpm_main.c @@ -315,7 +315,7 @@ static int sapi_cgibin_ub_write(const char *str, uint str_length TSRMLS_DC) } -static void sapi_cgibin_flush(void *server_context) +static void sapi_cgibin_flush(void *server_context TSRMLS_DC) { /* fpm has started, let use fcgi instead of stdout */ if (fpm_is_running) { @@ -498,8 +498,11 @@ static int sapi_cgi_read_post(char *buffer, uint count_bytes TSRMLS_DC) { uint read_bytes = 0; int tmp_read_bytes; + size_t remaining = SG(request_info).content_length - SG(read_post_bytes); - count_bytes = MIN(count_bytes, (uint) SG(request_info).content_length - SG(read_post_bytes)); + if (remaining < count_bytes) { + count_bytes = remaining; + } while (read_bytes < count_bytes) { fcgi_request *request = (fcgi_request*) SG(server_context); if (request_body_fd == -1) { @@ -1982,8 +1985,9 @@ consult the installation file that came with this distribution, or visit \n\ out: SG(server_context) = NULL; + php_module_shutdown(TSRMLS_C); + if (parent) { - php_module_shutdown(TSRMLS_C); sapi_shutdown(); } diff --git a/sapi/fpm/fpm/fpm_php_trace.c b/sapi/fpm/fpm/fpm_php_trace.c index d95d66a754c3e..925f2de64e93f 100644 --- a/sapi/fpm/fpm/fpm_php_trace.c +++ b/sapi/fpm/fpm/fpm_php_trace.c @@ -138,7 +138,7 @@ static int fpm_php_trace_dump(struct fpm_child_s *child, FILE *slowlog TSRMLS_DC void fpm_php_trace(struct fpm_child_s *child) /* {{{ */ { TSRMLS_FETCH(); - fpm_scoreboard_update(0, 0, 0, 0, 0, 0, 1, FPM_SCOREBOARD_ACTION_SET, child->wp->scoreboard); + fpm_scoreboard_update(0, 0, 0, 0, 0, 0, 1, FPM_SCOREBOARD_ACTION_INC, child->wp->scoreboard); FILE *slowlog; zlog(ZLOG_NOTICE, "about to trace %d", (int) child->pid); diff --git a/sapi/fpm/fpm/fpm_scoreboard.c b/sapi/fpm/fpm/fpm_scoreboard.c index 24463a90dddfd..8d0868182d763 100644 --- a/sapi/fpm/fpm/fpm_scoreboard.c +++ b/sapi/fpm/fpm/fpm_scoreboard.c @@ -111,7 +111,7 @@ void fpm_scoreboard_update(int idle, int active, int lq, int lq_len, int request scoreboard->max_children_reached = max_children_reached; } if (slow_rq > 0) { - scoreboard->slow_rq += slow_rq; + scoreboard->slow_rq = slow_rq; } } else { if (scoreboard->idle + idle > 0) { @@ -137,6 +137,12 @@ void fpm_scoreboard_update(int idle, int active, int lq, int lq_len, int request } else { scoreboard->max_children_reached = 0; } + + if (scoreboard->slow_rq + slow_rq > 0) { + scoreboard->slow_rq += slow_rq; + } else { + scoreboard->slow_rq = 0; + } } if (scoreboard->active > scoreboard->active_max) { diff --git a/sapi/fpm/fpm/fpm_sockets.c b/sapi/fpm/fpm/fpm_sockets.c index 145b2550c3bad..e056565ea4119 100644 --- a/sapi/fpm/fpm/fpm_sockets.c +++ b/sapi/fpm/fpm/fpm_sockets.c @@ -487,6 +487,7 @@ int fpm_socket_unix_test_connect(struct sockaddr_un *sock, size_t socklen) /* {{ } if (connect(fd, (struct sockaddr *)sock, socklen) == -1) { + close(fd); return -1; } diff --git a/sapi/fpm/fpm/fpm_sockets.h b/sapi/fpm/fpm/fpm_sockets.h index cce5712b8cfbf..121c016a7b89b 100644 --- a/sapi/fpm/fpm/fpm_sockets.h +++ b/sapi/fpm/fpm/fpm_sockets.h @@ -19,7 +19,7 @@ #if (__FreeBSD__) || (__OpenBSD__) #define FPM_BACKLOG_DEFAULT -1 #else -#define FPM_BACKLOG_DEFAULT 128 +#define FPM_BACKLOG_DEFAULT 65535 #endif enum fpm_address_domain fpm_sockets_domain_from_address(char *addr); diff --git a/sapi/fpm/php-fpm.8.in b/sapi/fpm/php-fpm.8.in index a4e7e74e208d8..b02aa25ba74d4 100644 --- a/sapi/fpm/php-fpm.8.in +++ b/sapi/fpm/php-fpm.8.in @@ -96,7 +96,7 @@ Specify alternative path to FastCGI process manager configuration file (the defa .PD 1 .B \-t Test FPM configuration file and exit -If called twice (-tt), the configuration is dumped before exiting. +If called twice (\-tt), the configuration is dumped before exiting. .TP .PD 0 .B \-\-daemonize diff --git a/sapi/fpm/php-fpm.conf.in b/sapi/fpm/php-fpm.conf.in index af4f2fa325a3f..9002a2933bb26 100644 --- a/sapi/fpm/php-fpm.conf.in +++ b/sapi/fpm/php-fpm.conf.in @@ -159,8 +159,8 @@ group = @php_fpm_group@ listen = 127.0.0.1:9000 ; Set listen(2) backlog. -; Default Value: 128 (-1 on FreeBSD and OpenBSD) -;listen.backlog = 128 +; Default Value: 65535 (-1 on FreeBSD and OpenBSD) +;listen.backlog = 65535 ; Set permissions for unix socket, if one is used. In Linux, read/write ; permissions must be set in order to allow connections from a web server. Many diff --git a/sapi/litespeed/Makefile.frag b/sapi/litespeed/Makefile.frag index b70e5e8702933..767c2e5eb1719 100644 --- a/sapi/litespeed/Makefile.frag +++ b/sapi/litespeed/Makefile.frag @@ -4,6 +4,6 @@ $(SAPI_LITESPEED_PATH): $(PHP_GLOBAL_OBJS) $(PHP_BINARY_OBJS) $(PHP_LITESPEED_OB $(BUILD_LITESPEED) install-litespeed: $(SAPI_LITESPEED_PATH) - @echo "Installing PHP LitSpeed binary: $(INSTALL_ROOT)$(bindir)/" + @echo "Installing PHP LiteSpeed binary: $(INSTALL_ROOT)$(bindir)/" @$(INSTALL) -m 0755 $(SAPI_LITESPEED_PATH) $(INSTALL_ROOT)$(bindir)/lsphp diff --git a/sapi/litespeed/lsapi_main.c b/sapi/litespeed/lsapi_main.c index 19364c66e06f2..850433d29c324 100644 --- a/sapi/litespeed/lsapi_main.c +++ b/sapi/litespeed/lsapi_main.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | + | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id$ */ +/* $Id: lsapi_main.c,v 1.59 2013/11/18 21:14:38 gwang Exp $ */ #include "php.h" #include "SAPI.h" @@ -75,7 +75,9 @@ static int lsapi_mode = 1; static char *php_self = ""; static char *script_filename = ""; static int source_highlight = 0; - +static int ignore_php_ini = 0; +static char * argv0 = NULL; +static int engine = 1; #ifdef ZTS zend_compiler_globals *compiler_globals; zend_executor_globals *executor_globals; @@ -90,53 +92,78 @@ zend_module_entry litespeed_module_entry; */ static int php_lsapi_startup(sapi_module_struct *sapi_module) { - if (php_module_startup(sapi_module, NULL, 0)==FAILURE) { - return FAILURE; - } - return SUCCESS; + if (php_module_startup(sapi_module, NULL, 0)==FAILURE) { + return FAILURE; + } + argv0 = sapi_module->executable_location; + return SUCCESS; } /* }}} */ +/* {{{ sapi_lsapi_ini_defaults */ + +/* overwriteable ini defaults must be set in sapi_cli_ini_defaults() */ +#define INI_DEFAULT(name,value)\ + ZVAL_STRING(tmp, value, 0);\ + zend_hash_update(configuration_hash, name, sizeof(name), tmp, sizeof(zval), (void**)&entry);\ + Z_STRVAL_P(entry) = zend_strndup(Z_STRVAL_P(entry), Z_STRLEN_P(entry)) + +static void sapi_lsapi_ini_defaults(HashTable *configuration_hash) +{ + zval *tmp, *entry; + +#if PHP_MAJOR_VERSION > 4 +/* + MAKE_STD_ZVAL(tmp); + + INI_DEFAULT("register_long_arrays", "0"); + + FREE_ZVAL(tmp); +*/ +#endif + +} +/* }}} */ /* {{{ sapi_lsapi_ub_write */ static int sapi_lsapi_ub_write(const char *str, uint str_length TSRMLS_DC) { - int ret; - int remain; - if ( lsapi_mode ) { - ret = LSAPI_Write( str, str_length ); - if ( ret < str_length ) { - php_handle_aborted_connection(); - return str_length - ret; - } - } else { - remain = str_length; - while( remain > 0 ) { - ret = write( 1, str, remain ); - if ( ret <= 0 ) { - php_handle_aborted_connection(); - return str_length - remain; - } - str += ret; - remain -= ret; - } - } - return str_length; + int ret; + int remain; + if ( lsapi_mode ) { + ret = LSAPI_Write( str, str_length ); + if ( ret < str_length ) { + php_handle_aborted_connection(); + return str_length - ret; + } + } else { + remain = str_length; + while( remain > 0 ) { + ret = write( 1, str, remain ); + if ( ret <= 0 ) { + php_handle_aborted_connection(); + return str_length - remain; + } + str += ret; + remain -= ret; + } + } + return str_length; } /* }}} */ /* {{{ sapi_lsapi_flush */ -static void sapi_lsapi_flush( void * server_context ) +static void sapi_lsapi_flush( void * server_context TSRMLS_DC ) { - if ( lsapi_mode ) { - if ( LSAPI_Flush() == -1) { - php_handle_aborted_connection(); - } - } + if ( lsapi_mode ) { + if ( LSAPI_Flush() == -1) { + php_handle_aborted_connection(); + } + } } /* }}} */ @@ -145,8 +172,12 @@ static void sapi_lsapi_flush( void * server_context ) */ static int sapi_lsapi_deactivate(TSRMLS_D) { - LSAPI_Finish(); - return SUCCESS; + if ( SG(request_info).path_translated ) + { + efree( SG(request_info).path_translated ); + } + + return SUCCESS; } /* }}} */ @@ -157,46 +188,99 @@ static int sapi_lsapi_deactivate(TSRMLS_D) */ static char *sapi_lsapi_getenv( char * name, size_t name_len TSRMLS_DC ) { - if ( lsapi_mode ) { - return LSAPI_GetEnv( name ); - } else { - return getenv( name ); - } + if ( lsapi_mode ) { + return LSAPI_GetEnv( name ); + } else { + return getenv( name ); + } } /* }}} */ +/* +static int add_variable( const char * pKey, int keyLen, const char * pValue, int valLen, + void * arg ) +{ + php_register_variable_safe((char *)pKey, (char *)pValue, valLen, (zval *)arg TSRMLS_CC); + return 1; +} +*/ static int add_variable( const char * pKey, int keyLen, const char * pValue, int valLen, - void * arg ) + void * arg ) { - php_register_variable_safe((char *)pKey, (char *)pValue, valLen, (zval *)arg TSRMLS_CC); - return 1; + zval * gpc_element, **gpc_element_p; + HashTable * symtable1 = Z_ARRVAL_P((zval * )arg); + register char * pKey1 = (char *)pKey; + + MAKE_STD_ZVAL(gpc_element); + Z_STRLEN_P( gpc_element ) = valLen; + Z_STRVAL_P( gpc_element ) = estrndup(pValue, valLen); + Z_TYPE_P( gpc_element ) = IS_STRING; +#if PHP_MAJOR_VERSION > 4 + zend_symtable_update( symtable1, pKey1, keyLen + 1, &gpc_element, sizeof( zval *), (void **) &gpc_element_p ); +#else + zend_hash_update( symtable1, pKey1, keyLen + 1, &gpc_element, sizeof( zval *), (void **) &gpc_element_p ); +#endif + return 1; } +#if ((PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 4) || PHP_MAJOR_VERSION < 5) +static int add_variable_magic_quote( const char * pKey, int keyLen, const char * pValue, int valLen, + void * arg ) +{ + zval * gpc_element, **gpc_element_p; + HashTable * symtable1 = Z_ARRVAL_P((zval * )arg); + register char * pKey1 = (char *)pKey; + + MAKE_STD_ZVAL(gpc_element); + Z_STRLEN_P( gpc_element ) = valLen; + Z_STRVAL_P( gpc_element ) = php_addslashes((char *)pValue, valLen, &Z_STRLEN_P( gpc_element ), 0 ); + Z_TYPE_P( gpc_element ) = IS_STRING; +#if PHP_MAJOR_VERSION > 4 + zend_symtable_update( symtable1, pKey1, keyLen + 1, &gpc_element, sizeof( zval *), (void **) &gpc_element_p ); +#else + zend_hash_update( symtable1, pKey1, keyLen + 1, &gpc_element, sizeof( zval *), (void **) &gpc_element_p ); +#endif + return 1; +} + +#endif /* {{{ sapi_lsapi_register_variables */ static void sapi_lsapi_register_variables(zval *track_vars_array TSRMLS_DC) { + char * php_self = ""; + if ( lsapi_mode ) { + if ( (SG(request_info).request_uri ) ) + php_self = (SG(request_info).request_uri ); - if ( lsapi_mode ) { - LSAPI_ForeachHeader( add_variable, track_vars_array ); - LSAPI_ForeachEnv( add_variable, track_vars_array ); - php_import_environment_variables(track_vars_array TSRMLS_CC); - - php_register_variable("PHP_SELF", (SG(request_info).request_uri ? SG(request_info).request_uri:""), track_vars_array TSRMLS_CC); - } else { - php_import_environment_variables(track_vars_array TSRMLS_CC); +#if ((PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 4) || PHP_MAJOR_VERSION < 5) + if (!PG(magic_quotes_gpc)) { +#endif + LSAPI_ForeachHeader( add_variable, track_vars_array ); + LSAPI_ForeachEnv( add_variable, track_vars_array ); + add_variable("PHP_SELF", 8, php_self, strlen( php_self ), track_vars_array ); +#if ((PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 4) || PHP_MAJOR_VERSION < 5) + } else { + LSAPI_ForeachHeader( add_variable_magic_quote, track_vars_array ); + LSAPI_ForeachEnv( add_variable_magic_quote, track_vars_array ); + add_variable_magic_quote("PHP_SELF", 8, php_self, strlen( php_self ), track_vars_array ); + } +#endif + php_import_environment_variables(track_vars_array TSRMLS_CC); + } else { + php_import_environment_variables(track_vars_array TSRMLS_CC); - php_register_variable("PHP_SELF", php_self, track_vars_array TSRMLS_CC); - php_register_variable("SCRIPT_NAME", php_self, track_vars_array TSRMLS_CC); - php_register_variable("SCRIPT_FILENAME", script_filename, track_vars_array TSRMLS_CC); - php_register_variable("PATH_TRANSLATED", script_filename, track_vars_array TSRMLS_CC); - php_register_variable("DOCUMENT_ROOT", "", track_vars_array TSRMLS_CC); + php_register_variable("PHP_SELF", php_self, track_vars_array TSRMLS_CC); + php_register_variable("SCRIPT_NAME", php_self, track_vars_array TSRMLS_CC); + php_register_variable("SCRIPT_FILENAME", script_filename, track_vars_array TSRMLS_CC); + php_register_variable("PATH_TRANSLATED", script_filename, track_vars_array TSRMLS_CC); + php_register_variable("DOCUMENT_ROOT", "", track_vars_array TSRMLS_CC); - } + } } /* }}} */ @@ -205,11 +289,11 @@ static void sapi_lsapi_register_variables(zval *track_vars_array TSRMLS_DC) */ static int sapi_lsapi_read_post(char *buffer, uint count_bytes TSRMLS_DC) { - if ( lsapi_mode ) { - return LSAPI_ReadReqBody( buffer, count_bytes ); - } else { - return 0; - } + if ( lsapi_mode ) { + return LSAPI_ReadReqBody( buffer, (unsigned long long)count_bytes ); + } else { + return 0; + } } /* }}} */ @@ -220,11 +304,11 @@ static int sapi_lsapi_read_post(char *buffer, uint count_bytes TSRMLS_DC) */ static char *sapi_lsapi_read_cookies(TSRMLS_D) { - if ( lsapi_mode ) { - return LSAPI_GetHeader( H_COOKIE ); - } else { - return NULL; - } + if ( lsapi_mode ) { + return LSAPI_GetHeader( H_COOKIE ); + } else { + return NULL; + } } /* }}} */ @@ -233,33 +317,33 @@ static char *sapi_lsapi_read_cookies(TSRMLS_D) */ static int sapi_lsapi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC) { - sapi_header_struct *h; - zend_llist_position pos; - if ( lsapi_mode ) { - LSAPI_SetRespStatus( SG(sapi_headers).http_response_code ); - - h = zend_llist_get_first_ex(&sapi_headers->headers, &pos); - while (h) { - if ( h->header_len > 0 ) { - LSAPI_AppendRespHeader(h->header, h->header_len); - } - h = zend_llist_get_next_ex(&sapi_headers->headers, &pos); - } - if (SG(sapi_headers).send_default_content_type) { - char *hd; - int len; - char headerBuf[SAPI_LSAPI_MAX_HEADER_LENGTH]; - - hd = sapi_get_default_content_type(TSRMLS_C); - len = snprintf( headerBuf, SAPI_LSAPI_MAX_HEADER_LENGTH - 1, - "Content-type: %s", hd ); - efree(hd); - - LSAPI_AppendRespHeader( headerBuf, len ); - } - } - LSAPI_FinalizeRespHeaders(); - return SAPI_HEADER_SENT_SUCCESSFULLY; + sapi_header_struct *h; + zend_llist_position pos; + if ( lsapi_mode ) { + LSAPI_SetRespStatus( SG(sapi_headers).http_response_code ); + + h = zend_llist_get_first_ex(&sapi_headers->headers, &pos); + while (h) { + if ( h->header_len > 0 ) { + LSAPI_AppendRespHeader(h->header, h->header_len); + } + h = zend_llist_get_next_ex(&sapi_headers->headers, &pos); + } + if (SG(sapi_headers).send_default_content_type) { + char *hd; + int len; + char headerBuf[SAPI_LSAPI_MAX_HEADER_LENGTH]; + + hd = sapi_get_default_content_type(TSRMLS_C); + len = snprintf( headerBuf, SAPI_LSAPI_MAX_HEADER_LENGTH - 1, + "Content-type: %s", hd ); + efree(hd); + + LSAPI_AppendRespHeader( headerBuf, len ); + } + } + LSAPI_FinalizeRespHeaders(); + return SAPI_HEADER_SENT_SUCCESSFULLY; } @@ -270,8 +354,15 @@ static int sapi_lsapi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC) */ static void sapi_lsapi_log_message(char *message TSRMLS_DC) { - int len = strlen( message ); - LSAPI_Write_Stderr( message, len); + char buf[8192]; + int len = strlen( message ); + if ( *(message + len - 1 ) != '\n' ) + { + snprintf( buf, 8191, "%s\n", message ); + message = buf; + ++len; + } + LSAPI_Write_Stderr( message, len); } /* }}} */ @@ -280,158 +371,251 @@ static void sapi_lsapi_log_message(char *message TSRMLS_DC) */ static sapi_module_struct lsapi_sapi_module = { - "litespeed", - "LiteSpeed", + "litespeed", + "LiteSpeed V6.6", - php_lsapi_startup, /* startup */ - php_module_shutdown_wrapper, /* shutdown */ + php_lsapi_startup, /* startup */ + php_module_shutdown_wrapper, /* shutdown */ - NULL, /* activate */ - sapi_lsapi_deactivate, /* deactivate */ + NULL, /* activate */ + sapi_lsapi_deactivate, /* deactivate */ - sapi_lsapi_ub_write, /* unbuffered write */ - sapi_lsapi_flush, /* flush */ - NULL, /* get uid */ - sapi_lsapi_getenv, /* getenv */ + sapi_lsapi_ub_write, /* unbuffered write */ + sapi_lsapi_flush, /* flush */ + NULL, /* get uid */ + sapi_lsapi_getenv, /* getenv */ - php_error, /* error handler */ + php_error, /* error handler */ - NULL, /* header handler */ - sapi_lsapi_send_headers, /* send headers handler */ - NULL, /* send header handler */ + NULL, /* header handler */ + sapi_lsapi_send_headers, /* send headers handler */ + NULL, /* send header handler */ - sapi_lsapi_read_post, /* read POST data */ - sapi_lsapi_read_cookies, /* read Cookies */ + sapi_lsapi_read_post, /* read POST data */ + sapi_lsapi_read_cookies, /* read Cookies */ - sapi_lsapi_register_variables, /* register server variables */ - sapi_lsapi_log_message, /* Log message */ + sapi_lsapi_register_variables, /* register server variables */ + sapi_lsapi_log_message, /* Log message */ - NULL, /* php.ini path override */ - NULL, /* block interruptions */ - NULL, /* unblock interruptions */ - NULL, /* default post reader */ - NULL, /* treat data */ - NULL, /* executable location */ + NULL, /* php.ini path override */ + NULL, /* block interruptions */ + NULL, /* unblock interruptions */ + NULL, /* default post reader */ + NULL, /* treat data */ + NULL, /* executable location */ - 0, /* php.ini ignore */ + 0, /* php.ini ignore */ - STANDARD_SAPI_MODULE_PROPERTIES + STANDARD_SAPI_MODULE_PROPERTIES }; /* }}} */ static int init_request_info( TSRMLS_D ) { - char * pContentType = LSAPI_GetHeader( H_CONTENT_TYPE ); - char * pAuth; - - SG(request_info).content_type = pContentType ? pContentType : ""; - SG(request_info).request_method = LSAPI_GetRequestMethod(); - SG(request_info).query_string = LSAPI_GetQueryString(); - SG(request_info).request_uri = LSAPI_GetScriptName(); - SG(request_info).content_length = LSAPI_GetReqBodyLen(); - SG(request_info).path_translated = LSAPI_GetScriptFileName(); + char * pContentType = LSAPI_GetHeader( H_CONTENT_TYPE ); + char * pAuth; + + SG(request_info).content_type = pContentType ? pContentType : ""; + SG(request_info).request_method = LSAPI_GetRequestMethod(); + SG(request_info).query_string = LSAPI_GetQueryString(); + SG(request_info).request_uri = LSAPI_GetScriptName(); + SG(request_info).content_length = LSAPI_GetReqBodyLen(); + SG(request_info).path_translated = estrdup( LSAPI_GetScriptFileName()); + + /* It is not reset by zend engine, set it to 0. */ + SG(sapi_headers).http_response_code = 0; + + pAuth = LSAPI_GetHeader( H_AUTHORIZATION ); + php_handle_auth_data(pAuth TSRMLS_CC); +} - /* It is not reset by zend engine, set it to 0. */ - SG(sapi_headers).http_response_code = 0; - - pAuth = LSAPI_GetHeader( H_AUTHORIZATION ); - php_handle_auth_data(pAuth TSRMLS_CC); +static char s_cur_chdir[4096] = ""; + +static int lsapi_chdir_primary_script( zend_file_handle * file_handle ) +{ +#if PHP_MAJOR_VERSION > 4 + char * p; + char ch; + + SG(options) |= SAPI_OPTION_NO_CHDIR; + getcwd( s_cur_chdir, sizeof( s_cur_chdir ) ); + + p = strrchr( file_handle->filename, '/' ); + if ( *p ) + { + *p = 0; + if ( strcmp( file_handle->filename, s_cur_chdir ) != 0 ) { + chdir( file_handle->filename ); + } + *p++ = '/'; + ch = *p; + *p = 0; + if ( !CWDG(cwd).cwd || + ( strcmp( file_handle->filename, CWDG(cwd).cwd ) != 0 ) ) { + CWDG(cwd).cwd_length = p - file_handle->filename; + CWDG(cwd).cwd = (char *) realloc(CWDG(cwd).cwd, CWDG(cwd).cwd_length+1); + memmove( CWDG(cwd).cwd, file_handle->filename, CWDG(cwd).cwd_length+1 ); + } + *p = ch; + } + /* virtual_file_ex(&CWDG(cwd), file_handle->filename, NULL, CWD_REALPATH); */ +#else + VCWD_CHDIR_FILE( file_handle->filename ); +#endif + return 0; } -static int lsapi_module_main(int show_source TSRMLS_DC) +static int lsapi_fopen_primary_script( zend_file_handle * file_handle ) +{ + FILE * fp; + char * p; + fp = fopen( SG(request_info).path_translated, "rb" ); + if ( !fp ) + { + return -1; + } + file_handle->type = ZEND_HANDLE_FP; + file_handle->handle.fp = fp; + file_handle->filename = SG(request_info).path_translated; + file_handle->free_filename = 0; + file_handle->opened_path = NULL; + + lsapi_chdir_primary_script( file_handle ); + + return 0; +} + +static int lsapi_execute_script( zend_file_handle * file_handle TSRMLS_DC) { - zend_file_handle file_handle = {0}; + char *p; + int len; + file_handle->type = ZEND_HANDLE_FILENAME; + file_handle->handle.fd = 0; + file_handle->filename = SG(request_info).path_translated; + file_handle->free_filename = 0; + file_handle->opened_path = NULL; + + p = argv0; + *p++ = ':'; + len = strlen( SG(request_info).path_translated ); + if ( len > 45 ) + len = len - 45; + else + len = 0; + memccpy( p, SG(request_info).path_translated + len, 0, 46 ); + + php_execute_script(file_handle TSRMLS_CC); + return 0; - if (php_request_startup(TSRMLS_C) == FAILURE ) { - return -1; - } - if (show_source) { - zend_syntax_highlighter_ini syntax_highlighter_ini; +} - php_get_highlight_struct(&syntax_highlighter_ini); - highlight_file(SG(request_info).path_translated, &syntax_highlighter_ini TSRMLS_CC); - } else { - file_handle.type = ZEND_HANDLE_FILENAME; - file_handle.handle.fd = 0; - file_handle.filename = SG(request_info).path_translated; - file_handle.free_filename = 0; - file_handle.opened_path = NULL; - php_execute_script(&file_handle TSRMLS_CC); - } - zend_try { - php_request_shutdown(NULL); - } zend_end_try(); - return 0; +static int lsapi_module_main(int show_source TSRMLS_DC) +{ + zend_file_handle file_handle = {0}; + + if (php_request_startup(TSRMLS_C) == FAILURE ) { + return -1; + } + if (show_source) { + zend_syntax_highlighter_ini syntax_highlighter_ini; + + php_get_highlight_struct(&syntax_highlighter_ini); + highlight_file(SG(request_info).path_translated, &syntax_highlighter_ini TSRMLS_CC); + } else { + lsapi_execute_script( &file_handle TSRMLS_CC); + } + zend_try { + php_request_shutdown(NULL); + memset( argv0, 0, 46 ); + } zend_end_try(); + return 0; } static int alter_ini( const char * pKey, int keyLen, const char * pValue, int valLen, - void * arg ) + void * arg ) { - int type = ZEND_INI_PERDIR; - if ( '\001' == *pKey ) { - ++pKey; - if ( *pKey == 4 ) { - type = ZEND_INI_SYSTEM; - } - ++pKey; - --keyLen; - zend_alter_ini_entry((char *)pKey, keyLen, - (char *)pValue, valLen, - type, PHP_INI_STAGE_ACTIVATE); - } - return 1; + int type = ZEND_INI_PERDIR; + if ( '\001' == *pKey ) { + ++pKey; + if ( *pKey == 4 ) { + type = ZEND_INI_SYSTEM; + } + ++pKey; + --keyLen; + if (( keyLen == 7 )&&( strncasecmp( pKey, "engine", 6 )== 0 )) + { + if ( *pValue == '0' ) + engine = 0; + } + else + zend_alter_ini_entry((char *)pKey, keyLen, + (char *)pValue, valLen, + type, PHP_INI_STAGE_ACTIVATE); + } + return 1; } static void override_ini() { - LSAPI_ForeachSpecialEnv( alter_ini, NULL ); + LSAPI_ForeachSpecialEnv( alter_ini, NULL ); } + static int processReq( TSRMLS_D ) { - int ret = 0; - zend_first_try { - /* avoid server_context==NULL checks */ - SG(server_context) = (void *) 1; - - init_request_info( TSRMLS_C ); - - override_ini(); - - if ( lsapi_module_main( source_highlight TSRMLS_CC ) == -1 ) { - ret = -1; - } - } zend_end_try(); - return ret; + int ret = 0; + zend_first_try { + + /* avoid server_context==NULL checks */ + SG(server_context) = (void *) 1; + + engine = 1; + override_ini(); + + if ( engine ) { + init_request_info( TSRMLS_C ); + + if ( lsapi_module_main( source_highlight TSRMLS_CC ) == -1 ) { + ret = -1; + } + } else { + LSAPI_AppendRespHeader( "status: 403", 11 ); + LSAPI_AppendRespHeader( "content-type: text/html", 23 ); + LSAPI_Write( "Forbidden: PHP engine is disable.\n", 34 ); + } + } zend_end_try(); + return ret; } static void cli_usage( TSRMLS_D ) { - static const char * usage = - "Usage: php\n" - " php -[b|c|h|i|q|s|v|?] [] [args...]\n" - " Run in LSAPI mode, only '-b', '-s' and '-c' are effective\n" - " Run in Command Line Interpreter mode when parameters are specified\n" - "\n" - " -b | Bind Path for external LSAPI Server mode\n" - " -c | Look for php.ini file in this directory\n" - " -h This help\n" - " -i PHP information\n" - " -q Quiet-mode. Suppress HTTP Header output.\n" - " -s Display colour syntax highlighted source.\n" - " -v Version number\n" - " -? This help\n" - "\n" - " args... Arguments passed to script.\n"; - php_output_startup(); - php_output_activate(TSRMLS_C); - php_printf( "%s", usage ); + static const char * usage = + "Usage: php\n" + " php -[b|c|n|h|i|q|s|v|?] [] [args...]\n" + " Run in LSAPI mode, only '-b', '-s' and '-c' are effective\n" + " Run in Command Line Interpreter mode when parameters are specified\n" + "\n" + " -b | Bind Path for external LSAPI Server mode\n" + " -c | Look for php.ini file in this directory\n" + " -n No php.ini file will be used\n" + " -h This help\n" + " -i PHP information\n" + " -l Syntax check\n" + " -q Quiet-mode. Suppress HTTP Header output.\n" + " -s Display colour syntax highlighted source.\n" + " -v Version number\n" + " -? This help\n" + "\n" + " args... Arguments passed to script.\n"; + php_output_startup(); + php_output_activate(TSRMLS_C); + php_printf( usage ); #ifdef PHP_OUTPUT_NEWAPI php_output_end_all(TSRMLS_C); #else @@ -440,349 +624,419 @@ static void cli_usage( TSRMLS_D ) } static int parse_opt( int argc, char * argv[], int *climode, - char **php_ini_path, char ** php_bind ) -{ - char ** p = &argv[1]; - char ** argend= &argv[argc]; - int c; - while (( p < argend )&&(**p == '-' )) { - c = *((*p)+1); - ++p; - switch( c ) { - case 'b': - if ( p >= argend ) { - fprintf( stderr, "TCP or socket address must be specified following '-b' option.\n"); - return -1; - } - *php_bind = *p++; - break; - - case 'c': - if ( p >= argend ) { - fprintf( stderr, " or must be specified following '-c' option.\n"); - - return -1; - } - *php_ini_path = *p++; - break; - case 's': - source_highlight = 1; - break; - case 'h': - case 'i': - case 'q': - case 'v': - case '?': - default: - *climode = 1; - break; - } - } - if ( p - argv < argc ) { - *climode = 1; - } - return 0; + char **php_ini_path, char ** php_bind ) +{ + char ** p = &argv[1]; + char ** argend= &argv[argc]; + int c; + while (( p < argend )&&(**p == '-' )) { + c = *((*p)+1); + ++p; + switch( c ) { + case 'b': + if ( p >= argend ) { + fprintf( stderr, "TCP or socket address must be specified following '-b' option.\n"); + return -1; + } + *php_bind = strdup(*p++); + break; + + case 'c': + if ( p >= argend ) { + fprintf( stderr, " or must be specified following '-c' option.\n"); + + return -1; + } + *php_ini_path = strdup( *p++ ); + break; + case 's': + source_highlight = 1; + break; + case 'n': + ignore_php_ini = 1; + break; + case '?': + if ( *((*(p-1))+2) == 's' ) + exit( 99 ); + case 'h': + case 'i': + case 'l': + case 'q': + case 'v': + default: + *climode = 1; + break; + } + } + if ( p - argv < argc ) { + *climode = 1; + } + return 0; } static int cli_main( int argc, char * argv[] ) { - static const char * ini_defaults[] = { - "report_zend_debug", "0", - "display_errors", "1", - "register_argc_argv", "1", - "html_errors", "0", - "implicit_flush", "1", - "output_buffering", "0", - "max_execution_time", "0", - "max_input_time", "-1", - NULL - }; - - const char ** ini; - char ** p = &argv[1]; - char ** argend= &argv[argc]; - int ret = 0; - int c; - lsapi_mode = 0; /* enter CLI mode */ + static const char * ini_defaults[] = { + "report_zend_debug", "0", + "display_errors", "1", + "register_argc_argv", "1", + "html_errors", "0", + "implicit_flush", "1", + "output_buffering", "0", + "max_execution_time", "0", + "max_input_time", "-1", + NULL + }; + + const char ** ini; + char ** p = &argv[1]; + char ** argend= &argv[argc]; + int ret = -1; + int c; + lsapi_mode = 0; /* enter CLI mode */ #ifdef PHP_WIN32 - _fmode = _O_BINARY; /*sets default for file streams to binary */ - setmode(_fileno(stdin), O_BINARY); /* make the stdio mode be binary */ - setmode(_fileno(stdout), O_BINARY); /* make the stdio mode be binary */ - setmode(_fileno(stderr), O_BINARY); /* make the stdio mode be binary */ + _fmode = _O_BINARY; /*sets default for file streams to binary */ + setmode(_fileno(stdin), O_BINARY); /* make the stdio mode be binary */ + setmode(_fileno(stdout), O_BINARY); /* make the stdio mode be binary */ + setmode(_fileno(stderr), O_BINARY); /* make the stdio mode be binary */ #endif - zend_first_try { - SG(server_context) = (void *) 1; - - zend_uv.html_errors = 0; /* tell the engine we're in non-html mode */ - CG(in_compilation) = 0; /* not initialized but needed for several options */ - EG(uninitialized_zval_ptr) = NULL; - - for( ini = ini_defaults; *ini; ini+=2 ) { - zend_alter_ini_entry( (char *)*ini, strlen( *ini )+1, - (char *)*(ini+1), strlen( *(ini+1) ), - PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE); - } - - while (( p < argend )&&(**p == '-' )) { - c = *((*p)+1); - ++p; - switch( c ) { - case 'q': - break; - case 'i': - if (php_request_startup(TSRMLS_C) != FAILURE) { - php_print_info(0xFFFFFFFF TSRMLS_CC); + zend_first_try { + SG(server_context) = (void *) 1; + + zend_uv.html_errors = 0; /* tell the engine we're in non-html mode */ + CG(in_compilation) = 0; /* not initialized but needed for several options */ + EG(uninitialized_zval_ptr) = NULL; + + for( ini = ini_defaults; *ini; ini+=2 ) { + zend_alter_ini_entry( (char *)*ini, strlen( *ini )+1, + (char *)*(ini+1), strlen( *(ini+1) ), + PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE); + } + + while (( p < argend )&&(**p == '-' )) { + c = *((*p)+1); + ++p; + switch( c ) { + case 'q': + break; + case 'i': + if (php_request_startup(TSRMLS_C) != FAILURE) { + php_print_info(0xFFFFFFFF TSRMLS_CC); #ifdef PHP_OUTPUT_NEWAPI php_output_end_all(TSRMLS_C); #else php_end_ob_buffers(1 TSRMLS_CC); #endif - php_request_shutdown( NULL ); - } - ret = 1; - break; - case 'v': - if (php_request_startup(TSRMLS_C) != FAILURE) { + php_request_shutdown( NULL ); + ret = 0; + } + break; + case 'v': + if (php_request_startup(TSRMLS_C) != FAILURE) { #if ZEND_DEBUG - php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2013 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); + php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); #else - php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2013 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); + php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); #endif #ifdef PHP_OUTPUT_NEWAPI php_output_end_all(TSRMLS_C); #else php_end_ob_buffers(1 TSRMLS_CC); #endif - php_request_shutdown( NULL ); - } - ret = 1; - break; - case 'c': - ++p; - /* fall through */ - case 's': - break; - - case 'h': - case '?': - default: - cli_usage(TSRMLS_C); - ret = 1; - break; - - } - } - if ( !ret ) { - if ( *p ) { - zend_file_handle file_handle = {0}; - - file_handle.type = ZEND_HANDLE_FP; - file_handle.handle.fp = VCWD_FOPEN(*p, "rb"); - - if ( file_handle.handle.fp ) { - script_filename = *p; - php_self = *p; - - SG(request_info).path_translated = *p; - SG(request_info).argc = argc - (p - argv); - SG(request_info).argv = p; - - if (php_request_startup(TSRMLS_C) == FAILURE ) { - fclose( file_handle.handle.fp ); - ret = 2; - } else { - if (source_highlight) { - zend_syntax_highlighter_ini syntax_highlighter_ini; - - php_get_highlight_struct(&syntax_highlighter_ini); - highlight_file(SG(request_info).path_translated, &syntax_highlighter_ini TSRMLS_CC); - } else { - file_handle.filename = *p; - file_handle.free_filename = 0; - file_handle.opened_path = NULL; - - php_execute_script(&file_handle TSRMLS_CC); - } - - php_request_shutdown( NULL ); - } - } else { - php_printf("Could not open input file: %s.\n", *p); - } - } else { - cli_usage(TSRMLS_C); - } - } - - }zend_end_try(); - - php_module_shutdown(TSRMLS_C); + php_request_shutdown( NULL ); + ret = 0; + } + break; + case 'c': + ++p; + /* fall through */ + case 's': + break; + case 'l': + source_highlight = 2; + break; + case 'h': + case '?': + default: + cli_usage(TSRMLS_C); + ret = 0; + break; + + } + } + if ( ret == -1 ) { + if ( *p ) { + zend_file_handle file_handle = {0}; + + file_handle.type = ZEND_HANDLE_FP; + file_handle.handle.fp = VCWD_FOPEN(*p, "rb"); + + if ( file_handle.handle.fp ) { + script_filename = *p; + php_self = *p; + + SG(request_info).path_translated = estrdup(*p); + SG(request_info).argc = argc - (p - argv); + SG(request_info).argv = p; + + if (php_request_startup(TSRMLS_C) == FAILURE ) { + fclose( file_handle.handle.fp ); + ret = 2; + } else { + if (source_highlight == 1) { + zend_syntax_highlighter_ini syntax_highlighter_ini; + + php_get_highlight_struct(&syntax_highlighter_ini); + highlight_file(SG(request_info).path_translated, &syntax_highlighter_ini TSRMLS_CC); + } else if (source_highlight == 2) { + file_handle.filename = *p; + file_handle.free_filename = 0; + file_handle.opened_path = NULL; + ret = php_lint_script(&file_handle TSRMLS_CC); + if (ret==SUCCESS) { + zend_printf("No syntax errors detected in %s\n", file_handle.filename); + } else { + zend_printf("Errors parsing %s\n", file_handle.filename); + } + + } else { + file_handle.filename = *p; + file_handle.free_filename = 0; + file_handle.opened_path = NULL; + + php_execute_script(&file_handle TSRMLS_CC); + ret = EG(exit_status); + } + + php_request_shutdown( NULL ); + } + } else { + php_printf("Could not open input file: %s.\n", *p); + } + } else { + cli_usage(TSRMLS_C); + } + } + + }zend_end_try(); + + php_module_shutdown(TSRMLS_C); #ifdef ZTS - tsrm_shutdown(); + tsrm_shutdown(); #endif - return ret; + return ret; } static int s_stop; void litespeed_cleanup(int signal) { - s_stop = signal; + s_stop = signal; } void start_children( int children ) { - struct sigaction act, old_term, old_quit, old_int, old_usr1; - int running = 0; - int status; - pid_t pid; - - /* Create a process group */ - setsid(); - - /* Set up handler to kill children upon exit */ - act.sa_flags = 0; - act.sa_handler = litespeed_cleanup; - if( sigaction( SIGTERM, &act, &old_term ) || - sigaction( SIGINT, &act, &old_int ) || - sigaction( SIGUSR1, &act, &old_usr1 ) || - sigaction( SIGQUIT, &act, &old_quit )) { - perror( "Can't set signals" ); - exit( 1 ); - } - s_stop = 0; - while( 1 ) { - while((!s_stop )&&( running < children )) { - pid = fork(); - switch( pid ) { - case 0: /* children process */ - - /* don't catch our signals */ - sigaction( SIGTERM, &old_term, 0 ); - sigaction( SIGQUIT, &old_quit, 0 ); - sigaction( SIGINT, &old_int, 0 ); - sigaction( SIGUSR1, &old_usr1, 0 ); - return ; - case -1: - perror( "php (pre-forking)" ); - exit( 1 ); - break; - default: /* parent process */ - running++; - break; - } - } - if ( s_stop ) { - break; - } - pid = wait( &status ); - running--; - } - kill( -getpgrp(), SIGUSR1 ); - exit( 0 ); + struct sigaction act, old_term, old_quit, old_int, old_usr1; + int running = 0; + int status; + pid_t pid; + + /* Create a process group */ + setsid(); + + /* Set up handler to kill children upon exit */ + act.sa_flags = 0; + act.sa_handler = litespeed_cleanup; + if( sigaction( SIGTERM, &act, &old_term ) || + sigaction( SIGINT, &act, &old_int ) || + sigaction( SIGUSR1, &act, &old_usr1 ) || + sigaction( SIGQUIT, &act, &old_quit )) { + perror( "Can't set signals" ); + exit( 1 ); + } + s_stop = 0; + while( 1 ) { + while((!s_stop )&&( running < children )) { + pid = fork(); + switch( pid ) { + case 0: /* children process */ + + /* don't catch our signals */ + sigaction( SIGTERM, &old_term, 0 ); + sigaction( SIGQUIT, &old_quit, 0 ); + sigaction( SIGINT, &old_int, 0 ); + sigaction( SIGUSR1, &old_usr1, 0 ); + return ; + case -1: + perror( "php (pre-forking)" ); + exit( 1 ); + break; + default: /* parent process */ + running++; + break; + } + } + if ( s_stop ) { + break; + } + pid = wait( &status ); + running--; + } + kill( -getpgrp(), SIGUSR1 ); + exit( 0 ); } - +void setArgv0( int argc, char * argv[] ) +{ + char * p; + int i; + argv0 = argv[0] + strlen( argv[0] ); + p = argv0; + while(( p > argv[0] )&&( p[-1] != '/')) + --p; + if ( p > argv[0] ) + { + memmove( argv[0], p, argv0 - p ); + memset( argv[0] + ( argv0 - p ), 0, p - argv[0] ); + argv0 = argv[0] + (argv0 - p); + } + for( i = 1; i < argc; ++i ) + { + memset( argv[i], 0, strlen( argv[i] ) ); + } +} #include int main( int argc, char * argv[] ) { - int ret; - int bindFd; - - char * php_ini_path = NULL; - char * php_bind = NULL; - char * p; - int n; - int climode = 0; - + int ret; + int bindFd; + + char * php_ini_path = NULL; + char * php_bind = NULL; + int n; + int climode = 0; + struct timeval tv_req_begin; + struct timeval tv_req_end; + int slow_script_msec = 0; + char time_buf[40]; + #ifdef HAVE_SIGNAL_H #if defined(SIGPIPE) && defined(SIG_IGN) - signal(SIGPIPE, SIG_IGN); + signal(SIGPIPE, SIG_IGN); #endif #endif #ifdef ZTS - tsrm_startup(1, 1, 0, NULL); + tsrm_startup(1, 1, 0, NULL); #endif - if (argc > 1 ) { - if ( parse_opt( argc, argv, &climode, - &php_ini_path, &php_bind ) == -1 ) { - return 1; - } - } - if ( climode ) { - lsapi_sapi_module.phpinfo_as_text = 1; - } - sapi_startup(&lsapi_sapi_module); + if (argc > 1 ) { + if ( parse_opt( argc, argv, &climode, + &php_ini_path, &php_bind ) == -1 ) { + return 1; + } + } + if ( climode ) { + lsapi_sapi_module.phpinfo_as_text = 1; + } else { + setArgv0(argc, argv ); + } + + sapi_startup(&lsapi_sapi_module); #ifdef ZTS - compiler_globals = ts_resource(compiler_globals_id); - executor_globals = ts_resource(executor_globals_id); - core_globals = ts_resource(core_globals_id); - sapi_globals = ts_resource(sapi_globals_id); - tsrm_ls = ts_resource(0); + compiler_globals = ts_resource(compiler_globals_id); + executor_globals = ts_resource(executor_globals_id); + core_globals = ts_resource(core_globals_id); + sapi_globals = ts_resource(sapi_globals_id); + tsrm_ls = ts_resource(0); - SG(request_info).path_translated = NULL; + SG(request_info).path_translated = NULL; #endif - lsapi_sapi_module.executable_location = argv[0]; + lsapi_sapi_module.executable_location = argv[0]; + + if ( ignore_php_ini ) + lsapi_sapi_module.php_ini_ignore = 1; + + if ( php_ini_path ) { + lsapi_sapi_module.php_ini_path_override = php_ini_path; + } - if ( php_ini_path ) { - lsapi_sapi_module.php_ini_path_override = php_ini_path; - } - if (php_module_startup(&lsapi_sapi_module, &litespeed_module_entry, 1) == FAILURE) { + lsapi_sapi_module.ini_defaults = sapi_lsapi_ini_defaults; + + if (php_module_startup(&lsapi_sapi_module, &litespeed_module_entry, 1) == FAILURE) { #ifdef ZTS - tsrm_shutdown(); + tsrm_shutdown(); #endif - return FAILURE; - } - - if ( climode ) { - return cli_main(argc, argv); - } - - - if ( php_bind ) { - bindFd = LSAPI_CreateListenSock( php_bind, 10 ); - if ( bindFd == -1 ) { - fprintf( stderr, - "Failed to bind socket [%s]: %s\n", php_bind, strerror( errno ) ); - exit( 2 ); - } - if ( bindFd != 0 ) { - dup2( bindFd, 0 ); - close( bindFd ); - } - } - - LSAPI_Init(); + return FAILURE; + } + + if ( climode ) { + return cli_main(argc, argv); + } + + if ( php_bind ) { + bindFd = LSAPI_CreateListenSock( php_bind, 10 ); + if ( bindFd == -1 ) { + fprintf( stderr, + "Failed to bind socket [%s]: %s\n", php_bind, strerror( errno ) ); + exit( 2 ); + } + if ( bindFd != 0 ) { + dup2( bindFd, 0 ); + close( bindFd ); + } + } + + LSAPI_Init(); - LSAPI_Init_Env_Parameters( NULL ); - - if ( php_bind ) { - LSAPI_No_Check_ppid(); - } - - while( LSAPI_Prefork_Accept_r( &g_req ) >= 0 ) { - ret = processReq(TSRMLS_C); - LSAPI_Finish(); - if ( ret ) { - break; - } - } - php_module_shutdown(TSRMLS_C); + LSAPI_Init_Env_Parameters( NULL ); + + slow_script_msec = LSAPI_Get_Slow_Req_Msecs(); + + if ( php_bind ) { + LSAPI_No_Check_ppid(); + free( php_bind ); + php_bind = NULL; + } + + while( LSAPI_Prefork_Accept_r( &g_req ) >= 0 ) { + if ( slow_script_msec ) { + gettimeofday( &tv_req_begin, NULL ); + } + ret = processReq(TSRMLS_C); + if ( slow_script_msec ) { + gettimeofday( &tv_req_end, NULL ); + n = ((long) tv_req_end.tv_sec - tv_req_begin.tv_sec ) * 1000 + + (tv_req_end.tv_usec - tv_req_begin.tv_usec) / 1000; + if ( n > slow_script_msec ) + { + strftime( time_buf, 30, "%d/%b/%Y:%H:%M:%S", localtime( &tv_req_end.tv_sec ) ); + fprintf( stderr, "[%s] Slow PHP script: %d ms\n URL: %s %s\n Query String: %s\n Script: %s\n", + time_buf, n, LSAPI_GetRequestMethod(), + LSAPI_GetScriptName(), LSAPI_GetQueryString(), + LSAPI_GetScriptFileName() ); + + } + } + LSAPI_Finish(); + if ( ret ) { + break; + } + } + php_module_shutdown(TSRMLS_C); #ifdef ZTS - tsrm_shutdown(); + tsrm_shutdown(); #endif - return ret; + return ret; } @@ -795,49 +1049,51 @@ ZEND_END_ARG_INFO() PHP_FUNCTION(litespeed_request_headers); PHP_FUNCTION(litespeed_response_headers); +PHP_FUNCTION(apache_get_modules); PHP_MINFO_FUNCTION(litespeed); zend_function_entry litespeed_functions[] = { - PHP_FE(litespeed_request_headers, arginfo_litespeed__void) - PHP_FE(litespeed_response_headers, arginfo_litespeed__void) - PHP_FALIAS(getallheaders, litespeed_request_headers, arginfo_litespeed__void) - PHP_FALIAS(apache_request_headers, litespeed_request_headers, arginfo_litespeed__void) - PHP_FALIAS(apache_response_headers, litespeed_response_headers, arginfo_litespeed__void) - {NULL, NULL, NULL} + PHP_FE(litespeed_request_headers, arginfo_litespeed__void) + PHP_FE(litespeed_response_headers, arginfo_litespeed__void) + PHP_FE(apache_get_modules, arginfo_litespeed__void) + PHP_FALIAS(getallheaders, litespeed_request_headers, arginfo_litespeed__void) + PHP_FALIAS(apache_request_headers, litespeed_request_headers, arginfo_litespeed__void) + PHP_FALIAS(apache_response_headers, litespeed_response_headers, arginfo_litespeed__void) + {NULL, NULL, NULL} }; static PHP_MINIT_FUNCTION(litespeed) { - /* REGISTER_INI_ENTRIES(); */ - return SUCCESS; + /* REGISTER_INI_ENTRIES(); */ + return SUCCESS; } static PHP_MSHUTDOWN_FUNCTION(litespeed) { - /* UNREGISTER_INI_ENTRIES(); */ - return SUCCESS; + /* UNREGISTER_INI_ENTRIES(); */ + return SUCCESS; } zend_module_entry litespeed_module_entry = { - STANDARD_MODULE_HEADER, - "litespeed", - litespeed_functions, - PHP_MINIT(litespeed), - PHP_MSHUTDOWN(litespeed), - NULL, - NULL, - NULL, - NO_VERSION_YET, - STANDARD_MODULE_PROPERTIES + STANDARD_MODULE_HEADER, + "litespeed", + litespeed_functions, + PHP_MINIT(litespeed), + PHP_MSHUTDOWN(litespeed), + NULL, + NULL, + NULL, + NO_VERSION_YET, + STANDARD_MODULE_PROPERTIES }; static int add_associate_array( const char * pKey, int keyLen, const char * pValue, int valLen, - void * arg ) + void * arg ) { - add_assoc_string_ex( (zval *)arg, (char *)pKey, keyLen+1, (char *)pValue, 1 ); - return 1; + add_assoc_string_ex( (zval *)arg, (char *)pKey, keyLen+1, (char *)pValue, 1 ); + return 1; } @@ -845,13 +1101,13 @@ static int add_associate_array( const char * pKey, int keyLen, const char * pVal Fetch all HTTP request headers */ PHP_FUNCTION(litespeed_request_headers) { - /* TODO: */ - if (ZEND_NUM_ARGS() > 0) { - WRONG_PARAM_COUNT; - } - array_init(return_value); + /* TODO: */ + if (ZEND_NUM_ARGS() > 0) { + WRONG_PARAM_COUNT; + } + array_init(return_value); - LSAPI_ForeachOrgHeader( add_associate_array, return_value ); + LSAPI_ForeachOrgHeader( add_associate_array, return_value ); } /* }}} */ @@ -862,45 +1118,62 @@ PHP_FUNCTION(litespeed_request_headers) Fetch all HTTP response headers */ PHP_FUNCTION(litespeed_response_headers) { - sapi_header_struct *h; - zend_llist_position pos; - char * p; - int len; - char headerBuf[SAPI_LSAPI_MAX_HEADER_LENGTH]; - - if (ZEND_NUM_ARGS() > 0) { - WRONG_PARAM_COUNT; - } - - if (!&SG(sapi_headers).headers) { - RETURN_FALSE; - } - array_init(return_value); - - h = zend_llist_get_first_ex(&SG(sapi_headers).headers, &pos); - while (h) { - if ( h->header_len > 0 ) { - p = strchr( h->header, ':' ); - len = p - h->header; - if (( p )&&( len > 0 )) { - memmove( headerBuf, h->header, len ); - while( len > 0 && (isspace( headerBuf[len-1])) ) { - --len; - } - headerBuf[len] = 0; - if ( len ) { - while( isspace(*++p)); - add_assoc_string_ex(return_value, headerBuf, len+1, p, 1 ); - } - } - } - h = zend_llist_get_next_ex(&SG(sapi_headers).headers, &pos); - } + sapi_header_struct *h; + zend_llist_position pos; + char * p; + int len; + char headerBuf[SAPI_LSAPI_MAX_HEADER_LENGTH]; + + if (ZEND_NUM_ARGS() > 0) { + WRONG_PARAM_COUNT; + } + + if (!&SG(sapi_headers).headers) { + RETURN_FALSE; + } + array_init(return_value); + + h = zend_llist_get_first_ex(&SG(sapi_headers).headers, &pos); + while (h) { + if ( h->header_len > 0 ) { + p = strchr( h->header, ':' ); + len = p - h->header; + if (( p )&&( len > 0 )) { + memmove( headerBuf, h->header, len ); + while( len > 0 && (isspace( headerBuf[len-1])) ) { + --len; + } + headerBuf[len] = 0; + if ( len ) { + while( isspace(*++p)); + add_assoc_string_ex(return_value, headerBuf, len+1, p, 1 ); + } + } + } + h = zend_llist_get_next_ex(&SG(sapi_headers).headers, &pos); + } } /* }}} */ +/* {{{ proto array apache_get_modules(void) + Fetch all loaded module names */ +PHP_FUNCTION(apache_get_modules) +{ + /* TODO: */ + if (ZEND_NUM_ARGS() > 0) { + WRONG_PARAM_COUNT; + } + array_init(return_value); + add_next_index_string(return_value, "mod_rewrite", 1); + add_next_index_string(return_value, "mod_mime", 1); + add_next_index_string(return_value, "mod_headers", 1); + add_next_index_string(return_value, "mod_expires", 1); +} +/* }}} */ + + /* * Local variables: * tab-width: 4 diff --git a/sapi/litespeed/lsapidef.h b/sapi/litespeed/lsapidef.h index c8940a930e947..5d5b4c1687a6c 100644 --- a/sapi/litespeed/lsapidef.h +++ b/sapi/litespeed/lsapidef.h @@ -1,25 +1,5 @@ - -/* - +----------------------------------------------------------------------+ - | PHP Version 5 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available at through the world-wide-web at the following url: | - | http://www.php.net/license/3_01.txt. | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Author: George Wang | - +----------------------------------------------------------------------+ -*/ - - /* -Copyright (c) 2007, Lite Speed Technologies Inc. +Copyright (c) 2005, Lite Speed Technologies Inc. All rights reserved. Redistribution and use in source and binary forms, with or without @@ -50,6 +30,13 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/*************************************************************************** + $Id: lsapidef.h,v 1.17 2012/12/01 19:23:31 gwang Exp $ + ------------------- + begin : Thu Feb 10 2005 + author : George Wang + email : gwang@litespeedtech.com + ***************************************************************************/ #ifndef _LSAPIDEF_H_ #define _LSAPIDEF_H_ @@ -113,12 +100,14 @@ enum #define LSAPI_RESP_END 5 #define LSAPI_STDERR_STREAM 6 #define LSAPI_REQ_RECEIVED 7 +#define LSAPI_CONN_CLOSE 8 +#define LSAPI_INTERNAL_ERROR 9 #define LSAPI_MAX_HEADER_LEN 65535 #define LSAPI_MAX_DATA_PACKET_LEN 16384 -#define LSAPI_RESP_HTTP_HEADER_MAX 4096 +#define LSAPI_RESP_HTTP_HEADER_MAX 32768 #define LSAPI_PACKET_HEADER_LEN 8 diff --git a/sapi/litespeed/lsapilib.c b/sapi/litespeed/lsapilib.c index 3a13000e11f28..cdd60763db2e5 100644 --- a/sapi/litespeed/lsapilib.c +++ b/sapi/litespeed/lsapilib.c @@ -1,25 +1,5 @@ /* - +----------------------------------------------------------------------+ - | PHP Version 5 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available at through the world-wide-web at the following url: | - | http://www.php.net/license/3_01.txt. | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Author: George Wang | - +----------------------------------------------------------------------+ -*/ - -/* $Id$ */ - -/* -Copyright (c) 2007, Lite Speed Technologies Inc. +Copyright (c) 2013, Lite Speed Technologies Inc. All rights reserved. Redistribution and use in source and binary forms, with or without @@ -50,17 +30,21 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +/*************************************************************************** + lsapilib.c - description + ------------------- + begin : Mon Feb 21 2005 + copyright : (C) 2005 by George Wang + email : gwang@litespeedtech.com + ***************************************************************************/ + #include +#include #include #include -#include -#include -#include -#include -#include +#include #include #include #include @@ -71,8 +55,48 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include +#include #include #include +#include +#include +#include +#include +#include + +#include "lsapilib.h" + +#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__) +#include +#endif + +#if defined(__FreeBSD__ ) || defined(__NetBSD__) || defined(__OpenBSD__) \ + || defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) +#include +#endif + +#include +#ifndef uint32 +#define uint32 uint32_t +#endif + +struct lsapi_MD5Context { + uint32 buf[4]; + uint32 bits[2]; + unsigned char in[64]; +}; + +void lsapi_MD5Init(struct lsapi_MD5Context *context); +void lsapi_MD5Update(struct lsapi_MD5Context *context, unsigned char const *buf, + unsigned len); +void lsapi_MD5Final(unsigned char digest[16], struct lsapi_MD5Context *context); + +/* + * This is needed to make RSAREF happy on some MS-DOS compilers. + */ +typedef struct lsapi_MD5Context lsapi_MD5_CTX; + #define LSAPI_ST_REQ_HEADER 1 #define LSAPI_ST_REQ_BODY 2 @@ -83,11 +107,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define LSAPI_INIT_RESP_HEADER_LEN 4096 + static int g_inited = 0; static int g_running = 1; static int s_ppid; +static int s_slow_req_msecs = 0; +static int s_keepListener = 0; +static int s_dump_debug_info = 0; +static int s_pid_dump_debug_info = 0; + LSAPI_Request g_req = { -1, -1 }; +static char s_pSecret[24]; + + void Flush_RespBuf_r( LSAPI_Request * pReq ); static const char *CGI_HEADERS[H_TRANSFER_ENCODING+1] = @@ -111,13 +144,13 @@ static const char *CGI_HEADERS[H_TRANSFER_ENCODING+1] = "HTTP_TRANSFER_ENCODING" }; -static int CGI_HEADER_LEN[H_TRANSFER_ENCODING+1] = { - 11, 19, 20, 20, 18, 15, 12, 14, 11, 12, 9, 11, 12, 15, 18, - 22, 13, 18, 13, 24, 15, 10, 20, 8, 22 -}; +static int CGI_HEADER_LEN[H_TRANSFER_ENCODING+1] = +{ 11, 19, 20, 20, 18, 15, 12, 14, 11, 12, 9, 11, 12, 15, 18, + 22, 13, 18, 13, 24, 15, 10, 20, 8, 22 }; -static const char *HTTP_HEADERS[H_TRANSFER_ENCODING+1] = { +static const char *HTTP_HEADERS[H_TRANSFER_ENCODING+1] = +{ "Accept", "Accept-Charset", "Accept-Encoding", "Accept-Language", "Authorization", @@ -137,8 +170,8 @@ static const char *HTTP_HEADERS[H_TRANSFER_ENCODING+1] = { "Transfer-Encoding" }; -static int HTTP_HEADER_LEN[H_TRANSFER_ENCODING+1] = { - 6, 14, 15, 15, 13, 10, 12, 14, 6, 7, 4, 6, 7, 10, /* user-agent */ +static int HTTP_HEADER_LEN[H_TRANSFER_ENCODING+1] = +{ 6, 14, 15, 15, 13, 10, 12, 14, 6, 7, 4, 6, 7, 10, //user-agent 13,17, 8, 13, 8, 19, 10, 5, 15, 3, 17 }; @@ -160,7 +193,8 @@ static void lsapi_signal(int signo, sighandler_t handler) sigaction(signo, NULL, &sa); - if (sa.sa_handler == SIG_DFL) { + if (sa.sa_handler == SIG_DFL) + { sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sa.sa_handler = handler; @@ -169,6 +203,34 @@ static void lsapi_signal(int signo, sighandler_t handler) } +static int s_enable_core_dump = 0; +static void lsapi_enable_core_dump() +{ +#if defined(__FreeBSD__ ) || defined(__NetBSD__) || defined(__OpenBSD__) \ + || defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) + int mib[2]; + size_t len; + + len = 2; + if ( sysctlnametomib("kern.sugid_coredump", mib, &len) == 0 ) + { + len = sizeof(s_enable_core_dump); + if (sysctl(mib, 2, NULL, 0, &s_enable_core_dump, len) == -1) + perror( "sysctl: Failed to set 'kern.sugid_coredump', " + "core dump may not be available!"); + } + + +#endif + +#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__) + if (prctl(PR_SET_DUMPABLE, s_enable_core_dump,0,0,0) == -1) + perror( "prctl: Failed to set dumpable, " + "core dump may not be available!"); +#endif +} + + static inline void lsapi_buildPacketHeader( struct lsapi_packet_header * pHeader, char type, int len ) { @@ -199,75 +261,115 @@ static int lsapi_set_nblock( int fd, int nonblock ) return 0; } - static int lsapi_close( int fd ) { int ret; - while( 1 ) { + while( 1 ) + { ret = close( fd ); - if (( ret == -1 )&&( errno == EINTR )&&(g_running)) { + if (( ret == -1 )&&( errno == EINTR )&&(g_running)) continue; - } return ret; } } -static inline int lsapi_read( int fd, void * pBuf, int len ) +static inline ssize_t lsapi_read( int fd, void * pBuf, size_t len ) { - int ret; - while( 1 ) { + ssize_t ret; + while( 1 ) + { ret = read( fd, (char *)pBuf, len ); - if (( ret == -1 )&&( errno == EINTR )&&(g_running)) { + if (( ret == -1 )&&( errno == EINTR )&&(g_running)) continue; - } return ret; } } +/* +static int lsapi_write( int fd, const void * pBuf, int len ) +{ + int ret; + const char * pCur; + const char * pEnd; + if ( len == 0 ) + return 0; + pCur = (const char *)pBuf; + pEnd = pCur + len; + while( g_running && (pCur < pEnd) ) + { + ret = write( fd, pCur, pEnd - pCur ); + if ( ret >= 0) + pCur += ret; + else if (( ret == -1 )&&( errno != EINTR )) + return ret; + } + return pCur - (const char *)pBuf; +} +*/ static int lsapi_writev( int fd, struct iovec ** pVec, int count, int totalLen ) { int ret; int left = totalLen; int n = count; - while(( left > 0 )&&g_running ) { + while(( left > 0 )&&g_running ) + { ret = writev( fd, *pVec, n ); - if ( ret > 0 ) { + if ( ret > 0 ) + { left -= ret; - if (( left <= 0)||( !g_running )) { + if (( left <= 0)||( !g_running )) return totalLen - left; - } - while( ret > 0 ) { - if ( (*pVec)->iov_len <= ret ) { + while( ret > 0 ) + { + if ( (*pVec)->iov_len <= (unsigned int )ret ) + { ret -= (*pVec)->iov_len; ++(*pVec); - } else { + } + else + { (*pVec)->iov_base = (char *)(*pVec)->iov_base + ret; (*pVec)->iov_len -= ret; break; } } - } else if ( ret == -1 ) { - if ( errno == EAGAIN ) { - if ( totalLen - left > 0 ) { + } + else if ( ret == -1 ) + { + if ( errno == EAGAIN ) + { + if ( totalLen - left > 0 ) return totalLen - left; - } else { + else return -1; - } - } else { - if ( errno != EINTR ) { - return ret; - } } + else if ( errno != EINTR ) + return ret; } } return totalLen - left; } +/* +static int getTotalLen( struct iovec * pVec, int count ) +{ + struct iovec * pEnd = pVec + count; + int total = 0; + while( pVec < pEnd ) + { + total += pVec->iov_len; + ++pVec; + } + return total; +} +*/ + static inline int allocateBuf( LSAPI_Request * pReq, int size ) { char * pBuf = (char *)realloc( pReq->m_pReqBuf, size ); - if ( pBuf ) { + if ( pBuf ) + { pReq->m_pReqBuf = pBuf; pReq->m_reqBufSize = size; pReq->m_pHeader = (struct lsapi_req_header *)pReq->m_pReqBuf; @@ -281,9 +383,8 @@ static int allocateIovec( LSAPI_Request * pReq, int n ) { struct iovec * p = (struct iovec *)realloc( pReq->m_pIovec, sizeof(struct iovec) * n ); - if ( !p ) { + if ( !p ) return -1; - } pReq->m_pIovecToWrite = p + ( pReq->m_pIovecToWrite - pReq->m_pIovec ); pReq->m_pIovecCur = p + ( pReq->m_pIovecCur - pReq->m_pIovec ); pReq->m_pIovec = p; @@ -294,9 +395,8 @@ static int allocateIovec( LSAPI_Request * pReq, int n ) static int allocateRespHeaderBuf( LSAPI_Request * pReq, int size ) { char * p = (char *)realloc( pReq->m_pRespHeaderBuf, size ); - if ( !p ) { + if ( !p ) return -1; - } pReq->m_pRespHeaderBufPos = p + ( pReq->m_pRespHeaderBufPos - pReq->m_pRespHeaderBuf ); pReq->m_pRespHeaderBuf = p; pReq->m_pRespHeaderBufEnd = p + size; @@ -308,10 +408,10 @@ static inline int verifyHeader( struct lsapi_packet_header * pHeader, char pktTy { if (( LSAPI_VERSION_B0 != pHeader->m_versionB0 )|| ( LSAPI_VERSION_B1 != pHeader->m_versionB1 )|| - ( pktType != pHeader->m_type )) { + ( pktType != pHeader->m_type )) return -1; - } - if ( LSAPI_ENDIAN != (pHeader->m_flag & LSAPI_ENDIAN_BIT )) { + if ( LSAPI_ENDIAN != (pHeader->m_flag & LSAPI_ENDIAN_BIT )) + { register char b; b = pHeader->m_packetLen.m_bytes[0]; pHeader->m_packetLen.m_bytes[0] = pHeader->m_packetLen.m_bytes[3]; @@ -327,21 +427,20 @@ static int allocateEnvList( struct LSAPI_key_value_pair ** pEnvList, int *curSize, int newSize ) { struct LSAPI_key_value_pair * pBuf; - if ( *curSize >= newSize ) { + if ( *curSize >= newSize ) return 0; - } - if ( newSize > 8192 ) { + if ( newSize > 8192 ) return -1; - } pBuf = (struct LSAPI_key_value_pair *)realloc( *pEnvList, newSize * sizeof(struct LSAPI_key_value_pair) ); - if ( pBuf ) { + if ( pBuf ) + { *pEnvList = pBuf; *curSize = newSize; return 0; - } else { - return -1; } + else + return -1; } @@ -350,36 +449,32 @@ static inline int isPipe( int fd ) char achPeer[128]; socklen_t len = 128; if (( getpeername( fd, (struct sockaddr *)achPeer, &len ) != 0 )&& - ( errno == ENOTCONN )) { + ( errno == ENOTCONN )) return 0; - } else { + else return 1; - } } static int parseEnv( struct LSAPI_key_value_pair * pEnvList, int count, char **pBegin, char * pEnd ) { struct LSAPI_key_value_pair * pEnvEnd; - int keyLen = 0, valLen = 0; - if ( count > 8192 ) { + int keyLen = 0, valLen = 0; + if ( count > 8192 ) return -1; - } pEnvEnd = pEnvList + count; - while( pEnvList != pEnvEnd ) { - if ( pEnd - *pBegin < 4 ) { + while( pEnvList != pEnvEnd ) + { + if ( pEnd - *pBegin < 4 ) return -1; - } keyLen = *((unsigned char *)((*pBegin)++)); keyLen = (keyLen << 8) + *((unsigned char *)((*pBegin)++)); valLen = *((unsigned char *)((*pBegin)++)); valLen = (valLen << 8) + *((unsigned char *)((*pBegin)++)); - if ( *pBegin + keyLen + valLen > pEnd ) { + if ( *pBegin + keyLen + valLen > pEnd ) return -1; - } - if (( !keyLen )||( !valLen )) { + if (( !keyLen )||( !valLen )) return -1; - } pEnvList->pKey = *pBegin; *pBegin += keyLen; @@ -390,9 +485,8 @@ static int parseEnv( struct LSAPI_key_value_pair * pEnvList, int count, pEnvList->valLen = valLen - 1; ++pEnvList; } - if ( memcmp( *pBegin, "\0\0\0\0", 4 ) != 0 ) { + if ( memcmp( *pBegin, "\0\0\0\0", 4 ) != 0 ) return -1; - } *pBegin += 4; return 0; } @@ -427,8 +521,10 @@ static inline void fixEndian( LSAPI_Request * pReq ) static void fixHeaderIndexEndian( LSAPI_Request * pReq ) { int i; - for( i = 0; i < H_TRANSFER_ENCODING; ++i ) { - if ( pReq->m_pHeaderIndex->m_headerOff[i] ) { + for( i = 0; i < H_TRANSFER_ENCODING; ++i ) + { + if ( pReq->m_pHeaderIndex->m_headerOff[i] ) + { register char b; char * p = (char *)(&pReq->m_pHeaderIndex->m_headerLen[i]); b = p[0]; @@ -437,20 +533,434 @@ static void fixHeaderIndexEndian( LSAPI_Request * pReq ) swapIntEndian( &pReq->m_pHeaderIndex->m_headerOff[i] ); } } - if ( pReq->m_pHeader->m_cntUnknownHeaders > 0 ) { + if ( pReq->m_pHeader->m_cntUnknownHeaders > 0 ) + { struct lsapi_header_offset * pCur, *pEnd; pCur = pReq->m_pUnknownHeader; pEnd = pCur + pReq->m_pHeader->m_cntUnknownHeaders; - while( pCur < pEnd ) { + while( pCur < pEnd ) + { swapIntEndian( &pCur->nameOff ); swapIntEndian( &pCur->nameLen ); swapIntEndian( &pCur->valueOff ); swapIntEndian( &pCur->valueLen ); ++pCur; } - } + } +} + +static uid_t s_uid = 0; +static uid_t s_defaultUid; //web server need set this +static gid_t s_defaultGid; + +#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__) + +#define LSAPI_LVE_DISABLED 0 +#define LSAPI_LVE_ENABLED 1 +#define LSAPI_CAGEFS_ENABLED 2 +#define LSAPI_CAGEFS_NO_SUEXEC 3 +struct liblve; +static int s_enable_lve = LSAPI_LVE_DISABLED; +static struct liblve * s_lve = NULL; + +static void *s_liblve; +static int (*fp_lve_is_available)(void) = NULL; +static int (*fp_lve_instance_init)(struct liblve *) = NULL; +static int (*fp_lve_destroy)(struct liblve *) = NULL; +static int (*fp_lve_enter)(struct liblve *, uint32_t, int32_t, int32_t, uint32_t *) = NULL; +static int (*fp_lve_leave)(struct liblve *, uint32_t *) = NULL; +static int (*fp_lve_jail)( struct passwd *, char *) = NULL; +static int lsapi_load_lve_lib() +{ + s_liblve = dlopen("liblve.so.0", RTLD_LAZY); + if (s_liblve) + { + fp_lve_is_available = dlsym(s_liblve, "lve_is_available"); + if (dlerror() == NULL) + { + if ( !(*fp_lve_is_available)() ) + { + int uid = getuid(); + if ( uid ) + { + setreuid( s_uid, uid ); + if ( !(*fp_lve_is_available)() ) + s_enable_lve = 0; + setreuid( uid, s_uid ); + } + } + } + } + else + { + s_enable_lve = LSAPI_LVE_DISABLED; + } + return (s_liblve)? 0 : -1; +} + +static int init_lve_ex() +{ + int rc; + if ( !s_liblve ) + return -1; + fp_lve_instance_init = dlsym(s_liblve, "lve_instance_init"); + fp_lve_destroy = dlsym(s_liblve, "lve_destroy"); + fp_lve_enter = dlsym(s_liblve, "lve_enter"); + fp_lve_leave = dlsym(s_liblve, "lve_leave"); + if ( s_enable_lve >= LSAPI_CAGEFS_ENABLED ) + fp_lve_jail = dlsym(s_liblve, "jail" ); + + if ( s_lve == NULL ) + { + rc = (*fp_lve_instance_init)(NULL); + s_lve = malloc(rc); + } + rc = (*fp_lve_instance_init)(s_lve); + if (rc != 0) + { + perror( "LSAPI: Unable to initialize LVE" ); + free( s_lve ); + s_lve = NULL; + return -1; + } + return 0; + +} + +#endif + + + +static int readSecret( const char * pSecretFile ) +{ + struct stat st; + int fd = open( pSecretFile, O_RDONLY , 0600 ); + if ( fd == -1 ) + { + fprintf( stderr, "LSAPI: failed to open secret file: %s!\n", pSecretFile ); + return -1; + } + if ( fstat( fd, &st ) == -1 ) + { + fprintf( stderr, "LSAPI: failed to check state of file: %s!\n", pSecretFile ); + close( fd ); + return -1; + } +/* + if ( st.st_uid != s_uid ) + { + fprintf( stderr, "LSAPI: file owner check failure: %s!\n", pSecretFile ); + close( fd ); + return -1; + } +*/ + if ( st.st_mode & 0077 ) + { + fprintf( stderr, "LSAPI: file permission check failure: %s\n", pSecretFile ); + close( fd ); + return -1; + } + if ( read( fd, s_pSecret, 16 ) < 16 ) + { + fprintf( stderr, "LSAPI: failed to read secret from secret file: %s\n", pSecretFile ); + close( fd ); + return -1; + } + close( fd ); + return 0; +} + +int LSAPI_is_suEXEC_Daemon() +{ + if (( !s_uid )&&( s_pSecret[0] )) + return 1; + else + return 0; +} + +static int LSAPI_perror_r( LSAPI_Request * pReq, const char * pErr1, const char *pErr2 ) +{ + char achError[1024]; + int n = snprintf(achError, 1024, "%s:%s: %s\n", pErr1, (pErr2)?pErr2:"", strerror( errno ) ); + if ( pReq ) + LSAPI_Write_Stderr_r( pReq, achError, n ); + else + write( STDERR_FILENO, achError, n ); + return 0; +} + +static int lsapi_lve_error( LSAPI_Request * pReq ) +{ + static const char * headers[] = + { + "Cache-Control: private, no-cache, no-store, must-revalidate, max-age=0", + "Pragma: no-cache", + "Retry-After: 60", + "Content-Type: text/html", + NULL + }; + static const char achBody[] = + "\n" + "\n508 Resource Limit Is Reached\n" + "\n" "

Resource Limit Is Reached

\n" + "The website is temporarily unable to service your request as it exceeded resource limit.\n" + "Please try again later.\n" + "
\n" + "\n"; + + LSAPI_ErrResponse_r( pReq, 508, headers, achBody, sizeof( achBody ) - 1 ); + return 0; +} + +static int lsapi_enterLVE( LSAPI_Request * pReq, uid_t uid ) +{ +#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__) + if ( s_lve && uid ) //root user should not do that + { + uint32_t cookie; + int ret = -1; + ret = (*fp_lve_enter)(s_lve, uid, -1, -1, &cookie); + if ( ret < 0 ) + { + fprintf( stderr, "Pid (%d): enter LVE (%d) : ressult: %d !\n", getpid(), uid, ret ); + LSAPI_perror_r(pReq, "LSAPI: lve_enter() failure, reached resource limit.", NULL ); + lsapi_lve_error( pReq ); + return -1; + } + } +#endif + + return 0; +} + +static int lsapi_jailLVE( LSAPI_Request * pReq, uid_t uid, struct passwd * pw ) +{ + int ret = 0; +#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__) + char error_msg[1024] = ""; + ret = (*fp_lve_jail)( pw, error_msg ); + if ( ret < 0 ) + { + fprintf( stderr, "LSAPI (%d): LVE jail(%d) ressult: %d, error: %s !\n", + getpid(), uid, ret, error_msg ); + LSAPI_perror_r( pReq, "LSAPI: jail() failure.", NULL ); + return -1; + } +#endif + return ret; } + +#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__) +static int lsapi_initLVE() +{ + const char * pEnv; + if ( (pEnv = getenv( "LSAPI_LVE_ENABLE" ))!= NULL ) + { + s_enable_lve = atol( pEnv ); + pEnv = NULL; + } + else if ( (pEnv = getenv( "LVE_ENABLE" ))!= NULL ) + { + s_enable_lve = atol( pEnv ); + pEnv = NULL; + } + if ( s_enable_lve && !s_uid ) + { + lsapi_load_lve_lib(); + if ( s_enable_lve ) + { + return init_lve_ex(); + } + + } + return 0; +} +#endif + + +static int setUID_LVE(LSAPI_Request * pReq, uid_t uid, gid_t gid, const char * pChroot) +{ + int rv; + struct passwd * pw; + pw = getpwuid( uid ); +#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__) + if ( s_lve ) + { + if( lsapi_enterLVE( pReq, uid ) == -1 ) + return -1; + if ( pw && fp_lve_jail) + { + rv = lsapi_jailLVE( pReq, uid, pw ); + if ( rv == -1 ) + return -1; + if (( rv == 1 )&&(s_enable_lve == LSAPI_CAGEFS_NO_SUEXEC )) //this mode only use cageFS, does not use suEXEC + { + uid = s_defaultUid; + gid = s_defaultGid; + pw = getpwuid( uid ); + } + } + } +#endif + //if ( !uid || !gid ) //do not allow root + //{ + // return -1; + //} + +#if defined(__FreeBSD__ ) || defined(__NetBSD__) || defined(__OpenBSD__) \ + || defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) + if ( s_enable_core_dump ) + lsapi_enable_core_dump(); +#endif + + rv = setgid(gid); + if (rv == -1) + { + LSAPI_perror_r(pReq, "LSAPI: setgid()", NULL); + return -1; + } + if ( pw && (pw->pw_gid == gid )) + { + rv = initgroups( pw->pw_name, gid ); + if (rv == -1) + { + LSAPI_perror_r(pReq, "LSAPI: initgroups()", NULL); + return -1; + } + } + else + { + rv = setgroups(1, &gid); + if (rv == -1) + { + LSAPI_perror_r(pReq, "LSAPI: setgroups()", NULL); + } + } + if ( pChroot ) + { + rv = chroot( pChroot ); + if ( rv == -1 ) + { + LSAPI_perror_r(pReq, "LSAPI: chroot()", NULL); + return -1; + } + } + rv = setuid(uid); + if (rv == -1) + { + LSAPI_perror_r(pReq, "LSAPI: setuid()", NULL); + return -1; + } +#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__) + if ( s_enable_core_dump ) + lsapi_enable_core_dump(); +#endif + return 0; +} + +static int lsapi_suexec_auth( LSAPI_Request *pReq, + char * pAuth, int len, char * pUgid, int ugidLen ) +{ + lsapi_MD5_CTX md5ctx; + unsigned char achMD5[16]; + if ( len < 32 ) + return -1; + memmove( achMD5, pAuth + 16, 16 ); + memmove( pAuth + 16, s_pSecret, 16 ); + lsapi_MD5Init( &md5ctx ); + lsapi_MD5Update( &md5ctx, (unsigned char *)pAuth, 32 ); + lsapi_MD5Update( &md5ctx, (unsigned char *)pUgid, 8 ); + lsapi_MD5Final( (unsigned char *)pAuth + 16, &md5ctx); + if ( memcmp( achMD5, pAuth + 16, 16 ) == 0 ) + return 0; + return 1; +} + + +static int lsapi_changeUGid( LSAPI_Request * pReq ) +{ + int uid = s_defaultUid; + int gid = s_defaultGid; + const char * pChroot = NULL; + struct LSAPI_key_value_pair * pEnv; + struct LSAPI_key_value_pair * pAuth; + int i; + if ( s_uid ) + return 0; + //with special ID 0x00 + //authenticate the suEXEC request; + //first one should be MD5( nonce + lscgid secret ) + //remember to clear the secret after verification + //it should be set at the end of special env + i = pReq->m_pHeader->m_cntSpecialEnv - 1; + if ( i >= 0 ) + { + pEnv = pReq->m_pSpecialEnvList + i; + if (( *pEnv->pKey == '\000' )&& + ( strcmp( pEnv->pKey+1, "SUEXEC_AUTH" ) == 0 )) + { + --pReq->m_pHeader->m_cntSpecialEnv; + pAuth = pEnv--; + if (( *pEnv->pKey == '\000' )&& + ( strcmp( pEnv->pKey+1, "SUEXEC_UGID" ) == 0 )) + { + --pReq->m_pHeader->m_cntSpecialEnv; + uid = *(uint32_t *)pEnv->pValue; + gid = *(((uint32_t *)pEnv->pValue) + 1 ); + //fprintf( stderr, "LSAPI: SUEXEC_UGID set UID: %d, GID: %d\n", uid, gid ); + } + else + { + fprintf( stderr, "LSAPI: missing SUEXEC_UGID env, use default user!\n" ); + pEnv = NULL; + } + if ( pEnv&& lsapi_suexec_auth( pReq, pAuth->pValue, pAuth->valLen, pEnv->pValue, pEnv->valLen ) == 0 ) + { + //read UID, GID from specialEnv + + } + else + { + //authentication error + fprintf( stderr, "LSAPI: SUEXEC_AUTH authentication failed, use default user!\n" ); + uid = 0; + } + } + else + { + //fprintf( stderr, "LSAPI: no SUEXEC_AUTH env, use default user!\n" ); + } + } + + + if ( !uid ) + { + uid = s_defaultUid; + gid = s_defaultGid; + } + + //change uid + if ( setUID_LVE( pReq, uid, gid, pChroot ) == -1 ) + { + return -1; + } + + s_uid = uid; + + return 0; + +} + +static int parseContentLenFromHeader(LSAPI_Request * pReq) +{ + const char * pContentLen = LSAPI_GetHeader_r( pReq, H_CONTENT_LENGTH ); + if ( pContentLen ) + pReq->m_reqBodyLen = strtoll( pContentLen, NULL, 10 ); + return 0; +} + + static int parseRequest( LSAPI_Request * pReq, int totalLen ) { int shouldFixEndian; @@ -458,29 +968,28 @@ static int parseRequest( LSAPI_Request * pReq, int totalLen ) char * pEnd = pReq->m_pReqBuf + totalLen; shouldFixEndian = ( LSAPI_ENDIAN != ( pReq->m_pHeader->m_pktHeader.m_flag & LSAPI_ENDIAN_BIT ) ); - if ( shouldFixEndian ) { + if ( shouldFixEndian ) + { fixEndian( pReq ); } if ( (pReq->m_specialEnvListSize < pReq->m_pHeader->m_cntSpecialEnv )&& allocateEnvList( &pReq->m_pSpecialEnvList, - &pReq->m_specialEnvListSize, - pReq->m_pHeader->m_cntSpecialEnv ) == -1 ) { + &pReq->m_specialEnvListSize, + pReq->m_pHeader->m_cntSpecialEnv ) == -1 ) return -1; - } if ( (pReq->m_envListSize < pReq->m_pHeader->m_cntEnv )&& allocateEnvList( &pReq->m_pEnvList, &pReq->m_envListSize, - pReq->m_pHeader->m_cntEnv ) == -1 ) { + pReq->m_pHeader->m_cntEnv ) == -1 ) return -1; - } + if ( parseEnv( pReq->m_pSpecialEnvList, - pReq->m_pHeader->m_cntSpecialEnv, - &pBegin, pEnd ) == -1 ) { + pReq->m_pHeader->m_cntSpecialEnv, + &pBegin, pEnd ) == -1 ) return -1; - } if ( parseEnv( pReq->m_pEnvList, pReq->m_pHeader->m_cntEnv, - &pBegin, pEnd ) == -1 ) { + &pBegin, pEnd ) == -1 ) return -1; - } + pReq->m_pScriptFile = pReq->m_pReqBuf + pReq->m_pHeader->m_scriptFileOff; pReq->m_pScriptName = pReq->m_pReqBuf + pReq->m_pHeader->m_scriptNameOff; pReq->m_pQueryString = pReq->m_pReqBuf + pReq->m_pHeader->m_queryStringOff; @@ -496,85 +1005,183 @@ static int parseRequest( LSAPI_Request * pReq, int totalLen ) pReq->m_pHttpHeader = pBegin; pBegin += pReq->m_pHeader->m_httpHeaderLen; - if ( pBegin != pEnd ) { + if ( pBegin != pEnd ) + { + fprintf( stderr, "%d: request header does match total size, total: %d, real: %ld\n", getpid(), totalLen, + pBegin - pReq->m_pReqBuf ); return -1; } - - if ( shouldFixEndian ) { + if ( shouldFixEndian ) + { fixHeaderIndexEndian( pReq ); } - + pReq->m_reqBodyLen = pReq->m_pHeader->m_reqBodyLen; + if ( pReq->m_reqBodyLen == -2 ) + { + parseContentLenFromHeader(pReq); + } + return 0; } -static struct lsapi_packet_header ack = {'L', 'S', +//OPTIMIZATION +static char s_accept_notify = 0; +static char s_schedule_notify = 0; +static char s_notify_scheduled = 0; +static char s_notified_pid = 0; + +static struct lsapi_packet_header s_ack = {'L', 'S', LSAPI_REQ_RECEIVED, LSAPI_ENDIAN, {LSAPI_PACKET_HEADER_LEN} }; -static inline int notify_req_received( LSAPI_Request * pReq ) + + +static inline int write_req_received_notification( int fd ) { - if ( write( pReq->m_fd, &ack, LSAPI_PACKET_HEADER_LEN ) - < LSAPI_PACKET_HEADER_LEN ) { + if ( write( fd, &s_ack, LSAPI_PACKET_HEADER_LEN ) + < LSAPI_PACKET_HEADER_LEN ) return -1; + return 0; +} + +static void lsapi_sigalarm( int sig ) +{ + if ( s_notify_scheduled ) + { + s_notify_scheduled = 0; + if ( g_req.m_fd != -1 ) + write_req_received_notification( g_req.m_fd ); + } +} + +static inline int lsapi_schedule_notify() +{ + if ( !s_notify_scheduled ) + { + alarm( 2 ); + s_notify_scheduled = 1; } return 0; } +static inline int notify_req_received( int fd ) +{ + if ( s_schedule_notify ) + return lsapi_schedule_notify(); + return write_req_received_notification( fd ); + +} + + +static inline int lsapi_notify_pid( int fd ) +{ + char achBuf[16]; + lsapi_buildPacketHeader( (struct lsapi_packet_header *)achBuf, LSAPI_STDERR_STREAM, + 8 + LSAPI_PACKET_HEADER_LEN ); + memmove( &achBuf[8], "\0PID", 4 ); + *((int *)&achBuf[12]) = getpid(); + + if ( write( fd, achBuf, 16 ) < 16 ) + return -1; + return 0; +} + +static char s_conn_key_packet[16]; +static inline int init_conn_key( int fd ) +{ + struct lsapi_packet_header * pHeader = (struct lsapi_packet_header *)s_conn_key_packet; + struct timeval tv; + int i; + gettimeofday( &tv, NULL ); + srand( (tv.tv_sec % 0x1000 + tv.tv_usec) ^ rand() ); + for( i = 8; i < 16; ++i ) + { + s_conn_key_packet[i]=(int) (256.0*rand()/(RAND_MAX+1.0)); + } + lsapi_buildPacketHeader( pHeader, LSAPI_REQ_RECEIVED, + 8 + LSAPI_PACKET_HEADER_LEN ); + if ( write( fd, s_conn_key_packet, LSAPI_PACKET_HEADER_LEN+8 ) + < LSAPI_PACKET_HEADER_LEN+8 ) + return -1; + return 0; + + +} static int readReq( LSAPI_Request * pReq ) { int len; int packetLen; - if ( !pReq ) { + if ( !pReq ) return -1; - } - if ( pReq->m_reqBufSize < 8192 ) { - if ( allocateBuf( pReq, 8192 ) == -1 ) { + if ( pReq->m_reqBufSize < 8192 ) + { + if ( allocateBuf( pReq, 8192 ) == -1 ) return -1; - } } - while ( pReq->m_bufRead < LSAPI_PACKET_HEADER_LEN ) { + while ( pReq->m_bufRead < LSAPI_PACKET_HEADER_LEN ) + { len = lsapi_read( pReq->m_fd, pReq->m_pReqBuf, pReq->m_reqBufSize ); - if ( len <= 0 ) { + if ( len <= 0 ) return -1; - } pReq->m_bufRead += len; } pReq->m_reqState = LSAPI_ST_REQ_HEADER; packetLen = verifyHeader( &pReq->m_pHeader->m_pktHeader, LSAPI_BEGIN_REQUEST ); - if ( packetLen < 0 ) { + if ( packetLen < 0 ) + { + fprintf( stderr, "%d: packetLen < 0\n", getpid() ); return -1; } - if ( packetLen > LSAPI_MAX_HEADER_LEN ) { + if ( packetLen > LSAPI_MAX_HEADER_LEN ) + { + fprintf( stderr, "%d: packetLen > %d\n", getpid(), LSAPI_MAX_HEADER_LEN ); return -1; } - if ( packetLen + 1024 > pReq->m_reqBufSize ) { - if ( allocateBuf( pReq, packetLen + 1024 ) == -1 ) { + if ( packetLen + 1024 > pReq->m_reqBufSize ) + { + if ( allocateBuf( pReq, packetLen + 1024 ) == -1 ) return -1; - } } - while( packetLen > pReq->m_bufRead ) { + while( packetLen > pReq->m_bufRead ) + { len = lsapi_read( pReq->m_fd, pReq->m_pReqBuf + pReq->m_bufRead, packetLen - pReq->m_bufRead ); - if ( len <= 0 ) { + if ( len <= 0 ) return -1; - } pReq->m_bufRead += len; } - if ( parseRequest( pReq, packetLen ) < 0 ) { + if ( parseRequest( pReq, packetLen ) < 0 ) + { + fprintf( stderr, "%d: parseRequest error\n", getpid() ); return -1; } - pReq->m_bufProcessed = packetLen; + pReq->m_reqState = LSAPI_ST_REQ_BODY | LSAPI_ST_RESP_HEADER; - return notify_req_received( pReq ); + if ( !s_uid ) + if ( lsapi_changeUGid( pReq ) ) + return -1; + pReq->m_bufProcessed = packetLen; + + //OPTIMIZATION + if ( !s_accept_notify && !s_notified_pid ) + return notify_req_received( pReq->m_fd ); + else + { + s_notified_pid = 0; + return 0; + } } int LSAPI_Init(void) { - if ( !g_inited ) { + if ( !g_inited ) + { + s_uid = geteuid(); + s_pSecret[0] = 0; lsapi_signal(SIGPIPE, lsapi_sigpipe); lsapi_signal(SIGUSR1, lsapi_siguser1); @@ -583,11 +1190,9 @@ int LSAPI_Init(void) #endif /* let STDOUT function as STDERR, just in case writing to STDOUT directly */ - dup2( 2, 1 ); - - if ( LSAPI_InitRequest( &g_req, LSAPI_SOCK_FILENO ) == -1 ) { + dup2( 2, 1 ); + if ( LSAPI_InitRequest( &g_req, LSAPI_SOCK_FILENO ) == -1 ) return -1; - } g_inited = 1; s_ppid = getppid(); } @@ -606,28 +1211,35 @@ int LSAPI_IsRunning(void) int LSAPI_InitRequest( LSAPI_Request * pReq, int fd ) { - if ( !pReq ) { + int newfd; + if ( !pReq ) return -1; - } memset( pReq, 0, sizeof( LSAPI_Request ) ); - if ( allocateIovec( pReq, 16 ) == -1 ) { + if ( allocateIovec( pReq, 16 ) == -1 ) return -1; - } pReq->m_pRespBuf = pReq->m_pRespBufPos = (char *)malloc( LSAPI_RESP_BUF_SIZE ); - if ( !pReq->m_pRespBuf ) { + if ( !pReq->m_pRespBuf ) return -1; - } pReq->m_pRespBufEnd = pReq->m_pRespBuf + LSAPI_RESP_BUF_SIZE; pReq->m_pIovecCur = pReq->m_pIovecToWrite = pReq->m_pIovec + 1; pReq->m_respPktHeaderEnd = &pReq->m_respPktHeader[5]; - if ( allocateRespHeaderBuf( pReq, LSAPI_INIT_RESP_HEADER_LEN ) == -1 ) { + if ( allocateRespHeaderBuf( pReq, LSAPI_INIT_RESP_HEADER_LEN ) == -1 ) return -1; - } - - if ( isPipe( fd ) ) { + + if ( fd == STDIN_FILENO ) + { + fd = dup( fd ); + newfd = open( "/dev/null", O_RDWR ); + dup2( newfd, STDIN_FILENO ); + } + + if ( isPipe( fd ) ) + { pReq->m_fdListen = -1; pReq->m_fd = fd; - } else { + } + else + { pReq->m_fdListen = fd; pReq->m_fd = -1; lsapi_set_nblock( fd, 1 ); @@ -653,38 +1265,48 @@ int LSAPI_Accept_r( LSAPI_Request * pReq ) socklen_t len; int nodelay = 1; - if ( !pReq ) { + if ( !pReq ) return -1; - } - if ( LSAPI_Finish_r( pReq ) == -1 ) { + if ( LSAPI_Finish_r( pReq ) == -1 ) return -1; - } - while( g_running ) { - if ( pReq->m_fd == -1 ) { - if ( pReq->m_fdListen != -1) { + lsapi_set_nblock( pReq->m_fdListen , 0 ); + while( g_running ) + { + if ( pReq->m_fd == -1 ) + { + if ( pReq->m_fdListen != -1) + { len = sizeof( achPeer ); pReq->m_fd = accept( pReq->m_fdListen, (struct sockaddr *)&achPeer, &len ); - if ( pReq->m_fd == -1 ) { - if (( errno == EINTR )||( errno == EAGAIN)) { + if ( pReq->m_fd == -1 ) + { + if (( errno == EINTR )||( errno == EAGAIN)) continue; - } else { + else return -1; - } - } else { + } + else + { lsapi_set_nblock( pReq->m_fd , 0 ); - if (((struct sockaddr *)&achPeer)->sa_family == AF_INET ) { + if (((struct sockaddr *)&achPeer)->sa_family == AF_INET ) + { setsockopt(pReq->m_fd, IPPROTO_TCP, TCP_NODELAY, - (char *)&nodelay, sizeof(nodelay)); + (char *)&nodelay, sizeof(nodelay)); } + //init_conn_key( pReq->m_fd ); + //OPTIMIZATION + if ( s_accept_notify ) + if ( notify_req_received( pReq->m_fd ) == -1 ) + return -1; } - } else { - return -1; } + else + return -1; } - if ( !readReq( pReq ) ) { + if ( !readReq( pReq ) ) break; - } + //abort(); lsapi_close( pReq->m_fd ); pReq->m_fd = -1; LSAPI_Reset_r( pReq ); @@ -698,15 +1320,18 @@ static struct lsapi_packet_header finish = {'L', 'S', int LSAPI_Finish_r( LSAPI_Request * pReq ) { /* finish req body */ - if ( !pReq ) { + if ( !pReq ) return -1; - } - if (pReq->m_reqState) { - if ( pReq->m_fd != -1 ) { - if ( pReq->m_reqState & LSAPI_ST_RESP_HEADER ) { + if (pReq->m_reqState) + { + if ( pReq->m_fd != -1 ) + { + if ( pReq->m_reqState & LSAPI_ST_RESP_HEADER ) + { LSAPI_FinalizeRespHeaders_r( pReq ); } - if ( pReq->m_pRespBufPos != pReq->m_pRespBuf ) { + if ( pReq->m_pRespBufPos != pReq->m_pRespBuf ) + { Flush_RespBuf_r( pReq ); } @@ -735,18 +1360,14 @@ void LSAPI_Reset_r( LSAPI_Request * pReq ) int LSAPI_Release_r( LSAPI_Request * pReq ) { - if ( pReq->m_pReqBuf ) { + if ( pReq->m_pReqBuf ) free( pReq->m_pReqBuf ); - } - if ( pReq->m_pSpecialEnvList ) { + if ( pReq->m_pSpecialEnvList ) free( pReq->m_pSpecialEnvList ); - } - if ( pReq->m_pEnvList ) { + if ( pReq->m_pEnvList ) free( pReq->m_pEnvList ); - } - if ( pReq->m_pRespHeaderBuf ) { + if ( pReq->m_pRespHeaderBuf ) free( pReq->m_pRespHeaderBuf ); - } return 0; } @@ -754,55 +1375,48 @@ int LSAPI_Release_r( LSAPI_Request * pReq ) char * LSAPI_GetHeader_r( LSAPI_Request * pReq, int headerIndex ) { int off; - if ( !pReq || ((unsigned int)headerIndex > H_TRANSFER_ENCODING) ) { + if ( !pReq || ((unsigned int)headerIndex > H_TRANSFER_ENCODING) ) return NULL; - } off = pReq->m_pHeaderIndex->m_headerOff[ headerIndex ]; - if ( !off ) { + if ( !off ) return NULL; - } - if ( *(pReq->m_pHttpHeader + off + - pReq->m_pHeaderIndex->m_headerLen[ headerIndex ]) ) { - *( pReq->m_pHttpHeader + off + - pReq->m_pHeaderIndex->m_headerLen[ headerIndex ]) = 0; - } + if ( *(pReq->m_pHttpHeader + off + + pReq->m_pHeaderIndex->m_headerLen[ headerIndex ]) ) + *( pReq->m_pHttpHeader + off + + pReq->m_pHeaderIndex->m_headerLen[ headerIndex ]) = 0; return pReq->m_pHttpHeader + off; } static int readBodyToReqBuf( LSAPI_Request * pReq ) { - int bodyLeft; - int len = pReq->m_bufRead - pReq->m_bufProcessed; - if ( len > 0 ) { + off_t bodyLeft; + ssize_t len = pReq->m_bufRead - pReq->m_bufProcessed; + if ( len > 0 ) return len; - } pReq->m_bufRead = pReq->m_bufProcessed = pReq->m_pHeader->m_pktHeader.m_packetLen.m_iLen; - bodyLeft = pReq->m_pHeader->m_reqBodyLen - pReq->m_reqBodyRead; + bodyLeft = pReq->m_reqBodyLen - pReq->m_reqBodyRead; len = pReq->m_reqBufSize - pReq->m_bufRead; - if ( len < 0 ) { + if ( len < 0 ) return -1; - } - if ( len > bodyLeft ) { + if ( len > bodyLeft ) len = bodyLeft; - } + len = lsapi_read( pReq->m_fd, pReq->m_pReqBuf + pReq->m_bufRead, len ); - if ( len > 0 ) { + if ( len > 0 ) pReq->m_bufRead += len; - } return len; } int LSAPI_ReqBodyGetChar_r( LSAPI_Request * pReq ) { - if (!pReq || (pReq->m_fd ==-1) ) { + if (!pReq || (pReq->m_fd ==-1) ) return EOF; - } - if ( pReq->m_bufProcessed >= pReq->m_bufRead ) { - if ( readBodyToReqBuf( pReq ) <= 0 ) { + if ( pReq->m_bufProcessed >= pReq->m_bufRead ) + { + if ( readBodyToReqBuf( pReq ) <= 0 ) return EOF; - } } ++pReq->m_reqBodyRead; return (unsigned char)*(pReq->m_pReqBuf + pReq->m_bufProcessed++); @@ -810,42 +1424,43 @@ int LSAPI_ReqBodyGetChar_r( LSAPI_Request * pReq ) -int LSAPI_ReqBodyGetLine_r( LSAPI_Request * pReq, char * pBuf, int bufLen, int *getLF ) +int LSAPI_ReqBodyGetLine_r( LSAPI_Request * pReq, char * pBuf, size_t bufLen, int *getLF ) { - int len; - int left; + ssize_t len; + ssize_t left; char * pBufEnd = pBuf + bufLen - 1; char * pBufCur = pBuf; char * pCur; char * p; - if (!pReq || (pReq->m_fd ==-1) ||( !pBuf )||(bufLen < 0 )|| !getLF ) { + if (!pReq || (pReq->m_fd ==-1) ||( !pBuf )||(bufLen < 0 )|| !getLF ) return -1; - } *getLF = 0; - while( (left = pBufEnd - pBufCur ) > 0 ) { + while( (left = pBufEnd - pBufCur ) > 0 ) + { len = pReq->m_bufRead - pReq->m_bufProcessed; - if ( len <= 0 ) { - if ( (len = readBodyToReqBuf( pReq )) <= 0 ) { + if ( len <= 0 ) + { + if ( (len = readBodyToReqBuf( pReq )) <= 0 ) + { *getLF = 1; break; } } - if ( len > left ) { + if ( len > left ) len = left; - } pCur = pReq->m_pReqBuf + pReq->m_bufProcessed; p = memchr( pCur, '\n', len ); - if ( p ) { + if ( p ) len = p - pCur + 1; - } memmove( pBufCur, pCur, len ); pBufCur += len; pReq->m_bufProcessed += len; pReq->m_reqBodyRead += len; - if ( p ) { + if ( p ) + { *getLF = 1; break; } @@ -856,48 +1471,47 @@ int LSAPI_ReqBodyGetLine_r( LSAPI_Request * pReq, char * pBuf, int bufLen, int * } -int LSAPI_ReadReqBody_r( LSAPI_Request * pReq, char * pBuf, int bufLen ) +ssize_t LSAPI_ReadReqBody_r( LSAPI_Request * pReq, char * pBuf, size_t bufLen ) { - int len; - int total; + ssize_t len; + off_t total; /* char *pOldBuf = pBuf; */ - if (!pReq || (pReq->m_fd ==-1) || ( !pBuf )||(bufLen < 0 )) { + if (!pReq || (pReq->m_fd ==-1) || ( !pBuf )||(bufLen < 0 )) return -1; - } - total = pReq->m_pHeader->m_reqBodyLen - pReq->m_reqBodyRead; + + total = pReq->m_reqBodyLen - pReq->m_reqBodyRead; - if ( total <= 0 ) { + if ( total <= 0 ) return 0; - } - if ( total < bufLen ) { + if ( total < bufLen ) bufLen = total; - } total = 0; len = pReq->m_bufRead - pReq->m_bufProcessed; - if ( len > 0 ) { - if ( len > bufLen ) { + if ( len > 0 ) + { + if ( len > bufLen ) len = bufLen; - } memmove( pBuf, pReq->m_pReqBuf + pReq->m_bufProcessed, len ); pReq->m_bufProcessed += len; total += len; pBuf += len; bufLen -= len; } - while( bufLen > 0 ) { + while( bufLen > 0 ) + { len = lsapi_read( pReq->m_fd, pBuf, bufLen ); - if ( len > 0 ) { + if ( len > 0 ) + { total += len; pBuf += len; bufLen -= len; - } else { - if ( len <= 0 ) { - if ( !total) { - return -1; - } - break; - } + } + else if ( len <= 0 ) + { + if ( !total) + return -1; + break; } } pReq->m_reqBodyRead += total; @@ -906,37 +1520,52 @@ int LSAPI_ReadReqBody_r( LSAPI_Request * pReq, char * pBuf, int bufLen ) } -int LSAPI_Write_r( LSAPI_Request * pReq, const char * pBuf, int len ) +ssize_t LSAPI_Write_r( LSAPI_Request * pReq, const char * pBuf, size_t len ) { struct lsapi_packet_header * pHeader; const char * pEnd; const char * p; - int bufLen; - int toWrite; - int packetLen; + ssize_t bufLen; + ssize_t toWrite; + ssize_t packetLen; + int skip = 0; - if ( !pReq || !pBuf || (pReq->m_fd == -1) ) { + if ( !pReq || !pBuf || (pReq->m_fd == -1) ) return -1; + if ( pReq->m_reqState & LSAPI_ST_RESP_HEADER ) + { + LSAPI_FinalizeRespHeaders_r( pReq ); +/* + if ( *pBuf == '\r' ) + { + ++skip; + } + if ( *pBuf == '\n' ) + { + ++skip; + } +*/ } - if ( len < pReq->m_pRespBufEnd - pReq->m_pRespBufPos ) { - memmove( pReq->m_pRespBufPos, pBuf, len ); - pReq->m_pRespBufPos += len; + pReq->m_reqState |= LSAPI_ST_RESP_BODY; + + if ( (len - skip) < pReq->m_pRespBufEnd - pReq->m_pRespBufPos ) + { + memmove( pReq->m_pRespBufPos, pBuf + skip, len - skip ); + pReq->m_pRespBufPos += len - skip; return len; } - if ( pReq->m_reqState & LSAPI_ST_RESP_HEADER ) { - LSAPI_FinalizeRespHeaders_r( pReq ); - } - pReq->m_reqState |= LSAPI_ST_RESP_BODY; pHeader = pReq->m_respPktHeader; - p = pBuf; + p = pBuf + skip; pEnd = pBuf + len; bufLen = pReq->m_pRespBufPos - pReq->m_pRespBuf; - while( ( toWrite = pEnd - p ) > 0 ) { + while( ( toWrite = pEnd - p ) > 0 ) + { packetLen = toWrite + bufLen; - if ( LSAPI_MAX_DATA_PACKET_LEN < packetLen) { + if ( LSAPI_MAX_DATA_PACKET_LEN < packetLen) + { packetLen = LSAPI_MAX_DATA_PACKET_LEN; toWrite = packetLen - bufLen; } @@ -949,7 +1578,8 @@ int LSAPI_Write_r( LSAPI_Request * pReq, const char * pBuf, int len ) pReq->m_pIovecCur->iov_len = LSAPI_PACKET_HEADER_LEN; ++pReq->m_pIovecCur; ++pHeader; - if ( bufLen > 0 ) { + if ( bufLen > 0 ) + { pReq->m_pIovecCur->iov_base = (void *)pReq->m_pRespBuf; pReq->m_pIovecCur->iov_len = bufLen; pReq->m_pRespBufPos = pReq->m_pRespBuf; @@ -962,21 +1592,108 @@ int LSAPI_Write_r( LSAPI_Request * pReq, const char * pBuf, int len ) ++pReq->m_pIovecCur; p += toWrite; - if ( pHeader >= pReq->m_respPktHeaderEnd - 1) { - if ( LSAPI_Flush_r( pReq ) == -1 ) { + if ( pHeader >= pReq->m_respPktHeaderEnd - 1) + { + if ( LSAPI_Flush_r( pReq ) == -1 ) return -1; - } pHeader = pReq->m_respPktHeader; } } - if ( pHeader != pReq->m_respPktHeader ) { - if ( LSAPI_Flush_r( pReq ) == -1 ) { + if ( pHeader != pReq->m_respPktHeader ) + if ( LSAPI_Flush_r( pReq ) == -1 ) return -1; - } - } return p - pBuf; } +#if defined(__FreeBSD__ ) || defined(__NetBSD__) || defined(__OpenBSD__) +ssize_t gsendfile( int fdOut, int fdIn, off_t* off, size_t size ) +{ + ssize_t ret; + off_t written; + ret = sendfile( fdIn, fdOut, *off, size, NULL, &written, 0 ); + if ( written > 0 ) + { + ret = written; + *off += ret; + } + return ret; +} +#endif + +#if defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) +ssize_t gsendfile( int fdOut, int fdIn, off_t* off, size_t size ) +{ + ssize_t ret; + off_t len = size; + ret = sendfile( fdIn, fdOut, *off, &len, NULL, 0 ); + if (( ret == 0 )&&( len > 0 )) + { + ret = len; + *off += len; + } + return ret; +} +#endif + +#if defined(sun) || defined(__sun) +#include +ssize_t gsendfile( int fdOut, int fdIn, off_t *off, size_t size ) +{ + int n = 0 ; + sendfilevec_t vec[1]; + + vec[n].sfv_fd = fdIn; + vec[n].sfv_flag = 0; + vec[n].sfv_off = *off; + vec[n].sfv_len = size; + ++n; + + size_t written; + ssize_t ret = sendfilev( fdOut, vec, n, &written ); + if (( !ret )||( errno == EAGAIN )) + ret = written; + if ( ret > 0 ) + *off += ret; + return ret; +} +#endif + +#if defined(linux) || defined(__linux) || defined(__linux__) || \ + defined(__gnu_linux__) +#include +#define gsendfile sendfile +#endif +#if defined(HPUX) +ssize_t gsendfile( int fdOut, int fdIn, off_t * off, size_t size ) +{ + return sendfile( fdOut, fdIn, off, size, NULL, 0 ); +} +#endif + +ssize_t LSAPI_sendfile_r( LSAPI_Request * pReq, int fdIn, off_t* off, size_t size ) +{ + struct lsapi_packet_header * pHeader = pReq->m_respPktHeader; + if ( !pReq || (pReq->m_fd == -1) || fdIn == -1 ) + return -1; + if ( pReq->m_reqState & LSAPI_ST_RESP_HEADER ) + { + LSAPI_FinalizeRespHeaders_r( pReq ); + } + pReq->m_reqState |= LSAPI_ST_RESP_BODY; + + LSAPI_Flush_r(pReq); + + lsapi_buildPacketHeader( pHeader, LSAPI_RESP_STREAM, + size + LSAPI_PACKET_HEADER_LEN ); + + + if (write(pReq->m_fd, (const char *) pHeader, LSAPI_PACKET_HEADER_LEN ) != LSAPI_PACKET_HEADER_LEN) + return -1; + + return gsendfile( pReq->m_fd, fdIn, off, size ); +} + + void Flush_RespBuf_r( LSAPI_Request * pReq ) { struct lsapi_packet_header * pHeader = pReq->m_respPktHeader; @@ -990,7 +1707,8 @@ void Flush_RespBuf_r( LSAPI_Request * pReq ) pReq->m_pIovecCur->iov_len = LSAPI_PACKET_HEADER_LEN; ++pReq->m_pIovecCur; ++pHeader; - if ( bufLen > 0 ) { + if ( bufLen > 0 ) + { pReq->m_pIovecCur->iov_base = (void *)pReq->m_pRespBuf; pReq->m_pIovecCur->iov_len = bufLen; pReq->m_pRespBufPos = pReq->m_pRespBuf; @@ -1006,32 +1724,35 @@ int LSAPI_Flush_r( LSAPI_Request * pReq ) { int ret = 0; int n; - if ( !pReq ) { + if ( !pReq ) return -1; - } n = pReq->m_pIovecCur - pReq->m_pIovecToWrite; - if (( 0 == n )&&( pReq->m_pRespBufPos == pReq->m_pRespBuf )) { + if (( 0 == n )&&( pReq->m_pRespBufPos == pReq->m_pRespBuf )) return 0; - } - if ( pReq->m_fd == -1 ) { + if ( pReq->m_fd == -1 ) + { pReq->m_pRespBufPos = pReq->m_pRespBuf; pReq->m_totalLen = 0; pReq->m_pIovecCur = pReq->m_pIovecToWrite = pReq->m_pIovec; return -1; } - if ( pReq->m_reqState & LSAPI_ST_RESP_HEADER ) { + if ( pReq->m_reqState & LSAPI_ST_RESP_HEADER ) + { LSAPI_FinalizeRespHeaders_r( pReq ); } - if ( pReq->m_pRespBufPos != pReq->m_pRespBuf ) { + if ( pReq->m_pRespBufPos != pReq->m_pRespBuf ) + { Flush_RespBuf_r( pReq ); } n = pReq->m_pIovecCur - pReq->m_pIovecToWrite; - if ( n > 0 ) { + if ( n > 0 ) + { ret = lsapi_writev( pReq->m_fd, &pReq->m_pIovecToWrite, n, pReq->m_totalLen ); - if ( ret < pReq->m_totalLen ) { + if ( ret < pReq->m_totalLen ) + { lsapi_close( pReq->m_fd ); pReq->m_fd = -1; ret = -1; @@ -1043,32 +1764,33 @@ int LSAPI_Flush_r( LSAPI_Request * pReq ) } -int LSAPI_Write_Stderr_r( LSAPI_Request * pReq, const char * pBuf, int len ) +ssize_t LSAPI_Write_Stderr_r( LSAPI_Request * pReq, const char * pBuf, size_t len ) { struct lsapi_packet_header header; const char * pEnd; const char * p; - int packetLen; - int totalLen; + ssize_t packetLen; + ssize_t totalLen; int ret; struct iovec iov[2]; struct iovec *pIov; - if ( !pReq ) { + if ( !pReq ) return -1; - } - if (( pReq->m_fd == -1 )||(pReq->m_fd == pReq->m_fdListen )) { + if (( pReq->m_fd == -1 )||(pReq->m_fd == pReq->m_fdListen )) return write( 2, pBuf, len ); - } - if ( pReq->m_pRespBufPos != pReq->m_pRespBuf ) { + if ( pReq->m_pRespBufPos != pReq->m_pRespBuf ) + { LSAPI_Flush_r( pReq ); } p = pBuf; pEnd = pBuf + len; - while( ( packetLen = pEnd - p ) > 0 ) { - if ( LSAPI_MAX_DATA_PACKET_LEN < packetLen) { + while( ( packetLen = pEnd - p ) > 0 ) + { + if ( LSAPI_MAX_DATA_PACKET_LEN < packetLen) + { packetLen = LSAPI_MAX_DATA_PACKET_LEN; } @@ -1085,7 +1807,8 @@ int LSAPI_Write_Stderr_r( LSAPI_Request * pReq, const char * pBuf, int len ) pIov = iov; ret = lsapi_writev( pReq->m_fd, &pIov, 2, totalLen ); - if ( ret < totalLen ) { + if ( ret < totalLen ) + { lsapi_close( pReq->m_fd ); pReq->m_fd = -1; ret = -1; @@ -1097,14 +1820,16 @@ int LSAPI_Write_Stderr_r( LSAPI_Request * pReq, const char * pBuf, int len ) static char * GetHeaderVar( LSAPI_Request * pReq, const char * name ) { int i; - for( i = 0; i < H_TRANSFER_ENCODING; ++i ) { - if ( pReq->m_pHeaderIndex->m_headerOff[i] ) { - if ( strcmp( name, CGI_HEADERS[i] ) == 0 ) { + for( i = 0; i < H_TRANSFER_ENCODING; ++i ) + { + if ( pReq->m_pHeaderIndex->m_headerOff[i] ) + { + if ( strcmp( name, CGI_HEADERS[i] ) == 0 ) return pReq->m_pHttpHeader + pReq->m_pHeaderIndex->m_headerOff[i]; - } } } - if ( pReq->m_pHeader->m_cntUnknownHeaders > 0 ) { + if ( pReq->m_pHeader->m_cntUnknownHeaders > 0 ) + { const char *p; char *pKey; char *pKeyEnd; @@ -1112,22 +1837,22 @@ static char * GetHeaderVar( LSAPI_Request * pReq, const char * name ) struct lsapi_header_offset * pCur, *pEnd; pCur = pReq->m_pUnknownHeader; pEnd = pCur + pReq->m_pHeader->m_cntUnknownHeaders; - while( pCur < pEnd ) { + while( pCur < pEnd ) + { pKey = pReq->m_pHttpHeader + pCur->nameOff; keyLen = pCur->nameLen; pKeyEnd = pKey + keyLen; p = &name[5]; - while(( pKey < pKeyEnd )&&( *p )) { + while(( pKey < pKeyEnd )&&( *p )) + { char ch = toupper( *pKey ); - if ((ch != *p )||(( *p == '_' )&&( ch != '-'))) { + if ((ch != *p )||(( *p == '_' )&&( ch != '-'))) break; - } ++p; ++pKey; } - if (( pKey == pKeyEnd )&& (!*p )) { + if (( pKey == pKeyEnd )&& (!*p )) return pReq->m_pHttpHeader + pCur->valueOff; - } ++pCur; } } @@ -1139,21 +1864,35 @@ char * LSAPI_GetEnv_r( LSAPI_Request * pReq, const char * name ) { struct LSAPI_key_value_pair * pBegin = pReq->m_pEnvList; struct LSAPI_key_value_pair * pEnd = pBegin + pReq->m_pHeader->m_cntEnv; - if ( !pReq || !name ) { + if ( !pReq || !name ) return NULL; - } - if ( strncmp( name, "HTTP_", 5 ) == 0 ) { + if ( strncmp( name, "HTTP_", 5 ) == 0 ) + { return GetHeaderVar( pReq, name ); } - while( pBegin < pEnd ) { - if ( strcmp( name, pBegin->pKey ) == 0 ) { + while( pBegin < pEnd ) + { + if ( strcmp( name, pBegin->pKey ) == 0 ) return pBegin->pValue; - } ++pBegin; } return NULL; } +struct _headerInfo +{ + const char * _name; + int _nameLen; + const char * _value; + int _valueLen; +}; + +int compareValueLocation(const void * v1, const void *v2 ) +{ + return ((const struct _headerInfo *)v1)->_value - + ((const struct _headerInfo *)v2)->_value; +} + int LSAPI_ForeachOrgHeader_r( LSAPI_Request * pReq, LSAPI_CB_EnvHandler fn, void * arg ) { @@ -1162,43 +1901,66 @@ int LSAPI_ForeachOrgHeader_r( LSAPI_Request * pReq, char * pValue; int ret; int count = 0; - if ( !pReq || !fn ) { + struct _headerInfo headers[512]; + if ( !pReq || !fn ) return -1; - } - for( i = 0; i < H_TRANSFER_ENCODING; ++i ) { - if ( pReq->m_pHeaderIndex->m_headerOff[i] ) { + + for( i = 0; i < H_TRANSFER_ENCODING; ++i ) + { + if ( pReq->m_pHeaderIndex->m_headerOff[i] ) + { len = pReq->m_pHeaderIndex->m_headerLen[i]; pValue = pReq->m_pHttpHeader + pReq->m_pHeaderIndex->m_headerOff[i]; *(pValue + len ) = 0; - ret = (*fn)( HTTP_HEADERS[i], HTTP_HEADER_LEN[i], - pValue, len, arg ); + headers[count]._name = HTTP_HEADERS[i]; + headers[count]._nameLen = HTTP_HEADER_LEN[i]; + headers[count]._value = pValue; + headers[count]._valueLen = len; ++count; - if ( ret <= 0 ) { - return ret; - } + + //ret = (*fn)( HTTP_HEADERS[i], HTTP_HEADER_LEN[i], + // pValue, len, arg ); + //if ( ret <= 0 ) + // return ret; } } - if ( pReq->m_pHeader->m_cntUnknownHeaders > 0 ) { + if ( pReq->m_pHeader->m_cntUnknownHeaders > 0 ) + { char *pKey; int keyLen; struct lsapi_header_offset * pCur, *pEnd; pCur = pReq->m_pUnknownHeader; pEnd = pCur + pReq->m_pHeader->m_cntUnknownHeaders; - while( pCur < pEnd ) { + while( pCur < pEnd ) + { pKey = pReq->m_pHttpHeader + pCur->nameOff; keyLen = pCur->nameLen; pValue = pReq->m_pHttpHeader + pCur->valueOff; *(pValue + pCur->valueLen ) = 0; - ret = (*fn)( pKey, keyLen, - pValue, pCur->valueLen, arg ); - if ( ret <= 0 ) { - return ret; - } + headers[count]._name = pKey; + headers[count]._nameLen = keyLen; + headers[count]._value = pValue; + headers[count]._valueLen = pCur->valueLen; + ++count; + if ( count == 512 ) + break; + //ret = (*fn)( pKey, keyLen, + // pValue, pCur->valueLen, arg ); + //if ( ret <= 0 ) + // return ret; ++pCur; } } - return count + pReq->m_pHeader->m_cntUnknownHeaders; + qsort( headers, count, sizeof( struct _headerInfo ), compareValueLocation ); + for( i = 0; i < count; ++i ) + { + ret = (*fn)( headers[i]._name, headers[i]._nameLen, + headers[i]._value, headers[i]._valueLen, arg ); + if ( ret <= 0 ) + return ret; + } + return count; } @@ -1211,23 +1973,24 @@ int LSAPI_ForeachHeader_r( LSAPI_Request * pReq, char * pValue; int ret; int count = 0; - if ( !pReq || !fn ) { + if ( !pReq || !fn ) return -1; - } - for( i = 0; i < H_TRANSFER_ENCODING; ++i ) { - if ( pReq->m_pHeaderIndex->m_headerOff[i] ) { + for( i = 0; i < H_TRANSFER_ENCODING; ++i ) + { + if ( pReq->m_pHeaderIndex->m_headerOff[i] ) + { len = pReq->m_pHeaderIndex->m_headerLen[i]; pValue = pReq->m_pHttpHeader + pReq->m_pHeaderIndex->m_headerOff[i]; *(pValue + len ) = 0; ret = (*fn)( CGI_HEADERS[i], CGI_HEADER_LEN[i], pValue, len, arg ); ++count; - if ( ret <= 0 ) { + if ( ret <= 0 ) return ret; - } } } - if ( pReq->m_pHeader->m_cntUnknownHeaders > 0 ) { + if ( pReq->m_pHeader->m_cntUnknownHeaders > 0 ) + { char achHeaderName[256]; char *p; char *pKey; @@ -1236,23 +1999,23 @@ int LSAPI_ForeachHeader_r( LSAPI_Request * pReq, struct lsapi_header_offset * pCur, *pEnd; pCur = pReq->m_pUnknownHeader; pEnd = pCur + pReq->m_pHeader->m_cntUnknownHeaders; - while( pCur < pEnd ) { + while( pCur < pEnd ) + { pKey = pReq->m_pHttpHeader + pCur->nameOff; keyLen = pCur->nameLen; + if ( keyLen > 250 ) + keyLen = 250; pKeyEnd = pKey + keyLen; memcpy( achHeaderName, "HTTP_", 5 ); p = &achHeaderName[5]; - if ( keyLen > 250 ) { - keyLen = 250; - } - while( pKey < pKeyEnd ) { + while( pKey < pKeyEnd ) + { char ch = *pKey++; - if ( ch == '-' ) { + if ( ch == '-' ) *p++ = '_'; - } else { + else *p++ = toupper( ch ); - } } *p = 0; keyLen += 5; @@ -1261,9 +2024,8 @@ int LSAPI_ForeachHeader_r( LSAPI_Request * pReq, *(pValue + pCur->valueLen ) = 0; ret = (*fn)( achHeaderName, keyLen, pValue, pCur->valueLen, arg ); - if ( ret <= 0 ) { + if ( ret <= 0 ) return ret; - } ++pCur; } } @@ -1276,15 +2038,14 @@ static int EnvForeach( struct LSAPI_key_value_pair * pEnv, { struct LSAPI_key_value_pair * pEnd = pEnv + n; int ret; - if ( !pEnv || !fn ) { + if ( !pEnv || !fn ) return -1; - } - while( pEnv < pEnd ) { + while( pEnv < pEnd ) + { ret = (*fn)( pEnv->pKey, pEnv->keyLen, pEnv->pValue, pEnv->valLen, arg ); - if ( ret <= 0 ) { + if ( ret <= 0 ) return ret; - } ++pEnv; } return n; @@ -1295,10 +2056,10 @@ static int EnvForeach( struct LSAPI_key_value_pair * pEnv, int LSAPI_ForeachEnv_r( LSAPI_Request * pReq, LSAPI_CB_EnvHandler fn, void * arg ) { - if ( !pReq || !fn ) { + if ( !pReq || !fn ) return -1; - } - if ( pReq->m_pHeader->m_cntEnv > 0 ) { + if ( pReq->m_pHeader->m_cntEnv > 0 ) + { return EnvForeach( pReq->m_pEnvList, pReq->m_pHeader->m_cntEnv, fn, arg ); } @@ -1310,10 +2071,10 @@ int LSAPI_ForeachEnv_r( LSAPI_Request * pReq, int LSAPI_ForeachSpecialEnv_r( LSAPI_Request * pReq, LSAPI_CB_EnvHandler fn, void * arg ) { - if ( !pReq || !fn ) { + if ( !pReq || !fn ) return -1; - } - if ( pReq->m_pHeader->m_cntSpecialEnv > 0 ) { + if ( pReq->m_pHeader->m_cntSpecialEnv > 0 ) + { return EnvForeach( pReq->m_pSpecialEnvList, pReq->m_pHeader->m_cntSpecialEnv, fn, arg ); @@ -1326,14 +2087,13 @@ int LSAPI_ForeachSpecialEnv_r( LSAPI_Request * pReq, int LSAPI_FinalizeRespHeaders_r( LSAPI_Request * pReq ) { - if ( !pReq || !pReq->m_pIovec ) { + if ( !pReq || !pReq->m_pIovec ) return -1; - } - if ( !( pReq->m_reqState & LSAPI_ST_RESP_HEADER ) ) { + if ( !( pReq->m_reqState & LSAPI_ST_RESP_HEADER ) ) return 0; - } pReq->m_reqState &= ~LSAPI_ST_RESP_HEADER; - if ( pReq->m_pRespHeaderBufPos > pReq->m_pRespHeaderBuf ) { + if ( pReq->m_pRespHeaderBufPos > pReq->m_pRespHeaderBuf ) + { pReq->m_pIovecCur->iov_base = (void *)pReq->m_pRespHeaderBuf; pReq->m_pIovecCur->iov_len = pReq->m_pRespHeaderBufPos - pReq->m_pRespHeaderBuf; pReq->m_totalLen += pReq->m_pIovecCur->iov_len; @@ -1352,25 +2112,87 @@ int LSAPI_FinalizeRespHeaders_r( LSAPI_Request * pReq ) } - - -int LSAPI_AppendRespHeader_r( LSAPI_Request * pReq, char * pBuf, int len ) +int LSAPI_AppendRespHeader2_r( LSAPI_Request * pReq, const char * pHeaderName, + const char * pHeaderValue ) { - if ( !pReq || !pBuf || len <= 0 || len > LSAPI_RESP_HTTP_HEADER_MAX ) { + int nameLen, valLen, len; + if ( !pReq || !pHeaderName || !pHeaderValue ) return -1; + if ( pReq->m_reqState & LSAPI_ST_RESP_BODY ) + return -1; + if ( pReq->m_respHeader.m_respInfo.m_cntHeaders >= LSAPI_MAX_RESP_HEADERS ) + return -1; + nameLen = strlen( pHeaderName ); + valLen = strlen( pHeaderValue ); + if ( nameLen == 0 ) + return -1; + while( nameLen > 0 ) + { + char ch = *(pHeaderName + nameLen - 1 ); + if (( ch == '\n' )||( ch == '\r' )) + --nameLen; + else + break; + } + if ( nameLen <= 0 ) + return 0; + while( valLen > 0 ) + { + char ch = *(pHeaderValue + valLen - 1 ); + if (( ch == '\n' )||( ch == '\r' )) + --valLen; + else + break; } - if ( pReq->m_reqState & LSAPI_ST_RESP_BODY ) { + len = nameLen + valLen + 1; + if ( len > LSAPI_RESP_HTTP_HEADER_MAX ) return -1; + + if ( pReq->m_pRespHeaderBufPos + len + 1 > pReq->m_pRespHeaderBufEnd ) + { + int newlen = pReq->m_pRespHeaderBufPos + len + 4096 - pReq->m_pRespHeaderBuf; + newlen -= newlen % 4096; + if ( allocateRespHeaderBuf( pReq, newlen ) == -1 ) + return -1; } - if ( pReq->m_respHeader.m_respInfo.m_cntHeaders >= LSAPI_MAX_RESP_HEADERS ) { + memmove( pReq->m_pRespHeaderBufPos, pHeaderName, nameLen ); + pReq->m_pRespHeaderBufPos += nameLen; + *pReq->m_pRespHeaderBufPos++ = ':'; + memmove( pReq->m_pRespHeaderBufPos, pHeaderValue, valLen ); + pReq->m_pRespHeaderBufPos += valLen; + *pReq->m_pRespHeaderBufPos++ = 0; + ++len; /* add one byte padding for \0 */ + pReq->m_respHeaderLen[pReq->m_respHeader.m_respInfo.m_cntHeaders] = len; + ++pReq->m_respHeader.m_respInfo.m_cntHeaders; + return 0; +} + + + +int LSAPI_AppendRespHeader_r( LSAPI_Request * pReq, const char * pBuf, int len ) +{ + if ( !pReq || !pBuf || len <= 0 || len > LSAPI_RESP_HTTP_HEADER_MAX ) return -1; + if ( pReq->m_reqState & LSAPI_ST_RESP_BODY ) + return -1; + if ( pReq->m_respHeader.m_respInfo.m_cntHeaders >= LSAPI_MAX_RESP_HEADERS ) + return -1; + while( len > 0 ) + { + char ch = *(pBuf + len - 1 ); + if (( ch == '\n' )||( ch == '\r' )) + --len; + else + break; } - if ( pReq->m_pRespHeaderBufPos + len + 1 > pReq->m_pRespHeaderBufEnd ) { + if ( len <= 0 ) + return 0; + if ( pReq->m_pRespHeaderBufPos + len + 1 > pReq->m_pRespHeaderBufEnd ) + { int newlen = pReq->m_pRespHeaderBufPos + len + 4096 - pReq->m_pRespHeaderBuf; newlen -= newlen % 4096; - if ( allocateRespHeaderBuf( pReq, newlen ) == -1 ) { + if ( allocateRespHeaderBuf( pReq, newlen ) == -1 ) return -1; - } } memmove( pReq->m_pRespHeaderBufPos, pBuf, len ); pReq->m_pRespHeaderBufPos += len; @@ -1389,7 +2211,8 @@ int LSAPI_CreateListenSock2( const struct sockaddr * pServerAddr, int backlog ) int flag = 1; int addr_len; - switch( pServerAddr->sa_family ) { + switch( pServerAddr->sa_family ) + { case AF_INET: addr_len = 16; break; @@ -1405,20 +2228,20 @@ int LSAPI_CreateListenSock2( const struct sockaddr * pServerAddr, int backlog ) } fd = socket( pServerAddr->sa_family, SOCK_STREAM, 0 ); - if ( fd == -1 ) { + if ( fd == -1 ) return -1; - } fcntl( fd, F_SETFD, FD_CLOEXEC ); if(setsockopt( fd, SOL_SOCKET, SO_REUSEADDR, - (char *)( &flag ), sizeof(flag)) == 0) { + (char *)( &flag ), sizeof(flag)) == 0) + { ret = bind( fd, pServerAddr, addr_len ); - if ( !ret ) { + if ( !ret ) + { ret = listen( fd, backlog ); - if ( !ret ) { + if ( !ret ) return fd; - } } } @@ -1438,17 +2261,16 @@ int LSAPI_ParseSockAddr( const char * pBind, struct sockaddr * pAddr ) int doAddrInfo = 0; int port; - if ( !pBind ) { + if ( !pBind ) return -1; - } - while( isspace( *pBind ) ) { + while( isspace( *pBind ) ) ++pBind; - } strncpy( achAddr, pBind, 256 ); - switch( *p ) { + switch( *p ) + { case '/': pAddr->sa_family = AF_UNIX; strncpy( ((struct sockaddr_un *)pAddr)->sun_path, p, @@ -1463,7 +2285,8 @@ int LSAPI_ParseSockAddr( const char * pBind, struct sockaddr * pAddr ) return -1; *pEnd++ = 0; - if ( *p == '*' ) { + if ( *p == '*' ) + { strcpy( achAddr, "::" ); p = achAddr; } @@ -1473,35 +2296,35 @@ int LSAPI_ParseSockAddr( const char * pBind, struct sockaddr * pAddr ) default: pAddr->sa_family = AF_INET; pEnd = strchr( p, ':' ); - if ( !pEnd ) { + if ( !pEnd ) return -1; - } *pEnd++ = 0; doAddrInfo = 0; - if ( *p == '*' ) { + if ( *p == '*' ) + { ((struct sockaddr_in *)pAddr)->sin_addr.s_addr = htonl(INADDR_ANY); - } else { - if (!strcasecmp( p, "localhost" ) ) { - ((struct sockaddr_in *)pAddr)->sin_addr.s_addr = htonl( INADDR_LOOPBACK ); - } else { - ((struct sockaddr_in *)pAddr)->sin_addr.s_addr = inet_addr( p ); - if ( ((struct sockaddr_in *)pAddr)->sin_addr.s_addr == INADDR_BROADCAST) { - doAddrInfo = 1; - } + } + else if (!strcasecmp( p, "localhost" ) ) + ((struct sockaddr_in *)pAddr)->sin_addr.s_addr = htonl( INADDR_LOOPBACK ); + else + { + ((struct sockaddr_in *)pAddr)->sin_addr.s_addr = inet_addr( p ); + if ( ((struct sockaddr_in *)pAddr)->sin_addr.s_addr == INADDR_BROADCAST) + { + doAddrInfo = 1; } } break; } - if ( *pEnd == ':' ) { + if ( *pEnd == ':' ) ++pEnd; - } port = atoi( pEnd ); - if (( port <= 0 )||( port > 65535 )) { + if (( port <= 0 )||( port > 65535 )) return -1; - } - if ( doAddrInfo ) { + if ( doAddrInfo ) + { memset(&hints, 0, sizeof(hints)); @@ -1509,7 +2332,8 @@ int LSAPI_ParseSockAddr( const char * pBind, struct sockaddr * pAddr ) hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; - if ( getaddrinfo(p, NULL, &hints, &res) ) { + if ( getaddrinfo(p, NULL, &hints, &res) ) + { return -1; } @@ -1517,11 +2341,10 @@ int LSAPI_ParseSockAddr( const char * pBind, struct sockaddr * pAddr ) freeaddrinfo(res); } - if ( pAddr->sa_family == AF_INET ) { + if ( pAddr->sa_family == AF_INET ) ((struct sockaddr_in *)pAddr)->sin_port = htons( port ); - } else { + else ((struct sockaddr_in6 *)pAddr)->sin6_port = htons( port ); - } return 0; } @@ -1532,7 +2355,8 @@ int LSAPI_CreateListenSock( const char * pBind, int backlog ) int ret; int fd = -1; ret = LSAPI_ParseSockAddr( pBind, (struct sockaddr *)serverAddr ); - if ( !ret ) { + if ( !ret ) + { fd = LSAPI_CreateListenSock2( (struct sockaddr *)serverAddr, backlog ); } return fd; @@ -1543,9 +2367,11 @@ static fn_select_t g_fnSelect = select; typedef struct _lsapi_child_status { int m_pid; + long m_tmStart; volatile short m_iKillSent; volatile short m_inProcess; + volatile int m_iReqCounter; volatile long m_tmWaitBegin; volatile long m_tmReqBegin; @@ -1568,6 +2394,8 @@ typedef struct _lsapi_prefork_server int m_iAvoidFork; lsapi_child_status * m_pChildrenStatus; + lsapi_child_status * m_pChildrenStatusCur; + lsapi_child_status * m_pChildrenStatusEnd; }lsapi_prefork_server; @@ -1575,43 +2403,42 @@ static lsapi_prefork_server * g_prefork_server = NULL; int LSAPI_Init_Prefork_Server( int max_children, fn_select_t fp, int avoidFork ) { - if ( g_prefork_server ) { + int pid; + if ( g_prefork_server ) return 0; - } - if ( max_children <= 1 ) { + if ( max_children <= 1 ) return -1; - } - if ( max_children >= 10000) { + if ( max_children >= 10000) max_children = 10000; - } g_prefork_server = (lsapi_prefork_server *)malloc( sizeof( lsapi_prefork_server ) ); - if ( !g_prefork_server ) { + if ( !g_prefork_server ) return -1; - } memset( g_prefork_server, 0, sizeof( lsapi_prefork_server ) ); - if ( fp != NULL ) { + if ( fp != NULL ) g_fnSelect = fp; - } s_ppid = getppid(); + pid = getpid(); + setpgid( pid, pid ); g_prefork_server->m_iAvoidFork = avoidFork; g_prefork_server->m_iMaxChildren = max_children; g_prefork_server->m_iExtraChildren = ( avoidFork ) ? 0 : (max_children / 3) ; g_prefork_server->m_iMaxIdleChildren = ( avoidFork ) ? (max_children + 1) : (max_children / 3); + if ( g_prefork_server->m_iMaxIdleChildren == 0 ) + g_prefork_server->m_iMaxIdleChildren = 1; g_prefork_server->m_iChildrenMaxIdleTime = 300; - g_prefork_server->m_iMaxReqProcessTime = 300; + g_prefork_server->m_iMaxReqProcessTime = 3600; return 0; } void LSAPI_Set_Server_fd( int fd ) { - if( g_prefork_server ) { + if( g_prefork_server ) g_prefork_server->m_fd = fd; - } } @@ -1624,11 +2451,17 @@ static int lsapi_accept( int fdListen ) len = sizeof( achPeer ); fd = accept( fdListen, (struct sockaddr *)&achPeer, &len ); - if ( fd != -1 ) { - if (((struct sockaddr *)&achPeer)->sa_family == AF_INET ) { + if ( fd != -1 ) + { + if (((struct sockaddr *)&achPeer)->sa_family == AF_INET ) + { setsockopt( fd, IPPROTO_TCP, TCP_NODELAY, (char *)&nodelay, sizeof(nodelay)); } + + //OPTIMIZATION + //if ( s_accept_notify ) + // notify_req_received( fd ); } return fd; @@ -1651,9 +2484,13 @@ static void lsapi_cleanup(int signal) static lsapi_child_status * find_child_status( int pid ) { lsapi_child_status * pStatus = g_prefork_server->m_pChildrenStatus; - lsapi_child_status * pEnd = g_prefork_server->m_pChildrenStatus + g_prefork_server->m_iMaxChildren * 2; - while( pStatus < pEnd ) { - if ( pStatus->m_pid == pid ) { + lsapi_child_status * pEnd = g_prefork_server->m_pChildrenStatusEnd; + while( pStatus < pEnd ) + { + if ( pStatus->m_pid == pid ) + { + if ( pStatus + 1 > g_prefork_server->m_pChildrenStatusCur ) + g_prefork_server->m_pChildrenStatusCur = pStatus + 1; return pStatus; } ++pStatus; @@ -1667,17 +2504,35 @@ static void lsapi_sigchild( int signal ) { int status, pid; lsapi_child_status * child_status; - while( 1 ) { + while( 1 ) + { pid = waitpid( -1, &status, WNOHANG|WUNTRACED ); - if ( pid <= 0 ) { + if ( pid <= 0 ) + { break; } + if ( WIFSIGNALED( status )) + { + int sig_num = WTERMSIG( status ); + int dump = WCOREDUMP( status ); + fprintf( stderr, "Child process with pid: %d was killed by signal: %d, core dump: %d\n", pid, sig_num, dump ); + } + if ( pid == s_pid_dump_debug_info ) + { + pid = 0; + continue; + } child_status = find_child_status( pid ); - if ( child_status ) { + if ( child_status ) + { child_status->m_pid = 0; + --g_prefork_server->m_iCurChildren; + } - --g_prefork_server->m_iCurChildren; } + while(( g_prefork_server->m_pChildrenStatusCur > g_prefork_server->m_pChildrenStatus ) + &&( g_prefork_server->m_pChildrenStatusCur[-1].m_pid == 0 )) + --g_prefork_server->m_pChildrenStatusCur; } @@ -1686,80 +2541,116 @@ static int lsapi_init_children_status() int size = 4096; char * pBuf; - size = g_prefork_server->m_iMaxChildren * sizeof( lsapi_child_status ) * 2; + size = (g_prefork_server->m_iMaxChildren + g_prefork_server->m_iExtraChildren ) * sizeof( lsapi_child_status ) * 2; size = (size + 4095 ) / 4096 * 4096; pBuf =( char*) mmap( NULL, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0 ); - if ( pBuf == MAP_FAILED ) { + if ( pBuf == MAP_FAILED ) + { perror( "Anonymous mmap() failed" ); return -1; } memset( pBuf, 0, size ); - g_prefork_server->m_pChildrenStatus = (lsapi_child_status *)pBuf; + g_prefork_server->m_pChildrenStatus = (lsapi_child_status *)pBuf; + g_prefork_server->m_pChildrenStatusCur = (lsapi_child_status *)pBuf; + g_prefork_server->m_pChildrenStatusEnd = (lsapi_child_status *)pBuf + size / sizeof( lsapi_child_status ); return 0; } +static void dump_debug_info( lsapi_child_status * pStatus, long tmCur ) +{ + char achCmd[1024]; + if ( s_pid_dump_debug_info ) + { + if ( kill( s_pid_dump_debug_info, 0 ) == 0 ) + return; + } + s_pid_dump_debug_info = fork(); + + fprintf( stderr, "[%s] Possible runaway process, PPID: %d, PID: %d, reqCount: %d, process time: %ld, checkpoint time: %ld, start time: %ld\n", + ctime(&tmCur), getpid(), pStatus->m_pid, pStatus->m_iReqCounter, + tmCur - pStatus->m_tmReqBegin, tmCur - pStatus->m_tmLastCheckPoint, tmCur - pStatus->m_tmStart ); + snprintf( achCmd, 1024, "gdb --batch -ex \"attach %d\" -ex \"set height 0\" -ex \"bt\" >&2;PATH=$PATH:/usr/sbin lsof -p %d >&2", pStatus->m_pid, pStatus->m_pid ); + if ( system( achCmd ) == -1 ) + perror( "system()" ); + exit( 0 ); +} + static void lsapi_check_child_status( long tmCur ) { int idle = 0; int tobekilled; int dying = 0; + int count = 0; lsapi_child_status * pStatus = g_prefork_server->m_pChildrenStatus; - lsapi_child_status * pEnd = g_prefork_server->m_pChildrenStatus + g_prefork_server->m_iMaxChildren * 2; - while( pStatus < pEnd ) { - tobekilled = pStatus->m_iKillSent; - if ( pStatus->m_pid != 0 ) { - if ( !tobekilled ) { - if ( !pStatus->m_inProcess ) { - - if (( g_prefork_server->m_iCurChildren - dying > g_prefork_server->m_iMaxChildren)|| - ( idle >= g_prefork_server->m_iMaxIdleChildren )) { - - tobekilled = 1; - } else { - if (( s_max_idle_secs> 0)&&(tmCur - pStatus->m_tmWaitBegin > s_max_idle_secs + 5 )) { - tobekilled = 1; - } - } - if ( !tobekilled ) { - ++idle; - } - } else { - if ( tmCur - pStatus->m_tmReqBegin > - g_prefork_server->m_iMaxReqProcessTime ) { - tobekilled = 1; - } + lsapi_child_status * pEnd = g_prefork_server->m_pChildrenStatusCur; + while( pStatus < pEnd ) + { + tobekilled = 0; + if ( pStatus->m_pid != 0 ) + { + ++count; + if ( !pStatus->m_inProcess ) + { + + if (( g_prefork_server->m_iCurChildren - dying > g_prefork_server->m_iMaxChildren)|| + ( idle > g_prefork_server->m_iMaxIdleChildren )) + { + ++pStatus->m_iKillSent; + //tobekilled = SIGUSR1; } - } else { - if ( pStatus->m_inProcess ) { - tobekilled = pStatus->m_iKillSent = 0; + else + { + if (( s_max_idle_secs> 0)&&(tmCur - pStatus->m_tmWaitBegin > s_max_idle_secs + 5 )) + { + ++pStatus->m_iKillSent; + //tobekilled = SIGUSR1; + } } + if ( !tobekilled ) + ++idle; } - if ( tobekilled ) { - tobekilled = 0; - if ( pStatus->m_iKillSent > 5 ) { - tobekilled = SIGKILL; - } else { - if ( pStatus->m_iKillSent == 3 ) { + else + { + if ( tmCur - pStatus->m_tmReqBegin > + g_prefork_server->m_iMaxReqProcessTime ) + { + if (( ( pStatus->m_iKillSent % 5 ) == 0 )&&( s_dump_debug_info )) + dump_debug_info( pStatus, tmCur ); + if ( pStatus->m_iKillSent > 5 ) + { + tobekilled = SIGKILL; + fprintf( stderr, "Force killing runaway process PID: %d with SIGKILL\n", pStatus->m_pid ); + } + else + { tobekilled = SIGTERM; - } else { - if ( pStatus->m_iKillSent == 1 ) { - tobekilled = SIGUSR1; - } + fprintf( stderr, "Killing runaway process PID: %d with SIGTERM\n", pStatus->m_pid ); } } - if ( tobekilled ) { - kill( pStatus->m_pid, tobekilled ); + } + if ( tobekilled ) + { + if (( kill( pStatus->m_pid, tobekilled ) == -1 )&&( errno == ESRCH )) + { + pStatus->m_pid = 0; + --count; + } + else + { + ++pStatus->m_iKillSent; + ++dying; } - ++pStatus->m_iKillSent; - ++dying; } - - } else { - ++dying; } ++pStatus; } + if ( abs( g_prefork_server->m_iCurChildren - count ) > 1 ) + { + fprintf( stderr, "Children tracking is wrong: PID: %d, Cur Childen: %d, count: %d, idle: %d, dying: %d\n", getpid(), + g_prefork_server->m_iCurChildren, count, idle, dying ); + + } } static int lsapi_all_children_must_die() @@ -1770,14 +2661,14 @@ static int lsapi_all_children_must_die() g_prefork_server->m_iMaxIdleChildren = -1; maxWait = 15; - while( g_prefork_server->m_iCurChildren && (sec < maxWait) ) { + while( g_prefork_server->m_iCurChildren && (sec < maxWait) ) + { lsapi_check_child_status(time(NULL)); sleep( 1 ); sec++; } - if ( g_prefork_server->m_iCurChildren != 0 ) { + if ( g_prefork_server->m_iCurChildren != 0 ) kill( -getpgrp(), SIGKILL ); - } return 0; } @@ -1796,13 +2687,17 @@ static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, LSAPI_Re fd_set readfds; struct timeval timeout; + sigset_t mask; + sigset_t orig_mask; + lsapi_init_children_status(); setsid(); act.sa_flags = 0; act.sa_handler = lsapi_sigchild; - if( sigaction( SIGCHLD, &act, &old_child ) ) { + if( sigaction( SIGCHLD, &act, &old_child ) ) + { perror( "Can't set signal handler for SIGCHILD" ); return -1; } @@ -1813,36 +2708,38 @@ static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, LSAPI_Re if( sigaction( SIGTERM, &act, &old_term ) || sigaction( SIGINT, &act, &old_int ) || sigaction( SIGUSR1, &act, &old_usr1 ) || - sigaction( SIGQUIT, &act, &old_quit )) { + sigaction( SIGQUIT, &act, &old_quit )) + { perror( "Can't set signals" ); return -1; } s_stop = 0; - while( !s_stop ) { - if ( ret ) { - curTime = time( NULL ); - } else { - ++curTime; - } - if (curTime != lastTime ) { + while( !s_stop ) + { + curTime = time( NULL ); + if (curTime != lastTime ) + { lastTime = curTime; - if (s_ppid && (getppid() != s_ppid )) { + if (s_ppid && (getppid() != s_ppid )) break; - } lsapi_check_child_status(curTime ); - if (pServer->m_iServerMaxIdle) { - if ( pServer->m_iCurChildren <= 0 ) { + if (pServer->m_iServerMaxIdle) + { + if ( pServer->m_iCurChildren <= 0 ) + { ++wait_secs; - if ( wait_secs > pServer->m_iServerMaxIdle ) { + if ( wait_secs > pServer->m_iServerMaxIdle ) return -1; - } - } else { - wait_secs = 0; } + else + wait_secs = 0; } } - if ( pServer->m_iCurChildren >= (pServer->m_iMaxChildren + pServer->m_iExtraChildren ) ) { + if ( pServer->m_iCurChildren >= (pServer->m_iMaxChildren + pServer->m_iExtraChildren ) ) + { + fprintf( stderr, "Reached max children process limit: %d, extra: %d, current: %d, please increase LSAPI_CHILDREN.\n", + pServer->m_iMaxChildren, pServer->m_iExtraChildren, pServer->m_iCurChildren ); usleep( 100000 ); continue; } @@ -1850,66 +2747,100 @@ static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, LSAPI_Re FD_ZERO( &readfds ); FD_SET( pServer->m_fd, &readfds ); timeout.tv_sec = 1; timeout.tv_usec = 0; - if ((ret = (*g_fnSelect)(pServer->m_fd+1, &readfds, NULL, NULL, &timeout)) == 1 ) { - if ( pServer->m_iCurChildren >= 0 ) { + if ((ret = (*g_fnSelect)(pServer->m_fd+1, &readfds, NULL, NULL, &timeout)) == 1 ) + { + /* + if ( pServer->m_iCurChildren >= 0 ) + { usleep( 10 ); FD_ZERO( &readfds ); FD_SET( pServer->m_fd, &readfds ); timeout.tv_sec = 0; timeout.tv_usec = 0; - if ( (*g_fnSelect)(pServer->m_fd+1, &readfds, NULL, NULL, &timeout) == 0 ) { - continue; - } - } - } else { - if ( ret == -1 ) { - if ( errno == EINTR ) { + if ( (*g_fnSelect)(pServer->m_fd+1, &readfds, NULL, NULL, &timeout) == 0 ) continue; - } - /* perror( "select()" ); */ - break; - } else { + }*/ + } + else if ( ret == -1 ) + { + if ( errno == EINTR ) continue; - } + /* perror( "select()" ); */ + break; + } + else + { + continue; } pReq->m_fd = lsapi_accept( pServer->m_fd ); - if ( pReq->m_fd != -1 ) { + if ( pReq->m_fd != -1 ) + { child_status = find_child_status( 0 ); + if ( child_status ) + memset( child_status, 0, sizeof( *child_status ) ); + + sigemptyset( &mask ); + sigaddset( &mask, SIGCHLD ); + + if ( sigprocmask(SIG_BLOCK, &mask, &orig_mask) < 0 ) + { + perror( "sigprocmask(SIG_BLOCK) to block SIGCHLD" ); + } + pid = fork(); - if ( !pid ) { + + if ( !pid ) + { + if (sigprocmask(SIG_SETMASK, &orig_mask, NULL) < 0) + perror( "sigprocmask( SIG_SETMASK ) to restore SIGMASK in child" ); g_prefork_server = NULL; s_ppid = getppid(); s_req_processed = 0; s_pChildStatus = child_status; - child_status->m_iKillSent = 0; lsapi_set_nblock( pReq->m_fd, 0 ); - + if ( pReq->m_fdListen != -1 ) + { + close( pReq->m_fdListen ); + pReq->m_fdListen = -1; + } /* don't catch our signals */ sigaction( SIGCHLD, &old_child, 0 ); sigaction( SIGTERM, &old_term, 0 ); sigaction( SIGQUIT, &old_quit, 0 ); sigaction( SIGINT, &old_int, 0 ); sigaction( SIGUSR1, &old_usr1, 0 ); + //init_conn_key( pReq->m_fd ); + lsapi_notify_pid( pReq->m_fd ); + s_notified_pid = 1; + //if ( s_accept_notify ) + // return notify_req_received( pReq->m_fd ); return 0; - } else { - if ( pid == -1 ) { - perror( "fork() failed, please increase process limit" ); - } else { - ++pServer->m_iCurChildren; - if ( child_status ) { - child_status->m_pid = pid; - child_status->m_iKillSent = 0; - child_status->m_tmWaitBegin = time(NULL); - } + } + else if ( pid == -1 ) + { + perror( "fork() failed, please increase process limit" ); + } + else + { + ++pServer->m_iCurChildren; + if ( child_status ) + { + child_status->m_pid = pid; + child_status->m_tmWaitBegin = curTime; + child_status->m_tmStart = curTime; } } close( pReq->m_fd ); pReq->m_fd = -1; - } else { - if (( errno == EINTR )||( errno == EAGAIN)) { + if (sigprocmask(SIG_SETMASK, &orig_mask, NULL) < 0) + perror( "sigprocmask( SIG_SETMASK ) to restore SIGMASK" ); + + } + else + { + if (( errno == EINTR )||( errno == EAGAIN)) continue; - } perror( "accept() failed" ); return -1; } @@ -1921,6 +2852,11 @@ static int lsapi_prefork_server_accept( lsapi_prefork_server * pServer, LSAPI_Re } +void lsapi_error( const char * pMessage, int err_no ) +{ + fprintf( stderr, "%d: %s, errno: %d (%s)\n", getpid(), pMessage, err_no, strerror( err_no ) ); +} + int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq ) { int fd; @@ -1932,88 +2868,105 @@ int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq ) LSAPI_Finish_r( pReq ); - if ( g_prefork_server ) { - if ( g_prefork_server->m_fd != -1 ) { - if ( lsapi_prefork_server_accept( g_prefork_server, pReq ) == -1 ) { + if ( g_prefork_server ) + { + if ( g_prefork_server->m_fd != -1 ) + if ( lsapi_prefork_server_accept( g_prefork_server, pReq ) == -1 ) return -1; - } - } } - if ( s_req_processed >= s_max_reqs ) { + if ( s_req_processed >= s_max_reqs ) return -1; - } - if ( s_pChildStatus ) { + if ( s_pChildStatus ) + { s_pChildStatus->m_tmWaitBegin = time( NULL ); } + - while( g_running ) { - if ( pReq->m_fd != -1 ) { + while( g_running ) + { + if ( pReq->m_fd != -1 ) + { fd = pReq->m_fd; - } else { - if ( pReq->m_fdListen != -1 ) { - fd = pReq->m_fdListen; - } else { - return -1; - } + } + else if ( pReq->m_fdListen != -1 ) + fd = pReq->m_fdListen; + else + { + break; } wait_secs = 0; - while( 1 ) { - if ( !g_running ) { + while( 1 ) + { + if ( !g_running ) return -1; - } - if (( s_pChildStatus )&&( s_pChildStatus->m_iKillSent )) { + if ((s_req_processed)&&( s_pChildStatus )&&( s_pChildStatus->m_iKillSent )) return -1; - } FD_ZERO( &readfds ); FD_SET( fd, &readfds ); timeout.tv_sec = 1; timeout.tv_usec = 0; ret = (*g_fnSelect)(fd+1, &readfds, NULL, NULL, &timeout); - if ( ret == 0 ) { - if ( s_pChildStatus ) { + if ( ret == 0 ) + { + if ( s_pChildStatus ) + { s_pChildStatus->m_inProcess = 0; } ++wait_secs; - if (( s_max_idle_secs > 0 )&&(wait_secs >= s_max_idle_secs )) { + if (( s_max_idle_secs > 0 )&&(wait_secs >= s_max_idle_secs )) return -1; - } - if ( s_ppid &&( getppid() != s_ppid)) { + if ( s_ppid &&( getppid() != s_ppid)) return -1; - } - } else { - if ( ret == -1 ) { - if ( errno == EINTR ) { - continue; - } else { - return -1; - } - } else { - if ( ret >= 1 ) { - if (( s_pChildStatus )&&( s_pChildStatus->m_iKillSent )) { - return -1; + } + else if ( ret == -1 ) + { + if ( errno == EINTR ) + continue; + else + return -1; + } + else if ( ret >= 1 ) + { + if (s_req_processed && ( s_pChildStatus )&&( s_pChildStatus->m_iKillSent )) + return -1; + if ( fd == pReq->m_fdListen ) + { + pReq->m_fd = lsapi_accept( pReq->m_fdListen ); + if ( pReq->m_fd != -1 ) + { + fd = pReq->m_fd; + lsapi_set_nblock( fd, 0 ); + //init_conn_key( pReq->m_fd ); + if ( !s_keepListener ) + { + close( pReq->m_fdListen ); + pReq->m_fdListen = -1; } - if ( fd == pReq->m_fdListen ) { - pReq->m_fd = lsapi_accept( pReq->m_fdListen ); - if ( pReq->m_fd != -1 ) { - fd = pReq->m_fd; - lsapi_set_nblock( fd, 0 ); - } else { - if (( errno == EINTR )||( errno == EAGAIN)) { - continue; - } + if ( s_accept_notify ) + if ( notify_req_received( pReq->m_fd ) == -1 ) return -1; - } - } else { - break; - } + } + else + { + if (( errno == EINTR )||( errno == EAGAIN)) + continue; + lsapi_error( "lsapi_accept() error", errno ); + return -1; } } + else + break; } } - if ( !readReq( pReq ) ) { - if ( s_pChildStatus ) { + + if ( !readReq( pReq ) ) + { + if ( s_pChildStatus ) + { + s_pChildStatus->m_iKillSent = 0; s_pChildStatus->m_inProcess = 1; + ++s_pChildStatus->m_iReqCounter; s_pChildStatus->m_tmReqBegin = s_pChildStatus->m_tmLastCheckPoint = time(NULL); } ++s_req_processed; @@ -2028,49 +2981,50 @@ int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq ) } void LSAPI_Set_Max_Reqs( int reqs ) -{ - s_max_reqs = reqs; -} +{ s_max_reqs = reqs; } void LSAPI_Set_Max_Idle( int secs ) -{ - s_max_idle_secs = secs; -} +{ s_max_idle_secs = secs; } void LSAPI_Set_Max_Children( int maxChildren ) { - if ( g_prefork_server ) { + if ( g_prefork_server ) g_prefork_server->m_iMaxChildren = maxChildren; - } } void LSAPI_Set_Extra_Children( int extraChildren ) { - if (( g_prefork_server )&&( extraChildren >= 0 )) { + if (( g_prefork_server )&&( extraChildren >= 0 )) g_prefork_server->m_iExtraChildren = extraChildren; - } } void LSAPI_Set_Max_Process_Time( int secs ) { - if (( g_prefork_server )&&( secs > 0 )) { + if (( g_prefork_server )&&( secs > 0 )) g_prefork_server->m_iMaxReqProcessTime = secs; - } } void LSAPI_Set_Max_Idle_Children( int maxIdleChld ) { - if (( g_prefork_server )&&( maxIdleChld > 0 )) { + if (( g_prefork_server )&&( maxIdleChld > 0 )) g_prefork_server->m_iMaxIdleChildren = maxIdleChld; - } } void LSAPI_Set_Server_Max_Idle_Secs( int serverMaxIdle ) { - if ( g_prefork_server ) { + if ( g_prefork_server ) g_prefork_server->m_iServerMaxIdle = serverMaxIdle; - } +} + +void LSAPI_Set_Slow_Req_Msecs( int msecs ) +{ + s_slow_req_msecs = msecs; +} + +int LSAPI_Get_Slow_Req_Msecs() +{ + return s_slow_req_msecs; } @@ -2092,101 +3046,421 @@ static void unset_lsapi_envs() #else env = environ; #endif - while( env != NULL && *env != NULL ) { - if ( !strncmp(*env, "LSAPI_", 6) || - !strncmp( *env, "PHP_LSAPI_", 10 ) ) { + while( env != NULL && *env != NULL ) + { + if (!strncmp(*env, "LSAPI_", 6) || !strncmp( *env, "PHP_LSAPI_", 10 ) + || (!strncmp( *env, "PHPRC=", 6 )&&(!s_uid))) + { char ** del = env; - do { + do *del = del[1]; - } while( *del++ ); - } else { - ++env; + while( *del++ ); } + else + ++env; } } -void LSAPI_Init_Env_Parameters( fn_select_t fp ) +static int lsapi_initSuEXEC() +{ + int i; + struct passwd * pw; + s_defaultUid = 0; + s_defaultGid = 0; + if ( s_uid == 0 ) + { + const char * p = getenv( "LSAPI_DEFAULT_UID" ); + if ( p ) + { + i = atoi( p ); + if ( i > 0 ) + s_defaultUid = i; + } + p = getenv( "LSAPI_DEFAULT_GID" ); + if ( p ) + { + i = atoi( p ); + if ( i > 0 ) + s_defaultGid = i; + } + p = getenv( "LSAPI_SECRET" ); + if (( !p )||( readSecret(p) == -1 )) + return -1; + if ( g_prefork_server ) + { + if ( g_prefork_server->m_iMaxChildren < 100 ) + g_prefork_server->m_iMaxChildren = 100; + if ( g_prefork_server->m_iExtraChildren < 1000 ) + g_prefork_server->m_iExtraChildren = 1000; + } + } + if ( !s_defaultUid || !s_defaultGid ) + { + pw = getpwnam( "nobody" ); + if ( !s_defaultUid ) + s_defaultUid = pw->pw_uid; + if ( !s_defaultGid ) + s_defaultGid = pw->pw_gid; + } + return 0; +} + + +int LSAPI_Init_Env_Parameters( fn_select_t fp ) { const char *p; int n; int avoidFork = 0; p = getenv( "PHP_LSAPI_MAX_REQUESTS" ); - if ( !p ) { + if ( !p ) p = getenv( "LSAPI_MAX_REQS" ); - } - if ( p ) { + if ( p ) + { n = atoi( p ); - if ( n > 0 ) { + if ( n > 0 ) LSAPI_Set_Max_Reqs( n ); - } } p = getenv( "LSAPI_AVOID_FORK" ); - if ( p ) { + if ( p ) + { avoidFork = atoi( p ); } + p = getenv( "LSAPI_ACCEPT_NOTIFY" ); + if ( p ) + { + s_accept_notify = atoi( p ); + } + + p = getenv( "LSAPI_SLOW_REQ_MSECS" ); + if ( p ) + { + n = atoi( p ); + LSAPI_Set_Slow_Req_Msecs( n ); + } + #if defined( RLIMIT_CORE ) p = getenv( "LSAPI_ALLOW_CORE_DUMP" ); - if ( !p ) { + if ( !p ) + { struct rlimit limit = { 0, 0 }; setrlimit( RLIMIT_CORE, &limit ); } -#endif + else + s_enable_core_dump = 1; + +#endif p = getenv( "LSAPI_MAX_IDLE" ); - if ( p ) { + if ( p ) + { n = atoi( p ); LSAPI_Set_Max_Idle( n ); } - if ( LSAPI_Is_Listen() ) { + p = getenv( "LSAPI_KEEP_LISTEN" ); + if ( p ) + { + n = atoi( p ); + s_keepListener = n; + } + + + if ( LSAPI_Is_Listen() ) + { n = 0; p = getenv( "PHP_LSAPI_CHILDREN" ); - if ( !p ) { + if ( !p ) p = getenv( "LSAPI_CHILDREN" ); - } - if ( p ) { + if ( p ) n = atoi( p ); - } - if ( n > 1 ) { + if ( n > 1 ) + { LSAPI_Init_Prefork_Server( n, fp, avoidFork ); LSAPI_Set_Server_fd( g_req.m_fdListen ); } p = getenv( "LSAPI_EXTRA_CHILDREN" ); - if ( p ) { + if ( p ) LSAPI_Set_Extra_Children( atoi( p ) ); - } p = getenv( "LSAPI_MAX_IDLE_CHILDREN" ); - if ( p ) { + if ( p ) LSAPI_Set_Max_Idle_Children( atoi( p ) ); - } + p = getenv( "LSAPI_PGRP_MAX_IDLE" ); - if ( p ) { + if ( p ) + { LSAPI_Set_Server_Max_Idle_Secs( atoi( p ) ); } p = getenv( "LSAPI_MAX_PROCESS_TIME" ); - if ( p ) { + if ( p ) LSAPI_Set_Max_Process_Time( atoi( p ) ); - } - if ( getenv( "LSAPI_PPID_NO_CHECK" ) ) { + + if ( getenv( "LSAPI_PPID_NO_CHECK" ) ) + { LSAPI_No_Check_ppid(); } + + p = getenv( "LSAPI_DUMP_DEBUG_INFO" ); + if ( p ) + s_dump_debug_info = atoi( p ); + + if ( lsapi_initSuEXEC() == -1 ) + return -1; +#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__) + lsapi_initLVE(); +#endif } unset_lsapi_envs(); + return 0; +} + + +int LSAPI_ErrResponse_r( LSAPI_Request * pReq, int code, const char ** pRespHeaders, + const char * pBody, int bodyLen ) +{ + LSAPI_SetRespStatus_r( pReq, code ); + if ( pRespHeaders ) + { + while( *pRespHeaders ) + { + LSAPI_AppendRespHeader_r( pReq, *pRespHeaders, strlen( *pRespHeaders ) ); + ++pRespHeaders; + } + } + if ( pBody &&( bodyLen > 0 )) + { + LSAPI_Write_r( pReq, pBody, bodyLen ); + } + LSAPI_Finish_r( pReq ); + return 0; +} + + +static void lsapi_MD5Transform(uint32 buf[4], uint32 const in[16]); + +/* + * Note: this code is harmless on little-endian machines. + */ +static void byteReverse(unsigned char *buf, unsigned longs) +{ + uint32 t; + do { + t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 | + ((unsigned) buf[1] << 8 | buf[0]); + *(uint32 *) buf = t; + buf += 4; + } while (--longs); +} + +/* + * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious + * initialization constants. + */ +void lsapi_MD5Init(struct lsapi_MD5Context *ctx) +{ + ctx->buf[0] = 0x67452301; + ctx->buf[1] = 0xefcdab89; + ctx->buf[2] = 0x98badcfe; + ctx->buf[3] = 0x10325476; + + ctx->bits[0] = 0; + ctx->bits[1] = 0; } +/* + * Update context to reflect the concatenation of another buffer full + * of bytes. + */ +void lsapi_MD5Update(struct lsapi_MD5Context *ctx, unsigned char const *buf, unsigned len) +{ + register uint32 t; + + /* Update bitcount */ + + t = ctx->bits[0]; + if ((ctx->bits[0] = t + ((uint32) len << 3)) < t) + ctx->bits[1]++; /* Carry from low to high */ + ctx->bits[1] += len >> 29; + + t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ + + /* Handle any leading odd-sized chunks */ + + if (t) { + unsigned char *p = (unsigned char *) ctx->in + t; + + t = 64 - t; + if (len < t) { + memmove(p, buf, len); + return; + } + memmove(p, buf, t); + byteReverse(ctx->in, 16); + lsapi_MD5Transform(ctx->buf, (uint32 *) ctx->in); + buf += t; + len -= t; + } + /* Process data in 64-byte chunks */ + + while (len >= 64) { + memmove(ctx->in, buf, 64); + byteReverse(ctx->in, 16); + lsapi_MD5Transform(ctx->buf, (uint32 *) ctx->in); + buf += 64; + len -= 64; + } + + /* Handle any remaining bytes of data. */ + + memmove(ctx->in, buf, len); +} /* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - * vim600: sw=4 ts=4 fdm=marker - * vim<600: sw=4 ts=4 + * Final wrapup - pad to 64-byte boundary with the bit pattern + * 1 0* (64-bit count of bits processed, MSB-first) */ +void lsapi_MD5Final(unsigned char digest[16], struct lsapi_MD5Context *ctx) +{ + unsigned int count; + unsigned char *p; + /* Compute number of bytes mod 64 */ + count = (ctx->bits[0] >> 3) & 0x3F; + + /* Set the first char of padding to 0x80. This is safe since there is + always at least one byte free */ + p = ctx->in + count; + *p++ = 0x80; + + /* Bytes of padding needed to make 64 bytes */ + count = 64 - 1 - count; + + /* Pad out to 56 mod 64 */ + if (count < 8) { + /* Two lots of padding: Pad the first block to 64 bytes */ + memset(p, 0, count); + byteReverse(ctx->in, 16); + lsapi_MD5Transform(ctx->buf, (uint32 *) ctx->in); + + /* Now fill the next block with 56 bytes */ + memset(ctx->in, 0, 56); + } else { + /* Pad block to 56 bytes */ + memset(p, 0, count - 8); + } + byteReverse(ctx->in, 14); + + /* Append length in bits and transform */ + ((uint32 *) ctx->in)[14] = ctx->bits[0]; + ((uint32 *) ctx->in)[15] = ctx->bits[1]; + + lsapi_MD5Transform(ctx->buf, (uint32 *) ctx->in); + byteReverse((unsigned char *) ctx->buf, 4); + memmove(digest, ctx->buf, 16); + memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ +} + +/* The four core functions - F1 is optimized somewhat */ + +/* #define F1(x, y, z) (x & y | ~x & z) */ +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +/* This is the central step in the MD5 algorithm. */ +#define MD5STEP(f, w, x, y, z, data, s) \ + ( w += f(x, y, z) + data, w = w<>(32-s), w += x ) + +/* + * The core of the MD5 algorithm, this alters an existing MD5 hash to + * reflect the addition of 16 longwords of new data. MD5Update blocks + * the data and converts bytes into longwords for this routine. + */ +static void lsapi_MD5Transform(uint32 buf[4], uint32 const in[16]) +{ + register uint32 a, b, c, d; + + a = buf[0]; + b = buf[1]; + c = buf[2]; + d = buf[3]; + + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); + MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); + MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); + MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); + MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); + MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); + + MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); + MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); + MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); + MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); + MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); + MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); + MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); + MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); + MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); + MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; +} diff --git a/sapi/litespeed/lsapilib.h b/sapi/litespeed/lsapilib.h index 538a170b44cd8..b0638fd436a09 100644 --- a/sapi/litespeed/lsapilib.h +++ b/sapi/litespeed/lsapilib.h @@ -1,24 +1,5 @@ - -/* - +----------------------------------------------------------------------+ - | PHP Version 5 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available at through the world-wide-web at the following url: | - | http://www.php.net/license/3_01.txt. | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Author: George Wang | - +----------------------------------------------------------------------+ -*/ - /* -Copyright (c) 2007, Lite Speed Technologies Inc. +Copyright (c) 2013, Lite Speed Technologies Inc. All rights reserved. Redistribution and use in source and binary forms, with or without @@ -49,6 +30,13 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/*************************************************************************** + lsapilib.h - description + ------------------- + begin : Mon Feb 21 2005 + copyright : (C) 2005 by George Wang + email : gwang@litespeedtech.com + ***************************************************************************/ #ifndef _LSAPILIB_H_ @@ -118,7 +106,8 @@ typedef struct lsapi_request char * m_pRequestMethod; int m_totalLen; int m_reqState; - int m_reqBodyRead; + off_t m_reqBodyLen; + off_t m_reqBodyRead; int m_bufProcessed; int m_bufRead; @@ -126,6 +115,7 @@ typedef struct lsapi_request struct lsapi_resp_header m_respHeader; short m_respHeaderLen[LSAPI_MAX_RESP_HEADERS]; + void * m_pAppData; }LSAPI_Request; @@ -170,22 +160,30 @@ int LSAPI_ForeachSpecialEnv_r( LSAPI_Request * pReq, char * LSAPI_GetEnv_r( LSAPI_Request * pReq, const char * name ); -int LSAPI_ReadReqBody_r( LSAPI_Request * pReq, char * pBuf, int len ); +ssize_t LSAPI_ReadReqBody_r( LSAPI_Request * pReq, char * pBuf, size_t len ); int LSAPI_ReqBodyGetChar_r( LSAPI_Request * pReq ); -int LSAPI_ReqBodyGetLine_r( LSAPI_Request * pReq, char * pBuf, int bufLen, int *getLF ); +int LSAPI_ReqBodyGetLine_r( LSAPI_Request * pReq, char * pBuf, size_t bufLen, int *getLF ); int LSAPI_FinalizeRespHeaders_r( LSAPI_Request * pReq ); -int LSAPI_Write_r( LSAPI_Request * pReq, const char * pBuf, int len ); +ssize_t LSAPI_Write_r( LSAPI_Request * pReq, const char * pBuf, size_t len ); -int LSAPI_Write_Stderr_r( LSAPI_Request * pReq, const char * pBuf, int len ); +ssize_t LSAPI_sendfile_r( LSAPI_Request * pReq, int fdIn, off_t* off, size_t size ); + +ssize_t LSAPI_Write_Stderr_r( LSAPI_Request * pReq, const char * pBuf, size_t len ); int LSAPI_Flush_r( LSAPI_Request * pReq ); -int LSAPI_AppendRespHeader_r( LSAPI_Request * pHeader, char * pBuf, int len ); +int LSAPI_AppendRespHeader_r( LSAPI_Request * pReq, const char * pBuf, int len ); + +int LSAPI_AppendRespHeader2_r( LSAPI_Request * pReq, const char * pHeaderName, + const char * pHeaderValue ); + +int LSAPI_ErrResponse_r( LSAPI_Request * pReq, int code, const char ** pRespHeaders, + const char * pBody, int bodyLen ); static inline int LSAPI_SetRespStatus_r( LSAPI_Request * pReq, int code ) { @@ -195,6 +193,21 @@ static inline int LSAPI_SetRespStatus_r( LSAPI_Request * pReq, int code ) return 0; } +static inline int LSAPI_SetAppData_r( LSAPI_Request * pReq, void * data ) +{ + if ( !pReq ) + return -1; + pReq->m_pAppData = data; + return 0; +} + +static inline void * LSAPI_GetAppData_r( LSAPI_Request * pReq ) +{ + if ( !pReq ) + return NULL; + return pReq->m_pAppData; +} + static inline char * LSAPI_GetQueryString_r( LSAPI_Request * pReq ) { if ( pReq ) @@ -228,21 +241,22 @@ static inline char * LSAPI_GetRequestMethod_r( LSAPI_Request * pReq) -static inline int LSAPI_GetReqBodyLen_r( LSAPI_Request * pReq ) +static inline off_t LSAPI_GetReqBodyLen_r( LSAPI_Request * pReq ) { if ( pReq ) - return pReq->m_pHeader->m_reqBodyLen; + return pReq->m_reqBodyLen; return -1; } -static inline int LSAPI_GetReqBodyRemain_r( LSAPI_Request * pReq ) +static inline off_t LSAPI_GetReqBodyRemain_r( LSAPI_Request * pReq ) { if ( pReq ) - return pReq->m_pHeader->m_reqBodyLen - pReq->m_reqBodyRead; + return pReq->m_reqBodyLen - pReq->m_reqBodyRead; return -1; } + int LSAPI_Is_Listen(void); static inline int LSAPI_Accept( void ) @@ -282,13 +296,13 @@ static inline char * LSAPI_GetScriptName() static inline char * LSAPI_GetRequestMethod() { return LSAPI_GetRequestMethod_r( &g_req ); } -static inline int LSAPI_GetReqBodyLen() +static inline off_t LSAPI_GetReqBodyLen() { return LSAPI_GetReqBodyLen_r( &g_req ); } -static inline int LSAPI_GetReqBodyRemain() +static inline off_t LSAPI_GetReqBodyRemain() { return LSAPI_GetReqBodyRemain_r( &g_req ); } -static inline int LSAPI_ReadReqBody( char * pBuf, int len ) +static inline ssize_t LSAPI_ReadReqBody( char * pBuf, size_t len ) { return LSAPI_ReadReqBody_r( &g_req, pBuf, len ); } static inline int LSAPI_ReqBodyGetChar() @@ -302,10 +316,15 @@ static inline int LSAPI_ReqBodyGetLine( char * pBuf, int len, int *getLF ) static inline int LSAPI_FinalizeRespHeaders(void) { return LSAPI_FinalizeRespHeaders_r( &g_req ); } -static inline int LSAPI_Write( const char * pBuf, int len ) +static inline ssize_t LSAPI_Write( const char * pBuf, ssize_t len ) { return LSAPI_Write_r( &g_req, pBuf, len ); } -static inline int LSAPI_Write_Stderr( const char * pBuf, int len ) +static inline ssize_t LSAPI_sendfile( int fdIn, off_t* off, size_t size ) +{ + return LSAPI_sendfile_r(&g_req, fdIn, off, size ); +} + +static inline ssize_t LSAPI_Write_Stderr( const char * pBuf, ssize_t len ) { return LSAPI_Write_Stderr_r( &g_req, pBuf, len ); } static inline int LSAPI_Flush() @@ -317,6 +336,9 @@ static inline int LSAPI_AppendRespHeader( char * pBuf, int len ) static inline int LSAPI_SetRespStatus( int code ) { return LSAPI_SetRespStatus_r( &g_req, code ); } +static inline int LSAPI_ErrResponse( int code, const char ** pRespHeaders, const char * pBody, int bodyLen ) +{ return LSAPI_ErrResponse_r( &g_req, code, pRespHeaders, pBody, bodyLen ); } + int LSAPI_IsRunning(void); int LSAPI_CreateListenSock( const char * pBind, int backlog ); @@ -341,7 +363,13 @@ void LSAPI_Set_Server_Max_Idle_Secs( int serverMaxIdle ); void LSAPI_Set_Max_Process_Time( int secs ); -void LSAPI_Init_Env_Parameters( fn_select_t fp ); +int LSAPI_Init_Env_Parameters( fn_select_t fp ); + +void LSAPI_Set_Slow_Req_Msecs( int msecs ); + +int LSAPI_Get_Slow_Req_Msecs( ); + +int LSAPI_is_suEXEC_Daemon(); #if defined (c_plusplus) || defined (__cplusplus) } diff --git a/sapi/milter/php_milter.c b/sapi/milter/php_milter.c index 6856c07bb64b8..f0ce1b02f72d1 100644 --- a/sapi/milter/php_milter.c +++ b/sapi/milter/php_milter.c @@ -860,10 +860,6 @@ static int sapi_milter_ub_write(const char *str, uint str_length TSRMLS_DC) return str_length; } -static void sapi_milter_flush(void *server_context) -{ -} - static void sapi_milter_register_variables(zval *track_vars_array TSRMLS_DC) { php_register_variable ("SERVER_SOFTWARE", "Sendmail Milter", track_vars_array TSRMLS_CC); @@ -906,7 +902,7 @@ static sapi_module_struct milter_sapi_module = { NULL, /* deactivate */ sapi_milter_ub_write, /* unbuffered write */ - sapi_milter_flush, /* flush */ + NULL, /* flush */ NULL, /* get uid */ NULL, /* getenv */ @@ -1119,7 +1115,7 @@ int main(int argc, char *argv[]) break; case 'z': /* load extension file */ - zend_load_extension(ap_php_optarg); + zend_load_extension(ap_php_optarg TSRMLS_CC); break; default: diff --git a/sapi/nsapi/nsapi.c b/sapi/nsapi/nsapi.c index 1e6a680c91a69..ee0f4b09cf5ff 100644 --- a/sapi/nsapi/nsapi.c +++ b/sapi/nsapi/nsapi.c @@ -467,10 +467,9 @@ static int sapi_nsapi_ub_write(const char *str, unsigned int str_length TSRMLS_D } /* modified version of apache2 */ -static void sapi_nsapi_flush(void *server_context) +static void sapi_nsapi_flush(void *server_context TSRMLS_DC) { nsapi_request_context *rc = (nsapi_request_context *)server_context; - TSRMLS_FETCH(); if (!rc) { /* we have no context, so no flushing needed. This fixes a SIGSEGV on shutdown */ diff --git a/sapi/phpdbg/.gdbinit b/sapi/phpdbg/.gdbinit new file mode 100644 index 0000000000000..401a4bb88c067 --- /dev/null +++ b/sapi/phpdbg/.gdbinit @@ -0,0 +1,10 @@ +define ____phpdbg_globals + if basic_functions_module.zts + if !$tsrm_ls + set $tsrm_ls = ts_resource_ex(0, 0) + end + set $phpdbg = ((zend_phpdbg_globals*) (*((void ***) $tsrm_ls))[phpdbg_globals_id-1]) + else + set $phpdbg = phpdbg_globals + end +end diff --git a/sapi/phpdbg/.gitignore b/sapi/phpdbg/.gitignore new file mode 100644 index 0000000000000..297efcbc420ea --- /dev/null +++ b/sapi/phpdbg/.gitignore @@ -0,0 +1,5 @@ +.libs/ +./phpdbg +*.lo +*.o +build diff --git a/sapi/phpdbg/.phpdbginit b/sapi/phpdbg/.phpdbginit new file mode 100644 index 0000000000000..1ad35218eded9 --- /dev/null +++ b/sapi/phpdbg/.phpdbginit @@ -0,0 +1,105 @@ +########################################################## +# .phpdbginit +# +# Lines starting with # are ignored +# Code must start and end with <: and :> respectively +########################################################## +# Place initialization commands one per line +########################################################## +# exec sapi/phpdbg/test.php +# set color prompt white-bold +# set color notice green +# set color error red + +########################################################## +# Embedding code in .phpdbginit +########################################################## +<: +/* +* This embedded PHP is executed at init time +*/ + +/* +* Functions defined and registered by init +* will persist across cleans +*/ + +/* +function my_debugging_function() +{ + var_dump(func_get_args()); +} +*/ + +/* phpdbg_break(PHPDBG_METHOD, "phpdbg::method"); */ +/* phpdbg_break(PHPDBG_FUNC, "my_global_function"); */ +/* phpdbg_break(PHPDBG_FILE, "/path/to/file.php:10"); */ + +/* + If readline is loaded, you might want to setup completion: +*/ +if (function_exists('readline_completion_function')) { + readline_completion_function(function(){ + return array_merge( + get_defined_functions()['user'], + array_keys(get_defined_constants()) + ); + }); +} + +/* + Setting argv made trivial ... + + argv 1 2 3 4 + ^ set argv for next execution + + argv + ^ unset argv for next execution + +*/ +function argv() +{ + $argv = func_get_args(); + + if (!$argv) { + $_SERVER['argv'] = array(); + $_SERVER['argc'] = 0; + return; + } + + $_SERVER['argv'] = array_merge + ( + array("phpdbg"), + $argv + ); + $_SERVER['argc'] = count($_SERVER['argv']); + + return $_SERVER['argv']; +} +:> +########################################################## +# Now carry on initializing phpdbg ... +########################################################## +# R my_debugging_function +# R argv + +########################################################## +# PHP has many functions that might be useful +# ... you choose ... +########################################################## +# R touch +# R unlink +# R scandir +# R glob + +########################################################## +# Remember: *you have access to the shell* +########################################################## +# The output of registered function calls is not, +# by default, very pretty (unless you implement +# and register a new implementation for phpdbg) +# The output of shell commands will usually be more +# readable on the console +########################################################## +# TLDR; if you have a good shell, use it ... +########################################################## diff --git a/sapi/phpdbg/.travis.yml b/sapi/phpdbg/.travis.yml new file mode 100644 index 0000000000000..353402858e05f --- /dev/null +++ b/sapi/phpdbg/.travis.yml @@ -0,0 +1,3 @@ +language: c + +script: ./travis/ci.sh diff --git a/sapi/phpdbg/Changelog.md b/sapi/phpdbg/Changelog.md new file mode 100644 index 0000000000000..c5d8b51514b37 --- /dev/null +++ b/sapi/phpdbg/Changelog.md @@ -0,0 +1,52 @@ +ChangeLog for phpdbg +==================== + +Version 0.3.0 2013-00-00 +------------------------ + +1. Added ability to disable an enable a single breakpoint +2. Added ability to override SAPI name +3. Added extended conditional breakpoint support "break at" +4. Fix loading of zend extnsions with -z +5. Fix crash when loading .phpdbginit with command line switch +6. Fix crash on startup errors +7. Added init.d for remote console (redhat) +8. Added phpdbg_exec userland function +9. Added testing facilities +10. Added break on n-th opline support +11. Improved trace output + +Version 0.2.0 2013-11-31 +------------------------ + +1. Added "break delete " command +2. Added "break opcode " command +3. Added "set" command - control prompt and console colors +4. .phpdbginit now searched in (additional) ini dirs +5. Added source command - load additional .phpdbginit script during session +6. Added remote console mode +7. Added info memory command + +Version 0.1.0 2013-11-23 +------------------------ + +1. New commands: + - until (continue until the current line is executed) + - frame (switch to a frame in the current stack for inspection) + - info (quick access to useful information on the console) + - finish (continue until the current function has returned) + - leave (continue until the current function is returning) + - shell (shell a command) + - register (register a function for use as a command) +2. Added printers for class and method +3. Make uniform commands and aliases where possible +4. Include all alias information and sub-command information in help +5. Added signal handling to break execution (ctrl-c) +6. Fixed #13 (Output Buffering Control seems fail) +7. Fixed #14 (Fixed typo in Makefile.frag) + + +Version 0.0.1 2013-11-15 +------------------------ + +1. Initial features diff --git a/sapi/phpdbg/Makefile.frag b/sapi/phpdbg/Makefile.frag new file mode 100644 index 0000000000000..5be6d5b00f4f3 --- /dev/null +++ b/sapi/phpdbg/Makefile.frag @@ -0,0 +1,28 @@ +phpdbg: $(BUILD_BINARY) + +phpdbg-shared: $(BUILD_SHARED) + +$(BUILD_SHARED): $(PHP_GLOBAL_OBJS) $(PHP_BINARY_OBJS) $(PHP_PHPDBG_OBJS) + $(BUILD_PHPDBG_SHARED) + +$(BUILD_BINARY): $(PHP_GLOBAL_OBJS) $(PHP_BINARY_OBJS) $(PHP_PHPDBG_OBJS) + $(BUILD_PHPDBG) + +install-phpdbg: $(BUILD_BINARY) + @echo "Installing phpdbg binary: $(INSTALL_ROOT)$(bindir)/" + @$(mkinstalldirs) $(INSTALL_ROOT)$(bindir) + @$(mkinstalldirs) $(INSTALL_ROOT)$(localstatedir)/log + @$(mkinstalldirs) $(INSTALL_ROOT)$(localstatedir)/run + @$(INSTALL) -m 0755 $(BUILD_BINARY) $(INSTALL_ROOT)$(bindir)/$(program_prefix)phpdbg$(program_suffix)$(EXEEXT) + +clean-phpdbg: + @echo "Cleaning phpdbg object files ..." + find sapi/phpdbg/ -name *.lo -o -name *.o | xargs rm -f + +test-phpdbg: + @echo "Running phpdbg tests ..." + @$(top_builddir)/sapi/cli/php sapi/phpdbg/tests/run-tests.php --phpdbg sapi/phpdbg/phpdbg + +.PHONY: clean-phpdbg test-phpdbg + + diff --git a/sapi/phpdbg/README.md b/sapi/phpdbg/README.md new file mode 100644 index 0000000000000..e7e5c731a805c --- /dev/null +++ b/sapi/phpdbg/README.md @@ -0,0 +1,83 @@ +The interactive PHP debugger +============================ + +Implemented as a SAPI module, phpdbg can excert complete control over the environment without impacting the functionality or performance of your code. + +phpdbg aims to be a lightweight, powerful, easy to use debugging platform for PHP 5.4+ + +[![phpdbg on travis-ci](https://travis-ci.org/krakjoe/phpdbg.png?branch=master)](https://travis-ci.org/krakjoe/phpdbg) + +Features +======== + + - Stepthrough Debugging + - Flexible Breakpoints (Class Method, Function, File:Line, Address, Opcode) + - Easy Access to PHP with built-in eval() + - Easy Access to Currently Executing Code + - Userland API + - SAPI Agnostic - Easily Integrated + - PHP Configuration File Support + - JIT Super Globals - Set Your Own!! + - Optional readline Support - Comfortable Terminal Operation + - Remote Debugging Support - Bundled Java GUI + - Easy Operation - See Help :) + +Planned +======= + + - Improve Everything :) + +Installation +============ + +To install **phpdbg**, you must compile the source against your PHP installation sources, and enable the SAPI with the configure command. + +``` +cd /usr/src/php-src/sapi +git clone https://github.com/krakjoe/phpdbg +cd ../ +./buildconf --force +./configure --enable-phpdbg +make -j8 +make install-phpdbg +``` + +Where the source directory has been used previously to build PHP, there exists a file named *config.nice* which can be used to invoke configure with the same +parameters as were used by the last execution of *configure*. + +**Note:** PHP must be configured with the switch --with-readline for phpdbg to support history, autocompletion, tab-listing etc. + +Command Line Options +==================== + +The following switches are implemented (just like cli SAPI): + + - -n ignore php ini + - -c search for php ini in path + - -z load zend extension + - -d define php ini entry + +The following switches change the default behaviour of phpdbg: + + - -v disables quietness + - -s enabled stepping + - -e sets execution context + - -b boring - disables use of colour on the console + - -I ignore .phpdbginit (default init file) + - -i override .phpgdbinit location (implies -I) + - -O set oplog output file + - -q do not print banner on startup + - -r jump straight to run + - -E enable step through eval() + - -l listen ports for remote mode + - -a listen address for remote mode + - -S override SAPI name + +**Note:** Passing -rr will cause phpdbg to quit after execution, rather than returning to the console. + +Getting Started +=============== + +See the website for tutorials/documentation + +http://phpdbg.com diff --git a/sapi/phpdbg/config.m4 b/sapi/phpdbg/config.m4 new file mode 100644 index 0000000000000..274e6409d04e4 --- /dev/null +++ b/sapi/phpdbg/config.m4 @@ -0,0 +1,61 @@ +dnl +dnl $Id$ +dnl + +PHP_ARG_ENABLE(phpdbg, for phpdbg support, +[ --enable-phpdbg Build phpdbg], yes, yes) + +PHP_ARG_ENABLE(phpdbg-debug, for phpdbg debug build, +[ --enable-phpdbg-debug Build phpdbg in debug mode], no, no) + +if test "$PHP_PHPDBG" != "no"; then + AC_DEFINE(HAVE_PHPDBG, 1, [ ]) + + if test "$PHP_PHPDBG_DEBUG" != "no"; then + AC_DEFINE(PHPDBG_DEBUG, 1, [ ]) + else + AC_DEFINE(PHPDBG_DEBUG, 0, [ ]) + fi + + PHP_PHPDBG_CFLAGS="-D_GNU_SOURCE" + PHP_PHPDBG_FILES="phpdbg.c phpdbg_prompt.c phpdbg_help.c phpdbg_break.c phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c phpdbg_info.c phpdbg_cmd.c phpdbg_set.c phpdbg_frame.c" + + PHP_SUBST(PHP_PHPDBG_CFLAGS) + PHP_SUBST(PHP_PHPDBG_FILES) + + PHP_ADD_MAKEFILE_FRAGMENT([$abs_srcdir/sapi/phpdbg/Makefile.frag]) + PHP_SELECT_SAPI(phpdbg, program, $PHP_PHPDBG_FILES, $PHP_PHPDBG_CFLAGS, [$(SAPI_PHPDBG_PATH)]) + + BUILD_BINARY="sapi/phpdbg/phpdbg" + BUILD_SHARED="sapi/phpdbg/libphpdbg.la" + + BUILD_PHPDBG="\$(LIBTOOL) --mode=link \ + \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \ + \$(PHP_GLOBAL_OBJS) \ + \$(PHP_BINARY_OBJS) \ + \$(PHP_PHPDBG_OBJS) \ + \$(EXTRA_LIBS) \ + \$(PHPDBG_EXTRA_LIBS) \ + \$(ZEND_EXTRA_LIBS) \ + -o \$(BUILD_BINARY)" + + BUILD_PHPDBG_SHARED="\$(LIBTOOL) --mode=link \ + \$(CC) -shared -Wl,-soname,libphpdbg.so -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \ + \$(PHP_GLOBAL_OBJS) \ + \$(PHP_BINARY_OBJS) \ + \$(PHP_PHPDBG_OBJS) \ + \$(EXTRA_LIBS) \ + \$(PHPDBG_EXTRA_LIBS) \ + \$(ZEND_EXTRA_LIBS) \ + \-DPHPDBG_SHARED \ + -o \$(BUILD_SHARED)" + + PHP_SUBST(BUILD_BINARY) + PHP_SUBST(BUILD_SHARED) + PHP_SUBST(BUILD_PHPDBG) + PHP_SUBST(BUILD_PHPDBG_SHARED) +fi + +dnl ## Local Variables: +dnl ## tab-width: 4 +dnl ## End: diff --git a/sapi/phpdbg/config.w32 b/sapi/phpdbg/config.w32 new file mode 100644 index 0000000000000..29031507b31a7 --- /dev/null +++ b/sapi/phpdbg/config.w32 @@ -0,0 +1,19 @@ +ARG_ENABLE('phpdbg', 'Build phpdbg', 'yes'); +ARG_ENABLE('phpdbgs', 'Build phpdbg shared', 'no'); + +PHPDBG_SOURCES='phpdbg.c phpdbg_prompt.c phpdbg_cmd.c phpdbg_info.c phpdbg_help.c phpdbg_break.c phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c phpdbg_set.c phpdbg_frame.c'; +PHPDBG_DLL='php' + PHP_VERSION + 'phpdbg.dll'; +PHPDBG_EXE='phpdbg.exe'; + +if (PHP_PHPDBG == "yes") { + /* build phpdbg binary */ + SAPI('phpdbg', PHPDBG_SOURCES, PHPDBG_EXE); + ADD_FLAG("LIBS_PHPDBG", "ws2_32.lib user32.lib"); +} + +if (PHP_PHPDBGS == "yes") { + SAPI('phpdbgs', PHPDBG_SOURCES, PHPDBG_DLL, '/D PHP_PHPDBG_EXPORTS /I win32'); + ADD_FLAG("LIBS_PHPDBGS", "ws2_32.lib user32.lib"); +} + + diff --git a/sapi/phpdbg/phpdbg.c b/sapi/phpdbg/phpdbg.c new file mode 100644 index 0000000000000..17193ed244cec --- /dev/null +++ b/sapi/phpdbg/phpdbg.c @@ -0,0 +1,1308 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Felipe Pena | + | Authors: Joe Watkins | + +----------------------------------------------------------------------+ +*/ + +#ifndef ZEND_SIGNALS +# include +#endif +#include "phpdbg.h" +#include "phpdbg_prompt.h" +#include "phpdbg_bp.h" +#include "phpdbg_break.h" +#include "phpdbg_utils.h" +#include "phpdbg_set.h" + +/* {{{ remote console headers */ +#ifndef _WIN32 +# include +# include +# include +# include +# include +# include +#endif /* }}} */ + +ZEND_DECLARE_MODULE_GLOBALS(phpdbg); + +static zend_bool phpdbg_booted = 0; + +#if PHP_VERSION_ID >= 50500 +void (*zend_execute_old)(zend_execute_data *execute_data TSRMLS_DC); +#else +void (*zend_execute_old)(zend_op_array *op_array TSRMLS_DC); +#endif + +static inline void php_phpdbg_globals_ctor(zend_phpdbg_globals *pg) /* {{{ */ +{ + pg->prompt[0] = NULL; + pg->prompt[1] = NULL; + + pg->colors[0] = NULL; + pg->colors[1] = NULL; + pg->colors[2] = NULL; + + pg->exec = NULL; + pg->exec_len = 0; + pg->ops = NULL; + pg->vmret = 0; + pg->bp_count = 0; + pg->lcmd = NULL; + pg->flags = PHPDBG_DEFAULT_FLAGS; + pg->oplog = NULL; + pg->io[PHPDBG_STDIN] = NULL; + pg->io[PHPDBG_STDOUT] = NULL; + pg->io[PHPDBG_STDERR] = NULL; + memset(&pg->lparam, 0, sizeof(phpdbg_param_t)); + pg->frame.num = 0; +} /* }}} */ + +static PHP_MINIT_FUNCTION(phpdbg) /* {{{ */ +{ + ZEND_INIT_MODULE_GLOBALS(phpdbg, php_phpdbg_globals_ctor, NULL); +#if PHP_VERSION_ID >= 50500 + zend_execute_old = zend_execute_ex; + zend_execute_ex = phpdbg_execute_ex; +#else + zend_execute_old = zend_execute; + zend_execute = phpdbg_execute_ex; +#endif + + REGISTER_STRINGL_CONSTANT("PHPDBG_VERSION", PHPDBG_VERSION, sizeof(PHPDBG_VERSION)-1, CONST_CS|CONST_PERSISTENT); + + REGISTER_LONG_CONSTANT("PHPDBG_FILE", FILE_PARAM, CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("PHPDBG_METHOD", METHOD_PARAM, CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("PHPDBG_LINENO", NUMERIC_PARAM, CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("PHPDBG_FUNC", STR_PARAM, CONST_CS|CONST_PERSISTENT); + + REGISTER_LONG_CONSTANT("PHPDBG_COLOR_PROMPT", PHPDBG_COLOR_PROMPT, CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("PHPDBG_COLOR_NOTICE", PHPDBG_COLOR_NOTICE, CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("PHPDBG_COLOR_ERROR", PHPDBG_COLOR_ERROR, CONST_CS|CONST_PERSISTENT); + + return SUCCESS; +} /* }}} */ + +static void php_phpdbg_destroy_bp_file(void *brake) /* {{{ */ +{ + zend_hash_destroy((HashTable*)brake); +} /* }}} */ + +static void php_phpdbg_destroy_bp_symbol(void *brake) /* {{{ */ +{ + efree((char*)((phpdbg_breaksymbol_t*)brake)->symbol); +} /* }}} */ + +static void php_phpdbg_destroy_bp_opcode(void *brake) /* {{{ */ +{ + efree((char*)((phpdbg_breakop_t*)brake)->name); +} /* }}} */ + + +static void php_phpdbg_destroy_bp_methods(void *brake) /* {{{ */ +{ + zend_hash_destroy((HashTable*)brake); +} /* }}} */ + +static void php_phpdbg_destroy_bp_condition(void *data) /* {{{ */ +{ + phpdbg_breakcond_t *brake = (phpdbg_breakcond_t*) data; + + if (brake) { + if (brake->ops) { + TSRMLS_FETCH(); + + destroy_op_array( + brake->ops TSRMLS_CC); + efree(brake->ops); + } + efree((char*)brake->code); + } +} /* }}} */ + +static void php_phpdbg_destroy_registered(void *data) /* {{{ */ +{ + TSRMLS_FETCH(); + + zend_function *function = (zend_function*) data; + + destroy_zend_function( + function TSRMLS_CC); +} /* }}} */ + +static PHP_RINIT_FUNCTION(phpdbg) /* {{{ */ +{ + zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], 8, NULL, php_phpdbg_destroy_bp_file, 0); + zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], 8, NULL, php_phpdbg_destroy_bp_symbol, 0); + zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], 8, NULL, php_phpdbg_destroy_bp_methods, 0); + zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], 8, NULL, php_phpdbg_destroy_bp_methods, 0); + zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], 8, NULL, php_phpdbg_destroy_bp_methods, 0); + zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], 8, NULL, NULL, 0); + zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], 8, NULL, php_phpdbg_destroy_bp_opcode, 0); + zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], 8, NULL, php_phpdbg_destroy_bp_methods, 0); + zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], 8, NULL, php_phpdbg_destroy_bp_condition, 0); + zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], 8, NULL, NULL, 0); + + zend_hash_init(&PHPDBG_G(seek), 8, NULL, NULL, 0); + zend_hash_init(&PHPDBG_G(registered), 8, NULL, php_phpdbg_destroy_registered, 0); + + return SUCCESS; +} /* }}} */ + +static PHP_RSHUTDOWN_FUNCTION(phpdbg) /* {{{ */ +{ + zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE]); + zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM]); + zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE]); + zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE]); + zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE]); + zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]); + zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE]); + zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD]); + zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_COND]); + zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP]); + zend_hash_destroy(&PHPDBG_G(seek)); + zend_hash_destroy(&PHPDBG_G(registered)); + + if (PHPDBG_G(exec)) { + efree(PHPDBG_G(exec)); + PHPDBG_G(exec) = NULL; + } + + if (PHPDBG_G(prompt)[0]) { + free(PHPDBG_G(prompt)[0]); + } + if (PHPDBG_G(prompt)[1]) { + free(PHPDBG_G(prompt)[1]); + } + + PHPDBG_G(prompt)[0] = NULL; + PHPDBG_G(prompt)[1] = NULL; + + if (PHPDBG_G(oplog)) { + fclose( + PHPDBG_G(oplog)); + PHPDBG_G(oplog) = NULL; + } + + if (PHPDBG_G(ops)) { + destroy_op_array(PHPDBG_G(ops) TSRMLS_CC); + efree(PHPDBG_G(ops)); + PHPDBG_G(ops) = NULL; + } + + return SUCCESS; +} /* }}} */ + +/* {{{ proto mixed phpdbg_exec(string context) + Attempt to set the execution context for phpdbg + If the execution context was set previously it is returned + If the execution context was not set previously boolean true is returned + If the request to set the context fails, boolean false is returned, and an E_WARNING raised */ +static PHP_FUNCTION(phpdbg_exec) +{ + char *exec = NULL; + zend_ulong exec_len = 0L; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &exec, &exec_len) == FAILURE) { + return; + } + + { + struct stat sb; + zend_bool result = 1; + + if (VCWD_STAT(exec, &sb) != FAILURE) { + if (sb.st_mode & (S_IFREG|S_IFLNK)) { + if (PHPDBG_G(exec)) { + ZVAL_STRINGL(return_value, PHPDBG_G(exec), PHPDBG_G(exec_len), 1); + efree(PHPDBG_G(exec)); + result = 0; + } + + PHPDBG_G(exec) = estrndup(exec, exec_len); + PHPDBG_G(exec_len) = exec_len; + + if (result) + ZVAL_BOOL(return_value, 1); + } else { + zend_error( + E_WARNING, "Failed to set execution context (%s), not a regular file or symlink", exec); + ZVAL_BOOL(return_value, 0); + } + } else { + zend_error( + E_WARNING, "Failed to set execution context (%s) the file does not exist", exec); + + ZVAL_BOOL(return_value, 0); + } + } +} /* }}} */ + +/* {{{ proto void phpdbg_break([integer type, string expression]) + instructs phpdbg to insert a breakpoint at the next opcode */ +static PHP_FUNCTION(phpdbg_break) +{ + if (ZEND_NUM_ARGS() > 0) { + long type; + char *expr = NULL; + zend_uint expr_len = 0; + phpdbg_param_t param; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &type, &expr, &expr_len) == FAILURE) { + return; + } + + phpdbg_parse_param(expr, expr_len, ¶m TSRMLS_CC); + + switch (type) { + case METHOD_PARAM: + phpdbg_do_break_method(¶m, NULL TSRMLS_CC); + break; + + case FILE_PARAM: + phpdbg_do_break_file(¶m, NULL TSRMLS_CC); + break; + + case NUMERIC_PARAM: + phpdbg_do_break_lineno(¶m, NULL TSRMLS_CC); + break; + + case STR_PARAM: + phpdbg_do_break_func(¶m, NULL TSRMLS_CC); + break; + + default: zend_error( + E_WARNING, "unrecognized parameter type %ld", type); + } + + phpdbg_clear_param(¶m TSRMLS_CC); + + } else if (EG(current_execute_data) && EG(active_op_array)) { + zend_ulong opline_num = (EG(current_execute_data)->opline - + EG(active_op_array)->opcodes); + + phpdbg_set_breakpoint_opline_ex( + &EG(active_op_array)->opcodes[opline_num+1] TSRMLS_CC); + } +} /* }}} */ + +/* {{{ proto void phpdbg_clear(void) + instructs phpdbg to clear breakpoints */ +static PHP_FUNCTION(phpdbg_clear) +{ + zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE]); + zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM]); + zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE]); + zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE]); + zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE]); + zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]); + zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD]); + zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_COND]); +} /* }}} */ + +/* {{{ proto void phpdbg_color(integer element, string color) */ +static PHP_FUNCTION(phpdbg_color) +{ + long element; + char *color; + zend_uint color_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &element, &color, &color_len) == FAILURE) { + return; + } + + switch (element) { + case PHPDBG_COLOR_NOTICE: + case PHPDBG_COLOR_ERROR: + case PHPDBG_COLOR_PROMPT: + phpdbg_set_color_ex(element, color, color_len TSRMLS_CC); + break; + + default: zend_error(E_ERROR, "phpdbg detected an incorrect color constant"); + } +} /* }}} */ + +/* {{{ proto void phpdbg_prompt(string prompt) */ +static PHP_FUNCTION(phpdbg_prompt) +{ + char *prompt; + zend_uint prompt_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &prompt, &prompt_len) == FAILURE) { + return; + } + + phpdbg_set_prompt(prompt TSRMLS_CC); +} /* }}} */ + +ZEND_BEGIN_ARG_INFO_EX(phpdbg_break_arginfo, 0, 0, 0) + ZEND_ARG_INFO(0, type) + ZEND_ARG_INFO(0, expression) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(phpdbg_color_arginfo, 0, 0, 0) + ZEND_ARG_INFO(0, element) + ZEND_ARG_INFO(0, color) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(phpdbg_prompt_arginfo, 0, 0, 0) + ZEND_ARG_INFO(0, string) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(phpdbg_exec_arginfo, 0, 0, 0) + ZEND_ARG_INFO(0, context) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(phpdbg_clear_arginfo, 0, 0, 0) +ZEND_END_ARG_INFO() + +zend_function_entry phpdbg_user_functions[] = { + PHP_FE(phpdbg_clear, phpdbg_clear_arginfo) + PHP_FE(phpdbg_break, phpdbg_break_arginfo) + PHP_FE(phpdbg_exec, phpdbg_exec_arginfo) + PHP_FE(phpdbg_color, phpdbg_color_arginfo) + PHP_FE(phpdbg_prompt, phpdbg_prompt_arginfo) +#ifdef PHP_FE_END + PHP_FE_END +#else + {NULL,NULL,NULL} +#endif +}; + +static zend_module_entry sapi_phpdbg_module_entry = { + STANDARD_MODULE_HEADER, + PHPDBG_NAME, + phpdbg_user_functions, + PHP_MINIT(phpdbg), + NULL, + PHP_RINIT(phpdbg), + PHP_RSHUTDOWN(phpdbg), + NULL, + PHPDBG_VERSION, + STANDARD_MODULE_PROPERTIES +}; + +static inline int php_sapi_phpdbg_module_startup(sapi_module_struct *module) /* {{{ */ +{ + if (php_module_startup(module, &sapi_phpdbg_module_entry, 1) == FAILURE) { + return FAILURE; + } + + phpdbg_booted=1; + + return SUCCESS; +} /* }}} */ + +static char* php_sapi_phpdbg_read_cookies(TSRMLS_D) /* {{{ */ +{ + return NULL; +} /* }}} */ + +static int php_sapi_phpdbg_header_handler(sapi_header_struct *h, sapi_header_op_enum op, sapi_headers_struct *s TSRMLS_DC) /* {{{ */ +{ + return 0; +} +/* }}} */ + +static int php_sapi_phpdbg_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC) /* {{{ */ +{ + /* We do nothing here, this function is needed to prevent that the fallback + * header handling is called. */ + return SAPI_HEADER_SENT_SUCCESSFULLY; +} +/* }}} */ + +static void php_sapi_phpdbg_send_header(sapi_header_struct *sapi_header, void *server_context TSRMLS_DC) /* {{{ */ +{ +} +/* }}} */ + +static void php_sapi_phpdbg_log_message(char *message TSRMLS_DC) /* {{{ */ +{ + /* + * We must not request TSRM before being boot + */ + if (phpdbg_booted) { + phpdbg_error("%s", message); + } else fprintf(stdout, "%s\n", message); +} +/* }}} */ + +static int php_sapi_phpdbg_deactivate(TSRMLS_D) /* {{{ */ +{ + fflush(stdout); + if(SG(request_info).argv0) { + free(SG(request_info).argv0); + SG(request_info).argv0 = NULL; + } + return SUCCESS; +} +/* }}} */ + +static void php_sapi_phpdbg_register_vars(zval *track_vars_array TSRMLS_DC) /* {{{ */ +{ + unsigned int len; + char *docroot = ""; + + /* In phpdbg mode, we consider the environment to be a part of the server variables + */ + php_import_environment_variables(track_vars_array TSRMLS_CC); + + if (PHPDBG_G(exec)) { + len = PHPDBG_G(exec_len); + if (sapi_module.input_filter(PARSE_SERVER, "PHP_SELF", + &PHPDBG_G(exec), PHPDBG_G(exec_len), &len TSRMLS_CC)) { + php_register_variable("PHP_SELF", PHPDBG_G(exec), + track_vars_array TSRMLS_CC); + } + if (sapi_module.input_filter(PARSE_SERVER, "SCRIPT_NAME", + &PHPDBG_G(exec), PHPDBG_G(exec_len), &len TSRMLS_CC)) { + php_register_variable("SCRIPT_NAME", PHPDBG_G(exec), + track_vars_array TSRMLS_CC); + } + + if (sapi_module.input_filter(PARSE_SERVER, "SCRIPT_FILENAME", + &PHPDBG_G(exec), PHPDBG_G(exec_len), &len TSRMLS_CC)) { + php_register_variable("SCRIPT_FILENAME", PHPDBG_G(exec), + track_vars_array TSRMLS_CC); + } + if (sapi_module.input_filter(PARSE_SERVER, "PATH_TRANSLATED", + &PHPDBG_G(exec), PHPDBG_G(exec_len), &len TSRMLS_CC)) { + php_register_variable("PATH_TRANSLATED", PHPDBG_G(exec), + track_vars_array TSRMLS_CC); + } + } + + /* any old docroot will doo */ + len = 0U; + if (sapi_module.input_filter(PARSE_SERVER, "DOCUMENT_ROOT", + &docroot, len, &len TSRMLS_CC)) { + php_register_variable("DOCUMENT_ROOT", docroot, track_vars_array TSRMLS_CC); + } +} +/* }}} */ + +static inline int php_sapi_phpdbg_ub_write(const char *message, unsigned int length TSRMLS_DC) /* {{{ */ +{ + return phpdbg_write("%s", message); +} /* }}} */ + +#if PHP_VERSION_ID >= 50700 +static inline void php_sapi_phpdbg_flush(void *context TSRMLS_DC) /* {{{ */ +{ +#else +static inline void php_sapi_phpdbg_flush(void *context) /* {{{ */ +{ + TSRMLS_FETCH(); +#endif + + fflush(PHPDBG_G(io)[PHPDBG_STDOUT]); +} /* }}} */ + +/* {{{ sapi_module_struct phpdbg_sapi_module +*/ +static sapi_module_struct phpdbg_sapi_module = { + "phpdbg", /* name */ + "phpdbg", /* pretty name */ + + php_sapi_phpdbg_module_startup, /* startup */ + php_module_shutdown_wrapper, /* shutdown */ + + NULL, /* activate */ + php_sapi_phpdbg_deactivate, /* deactivate */ + + php_sapi_phpdbg_ub_write, /* unbuffered write */ + php_sapi_phpdbg_flush, /* flush */ + NULL, /* get uid */ + NULL, /* getenv */ + + php_error, /* error handler */ + + php_sapi_phpdbg_header_handler, /* header handler */ + php_sapi_phpdbg_send_headers, /* send headers handler */ + php_sapi_phpdbg_send_header, /* send header handler */ + + NULL, /* read POST data */ + php_sapi_phpdbg_read_cookies, /* read Cookies */ + + php_sapi_phpdbg_register_vars, /* register server variables */ + php_sapi_phpdbg_log_message, /* Log message */ + NULL, /* Get request time */ + NULL, /* Child terminate */ + STANDARD_SAPI_MODULE_PROPERTIES +}; +/* }}} */ + +const opt_struct OPTIONS[] = { /* {{{ */ + {'c', 1, "ini path override"}, + {'d', 1, "define ini entry on command line"}, + {'n', 0, "no php.ini"}, + {'z', 1, "load zend_extension"}, + /* phpdbg options */ + {'q', 0, "no banner"}, + {'e', 1, "exec"}, + {'v', 0, "disable quietness"}, + {'s', 0, "enable stepping"}, + {'b', 0, "boring colours"}, + {'i', 1, "specify init"}, + {'I', 0, "ignore init"}, + {'O', 1, "opline log"}, + {'r', 0, "run"}, + {'E', 0, "step-through-eval"}, + {'S', 1, "sapi-name"}, +#ifndef _WIN32 + {'l', 1, "listen"}, + {'a', 1, "address-or-any"}, +#endif + {'V', 0, "version"}, + {'-', 0, NULL} +}; /* }}} */ + +const char phpdbg_ini_hardcoded[] = +"html_errors=Off\n" +"register_argc_argv=On\n" +"implicit_flush=On\n" +"display_errors=Off\n" +"log_errors=On\n" +"max_execution_time=0\n" +"max_input_time=-1\n\0"; + +/* overwriteable ini defaults must be set in phpdbg_ini_defaults() */ +#define INI_DEFAULT(name, value) \ + Z_SET_REFCOUNT(tmp, 0); \ + Z_UNSET_ISREF(tmp); \ + ZVAL_STRINGL(&tmp, zend_strndup(value, sizeof(value)-1), sizeof(value)-1, 0); \ + zend_hash_update(configuration_hash, name, sizeof(name), &tmp, sizeof(zval), NULL); + +void phpdbg_ini_defaults(HashTable *configuration_hash) /* {{{ */ +{ + zval tmp; + INI_DEFAULT("report_zend_debug", "0"); +} /* }}} */ + +static void phpdbg_welcome(zend_bool cleaning TSRMLS_DC) /* {{{ */ +{ + /* print blurb */ + if (!cleaning) { + phpdbg_notice("Welcome to phpdbg, the interactive PHP debugger, v%s", + PHPDBG_VERSION); + phpdbg_writeln("To get help using phpdbg type \"help\" and press enter"); + phpdbg_notice("Please report bugs to <%s>", PHPDBG_ISSUES); + } else { + phpdbg_notice("Clean Execution Environment"); + + phpdbg_writeln("Classes\t\t\t%d", zend_hash_num_elements(EG(class_table))); + phpdbg_writeln("Functions\t\t%d", zend_hash_num_elements(EG(function_table))); + phpdbg_writeln("Constants\t\t%d", zend_hash_num_elements(EG(zend_constants))); + phpdbg_writeln("Includes\t\t%d", zend_hash_num_elements(&EG(included_files))); + } +} /* }}} */ + +static inline void phpdbg_sigint_handler(int signo) /* {{{ */ +{ + TSRMLS_FETCH(); + + if (EG(in_execution)) { + /* set signalled only when not interactive */ + if (!(PHPDBG_G(flags) & PHPDBG_IS_INTERACTIVE)) { + PHPDBG_G(flags) |= PHPDBG_IS_SIGNALED; + } + } else { + PHPDBG_G(flags) |= PHPDBG_IS_QUITTING; + zend_bailout(); + } +} /* }}} */ + +#ifndef _WIN32 +int phpdbg_open_socket(const char *interface, short port) /* {{{ */ +{ + int fd = socket(AF_INET, SOCK_STREAM, 0); + + switch (fd) { + case -1: + return -1; + + default: { + int reuse = 1; + + switch (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*) &reuse, sizeof(reuse))) { + case -1: + close(fd); + return -2; + + default: { + struct sockaddr_in address; + + memset(&address, 0, sizeof(address)); + + address.sin_port = htons(port); + address.sin_family = AF_INET; + + if ((*interface == '*')) { + address.sin_addr.s_addr = htonl(INADDR_ANY); + } else if (!inet_pton(AF_INET, interface, &address.sin_addr)) { + close(fd); + return -3; + } + + switch (bind(fd, (struct sockaddr *)&address, sizeof(address))) { + case -1: + close(fd); + return -4; + + default: { + listen(fd, 5); + } + } + } + } + } + } + + return fd; +} /* }}} */ + +static inline void phpdbg_close_sockets(int (*socket)[2], FILE *streams[2]) /* {{{ */ +{ + if ((*socket)[0] >= 0) { + shutdown( + (*socket)[0], SHUT_RDWR); + close((*socket)[0]); + } + + if (streams[0]) { + fclose(streams[0]); + } + + if ((*socket)[1] >= 0) { + shutdown( + (*socket)[1], SHUT_RDWR); + close((*socket)[1]); + } + + if (streams[1]) { + fclose(streams[1]); + } +} /* }}} */ + +/* don't inline this, want to debug it easily, will inline when done */ + +int phpdbg_open_sockets(char *address, int port[2], int (*listen)[2], int (*socket)[2], FILE* streams[2]) /* {{{ */ +{ + if (((*listen)[0]) < 0 && ((*listen)[1]) < 0) { + ((*listen)[0]) = phpdbg_open_socket(address, (short)port[0]); + ((*listen)[1]) = phpdbg_open_socket(address, (short)port[1]); + } + + streams[0] = NULL; + streams[1] = NULL; + + if ((*listen)[0] < 0 || (*listen)[1] < 0) { + if ((*listen)[0] < 0) { + phpdbg_rlog(stderr, + "console failed to initialize (stdin) on %s:%d", address, port[0]); + } + + if ((*listen)[1] < 0) { + phpdbg_rlog(stderr, + "console failed to initialize (stdout) on %s:%d", address, port[1]); + } + + if ((*listen)[0] >= 0) { + close((*listen)[0]); + } + + if ((*listen)[1] >= 0) { + close((*listen)[1]); + } + + return FAILURE; + } + + phpdbg_close_sockets(socket, streams); + + phpdbg_rlog(stderr, + "accepting connections on %s:%d/%d", address, port[0], port[1]); + { + struct sockaddr_in address; + socklen_t size = sizeof(address); + char buffer[20] = {0}; + + { + memset(&address, 0, size); + (*socket)[0] = accept( + (*listen)[0], (struct sockaddr *) &address, &size); + inet_ntop(AF_INET, &address.sin_addr, buffer, sizeof(buffer)); + + phpdbg_rlog(stderr, "connection (stdin) from %s", buffer); + } + + { + memset(&address, 0, size); + (*socket)[1] = accept( + (*listen)[1], (struct sockaddr *) &address, &size); + inet_ntop(AF_INET, &address.sin_addr, buffer, sizeof(buffer)); + + phpdbg_rlog(stderr, "connection (stdout) from %s", buffer); + } + } + + dup2((*socket)[0], fileno(stdin)); + dup2((*socket)[1], fileno(stdout)); + + setbuf(stdout, NULL); + + streams[0] = fdopen((*socket)[0], "r"); + streams[1] = fdopen((*socket)[1], "w"); + + return SUCCESS; +} /* }}} */ +#endif + +int main(int argc, char **argv) /* {{{ */ +{ + sapi_module_struct *phpdbg = &phpdbg_sapi_module; + char *sapi_name; + char *ini_entries; + int ini_entries_len; + char **zend_extensions = NULL; + zend_ulong zend_extensions_len = 0L; + zend_bool ini_ignore; + char *ini_override; + char *exec; + size_t exec_len; + char *init_file; + size_t init_file_len; + zend_bool init_file_default; + char *oplog_file; + size_t oplog_file_len; + zend_ulong flags; + char *php_optarg; + int php_optind, opt, show_banner = 1; + long cleaning = 0; + zend_bool remote = 0; + int run = 0; + int step = 0; + char *bp_tmp_file; +#ifndef _WIN32 + char *address; + int listen[2]; + int server[2]; + int socket[2]; + FILE* streams[2] = {NULL, NULL}; +#endif + +#ifdef ZTS + void ***tsrm_ls; +#endif + +#ifndef _WIN32 + address = strdup("127.0.0.1"); + socket[0] = -1; + socket[1] = -1; + listen[0] = -1; + listen[1] = -1; + server[0] = -1; + server[1] = -1; + streams[0] = NULL; + streams[1] = NULL; +#endif + +#ifdef PHP_WIN32 + _fmode = _O_BINARY; /* sets default for file streams to binary */ + setmode(_fileno(stdin), O_BINARY); /* make the stdio mode be binary */ + setmode(_fileno(stdout), O_BINARY); /* make the stdio mode be binary */ + setmode(_fileno(stderr), O_BINARY); /* make the stdio mode be binary */ +#endif + +#ifdef ZTS + tsrm_startup(1, 1, 0, NULL); + + tsrm_ls = ts_resource(0); +#endif + +phpdbg_main: + if (!cleaning) { + bp_tmp_file = malloc(L_tmpnam); + tmpnam(bp_tmp_file); + if (bp_tmp_file == NULL) { + phpdbg_error("Unable to create temporary file"); + } + } + ini_entries = NULL; + ini_entries_len = 0; + ini_ignore = 0; + ini_override = NULL; + zend_extensions = NULL; + zend_extensions_len = 0L; + exec = NULL; + exec_len = 0; + init_file = NULL; + init_file_len = 0; + init_file_default = 1; + oplog_file = NULL; + oplog_file_len = 0; + flags = PHPDBG_DEFAULT_FLAGS; + php_optarg = NULL; + php_optind = 1; + opt = 0; + run = 0; + step = 0; + sapi_name = NULL; + + + while ((opt = php_getopt(argc, argv, OPTIONS, &php_optarg, &php_optind, 0, 2)) != -1) { + switch (opt) { + case 'r': + run++; + break; + case 'n': + ini_ignore = 1; + break; + case 'c': + if (ini_override) { + free(ini_override); + } + ini_override = strdup(php_optarg); + break; + case 'd': { + int len = strlen(php_optarg); + char *val; + + if ((val = strchr(php_optarg, '='))) { + val++; + if (!isalnum(*val) && *val != '"' && *val != '\'' && *val != '\0') { + ini_entries = realloc(ini_entries, ini_entries_len + len + sizeof("\"\"\n\0")); + memcpy(ini_entries + ini_entries_len, php_optarg, (val - php_optarg)); + ini_entries_len += (val - php_optarg); + memcpy(ini_entries + ini_entries_len, "\"", 1); + ini_entries_len++; + memcpy(ini_entries + ini_entries_len, val, len - (val - php_optarg)); + ini_entries_len += len - (val - php_optarg); + memcpy(ini_entries + ini_entries_len, "\"\n\0", sizeof("\"\n\0")); + ini_entries_len += sizeof("\n\0\"") - 2; + } else { + ini_entries = realloc(ini_entries, ini_entries_len + len + sizeof("\n\0")); + memcpy(ini_entries + ini_entries_len, php_optarg, len); + memcpy(ini_entries + ini_entries_len + len, "\n\0", sizeof("\n\0")); + ini_entries_len += len + sizeof("\n\0") - 2; + } + } else { + ini_entries = realloc(ini_entries, ini_entries_len + len + sizeof("=1\n\0")); + memcpy(ini_entries + ini_entries_len, php_optarg, len); + memcpy(ini_entries + ini_entries_len + len, "=1\n\0", sizeof("=1\n\0")); + ini_entries_len += len + sizeof("=1\n\0") - 2; + } + } break; + + case 'z': + zend_extensions_len++; + if (zend_extensions) { + zend_extensions = realloc(zend_extensions, sizeof(char*) * zend_extensions_len); + } else zend_extensions = malloc(sizeof(char*) * zend_extensions_len); + zend_extensions[zend_extensions_len-1] = strdup(php_optarg); + break; + + /* begin phpdbg options */ + + case 'e': { /* set execution context */ + exec_len = strlen(php_optarg); + if (exec_len) { + if (exec) { + free(exec); + } + exec = strdup(php_optarg); + } + } break; + + case 'S': { /* set SAPI name */ + if (sapi_name) { + free(sapi_name); + } + sapi_name = strdup(php_optarg); + } break; + + case 'I': { /* ignore .phpdbginit */ + init_file_default = 0; + } break; + + case 'i': { /* set init file */ + if (init_file) { + free(init_file); + } + + init_file_len = strlen(php_optarg); + if (init_file_len) { + init_file = strdup(php_optarg); + } + } break; + + case 'O': { /* set oplog output */ + oplog_file_len = strlen(php_optarg); + if (oplog_file_len) { + oplog_file = strdup(php_optarg); + } + } break; + + case 'v': /* set quietness off */ + flags &= ~PHPDBG_IS_QUIET; + break; + + case 's': /* set stepping on */ + step = 1; + break; + + case 'E': /* stepping through eval on */ + flags |= PHPDBG_IS_STEPONEVAL; + break; + + case 'b': /* set colours off */ + flags &= ~PHPDBG_IS_COLOURED; + break; + + case 'q': /* hide banner */ + show_banner = 0; + break; + +#ifndef _WIN32 + /* if you pass a listen port, we will accept input on listen port */ + /* and write output to listen port * 2 */ + + case 'l': { /* set listen ports */ + if (sscanf(php_optarg, "%d/%d", &listen[0], &listen[1]) != 2) { + if (sscanf(php_optarg, "%d", &listen[0]) != 1) { + /* default to hardcoded ports */ + listen[0] = 4000; + listen[1] = 8000; + } else { + listen[1] = (listen[0] * 2); + } + } + } break; + + case 'a': { /* set bind address */ + free(address); + if (!php_optarg) { + address = strdup("*"); + } else address = strdup(php_optarg); + } break; +#endif + + case 'V': { + sapi_startup(phpdbg); + phpdbg->startup(phpdbg); + printf( + "phpdbg %s (built: %s %s)\nCopyright (c) 2013 %s\nPHP %s, Copyright (c) 1997-2013 The PHP Group\n%s", + PHPDBG_VERSION, + __DATE__, + __TIME__, + PHPDBG_AUTHORS, + PHP_VERSION, + get_zend_version() + ); + sapi_deactivate(TSRMLS_C); + sapi_shutdown(); + return 0; + } break; + } + } + +#ifndef _WIN32 + /* setup remote server if necessary */ + if (!cleaning && + (listen[0] > 0 && listen[1] > 0)) { + if (phpdbg_open_sockets(address, listen, &server, &socket, streams) == FAILURE) { + remote = 0; + exit(0); + } + /* set remote flag to stop service shutting down upon quit */ + remote = 1; + } +#endif + + if (sapi_name) { + phpdbg->name = sapi_name; + } + + phpdbg->ini_defaults = phpdbg_ini_defaults; + phpdbg->phpinfo_as_text = 1; + phpdbg->php_ini_ignore_cwd = 1; + + sapi_startup(phpdbg); + + phpdbg->executable_location = argv[0]; + phpdbg->phpinfo_as_text = 1; + phpdbg->php_ini_ignore = ini_ignore; + phpdbg->php_ini_path_override = ini_override; + + if (ini_entries) { + ini_entries = realloc(ini_entries, ini_entries_len + sizeof(phpdbg_ini_hardcoded)); + memmove(ini_entries + sizeof(phpdbg_ini_hardcoded) - 2, ini_entries, ini_entries_len + 1); + memcpy(ini_entries, phpdbg_ini_hardcoded, sizeof(phpdbg_ini_hardcoded) - 2); + } else { + ini_entries = malloc(sizeof(phpdbg_ini_hardcoded)); + memcpy(ini_entries, phpdbg_ini_hardcoded, sizeof(phpdbg_ini_hardcoded)); + } + ini_entries_len += sizeof(phpdbg_ini_hardcoded) - 2; + + if (zend_extensions_len) { + zend_ulong zend_extension = 0L; + + while (zend_extension < zend_extensions_len) { + const char *ze = zend_extensions[zend_extension]; + size_t ze_len = strlen(ze); + + ini_entries = realloc( + ini_entries, ini_entries_len + (ze_len + (sizeof("zend_extension=\n")))); + memcpy(&ini_entries[ini_entries_len], "zend_extension=", (sizeof("zend_extension=\n")-1)); + ini_entries_len += (sizeof("zend_extension=")-1); + memcpy(&ini_entries[ini_entries_len], ze, ze_len); + ini_entries_len += ze_len; + memcpy(&ini_entries[ini_entries_len], "\n", (sizeof("\n") - 1)); + + free(zend_extensions[zend_extension]); + zend_extension++; + } + + free(zend_extensions); + } + + phpdbg->ini_entries = ini_entries; + + if (phpdbg->startup(phpdbg) == SUCCESS) { + + zend_activate(TSRMLS_C); + + /* do not install sigint handlers for remote consoles */ + /* sending SIGINT then provides a decent way of shutting down the server */ +#ifdef ZEND_SIGNALS +# ifndef _WIN32 + if (listen[0] < 0) { +# endif + zend_try { + zend_signal_activate(TSRMLS_C); + zend_signal(SIGINT, phpdbg_sigint_handler TSRMLS_CC); + } zend_end_try(); +# ifndef _WIN32 + } +# endif +#else +# ifndef _WIN32 + if (listen[0] < 0) { +# endif + signal(SIGINT, phpdbg_sigint_handler); +#ifndef _WIN32 + } +#endif +#endif + + PG(modules_activated) = 0; + + /* set flags from command line */ + PHPDBG_G(flags) = flags; + +#ifndef _WIN32 + /* setup io here */ + if (streams[0] && streams[1]) { + PHPDBG_G(flags) |= PHPDBG_IS_REMOTE; + + signal(SIGPIPE, SIG_IGN); + } +#endif + + PHPDBG_G(io)[PHPDBG_STDIN] = stdin; + PHPDBG_G(io)[PHPDBG_STDOUT] = stdout; + PHPDBG_G(io)[PHPDBG_STDERR] = stderr; + + if (exec) { /* set execution context */ + PHPDBG_G(exec) = phpdbg_resolve_path( + exec TSRMLS_CC); + PHPDBG_G(exec_len) = strlen(PHPDBG_G(exec)); + + free(exec); + } + + if (oplog_file) { /* open oplog */ + PHPDBG_G(oplog) = fopen(oplog_file, "w+"); + if (!PHPDBG_G(oplog)) { + phpdbg_error( + "Failed to open oplog %s", oplog_file); + } + free(oplog_file); + } + + /* set default colors */ + phpdbg_set_color_ex(PHPDBG_COLOR_PROMPT, PHPDBG_STRL("white-bold") TSRMLS_CC); + phpdbg_set_color_ex(PHPDBG_COLOR_ERROR, PHPDBG_STRL("red-bold") TSRMLS_CC); + phpdbg_set_color_ex(PHPDBG_COLOR_NOTICE, PHPDBG_STRL("green") TSRMLS_CC); + + /* set default prompt */ + phpdbg_set_prompt(PROMPT TSRMLS_CC); + + zend_try { + zend_activate_modules(TSRMLS_C); + } zend_end_try(); + + if (show_banner) { + /* print blurb */ + phpdbg_welcome((cleaning > 0) TSRMLS_CC); + } + + zend_try { + /* activate globals, they can be overwritten */ + zend_activate_auto_globals(TSRMLS_C); + } zend_end_try(); + + /* initialize from file */ + zend_try { + PHPDBG_G(flags) |= PHPDBG_IS_INITIALIZING; + phpdbg_init(init_file, init_file_len, init_file_default TSRMLS_CC); + phpdbg_try_file_init(bp_tmp_file, strlen(bp_tmp_file), 0 TSRMLS_CC); + PHPDBG_G(flags) &= ~PHPDBG_IS_INITIALIZING; + } zend_catch { + PHPDBG_G(flags) &= ~PHPDBG_IS_INITIALIZING; + if (PHPDBG_G(flags) & PHPDBG_IS_QUITTING) { + goto phpdbg_out; + } + } zend_end_try(); + + /* step from here, not through init */ + if (step) { + PHPDBG_G(flags) |= PHPDBG_IS_STEPPING; + } + + if (run) { + /* no need to try{}, run does it ... */ + PHPDBG_COMMAND_HANDLER(run)(NULL, NULL TSRMLS_CC); + if (run > 1) { + /* if -r is on the command line more than once just quit */ + goto phpdbg_out; + } + } + +phpdbg_interact: + /* phpdbg main() */ + do { + zend_try { + phpdbg_interactive(TSRMLS_C); + } zend_catch { + if ((PHPDBG_G(flags) & PHPDBG_IS_CLEANING)) { + FILE *bp_tmp_fp = fopen(bp_tmp_file, "w"); + phpdbg_export_breakpoints(bp_tmp_fp TSRMLS_CC); + fclose(bp_tmp_fp); + cleaning = 1; + goto phpdbg_out; + } else { + cleaning = 0; + } +#ifndef _WIN32 + /* remote client disconnected */ + if ((PHPDBG_G(flags) & PHPDBG_IS_DISCONNECTED)) { + + /* renegociate connections */ + phpdbg_open_sockets( + address, listen, &server, &socket, streams); + + /* set streams */ + if (streams[0] && streams[1]) { + PHPDBG_G(flags) &= ~PHPDBG_IS_QUITTING; + } + + /* this must be forced */ + CG(unclean_shutdown) = 0; + } +#endif + if (PHPDBG_G(flags) & PHPDBG_IS_QUITTING) { + goto phpdbg_out; + } + } zend_end_try(); + } while(!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)); + + /* this must be forced */ + CG(unclean_shutdown) = 0; + +phpdbg_out: +#ifndef _WIN32 + if (PHPDBG_G(flags) & PHPDBG_IS_DISCONNECTED) { + PHPDBG_G(flags) &= ~PHPDBG_IS_DISCONNECTED; + goto phpdbg_interact; + } +#endif + +#ifndef ZTS + /* force cleanup of auto and core globals */ + zend_hash_clean(CG(auto_globals)); + memset( + &core_globals, 0, sizeof(php_core_globals)); +#endif + + if (ini_entries) { + free(ini_entries); + } + + if (ini_override) { + free(ini_override); + } + + if (PG(modules_activated)) { + zend_try { + zend_deactivate_modules(TSRMLS_C); + } zend_end_try(); + } + + zend_deactivate(TSRMLS_C); + + zend_try { + zend_post_deactivate_modules(TSRMLS_C); + } zend_end_try(); + +#ifdef ZEND_SIGNALS + zend_try { + zend_signal_deactivate(TSRMLS_C); + } zend_end_try(); +#endif + + zend_try { + php_module_shutdown(TSRMLS_C); + } zend_end_try(); + + sapi_shutdown(); + } + + if (cleaning || remote) { + goto phpdbg_main; + } + +#ifdef ZTS + /* bugggy */ + /* tsrm_shutdown(); */ +#endif + +#ifndef _WIN32 + if (address) { + free(address); + } +#endif + + if (sapi_name) { + free(sapi_name); + } + + free(bp_tmp_file); + + return 0; +} /* }}} */ diff --git a/sapi/phpdbg/phpdbg.h b/sapi/phpdbg/phpdbg.h new file mode 100644 index 0000000000000..f0a59ce4731df --- /dev/null +++ b/sapi/phpdbg/phpdbg.h @@ -0,0 +1,187 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Felipe Pena | + | Authors: Joe Watkins | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHPDBG_H +#define PHPDBG_H + +#ifdef PHP_WIN32 +# define PHPDBG_API __declspec(dllexport) +#elif defined(__GNUC__) && __GNUC__ >= 4 +# define PHPDBG_API __attribute__ ((visibility("default"))) +#else +# define PHPDBG_API +#endif + +#include "php.h" +#include "php_globals.h" +#include "php_variables.h" +#include "php_getopt.h" +#include "zend_builtin_functions.h" +#include "zend_extensions.h" +#include "zend_modules.h" +#include "zend_globals.h" +#include "zend_ini_scanner.h" +#include "zend_stream.h" +#include "SAPI.h" +#include +#include +#if defined(_WIN32) && !defined(__MINGW32__) +# include +# include "config.w32.h" +# undef strcasecmp +# undef strncasecmp +# define strcasecmp _stricmp +# define strncasecmp _strnicmp +#else +# include "php_config.h" +#endif +#ifndef O_BINARY +# define O_BINARY 0 +#endif +#include "php_main.h" + +#ifdef ZTS +# include "TSRM.h" +#endif + +#ifdef HAVE_LIBREADLINE +# include +# include +#endif + +#include "phpdbg_cmd.h" +#include "phpdbg_utils.h" + +#ifdef ZTS +# define PHPDBG_G(v) TSRMG(phpdbg_globals_id, zend_phpdbg_globals *, v) +#else +# define PHPDBG_G(v) (phpdbg_globals.v) +#endif + +#define PHPDBG_NEXT 2 +#define PHPDBG_UNTIL 3 +#define PHPDBG_FINISH 4 +#define PHPDBG_LEAVE 5 + +/* + BEGIN: DO NOT CHANGE DO NOT CHANGE DO NOT CHANGE +*/ + +/* {{{ tables */ +#define PHPDBG_BREAK_FILE 0 +#define PHPDBG_BREAK_SYM 1 +#define PHPDBG_BREAK_OPLINE 2 +#define PHPDBG_BREAK_METHOD 3 +#define PHPDBG_BREAK_COND 4 +#define PHPDBG_BREAK_OPCODE 5 +#define PHPDBG_BREAK_FUNCTION_OPLINE 6 +#define PHPDBG_BREAK_METHOD_OPLINE 7 +#define PHPDBG_BREAK_FILE_OPLINE 8 +#define PHPDBG_BREAK_MAP 9 +#define PHPDBG_BREAK_TABLES 10 /* }}} */ + +/* {{{ flags */ +#define PHPDBG_HAS_FILE_BP (1<<1) +#define PHPDBG_HAS_SYM_BP (1<<2) +#define PHPDBG_HAS_OPLINE_BP (1<<3) +#define PHPDBG_HAS_METHOD_BP (1<<4) +#define PHPDBG_HAS_COND_BP (1<<5) +#define PHPDBG_HAS_OPCODE_BP (1<<6) +#define PHPDBG_HAS_FUNCTION_OPLINE_BP (1<<7) +#define PHPDBG_HAS_METHOD_OPLINE_BP (1<<8) +#define PHPDBG_HAS_FILE_OPLINE_BP (1<<9) /* }}} */ + +/* + END: DO NOT CHANGE DO NOT CHANGE DO NOT CHANGE +*/ + +#define PHPDBG_IN_COND_BP (1<<10) +#define PHPDBG_IN_EVAL (1<<11) + +#define PHPDBG_IS_STEPPING (1<<12) +#define PHPDBG_IS_QUIET (1<<13) +#define PHPDBG_IS_QUITTING (1<<14) +#define PHPDBG_IS_COLOURED (1<<15) +#define PHPDBG_IS_CLEANING (1<<16) + +#define PHPDBG_IN_UNTIL (1<<17) +#define PHPDBG_IN_FINISH (1<<18) +#define PHPDBG_IN_LEAVE (1<<19) + +#define PHPDBG_IS_REGISTERED (1<<20) +#define PHPDBG_IS_STEPONEVAL (1<<21) +#define PHPDBG_IS_INITIALIZING (1<<22) +#define PHPDBG_IS_SIGNALED (1<<23) +#define PHPDBG_IS_INTERACTIVE (1<<24) +#define PHPDBG_IS_BP_ENABLED (1<<25) +#define PHPDBG_IS_REMOTE (1<<26) +#define PHPDBG_IS_DISCONNECTED (1<<27) + +#define PHPDBG_SEEK_MASK (PHPDBG_IN_UNTIL|PHPDBG_IN_FINISH|PHPDBG_IN_LEAVE) +#define PHPDBG_BP_RESOLVE_MASK (PHPDBG_HAS_FUNCTION_OPLINE_BP|PHPDBG_HAS_METHOD_OPLINE_BP|PHPDBG_HAS_FILE_OPLINE_BP) +#define PHPDBG_BP_MASK (PHPDBG_HAS_FILE_BP|PHPDBG_HAS_SYM_BP|PHPDBG_HAS_METHOD_BP|PHPDBG_HAS_OPLINE_BP|PHPDBG_HAS_COND_BP|PHPDBG_HAS_OPCODE_BP|PHPDBG_HAS_FUNCTION_OPLINE_BP|PHPDBG_HAS_METHOD_OPLINE_BP|PHPDBG_HAS_FILE_OPLINE_BP) + +#ifndef _WIN32 +# define PHPDBG_DEFAULT_FLAGS (PHPDBG_IS_QUIET|PHPDBG_IS_COLOURED|PHPDBG_IS_BP_ENABLED) +#else +# define PHPDBG_DEFAULT_FLAGS (PHPDBG_IS_QUIET|PHPDBG_IS_BP_ENABLED) +#endif /* }}} */ + +/* {{{ strings */ +#define PHPDBG_NAME "phpdbg" +#define PHPDBG_AUTHORS "Felipe Pena, Joe Watkins and Bob Weinand" /* Ordered by last name */ +#define PHPDBG_URL "http://phpdbg.com/" +#define PHPDBG_ISSUES "http://github.com/krakjoe/phpdbg/issues" +#define PHPDBG_VERSION "0.3.0" +#define PHPDBG_INIT_FILENAME ".phpdbginit" +/* }}} */ + +/* {{{ output descriptors */ +#define PHPDBG_STDIN 0 +#define PHPDBG_STDOUT 1 +#define PHPDBG_STDERR 2 +#define PHPDBG_IO_FDS 3 /* }}} */ + +/* {{{ structs */ +ZEND_BEGIN_MODULE_GLOBALS(phpdbg) + HashTable bp[PHPDBG_BREAK_TABLES]; /* break points */ + HashTable registered; /* registered */ + HashTable seek; /* seek oplines */ + phpdbg_frame_t frame; /* frame */ + + char *exec; /* file to execute */ + size_t exec_len; /* size of exec */ + zend_op_array *ops; /* op_array */ + zval *retval; /* return value */ + int bp_count; /* breakpoint count */ + int vmret; /* return from last opcode handler execution */ + + FILE *oplog; /* opline log */ + FILE *io[PHPDBG_IO_FDS]; /* io */ + + char *prompt[2]; /* prompt */ + const phpdbg_color_t *colors[PHPDBG_COLORS]; /* colors */ + + phpdbg_command_t *lcmd; /* last command */ + phpdbg_param_t lparam; /* last param */ + + zend_ulong flags; /* phpdbg flags */ +ZEND_END_MODULE_GLOBALS(phpdbg) /* }}} */ + +#endif /* PHPDBG_H */ diff --git a/sapi/phpdbg/phpdbg.init.d b/sapi/phpdbg/phpdbg.init.d new file mode 100755 index 0000000000000..99a1ab328b897 --- /dev/null +++ b/sapi/phpdbg/phpdbg.init.d @@ -0,0 +1,122 @@ +################################################################ +# File: /etc/init.d/phpdbg # +# Author: krakjoe # +# Purpose: Daemonize phpdbg automatically on boot # +# chkconfig: 2345 07 09 # +# description: Starts, stops and restarts phpdbg daemon # +################################################################ +LOCKFILE=/var/lock/subsys/phpdbg +PIDFILE=/var/run/phpdbg.pid +STDIN=4000 +STDOUT=8000 +################################################################ +# Either set path to phpdbg here or rely on phpdbg in ENV/PATH # +################################################################ +if [ "x${PHPDBG}" == "x" ]; then + PHPDBG=$(which phpdbg 2>/dev/null) +fi +################################################################ +# Options to pass to phpdbg upon boot # +################################################################ +OPTIONS= +LOGFILE=/var/log/phpdbg.log +################################################################ +# STOP EDITING STOP EDITING STOP EDITING STOP EDITING # +################################################################ +. /etc/rc.d/init.d/functions +RETVAL=1 +################################################################ +insanity() +{ + if [ "x${PHPDBG}" == "x" ]; then + PHPDBG=$(which phpdbg 2>>/dev/null) + if [ $? != 0 ]; then + echo -n $"Fatal: cannot find phpdbg ${PHPDBG}" + echo_failure + echo + return 1 + fi + else + if [ ! -x ${PHPDBG} ]; then + echo -n $"Fatal: cannot execute phpdbg ${PHPDBG}" + echo_failure + echo + return 1 + fi + fi + + return 0 +} + +start() +{ + insanity + + if [ $? -eq 1 ]; then + return $RETVAL + fi + + echo -n $"Starting: phpdbg ${OPTIONS} on ${STDIN}/${STDOUT} " + nohup ${PHPDBG} -l${STDIN}/${STDOUT} ${OPTIONS} 2>>${LOGFILE} 1>/dev/null $PIDFILE + echo_success + else + echo_failure + fi + echo + [ $RETVAL = 0 ] && touch ${LOCKFILE} + return $RETVAL +} + +stop() +{ + insanity + + if [ $? -eq 1 ]; then + return $RETVAL + fi + + if [ -f ${LOCKFILE} ] && [ -f ${PIDFILE} ] + then + echo -n $"Stopping: phpdbg ${OPTIONS} on ${STDIN}/${STDOUT} " + kill -s TERM $(cat $PIDFILE) + RETVAL=$? + if [ $RETVAL -eq 0 ]; then + echo_success + else + echo_failure + fi + echo + [ $RETVAL = 0 ] && rm -f ${LOCKFILE} ${PIDFILE} + else + echo -n $"Error: phpdbg not running" + echo_failure + echo + [ $RETVAL = 1 ] + fi + return $RETVAL +} +################################################################## +case "$1" in + start) + start + ;; + stop) + stop + ;; + status) + status $PHPDBG + ;; + restart) + $0 stop + $0 start + ;; + *) + echo "usage: $0 start|stop|restart|status" + ;; +esac +################################################################### +exit $RETVAL diff --git a/sapi/phpdbg/phpdbg_bp.c b/sapi/phpdbg/phpdbg_bp.c new file mode 100644 index 0000000000000..69e0fa7086df7 --- /dev/null +++ b/sapi/phpdbg/phpdbg_bp.c @@ -0,0 +1,1661 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Felipe Pena | + | Authors: Joe Watkins | + | Authors: Bob Weinand | + +----------------------------------------------------------------------+ +*/ + +#include "zend.h" +#include "zend_hash.h" +#include "phpdbg.h" +#include "phpdbg_bp.h" +#include "phpdbg_utils.h" +#include "phpdbg_opcode.h" +#include "zend_globals.h" + +ZEND_EXTERN_MODULE_GLOBALS(phpdbg); + +/* {{{ private api functions */ +static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_file(zend_op_array* TSRMLS_DC); +static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_symbol(zend_function* TSRMLS_DC); +static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_method(zend_op_array* TSRMLS_DC); +static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_opline(phpdbg_opline_ptr_t TSRMLS_DC); +static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_opcode(zend_uchar TSRMLS_DC); +static inline phpdbg_breakbase_t *phpdbg_find_conditional_breakpoint(zend_execute_data *execute_data TSRMLS_DC); /* }}} */ + +/* +* Note: +* A break point must always set the correct id and type +* A set breakpoint function must always map new points +*/ +static inline void _phpdbg_break_mapping(int id, HashTable *table TSRMLS_DC) +{ + zend_hash_index_update( + &PHPDBG_G(bp)[PHPDBG_BREAK_MAP], (id), (void**) &table, sizeof(void*), NULL); +} + +#define PHPDBG_BREAK_MAPPING(id, table) _phpdbg_break_mapping(id, table TSRMLS_CC) +#define PHPDBG_BREAK_UNMAPPING(id) \ + zend_hash_index_del(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], (id)) + +#define PHPDBG_BREAK_INIT(b, t) do {\ + b.id = PHPDBG_G(bp_count)++; \ + b.type = t; \ + b.disabled = 0;\ + b.hits = 0; \ +} while(0) + +static void phpdbg_file_breaks_dtor(void *data) /* {{{ */ +{ + phpdbg_breakfile_t *bp = (phpdbg_breakfile_t*) data; + + efree((char*)bp->filename); +} /* }}} */ + +static void phpdbg_class_breaks_dtor(void *data) /* {{{ */ +{ + phpdbg_breakmethod_t *bp = (phpdbg_breakmethod_t*) data; + + efree((char*)bp->class_name); + efree((char*)bp->func_name); +} /* }}} */ + +static void phpdbg_opline_class_breaks_dtor(void *data) /* {{{ */ +{ + zend_hash_destroy((HashTable *)data); +} /* }}} */ + +static void phpdbg_opline_breaks_dtor(void *data) /* {{{ */ +{ + phpdbg_breakopline_t *bp = (phpdbg_breakopline_t *) data; + + if (bp->class_name) { + efree((char*)bp->class_name); + } + if (bp->func_name) { + efree((char*)bp->func_name); + } +} /* }}} */ + +PHPDBG_API void phpdbg_reset_breakpoints(TSRMLS_D) /* {{{ */ +{ + if (zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP])) { + HashPosition position[2]; + HashTable **table = NULL; + + for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], &position[0]); + zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], (void**)&table, &position[0]) == SUCCESS; + zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], &position[0])) { + phpdbg_breakbase_t *brake; + + for (zend_hash_internal_pointer_reset_ex((*table), &position[1]); + zend_hash_get_current_data_ex((*table), (void**)&brake, &position[1]) == SUCCESS; + zend_hash_move_forward_ex((*table), &position[1])) { + brake->hits = 0; + } + } + } +} /* }}} */ + +PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */ +{ + HashPosition position[2]; + HashTable **table = NULL; + zend_ulong id = 0L; + + if (zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP])) { + phpdbg_notice( + "Exporting %d breakpoints", + zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP])); + /* this only looks like magic, it isn't */ + for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], &position[0]); + zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], (void**)&table, &position[0]) == SUCCESS; + zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], &position[0])) { + phpdbg_breakbase_t *brake; + + zend_hash_get_current_key_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], NULL, NULL, &id, 0, &position[0]); + + for (zend_hash_internal_pointer_reset_ex((*table), &position[1]); + zend_hash_get_current_data_ex((*table), (void**)&brake, &position[1]) == SUCCESS; + zend_hash_move_forward_ex((*table), &position[1])) { + if (brake->id == id) { + switch (brake->type) { + case PHPDBG_BREAK_FILE: { + fprintf(handle, + "break file %s:%lu\n", + ((phpdbg_breakfile_t*)brake)->filename, + ((phpdbg_breakfile_t*)brake)->line); + } break; + + case PHPDBG_BREAK_SYM: { + fprintf(handle, + "break func %s\n", + ((phpdbg_breaksymbol_t*)brake)->symbol); + } break; + + case PHPDBG_BREAK_METHOD: { + fprintf(handle, + "break method %s::%s\n", + ((phpdbg_breakmethod_t*)brake)->class_name, + ((phpdbg_breakmethod_t*)brake)->func_name); + } break; + + case PHPDBG_BREAK_METHOD_OPLINE: { + fprintf(handle, + "break address %s::%s#%ld\n", + ((phpdbg_breakopline_t*)brake)->class_name, + ((phpdbg_breakopline_t*)brake)->func_name, + ((phpdbg_breakopline_t*)brake)->opline_num); + } break; + + case PHPDBG_BREAK_FUNCTION_OPLINE: { + fprintf(handle, + "break address %s#%ld\n", + ((phpdbg_breakopline_t*)brake)->func_name, + ((phpdbg_breakopline_t*)brake)->opline_num); + } break; + + case PHPDBG_BREAK_FILE_OPLINE: { + fprintf(handle, + "break address %s:%ld\n", + ((phpdbg_breakopline_t*)brake)->class_name, + ((phpdbg_breakopline_t*)brake)->opline_num); + } break; + + case PHPDBG_BREAK_OPCODE: { + fprintf(handle, + "break op %s\n", + ((phpdbg_breakop_t*)brake)->name); + } break; + + case PHPDBG_BREAK_COND: { + phpdbg_breakcond_t *conditional = (phpdbg_breakcond_t*) brake; + + if (conditional->paramed) { + switch (conditional->param.type) { + case STR_PARAM: + fprintf(handle, + "break at %s if %s\n", conditional->param.str, conditional->code); + break; + + case METHOD_PARAM: + fprintf(handle, + "break at %s::%s if %s\n", + conditional->param.method.class, conditional->param.method.name, + conditional->code); + break; + + case FILE_PARAM: + fprintf(handle, + "break at %s:%lu if %s\n", + conditional->param.file.name, conditional->param.file.line, + conditional->code); + break; + + default: { /* do nothing */ } break; + } + } else { + fprintf( + handle, "break on %s\n", conditional->code); + } + } break; + } + } + } + } + } +} /* }}} */ + +PHPDBG_API void phpdbg_set_breakpoint_file(const char *path, long line_num TSRMLS_DC) /* {{{ */ +{ + struct stat sb; + + if (VCWD_STAT(path, &sb) != FAILURE) { + if (sb.st_mode & (S_IFREG|S_IFLNK)) { + HashTable *broken; + phpdbg_breakfile_t new_break; + size_t path_len = strlen(path); + + if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], + path, path_len, (void**)&broken) == FAILURE) { + HashTable breaks; + + zend_hash_init(&breaks, 8, NULL, phpdbg_file_breaks_dtor, 0); + + zend_hash_update(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], + path, path_len, &breaks, sizeof(HashTable), + (void**)&broken); + } + + if (!zend_hash_index_exists(broken, line_num)) { + PHPDBG_G(flags) |= PHPDBG_HAS_FILE_BP; + + PHPDBG_BREAK_INIT(new_break, PHPDBG_BREAK_FILE); + new_break.filename = estrndup(path, path_len); + new_break.line = line_num; + + zend_hash_index_update( + broken, line_num, (void**)&new_break, sizeof(phpdbg_breakfile_t), NULL); + + phpdbg_notice("Breakpoint #%d added at %s:%ld", + new_break.id, new_break.filename, new_break.line); + + PHPDBG_BREAK_MAPPING(new_break.id, broken); + } else { + phpdbg_error("Breakpoint at %s:%ld exists", path, line_num); + } + + } else { + phpdbg_error("Cannot set breakpoint in %s, it is not a regular file", path); + } + } else { + phpdbg_error("Cannot stat %s, it does not exist", path); + } +} /* }}} */ + +PHPDBG_API void phpdbg_set_breakpoint_symbol(const char *name, size_t name_len TSRMLS_DC) /* {{{ */ +{ + if (!zend_hash_exists(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], name, name_len)) { + phpdbg_breaksymbol_t new_break; + + PHPDBG_G(flags) |= PHPDBG_HAS_SYM_BP; + + PHPDBG_BREAK_INIT(new_break, PHPDBG_BREAK_SYM); + new_break.symbol = estrndup(name, name_len); + + zend_hash_update(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], new_break.symbol, + name_len, &new_break, sizeof(phpdbg_breaksymbol_t), NULL); + + phpdbg_notice("Breakpoint #%d added at %s", + new_break.id, new_break.symbol); + + PHPDBG_BREAK_MAPPING(new_break.id, &PHPDBG_G(bp)[PHPDBG_BREAK_SYM]); + } else { + phpdbg_notice("Breakpoint exists at %s", name); + } +} /* }}} */ + +PHPDBG_API void phpdbg_set_breakpoint_method(const char *class_name, const char *func_name TSRMLS_DC) /* {{{ */ +{ + HashTable class_breaks, *class_table; + size_t class_len = strlen(class_name); + size_t func_len = strlen(func_name); + char *lcname = zend_str_tolower_dup(func_name, func_len); + + if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], class_name, + class_len, (void**)&class_table) != SUCCESS) { + zend_hash_init(&class_breaks, 8, NULL, phpdbg_class_breaks_dtor, 0); + zend_hash_update( + &PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], + class_name, class_len, + (void**)&class_breaks, sizeof(HashTable), (void**)&class_table); + } + + if (!zend_hash_exists(class_table, lcname, func_len)) { + phpdbg_breakmethod_t new_break; + + PHPDBG_G(flags) |= PHPDBG_HAS_METHOD_BP; + + PHPDBG_BREAK_INIT(new_break, PHPDBG_BREAK_METHOD); + new_break.class_name = estrndup(class_name, class_len); + new_break.class_len = class_len; + new_break.func_name = estrndup(func_name, func_len); + new_break.func_len = func_len; + + zend_hash_update(class_table, lcname, func_len, + &new_break, sizeof(phpdbg_breakmethod_t), NULL); + + phpdbg_notice("Breakpoint #%d added at %s::%s", + new_break.id, class_name, func_name); + + PHPDBG_BREAK_MAPPING(new_break.id, class_table); + } else { + phpdbg_notice("Breakpoint exists at %s::%s", class_name, func_name); + } + + efree(lcname); +} /* }}} */ + +PHPDBG_API void phpdbg_set_breakpoint_opline(zend_ulong opline TSRMLS_DC) /* {{{ */ +{ + if (!zend_hash_index_exists(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], opline)) { + phpdbg_breakline_t new_break; + + PHPDBG_G(flags) |= PHPDBG_HAS_OPLINE_BP; + + PHPDBG_BREAK_INIT(new_break, PHPDBG_BREAK_OPLINE); + new_break.name = NULL; + new_break.opline = opline; + new_break.base = NULL; + + zend_hash_index_update(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], opline, + &new_break, sizeof(phpdbg_breakline_t), NULL); + + phpdbg_notice("Breakpoint #%d added at %#lx", + new_break.id, new_break.opline); + PHPDBG_BREAK_MAPPING(new_break.id, &PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]); + } else { + phpdbg_notice("Breakpoint exists at %#lx", opline); + } +} /* }}} */ + +PHPDBG_API int phpdbg_resolve_op_array_break(phpdbg_breakopline_t *brake, zend_op_array *op_array TSRMLS_DC) /* {{{ */ +{ + phpdbg_breakline_t opline_break; + if (op_array->last < brake->opline_num) { + if (brake->class_name == NULL) { + phpdbg_error("There are only %d oplines in function %s (breaking at opline %ld impossible)", op_array->last, brake->func_name, brake->opline_num); + } else if (brake->func_name == NULL) { + phpdbg_error("There are only %d oplines in file %s (breaking at opline %ld impossible)", op_array->last, brake->class_name, brake->opline_num); + } else { + phpdbg_error("There are only %d oplines in method %s::%s (breaking at opline %ld impossible)", op_array->last, brake->class_name, brake->func_name, brake->opline_num); + } + + return FAILURE; + } + + opline_break.disabled = 0; + opline_break.hits = 0; + opline_break.id = brake->id; + opline_break.opline = brake->opline = (zend_ulong)(op_array->opcodes + brake->opline_num); + opline_break.name = NULL; + opline_break.base = brake; + if (op_array->scope) { + opline_break.type = PHPDBG_BREAK_METHOD_OPLINE; + } else if (op_array->function_name) { + opline_break.type = PHPDBG_BREAK_FUNCTION_OPLINE; + } else { + opline_break.type = PHPDBG_BREAK_FILE_OPLINE; + } + + PHPDBG_G(flags) |= PHPDBG_HAS_OPLINE_BP; + + zend_hash_index_update(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], opline_break.opline, &opline_break, sizeof(phpdbg_breakline_t), NULL); + + return SUCCESS; +} /* }}} */ + +PHPDBG_API void phpdbg_resolve_op_array_breaks(zend_op_array *op_array TSRMLS_DC) /* {{{ */ +{ + HashTable *func_table = &PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE]; + HashTable *oplines_table; + HashPosition position; + phpdbg_breakopline_t *brake; + + if (op_array->scope != NULL && + zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], op_array->scope->name, op_array->scope->name_length, (void **)&func_table) == FAILURE) { + return; + } + + if (op_array->function_name == NULL) { + if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], op_array->filename, strlen(op_array->filename), (void **)&oplines_table) == FAILURE) { + return; + } + } else if (zend_hash_find(func_table, op_array->function_name?op_array->function_name:"", op_array->function_name?strlen(op_array->function_name):0, (void **)&oplines_table) == FAILURE) { + return; + } + + for (zend_hash_internal_pointer_reset_ex(oplines_table, &position); + zend_hash_get_current_data_ex(oplines_table, (void**) &brake, &position) == SUCCESS; + zend_hash_move_forward_ex(oplines_table, &position)) { + if (phpdbg_resolve_op_array_break(brake, op_array TSRMLS_CC) == SUCCESS) { + phpdbg_breakline_t *opline_break; + + zend_hash_internal_pointer_end(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]); + zend_hash_get_current_data(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], (void **)&opline_break); + + phpdbg_notice("Breakpoint #%d resolved at %s%s%s#%ld (opline %#lx)", + brake->id, + brake->class_name?brake->class_name:"", + brake->class_name&&brake->func_name?"::":"", + brake->func_name?brake->func_name:"", + brake->opline_num, + brake->opline); + } + } +} /* }}} */ + +PHPDBG_API int phpdbg_resolve_opline_break(phpdbg_breakopline_t *new_break TSRMLS_DC) /* {{{ */ +{ + HashTable *func_table = EG(function_table); + zend_function *func; + + if (new_break->func_name == NULL) { + if (EG(current_execute_data) == NULL) { + if (PHPDBG_G(ops) != NULL && !memcmp(PHPDBG_G(ops)->filename, new_break->class_name, new_break->class_len)) { + if (phpdbg_resolve_op_array_break(new_break, PHPDBG_G(ops) TSRMLS_CC) == SUCCESS) { + return SUCCESS; + } else { + return 2; + } + } + return FAILURE; + } else { + zend_execute_data *execute_data = EG(current_execute_data); + do { + if (execute_data->op_array->function_name == NULL && execute_data->op_array->scope == NULL && !memcmp(execute_data->op_array->filename, new_break->class_name, new_break->class_len)) { + if (phpdbg_resolve_op_array_break(new_break, execute_data->op_array TSRMLS_CC) == SUCCESS) { + return SUCCESS; + } else { + return 2; + } + } + } while ((execute_data = execute_data->prev_execute_data) != NULL); + return FAILURE; + } + } + + if (new_break->class_name != NULL) { + zend_class_entry **ce; + if (zend_hash_find(EG(class_table), zend_str_tolower_dup(new_break->class_name, new_break->class_len), new_break->class_len + 1, (void **)&ce) == FAILURE) { + return FAILURE; + } + func_table = &(*ce)->function_table; + } + + if (zend_hash_find(func_table, zend_str_tolower_dup(new_break->func_name, new_break->func_len), new_break->func_len + 1, (void **)&func) == FAILURE) { + if (new_break->class_name != NULL && new_break->func_name != NULL) { + phpdbg_error("Method %s doesn't exist in class %s", new_break->func_name, new_break->class_name); + return 2; + } + return FAILURE; + } + + if (func->type != ZEND_USER_FUNCTION) { + if (new_break->class_name == NULL) { + phpdbg_error("%s is not an user defined function, no oplines exist", new_break->func_name); + } else { + phpdbg_error("%s::%s is not an user defined method, no oplines exist", new_break->class_name, new_break->func_name); + } + return 2; + } + + if (phpdbg_resolve_op_array_break(new_break, &func->op_array TSRMLS_CC) == FAILURE) { + return 2; + } + + return SUCCESS; +} /* }}} */ + +PHPDBG_API void phpdbg_set_breakpoint_method_opline(const char *class, const char *method, zend_ulong opline TSRMLS_DC) /* {{{ */ +{ + phpdbg_breakopline_t new_break; + HashTable class_breaks, *class_table; + HashTable method_breaks, *method_table; + + PHPDBG_BREAK_INIT(new_break, PHPDBG_BREAK_METHOD_OPLINE); + new_break.func_len = strlen(method); + new_break.func_name = estrndup(method, new_break.func_len); + new_break.class_len = strlen(class); + new_break.class_name = estrndup(class, new_break.class_len); + new_break.opline_num = opline; + new_break.opline = 0; + + switch (phpdbg_resolve_opline_break(&new_break TSRMLS_CC)) { + case FAILURE: + phpdbg_notice("Pending breakpoint #%d at %s::%s#%ld", new_break.id, new_break.class_name, new_break.func_name, opline); + break; + + case SUCCESS: + phpdbg_notice("Breakpoint #%d added at %s::%s#%ld", new_break.id, new_break.class_name, new_break.func_name, opline); + break; + + case 2: + return; + } + + if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], new_break.class_name, new_break.class_len, (void **)&class_table) == FAILURE) { + zend_hash_init(&class_breaks, 8, NULL, phpdbg_opline_class_breaks_dtor, 0); + zend_hash_update( + &PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], + new_break.class_name, + new_break.class_len, + (void **)&class_breaks, sizeof(HashTable), (void **)&class_table); + } + + if (zend_hash_find(class_table, new_break.func_name, new_break.func_len, (void **)&method_table) == FAILURE) { + zend_hash_init(&method_breaks, 8, NULL, phpdbg_opline_breaks_dtor, 0); + zend_hash_update( + class_table, + new_break.func_name, + new_break.func_len, + (void **)&method_breaks, sizeof(HashTable), (void **)&method_table); + } + + if (zend_hash_index_exists(method_table, opline)) { + phpdbg_notice("Breakpoint already exists for %s::%s#%ld", new_break.class_name, new_break.func_name, opline); + efree((char*)new_break.func_name); + efree((char*)new_break.class_name); + PHPDBG_G(bp_count)--; + return; + } + + PHPDBG_G(flags) |= PHPDBG_HAS_METHOD_OPLINE_BP; + + PHPDBG_BREAK_MAPPING(new_break.id, method_table); + + zend_hash_index_update(method_table, opline, &new_break, sizeof(phpdbg_breakopline_t), NULL); +} + +PHPDBG_API void phpdbg_set_breakpoint_function_opline(const char *function, zend_ulong opline TSRMLS_DC) /* {{{ */ +{ + phpdbg_breakopline_t new_break; + HashTable func_breaks, *func_table; + + PHPDBG_BREAK_INIT(new_break, PHPDBG_BREAK_FUNCTION_OPLINE); + new_break.func_len = strlen(function); + new_break.func_name = estrndup(function, new_break.func_len); + new_break.class_len = 0; + new_break.class_name = NULL; + new_break.opline_num = opline; + new_break.opline = 0; + + switch (phpdbg_resolve_opline_break(&new_break TSRMLS_CC)) { + case FAILURE: + phpdbg_notice("Pending breakpoint #%d at %s#%ld", new_break.id, new_break.func_name, opline); + break; + + case SUCCESS: + phpdbg_notice("Breakpoint #%d added at %s#%ld", new_break.id, new_break.func_name, opline); + break; + + case 2: + return; + } + + if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], new_break.func_name, new_break.func_len, (void **)&func_table) == FAILURE) { + zend_hash_init(&func_breaks, 8, NULL, phpdbg_opline_breaks_dtor, 0); + zend_hash_update( + &PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], + new_break.func_name, + new_break.func_len, + (void **)&func_breaks, sizeof(HashTable), (void **)&func_table); + } + + if (zend_hash_index_exists(func_table, opline)) { + phpdbg_notice("Breakpoint already exists for %s#%ld", new_break.func_name, opline); + efree((char*)new_break.func_name); + PHPDBG_G(bp_count)--; + return; + } + + PHPDBG_BREAK_MAPPING(new_break.id, func_table); + + PHPDBG_G(flags) |= PHPDBG_HAS_FUNCTION_OPLINE_BP; + + zend_hash_index_update(func_table, opline, &new_break, sizeof(phpdbg_breakopline_t), NULL); +} + +PHPDBG_API void phpdbg_set_breakpoint_file_opline(const char *file, zend_ulong opline TSRMLS_DC) /* {{{ */ +{ + phpdbg_breakopline_t new_break; + HashTable file_breaks, *file_table; + + PHPDBG_BREAK_INIT(new_break, PHPDBG_BREAK_FILE_OPLINE); + new_break.func_len = 0; + new_break.func_name = NULL; + new_break.class_len = strlen(file); + new_break.class_name = estrndup(file, new_break.class_len); + new_break.opline_num = opline; + new_break.opline = 0; + + switch (phpdbg_resolve_opline_break(&new_break TSRMLS_CC)) { + case FAILURE: + phpdbg_notice("Pending breakpoint #%d at %s:%ld", new_break.id, new_break.class_name, opline); + break; + + case SUCCESS: + phpdbg_notice("Breakpoint #%d added at %s:%ld", new_break.id, new_break.class_name, opline); + break; + + case 2: + return; + } + + if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], new_break.class_name, new_break.class_len, (void **)&file_table) == FAILURE) { + zend_hash_init(&file_breaks, 8, NULL, phpdbg_opline_breaks_dtor, 0); + zend_hash_update( + &PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], + new_break.class_name, + new_break.class_len, + (void **)&file_breaks, sizeof(HashTable), (void **)&file_table); + } + + if (zend_hash_index_exists(file_table, opline)) { + phpdbg_notice("Breakpoint already exists for %s:%ld", new_break.class_name, opline); + efree((char*)new_break.class_name); + PHPDBG_G(bp_count)--; + return; + } + + PHPDBG_BREAK_MAPPING(new_break.id, file_table); + + PHPDBG_G(flags) |= PHPDBG_HAS_FILE_OPLINE_BP; + + zend_hash_index_update(file_table, opline, &new_break, sizeof(phpdbg_breakopline_t), NULL); +} + +PHPDBG_API void phpdbg_set_breakpoint_opcode(const char *name, size_t name_len TSRMLS_DC) /* {{{ */ +{ + phpdbg_breakop_t new_break; + zend_ulong hash = zend_hash_func(name, name_len); + + if (zend_hash_index_exists(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], hash)) { + phpdbg_notice( + "Breakpoint exists for %s", name); + return; + } + + PHPDBG_BREAK_INIT(new_break, PHPDBG_BREAK_OPCODE); + new_break.hash = hash; + new_break.name = estrndup(name, name_len); + + zend_hash_index_update(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], hash, + &new_break, sizeof(phpdbg_breakop_t), NULL); + + PHPDBG_G(flags) |= PHPDBG_HAS_OPCODE_BP; + + phpdbg_notice("Breakpoint #%d added at %s", new_break.id, name); + PHPDBG_BREAK_MAPPING(new_break.id, &PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE]); +} /* }}} */ + +PHPDBG_API void phpdbg_set_breakpoint_opline_ex(phpdbg_opline_ptr_t opline TSRMLS_DC) /* {{{ */ +{ + if (!zend_hash_index_exists(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], (zend_ulong) opline)) { + phpdbg_breakline_t new_break; + + PHPDBG_G(flags) |= PHPDBG_HAS_OPLINE_BP; + + PHPDBG_BREAK_INIT(new_break, PHPDBG_BREAK_OPLINE); + new_break.opline = (zend_ulong) opline; + + zend_hash_index_update(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], + (zend_ulong) opline, &new_break, sizeof(phpdbg_breakline_t), NULL); + + phpdbg_notice("Breakpoint #%d added at %#lx", + new_break.id, new_break.opline); + PHPDBG_BREAK_MAPPING(new_break.id, &PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]); + } +} /* }}} */ + +static inline void phpdbg_create_conditional_break(phpdbg_breakcond_t *brake, const phpdbg_param_t *param, const char *expr, size_t expr_len, zend_ulong hash TSRMLS_DC) /* {{{ */ +{ + phpdbg_breakcond_t new_break; + zend_uint cops = CG(compiler_options); + zval pv; + + PHPDBG_BREAK_INIT(new_break, PHPDBG_BREAK_COND); + new_break.hash = hash; + + if (param) { + new_break.paramed = 1; + phpdbg_copy_param( + param, &new_break.param TSRMLS_CC); + } else { + new_break.paramed = 0; + } + + cops = CG(compiler_options); + + CG(compiler_options) = ZEND_COMPILE_DEFAULT_FOR_EVAL; + + new_break.code = estrndup(expr, expr_len); + new_break.code_len = expr_len; + + Z_STRLEN(pv) = expr_len + sizeof("return ;") - 1; + Z_STRVAL(pv) = emalloc(Z_STRLEN(pv) + 1); + memcpy(Z_STRVAL(pv), "return ", sizeof("return ") - 1); + memcpy(Z_STRVAL(pv) + sizeof("return ") - 1, expr, expr_len); + Z_STRVAL(pv)[Z_STRLEN(pv) - 1] = ';'; + Z_STRVAL(pv)[Z_STRLEN(pv)] = '\0'; + Z_TYPE(pv) = IS_STRING; + + new_break.ops = zend_compile_string( + &pv, "Conditional Breakpoint Code" TSRMLS_CC); + + zval_dtor(&pv); + + if (new_break.ops) { + zend_hash_index_update( + &PHPDBG_G(bp)[PHPDBG_BREAK_COND], hash, &new_break, + sizeof(phpdbg_breakcond_t), (void**)&brake); + + phpdbg_notice("Conditional breakpoint #%d added %s/%p", + brake->id, brake->code, brake->ops); + + PHPDBG_G(flags) |= PHPDBG_HAS_COND_BP; + PHPDBG_BREAK_MAPPING(new_break.id, &PHPDBG_G(bp)[PHPDBG_BREAK_COND]); + } else { + phpdbg_error( + "Failed to compile code for expression %s", expr); + efree((char*)new_break.code); + PHPDBG_G(bp_count)--; + } + CG(compiler_options) = cops; +} /* }}} */ + +PHPDBG_API void phpdbg_set_breakpoint_expression(const char *expr, size_t expr_len TSRMLS_DC) /* {{{ */ +{ + zend_ulong expr_hash = zend_inline_hash_func(expr, expr_len); + phpdbg_breakcond_t new_break; + + if (!zend_hash_index_exists(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], expr_hash)) { + phpdbg_create_conditional_break( + &new_break, NULL, expr, expr_len, expr_hash TSRMLS_CC); + } else { + phpdbg_notice("Conditional break %s exists", expr); + } +} /* }}} */ + +PHPDBG_API void phpdbg_set_breakpoint_at(const phpdbg_param_t *param, const phpdbg_input_t *input TSRMLS_DC) /* {{{ */ +{ + if (input->argc > 3 && phpdbg_argv_is(2, "if")) { + phpdbg_breakcond_t new_break; + phpdbg_param_t new_param; + + zend_ulong expr_hash = 0L; + size_t expr_len; + const char *join = strstr(input->string, "if"); + const char *expr = (join) + sizeof("if"); + + expr_len = strlen(expr); + expr = phpdbg_trim(expr, expr_len, &expr_len); + expr_hash = zend_inline_hash_func(expr, expr_len); + + { + /* get a clean parameter from input string */ + size_t sparam_len = 0L; + char *sparam = input->string; + + sparam[ + strstr(input->string, " ") - input->string] = 0; + sparam_len = strlen(sparam); + + switch (phpdbg_parse_param(sparam, sparam_len, &new_param TSRMLS_CC)) { + case EMPTY_PARAM: + case NUMERIC_PARAM: + phpdbg_clear_param( + &new_param TSRMLS_CC); + goto usage; + + default: { /* do nothing */ } break; + } + + expr_hash += phpdbg_hash_param(&new_param TSRMLS_CC); + } + + if (!zend_hash_index_exists(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], expr_hash)) { + phpdbg_create_conditional_break( + &new_break, &new_param, expr, expr_len, expr_hash TSRMLS_CC); + } else { + phpdbg_notice( + "Conditional break %s exists at the specified location", expr); + } + + phpdbg_clear_param(&new_param TSRMLS_CC); + } else { +usage: + phpdbg_error("usage: break at if "); + } +} /* }}} */ + +static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_file(zend_op_array *op_array TSRMLS_DC) /* {{{ */ +{ + HashTable *breaks; + phpdbg_breakbase_t *brake; + size_t name_len = strlen(op_array->filename); + + if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], op_array->filename, + name_len, (void**)&breaks) == FAILURE) { + return NULL; + } + + if (zend_hash_index_find(breaks, (*EG(opline_ptr))->lineno, (void**)&brake) == SUCCESS) { + return brake; + } + + return NULL; +} /* }}} */ + +static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_symbol(zend_function *fbc TSRMLS_DC) /* {{{ */ +{ + const char *fname; + zend_op_array *ops; + phpdbg_breakbase_t *brake; + + if (fbc->type != ZEND_USER_FUNCTION) { + return NULL; + } + + ops = (zend_op_array*)fbc; + + if (ops->scope) { + /* find method breaks here */ + return phpdbg_find_breakpoint_method(ops TSRMLS_CC); + } + + fname = ops->function_name; + + if (!fname) { + fname = "main"; + } + + if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], fname, strlen(fname), (void**)&brake) == SUCCESS) { + return brake; + } + + return NULL; +} /* }}} */ + +static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_method(zend_op_array *ops TSRMLS_DC) /* {{{ */ +{ + HashTable *class_table; + phpdbg_breakbase_t *brake; + + if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], ops->scope->name, + ops->scope->name_length, (void**)&class_table) == SUCCESS) { + char *lcname = zend_str_tolower_dup(ops->function_name, strlen(ops->function_name)); + size_t lcname_len = strlen(lcname); + + if (zend_hash_find( + class_table, + lcname, + lcname_len, (void**)&brake) == SUCCESS) { + efree(lcname); + return brake; + } + + efree(lcname); + } + + return NULL; +} /* }}} */ + +static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_opline(phpdbg_opline_ptr_t opline TSRMLS_DC) /* {{{ */ +{ + phpdbg_breakline_t *brake; + + if (zend_hash_index_find(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], + (zend_ulong) opline, (void**)&brake) == SUCCESS) { + return (brake->base?(phpdbg_breakbase_t *)brake->base:(phpdbg_breakbase_t *)brake); + } + + return NULL; +} /* }}} */ + +static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_opcode(zend_uchar opcode TSRMLS_DC) /* {{{ */ +{ + phpdbg_breakbase_t *brake; + const char *opname = phpdbg_decode_opcode(opcode); + + if (memcmp(opname, PHPDBG_STRL("UNKNOWN")) == 0) { + return NULL; + } + + if (zend_hash_index_find(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], + zend_hash_func(opname, strlen(opname)), (void**)&brake) == SUCCESS) { + return brake; + } + return NULL; +} /* }}} */ + +static inline zend_bool phpdbg_find_breakpoint_param(phpdbg_param_t *param, zend_execute_data *execute_data TSRMLS_DC) /* {{{ */ +{ + zend_function *function = (zend_function*) execute_data->function_state.function; + + switch (param->type) { + case NUMERIC_FUNCTION_PARAM: + case STR_PARAM: { + /* function breakpoint */ + + if (function->type != ZEND_USER_FUNCTION) { + return 0; + } + + { + const char *str = NULL; + size_t len = 0L; + zend_op_array *ops = (zend_op_array*)function; + str = ops->function_name ? ops->function_name : "main"; + len = strlen(str); + + if (len == param->len && memcmp(param->str, str, len) == SUCCESS) { + return param->type == STR_PARAM || execute_data->opline - ops->opcodes == param->num; + } + } + } break; + + case FILE_PARAM: { + if (param->file.line == zend_get_executed_lineno(TSRMLS_C)) { + const char *str = zend_get_executed_filename(TSRMLS_C); + size_t lengths[2] = {strlen(param->file.name), strlen(str)}; + + if (lengths[0] == lengths[1]) { + return (memcmp( + param->file.name, str, lengths[0]) == SUCCESS); + } + } + } break; + + case NUMERIC_METHOD_PARAM: + case METHOD_PARAM: { + if (function->type != ZEND_USER_FUNCTION) { + return 0; + } + + { + zend_op_array *ops = (zend_op_array*) function; + + if (ops->scope) { + size_t lengths[2] = {strlen(param->method.class), ops->scope->name_length}; + if (lengths[0] == lengths[1] && memcmp(param->method.class, ops->scope->name, lengths[0]) == SUCCESS) { + lengths[0] = strlen(param->method.name); + lengths[1] = strlen(ops->function_name); + + if (lengths[0] == lengths[1] && memcmp(param->method.name, ops->function_name, lengths[0]) == SUCCESS) { + return param->type == METHOD_PARAM || (execute_data->opline - ops->opcodes) == param->num; + } + } + } + } + } break; + + case ADDR_PARAM: { + return ((zend_ulong)(phpdbg_opline_ptr_t)execute_data->opline == param->addr); + } break; + + default: { + /* do nothing */ + } break; + } + return 0; +} /* }}} */ + +static inline phpdbg_breakbase_t *phpdbg_find_conditional_breakpoint(zend_execute_data *execute_data TSRMLS_DC) /* {{{ */ +{ + phpdbg_breakcond_t *bp; + HashPosition position; + int breakpoint = FAILURE; + + for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], &position); + zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], (void*)&bp, &position) == SUCCESS; + zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], &position)) { + zval *retval = NULL; + int orig_interactive = CG(interactive); + zval **orig_retval = EG(return_value_ptr_ptr); + zend_op_array *orig_ops = EG(active_op_array); + zend_op **orig_opline = EG(opline_ptr); + + if (((phpdbg_breakbase_t*)bp)->disabled) { + continue; + } + + if (bp->paramed) { + if (!phpdbg_find_breakpoint_param(&bp->param, execute_data TSRMLS_CC)) { + continue; + } + } + + ALLOC_INIT_ZVAL(retval); + + EG(return_value_ptr_ptr) = &retval; + EG(active_op_array) = bp->ops; + EG(no_extensions) = 1; + + if (!EG(active_symbol_table)) { + zend_rebuild_symbol_table(TSRMLS_C); + } + + CG(interactive) = 0; + + zend_try { + PHPDBG_G(flags) |= PHPDBG_IN_COND_BP; + zend_execute(EG(active_op_array) TSRMLS_CC); +#if PHP_VERSION_ID >= 50700 + if (zend_is_true(retval TSRMLS_CC)) { +#else + if (zend_is_true(retval)) { +#endif + breakpoint = SUCCESS; + } + } zend_catch { + CG(interactive) = orig_interactive; + + EG(no_extensions)=1; + EG(return_value_ptr_ptr) = orig_retval; + EG(active_op_array) = orig_ops; + EG(opline_ptr) = orig_opline; + PHPDBG_G(flags) &= ~PHPDBG_IN_COND_BP; + } zend_end_try(); + + CG(interactive) = orig_interactive; + + EG(no_extensions)=1; + EG(return_value_ptr_ptr) = orig_retval; + EG(active_op_array) = orig_ops; + EG(opline_ptr) = orig_opline; + PHPDBG_G(flags) &= ~PHPDBG_IN_COND_BP; + + if (breakpoint == SUCCESS) { + break; + } + } + + return (breakpoint == SUCCESS) ? ((phpdbg_breakbase_t*)bp) : NULL; +} /* }}} */ + +PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakpoint(zend_execute_data* execute_data TSRMLS_DC) /* {{{ */ +{ + phpdbg_breakbase_t *base = NULL; + + if (!(PHPDBG_G(flags) & PHPDBG_IS_BP_ENABLED)) { + return NULL; + } + + /* conditions cannot be executed by eval()'d code */ + if (!(PHPDBG_G(flags) & PHPDBG_IN_EVAL) && + (PHPDBG_G(flags) & PHPDBG_HAS_COND_BP) && + (base = phpdbg_find_conditional_breakpoint(execute_data TSRMLS_CC))) { + goto result; + } + + if ((PHPDBG_G(flags) & PHPDBG_HAS_FILE_BP) && + (base = phpdbg_find_breakpoint_file(execute_data->op_array TSRMLS_CC))) { + goto result; + } + + if (PHPDBG_G(flags) & (PHPDBG_HAS_METHOD_BP|PHPDBG_HAS_SYM_BP)) { + /* check we are at the beginning of the stack */ + if (execute_data->opline == EG(active_op_array)->opcodes) { + if ((base = phpdbg_find_breakpoint_symbol( + execute_data->function_state.function TSRMLS_CC))) { + goto result; + } + } + } + + if ((PHPDBG_G(flags) & PHPDBG_HAS_OPLINE_BP) && + (base = phpdbg_find_breakpoint_opline(execute_data->opline TSRMLS_CC))) { + goto result; + } + + if ((PHPDBG_G(flags) & PHPDBG_HAS_OPCODE_BP) && + (base = phpdbg_find_breakpoint_opcode(execute_data->opline->opcode TSRMLS_CC))) { + goto result; + } + + return NULL; + +result: + /* we return nothing for disable breakpoints */ + if (base->disabled) { + return NULL; + } + + return base; +} /* }}} */ + +PHPDBG_API void phpdbg_delete_breakpoint(zend_ulong num TSRMLS_DC) /* {{{ */ +{ + HashTable **table; + HashPosition position; + phpdbg_breakbase_t *brake; + + if ((brake = phpdbg_find_breakbase_ex(num, &table, &position TSRMLS_CC))) { + char *key; + zend_uint klen; + zend_ulong idx; + int type = brake->type; + char *name = NULL; + size_t name_len = 0L; + + switch (type) { + case PHPDBG_BREAK_FILE: + case PHPDBG_BREAK_METHOD: + if (zend_hash_num_elements((*table)) == 1) { + name = estrdup(brake->name); + name_len = strlen(name); + if (zend_hash_num_elements(&PHPDBG_G(bp)[type]) == 1) { + PHPDBG_G(flags) &= ~(1<<(brake->type+1)); + } + } + break; + + default: { + if (zend_hash_num_elements((*table)) == 1) { + PHPDBG_G(flags) &= ~(1<<(brake->type+1)); + } + } + } + + switch (type) { + case PHPDBG_BREAK_FILE_OPLINE: + case PHPDBG_BREAK_FUNCTION_OPLINE: + case PHPDBG_BREAK_METHOD_OPLINE: + if (zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]) == 1) { + PHPDBG_G(flags) &= PHPDBG_HAS_OPLINE_BP; + } + zend_hash_index_del(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], ((phpdbg_breakopline_t*)brake)->opline); + } + + switch (zend_hash_get_current_key_ex( + (*table), &key, &klen, &idx, 0, &position)) { + + case HASH_KEY_IS_STRING: + zend_hash_del((*table), key, klen); + break; + + default: + zend_hash_index_del((*table), idx); + } + + switch (type) { + case PHPDBG_BREAK_FILE: + case PHPDBG_BREAK_METHOD: + if (name) { + zend_hash_del(&PHPDBG_G(bp)[type], name, name_len); + efree(name); + } + break; + } + + phpdbg_notice("Deleted breakpoint #%ld", num); + PHPDBG_BREAK_UNMAPPING(num); + } else { + phpdbg_error("Failed to find breakpoint #%ld", num); + } +} /* }}} */ + +PHPDBG_API void phpdbg_clear_breakpoints(TSRMLS_D) /* {{{ */ +{ + zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE]); + zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM]); + zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]); + zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE]); + zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE]); + zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE]); + zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE]); + zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD]); + zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_COND]); + zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP]); + + PHPDBG_G(flags) &= ~PHPDBG_BP_MASK; + + PHPDBG_G(bp_count) = 0; +} /* }}} */ + +PHPDBG_API void phpdbg_hit_breakpoint(phpdbg_breakbase_t *brake, zend_bool output TSRMLS_DC) /* {{{ */ +{ + brake->hits++; + + if (output) { + phpdbg_print_breakpoint(brake TSRMLS_CC); + } +} /* }}} */ + +PHPDBG_API void phpdbg_print_breakpoint(phpdbg_breakbase_t *brake TSRMLS_DC) /* {{{ */ +{ + if (!brake) + goto unknown; + + switch (brake->type) { + case PHPDBG_BREAK_FILE: { + phpdbg_notice("Breakpoint #%d at %s:%ld, hits: %lu", + ((phpdbg_breakfile_t*)brake)->id, + ((phpdbg_breakfile_t*)brake)->filename, + ((phpdbg_breakfile_t*)brake)->line, + ((phpdbg_breakfile_t*)brake)->hits); + } break; + + case PHPDBG_BREAK_SYM: { + phpdbg_notice("Breakpoint #%d in %s() at %s:%u, hits: %lu", + ((phpdbg_breaksymbol_t*)brake)->id, + ((phpdbg_breaksymbol_t*)brake)->symbol, + zend_get_executed_filename(TSRMLS_C), + zend_get_executed_lineno(TSRMLS_C), + ((phpdbg_breakfile_t*)brake)->hits); + } break; + + case PHPDBG_BREAK_OPLINE: { + phpdbg_notice("Breakpoint #%d in %#lx at %s:%u, hits: %lu", + ((phpdbg_breakline_t*)brake)->id, + ((phpdbg_breakline_t*)brake)->opline, + zend_get_executed_filename(TSRMLS_C), + zend_get_executed_lineno(TSRMLS_C), + ((phpdbg_breakline_t*)brake)->hits); + } break; + + case PHPDBG_BREAK_METHOD_OPLINE: { + phpdbg_notice("Breakpoint #%d in %s::%s()#%lu at %s:%u, hits: %lu", + ((phpdbg_breakopline_t*)brake)->id, + ((phpdbg_breakopline_t*)brake)->class_name, + ((phpdbg_breakopline_t*)brake)->func_name, + ((phpdbg_breakopline_t*)brake)->opline_num, + zend_get_executed_filename(TSRMLS_C), + zend_get_executed_lineno(TSRMLS_C), + ((phpdbg_breakopline_t*)brake)->hits); + } break; + + case PHPDBG_BREAK_FUNCTION_OPLINE: { + phpdbg_notice("Breakpoint #%d in %s()#%lu at %s:%u, hits: %lu", + ((phpdbg_breakopline_t*)brake)->id, + ((phpdbg_breakopline_t*)brake)->func_name, + ((phpdbg_breakopline_t*)brake)->opline_num, + zend_get_executed_filename(TSRMLS_C), + zend_get_executed_lineno(TSRMLS_C), + ((phpdbg_breakopline_t*)brake)->hits); + } break; + + case PHPDBG_BREAK_FILE_OPLINE: { + phpdbg_notice("Breakpoint #%d in %s:%lu at %s:%u, hits: %lu", + ((phpdbg_breakopline_t*)brake)->id, + ((phpdbg_breakopline_t*)brake)->class_name, + ((phpdbg_breakopline_t*)brake)->opline_num, + zend_get_executed_filename(TSRMLS_C), + zend_get_executed_lineno(TSRMLS_C), + ((phpdbg_breakopline_t*)brake)->hits); + } break; + + case PHPDBG_BREAK_OPCODE: { + phpdbg_notice("Breakpoint #%d in %s at %s:%u, hits: %lu", + ((phpdbg_breakop_t*)brake)->id, + ((phpdbg_breakop_t*)brake)->name, + zend_get_executed_filename(TSRMLS_C), + zend_get_executed_lineno(TSRMLS_C), + ((phpdbg_breakop_t*)brake)->hits); + } break; + + case PHPDBG_BREAK_METHOD: { + phpdbg_notice("Breakpoint #%d in %s::%s() at %s:%u, hits: %lu", + ((phpdbg_breakmethod_t*)brake)->id, + ((phpdbg_breakmethod_t*)brake)->class_name, + ((phpdbg_breakmethod_t*)brake)->func_name, + zend_get_executed_filename(TSRMLS_C), + zend_get_executed_lineno(TSRMLS_C), + ((phpdbg_breakmethod_t*)brake)->hits); + } break; + + case PHPDBG_BREAK_COND: { + if (((phpdbg_breakcond_t*)brake)->paramed) { + char *param; + phpdbg_notice("Conditional breakpoint #%d: at %s if %s %s:%u, hits: %lu", + ((phpdbg_breakcond_t*)brake)->id, + phpdbg_param_tostring(&((phpdbg_breakcond_t*)brake)->param, ¶m TSRMLS_CC), + ((phpdbg_breakcond_t*)brake)->code, + zend_get_executed_filename(TSRMLS_C), + zend_get_executed_lineno(TSRMLS_C), + ((phpdbg_breakcond_t*)brake)->hits); + if (param) + free(param); + } else { + phpdbg_notice("Conditional breakpoint #%d: on %s == true %s:%u, hits: %lu", + ((phpdbg_breakcond_t*)brake)->id, + ((phpdbg_breakcond_t*)brake)->code, + zend_get_executed_filename(TSRMLS_C), + zend_get_executed_lineno(TSRMLS_C), + ((phpdbg_breakcond_t*)brake)->hits); + } + + } break; + + default: { +unknown: + phpdbg_notice("Unknown breakpoint at %s:%u", + zend_get_executed_filename(TSRMLS_C), + zend_get_executed_lineno(TSRMLS_C)); + } + } +} /* }}} */ + +PHPDBG_API void phpdbg_enable_breakpoint(zend_ulong id TSRMLS_DC) /* {{{ */ +{ + phpdbg_breakbase_t *brake = phpdbg_find_breakbase(id TSRMLS_CC); + + if (brake) { + brake->disabled = 0; + } +} /* }}} */ + +PHPDBG_API void phpdbg_disable_breakpoint(zend_ulong id TSRMLS_DC) /* {{{ */ +{ + phpdbg_breakbase_t *brake = phpdbg_find_breakbase(id TSRMLS_CC); + + if (brake) { + brake->disabled = 1; + } +} /* }}} */ + +PHPDBG_API void phpdbg_enable_breakpoints(TSRMLS_D) /* {{{ */ +{ + PHPDBG_G(flags) |= PHPDBG_IS_BP_ENABLED; +} /* }}} */ + +PHPDBG_API void phpdbg_disable_breakpoints(TSRMLS_D) { /* {{{ */ + PHPDBG_G(flags) &= ~PHPDBG_IS_BP_ENABLED; +} /* }}} */ + +PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakbase(zend_ulong id TSRMLS_DC) /* {{{ */ +{ + HashTable **table; + HashPosition position; + + return phpdbg_find_breakbase_ex(id, &table, &position TSRMLS_CC); +} /* }}} */ + +PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakbase_ex(zend_ulong id, HashTable ***table, HashPosition *position TSRMLS_DC) /* {{{ */ +{ + if (zend_hash_index_find(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], id, (void**)table) == SUCCESS) { + phpdbg_breakbase_t *brake; + + for (zend_hash_internal_pointer_reset_ex((**table), position); + zend_hash_get_current_data_ex((**table), (void**)&brake, position) == SUCCESS; + zend_hash_move_forward_ex((**table), position)) { + + if (brake->id == id) { + return brake; + } + } + } + return NULL; +} /* }}} */ + +PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ +{ + switch (type) { + case PHPDBG_BREAK_SYM: if ((PHPDBG_G(flags) & PHPDBG_HAS_SYM_BP)) { + HashPosition position; + phpdbg_breaksymbol_t *brake; + + phpdbg_writeln(SEPARATE); + phpdbg_writeln("Function Breakpoints:"); + for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], &position); + zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], (void**) &brake, &position) == SUCCESS; + zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], &position)) { + phpdbg_writeln("#%d\t\t%s%s", + brake->id, brake->symbol, + ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); + } + } break; + + case PHPDBG_BREAK_METHOD: if ((PHPDBG_G(flags) & PHPDBG_HAS_METHOD_BP)) { + HashPosition position[2]; + HashTable *class_table; + char *class_name = NULL; + zend_uint class_len = 0; + zend_ulong class_idx = 0L; + + phpdbg_writeln(SEPARATE); + phpdbg_writeln("Method Breakpoints:"); + for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], &position[0]); + zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], (void**) &class_table, &position[0]) == SUCCESS; + zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], &position[0])) { + + if (zend_hash_get_current_key_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], + &class_name, &class_len, &class_idx, 0, &position[0]) == HASH_KEY_IS_STRING) { + phpdbg_breakmethod_t *brake; + + for (zend_hash_internal_pointer_reset_ex(class_table, &position[1]); + zend_hash_get_current_data_ex(class_table, (void**)&brake, &position[1]) == SUCCESS; + zend_hash_move_forward_ex(class_table, &position[1])) { + phpdbg_writeln("#%d\t\t%s::%s%s", + brake->id, brake->class_name, brake->func_name, + ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); + } + } + + } + } break; + + case PHPDBG_BREAK_FILE: if ((PHPDBG_G(flags) & PHPDBG_HAS_FILE_BP)) { + HashPosition position[2]; + HashTable *points; + + phpdbg_writeln(SEPARATE); + phpdbg_writeln("File Breakpoints:"); + for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], &position[0]); + zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], (void**) &points, &position[0]) == SUCCESS; + zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], &position[0])) { + phpdbg_breakfile_t *brake; + + for (zend_hash_internal_pointer_reset_ex(points, &position[1]); + zend_hash_get_current_data_ex(points, (void**)&brake, &position[1]) == SUCCESS; + zend_hash_move_forward_ex(points, &position[1])) { + phpdbg_writeln("#%d\t\t%s:%lu%s", + brake->id, brake->filename, brake->line, + ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); + } + } + + } break; + + case PHPDBG_BREAK_OPLINE: if ((PHPDBG_G(flags) & PHPDBG_HAS_OPLINE_BP)) { + HashPosition position; + phpdbg_breakline_t *brake; + + phpdbg_writeln(SEPARATE); + phpdbg_writeln("Opline Breakpoints:"); + for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], &position); + zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], (void**) &brake, &position) == SUCCESS; + zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], &position)) { + switch (brake->type) { + case PHPDBG_BREAK_METHOD_OPLINE: + case PHPDBG_BREAK_FUNCTION_OPLINE: + case PHPDBG_BREAK_FILE_OPLINE: + phpdbg_writeln("#%d\t\t%#lx\t\t(%s breakpoint)%s", brake->id, brake->opline, + brake->type == PHPDBG_BREAK_METHOD_OPLINE?"method": + brake->type == PHPDBG_BREAK_FUNCTION_OPLINE?"function": + brake->type == PHPDBG_BREAK_FILE_OPLINE?"file": + "--- error ---", + ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); + break; + + default: + phpdbg_writeln("#%d\t\t%#lx", brake->id, brake->opline); + break; + } + } + } break; + + case PHPDBG_BREAK_METHOD_OPLINE: if ((PHPDBG_G(flags) & PHPDBG_HAS_METHOD_OPLINE_BP)) { + HashPosition position[3]; + HashTable *class_table, *method_table; + char *class_name = NULL, *method_name = NULL; + zend_uint class_len = 0, method_len = 0; + zend_ulong class_idx = 0L, method_idx = 0L; + + phpdbg_writeln(SEPARATE); + phpdbg_writeln("Method opline Breakpoints:"); + for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], &position[0]); + zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], (void**) &class_table, &position[0]) == SUCCESS; + zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], &position[0])) { + + if (zend_hash_get_current_key_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], + &class_name, &class_len, &class_idx, 0, &position[0]) == HASH_KEY_IS_STRING) { + + for (zend_hash_internal_pointer_reset_ex(class_table, &position[1]); + zend_hash_get_current_data_ex(class_table, (void**) &method_table, &position[1]) == SUCCESS; + zend_hash_move_forward_ex(class_table, &position[1])) { + + if (zend_hash_get_current_key_ex(class_table, + &method_name, &method_len, &method_idx, 0, &position[0]) == HASH_KEY_IS_STRING) { + + phpdbg_breakopline_t *brake; + + for (zend_hash_internal_pointer_reset_ex(method_table, &position[2]); + zend_hash_get_current_data_ex(method_table, (void**)&brake, &position[2]) == SUCCESS; + zend_hash_move_forward_ex(method_table, &position[2])) { + phpdbg_writeln("#%d\t\t%s::%s opline %ld%s", + brake->id, brake->class_name, brake->func_name, brake->opline_num, + ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); + } + } + } + } + + } + } break; + + case PHPDBG_BREAK_FUNCTION_OPLINE: if ((PHPDBG_G(flags) & PHPDBG_HAS_FUNCTION_OPLINE_BP)) { + HashPosition position[2]; + HashTable *function_table; + char *function_name = NULL; + zend_uint function_len = 0; + zend_ulong function_idx = 0L; + + phpdbg_writeln(SEPARATE); + phpdbg_writeln("Function opline Breakpoints:"); + for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], &position[0]); + zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], (void**) &function_table, &position[0]) == SUCCESS; + zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], &position[0])) { + + if (zend_hash_get_current_key_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], + &function_name, &function_len, &function_idx, 0, &position[0]) == HASH_KEY_IS_STRING) { + + phpdbg_breakopline_t *brake; + + for (zend_hash_internal_pointer_reset_ex(function_table, &position[1]); + zend_hash_get_current_data_ex(function_table, (void**)&brake, &position[1]) == SUCCESS; + zend_hash_move_forward_ex(function_table, &position[1])) { + phpdbg_writeln("#%d\t\t%s opline %ld%s", + brake->id, brake->func_name, brake->opline_num, + ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); + } + } + + } + } break; + + case PHPDBG_BREAK_FILE_OPLINE: if ((PHPDBG_G(flags) & PHPDBG_HAS_FILE_OPLINE_BP)) { + HashPosition position[2]; + HashTable *file_table; + char *file_name = NULL; + zend_uint file_len = 0; + zend_ulong file_idx = 0L; + + phpdbg_writeln(SEPARATE); + phpdbg_writeln("File opline Breakpoints:"); + for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], &position[0]); + zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], (void**) &file_table, &position[0]) == SUCCESS; + zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], &position[0])) { + + if (zend_hash_get_current_key_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], + &file_name, &file_len, &file_idx, 0, &position[0]) == HASH_KEY_IS_STRING) { + + phpdbg_breakopline_t *brake; + + for (zend_hash_internal_pointer_reset_ex(file_table, &position[1]); + zend_hash_get_current_data_ex(file_table, (void**)&brake, &position[1]) == SUCCESS; + zend_hash_move_forward_ex(file_table, &position[1])) { + phpdbg_writeln("#%d\t\t%s opline %ld%s", + brake->id, brake->class_name, brake->opline_num, + ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); + } + } + } + } break; + + case PHPDBG_BREAK_COND: if ((PHPDBG_G(flags) & PHPDBG_HAS_COND_BP)) { + HashPosition position; + phpdbg_breakcond_t *brake; + + phpdbg_writeln(SEPARATE); + phpdbg_writeln("Conditional Breakpoints:"); + for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], &position); + zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], (void**) &brake, &position) == SUCCESS; + zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], &position)) { + if (brake->paramed) { + switch (brake->param.type) { + case STR_PARAM: + phpdbg_writeln("#%d\t\tat %s if %s%s", + brake->id, + brake->param.str, + brake->code, + ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); + break; + + case NUMERIC_FUNCTION_PARAM: + phpdbg_writeln("#%d\t\tat %s#%ld if %s%s", + brake->id, + brake->param.str, + brake->param.num, + brake->code, + ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); + break; + + case METHOD_PARAM: + phpdbg_writeln("#%d\t\tat %s::%s if %s%s", + brake->id, + brake->param.method.class, + brake->param.method.name, + brake->code, + ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); + break; + + case NUMERIC_METHOD_PARAM: + phpdbg_writeln("#%d\t\tat %s::%s#%ld if %s%s", + brake->id, + brake->param.method.class, + brake->param.method.name, + brake->param.num, + brake->code, + ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); + break; + + case FILE_PARAM: + phpdbg_writeln("#%d\t\tat %s:%lu if %s%s", + brake->id, + brake->param.file.name, + brake->param.file.line, + brake->code, + ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); + break; + + case ADDR_PARAM: + phpdbg_writeln("#%d\t\tat #%lx if %s%s", + brake->id, + brake->param.addr, + brake->code, + ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); + break; + + default: + phpdbg_error("Invalid parameter type for conditional breakpoint"); + return; + } + } else { + phpdbg_writeln("#%d\t\tif %s%s", + brake->id, brake->code, + ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); + } + } + } break; + + case PHPDBG_BREAK_OPCODE: if (PHPDBG_G(flags) & PHPDBG_HAS_OPCODE_BP) { + HashPosition position; + phpdbg_breakop_t *brake; + + phpdbg_writeln(SEPARATE); + phpdbg_writeln("Opcode Breakpoints:"); + for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], &position); + zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], (void**) &brake, &position) == SUCCESS; + zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], &position)) { + phpdbg_writeln("#%d\t\t%s%s", + brake->id, brake->name, + ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); + } + } break; + } +} /* }}} */ diff --git a/sapi/phpdbg/phpdbg_bp.h b/sapi/phpdbg/phpdbg_bp.h new file mode 100644 index 0000000000000..ed1b413f6d3dc --- /dev/null +++ b/sapi/phpdbg/phpdbg_bp.h @@ -0,0 +1,146 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Felipe Pena | + | Authors: Joe Watkins | + | Authors: Bob Weinand | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHPDBG_BP_H +#define PHPDBG_BP_H + +/* {{{ */ +typedef struct _zend_op *phpdbg_opline_ptr_t; /* }}} */ + +/* {{{ breakpoint base structure */ +#define phpdbg_breakbase(name) \ + int id; \ + zend_uchar type; \ + zend_ulong hits; \ + zend_bool disabled; \ + const char *name /* }}} */ + +/* {{{ breakpoint base */ +typedef struct _phpdbg_breakbase_t { + phpdbg_breakbase(name); +} phpdbg_breakbase_t; /* }}} */ + +/** + * Breakpoint file-based representation + */ +typedef struct _phpdbg_breakfile_t { + phpdbg_breakbase(filename); + long line; +} phpdbg_breakfile_t; + +/** + * Breakpoint symbol-based representation + */ +typedef struct _phpdbg_breaksymbol_t { + phpdbg_breakbase(symbol); +} phpdbg_breaksymbol_t; + +/** + * Breakpoint method based representation + */ +typedef struct _phpdbg_breakmethod_t { + phpdbg_breakbase(class_name); + size_t class_len; + const char *func_name; + size_t func_len; +} phpdbg_breakmethod_t; + +/** + * Breakpoint opline num based representation + */ +typedef struct _phpdbg_breakopline_t { + phpdbg_breakbase(func_name); + size_t func_len; + const char *class_name; + size_t class_len; + zend_ulong opline_num; + zend_ulong opline; +} phpdbg_breakopline_t; + +/** + * Breakpoint opline based representation + */ +typedef struct _phpdbg_breakline_t { + phpdbg_breakbase(name); + zend_ulong opline; + phpdbg_breakopline_t *base; +} phpdbg_breakline_t; + +/** + * Breakpoint opcode based representation + */ +typedef struct _phpdbg_breakop_t { + phpdbg_breakbase(name); + zend_ulong hash; +} phpdbg_breakop_t; + +/** + * Breakpoint condition based representation + */ +typedef struct _phpdbg_breakcond_t { + phpdbg_breakbase(code); + size_t code_len; + zend_bool paramed; + phpdbg_param_t param; + zend_ulong hash; + zend_op_array *ops; +} phpdbg_breakcond_t; + +/* {{{ Opline breaks API */ +PHPDBG_API void phpdbg_resolve_op_array_breaks(zend_op_array *op_array TSRMLS_DC); +PHPDBG_API int phpdbg_resolve_op_array_break(phpdbg_breakopline_t *brake, zend_op_array *op_array TSRMLS_DC); +PHPDBG_API int phpdbg_resolve_opline_break(phpdbg_breakopline_t *new_break TSRMLS_DC); /* }}} */ + +/* {{{ Breakpoint Creation API */ +PHPDBG_API void phpdbg_set_breakpoint_file(const char* filename, long lineno TSRMLS_DC); +PHPDBG_API void phpdbg_set_breakpoint_symbol(const char* func_name, size_t func_name_len TSRMLS_DC); +PHPDBG_API void phpdbg_set_breakpoint_method(const char* class_name, const char* func_name TSRMLS_DC); +PHPDBG_API void phpdbg_set_breakpoint_opcode(const char* opname, size_t opname_len TSRMLS_DC); +PHPDBG_API void phpdbg_set_breakpoint_opline(zend_ulong opline TSRMLS_DC); +PHPDBG_API void phpdbg_set_breakpoint_opline_ex(phpdbg_opline_ptr_t opline TSRMLS_DC); +PHPDBG_API void phpdbg_set_breakpoint_method_opline(const char *class, const char *method, zend_ulong opline TSRMLS_DC); +PHPDBG_API void phpdbg_set_breakpoint_function_opline(const char *function, zend_ulong opline TSRMLS_DC); +PHPDBG_API void phpdbg_set_breakpoint_file_opline(const char *file, zend_ulong opline TSRMLS_DC); +PHPDBG_API void phpdbg_set_breakpoint_expression(const char* expression, size_t expression_len TSRMLS_DC); +PHPDBG_API void phpdbg_set_breakpoint_at(const phpdbg_param_t *param, const phpdbg_input_t *input TSRMLS_DC); /* }}} */ + +/* {{{ Breakpoint Detection API */ +PHPDBG_API phpdbg_breakbase_t* phpdbg_find_breakpoint(zend_execute_data* TSRMLS_DC); /* }}} */ + +/* {{{ Misc Breakpoint API */ +PHPDBG_API void phpdbg_hit_breakpoint(phpdbg_breakbase_t* brake, zend_bool output TSRMLS_DC); +PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC); +PHPDBG_API void phpdbg_print_breakpoint(phpdbg_breakbase_t* brake TSRMLS_DC); +PHPDBG_API void phpdbg_reset_breakpoints(TSRMLS_D); +PHPDBG_API void phpdbg_clear_breakpoints(TSRMLS_D); +PHPDBG_API void phpdbg_delete_breakpoint(zend_ulong num TSRMLS_DC); +PHPDBG_API void phpdbg_enable_breakpoints(TSRMLS_D); +PHPDBG_API void phpdbg_enable_breakpoint(zend_ulong id TSRMLS_DC); +PHPDBG_API void phpdbg_disable_breakpoint(zend_ulong id TSRMLS_DC); +PHPDBG_API void phpdbg_disable_breakpoints(TSRMLS_D); /* }}} */ + +/* {{{ Breakbase API */ +PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakbase(zend_ulong id TSRMLS_DC); +PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakbase_ex(zend_ulong id, HashTable ***table, HashPosition *position TSRMLS_DC); /* }}} */ + +/* {{{ Breakpoint Exportation API */ +PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC); /* }}} */ + +#endif /* PHPDBG_BP_H */ diff --git a/sapi/phpdbg/phpdbg_break.c b/sapi/phpdbg/phpdbg_break.c new file mode 100644 index 0000000000000..1423b960e66e3 --- /dev/null +++ b/sapi/phpdbg/phpdbg_break.c @@ -0,0 +1,155 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Felipe Pena | + | Authors: Joe Watkins | + | Authors: Bob Weinand | + +----------------------------------------------------------------------+ +*/ + +#include "phpdbg.h" +#include "phpdbg_print.h" +#include "phpdbg_utils.h" +#include "phpdbg_opcode.h" +#include "phpdbg_break.h" +#include "phpdbg_bp.h" + +ZEND_EXTERN_MODULE_GLOBALS(phpdbg); + +PHPDBG_BREAK(file) /* {{{ */ +{ + switch (param->type) { + case FILE_PARAM: + phpdbg_set_breakpoint_file(param->file.name, param->file.line TSRMLS_CC); + break; + + phpdbg_default_switch_case(); + } + + return SUCCESS; +} /* }}} */ + +PHPDBG_BREAK(method) /* {{{ */ +{ + switch (param->type) { + case METHOD_PARAM: + phpdbg_set_breakpoint_method(param->method.class, param->method.name TSRMLS_CC); + break; + + phpdbg_default_switch_case(); + } + + return SUCCESS; +} /* }}} */ + +PHPDBG_BREAK(address) /* {{{ */ +{ + switch (param->type) { + case ADDR_PARAM: + phpdbg_set_breakpoint_opline(param->addr TSRMLS_CC); + break; + + case NUMERIC_METHOD_PARAM: + phpdbg_set_breakpoint_method_opline(param->method.class, param->method.name, param->num TSRMLS_CC); + break; + + case NUMERIC_FUNCTION_PARAM: + phpdbg_set_breakpoint_function_opline(param->str, param->num TSRMLS_CC); + break; + + case FILE_PARAM: + phpdbg_set_breakpoint_file_opline(param->file.name, param->file.line TSRMLS_CC); + break; + + phpdbg_default_switch_case(); + } + + return SUCCESS; +} /* }}} */ + +PHPDBG_BREAK(on) /* {{{ */ +{ + switch (param->type) { + case STR_PARAM: + phpdbg_set_breakpoint_expression(param->str, param->len TSRMLS_CC); + break; + + phpdbg_default_switch_case(); + } + + return SUCCESS; +} /* }}} */ + +PHPDBG_BREAK(at) /* {{{ */ +{ + phpdbg_set_breakpoint_at(param, input TSRMLS_CC); + + return SUCCESS; +} /* }}} */ + +PHPDBG_BREAK(lineno) /* {{{ */ +{ + switch (param->type) { + case NUMERIC_PARAM: { + if (PHPDBG_G(exec)) { + phpdbg_set_breakpoint_file(phpdbg_current_file(TSRMLS_C), param->num TSRMLS_CC); + } else { + phpdbg_error("Execution context not set!"); + } + } break; + + phpdbg_default_switch_case(); + } + + return SUCCESS; +} /* }}} */ + +PHPDBG_BREAK(func) /* {{{ */ +{ + switch (param->type) { + case STR_PARAM: + phpdbg_set_breakpoint_symbol(param->str, param->len TSRMLS_CC); + break; + + phpdbg_default_switch_case(); + } + + return SUCCESS; +} /* }}} */ + +PHPDBG_BREAK(op) /* {{{ */ +{ + switch (param->type) { + case STR_PARAM: + phpdbg_set_breakpoint_opcode(param->str, param->len TSRMLS_CC); + break; + + phpdbg_default_switch_case(); + } + + return SUCCESS; +} /* }}} */ + +PHPDBG_BREAK(del) /* {{{ */ +{ + switch (param->type) { + case NUMERIC_PARAM: { + phpdbg_delete_breakpoint(param->num TSRMLS_CC); + } break; + + phpdbg_default_switch_case(); + } + + return SUCCESS; +} /* }}} */ diff --git a/sapi/phpdbg/phpdbg_break.h b/sapi/phpdbg/phpdbg_break.h new file mode 100644 index 0000000000000..04abeb6805fb0 --- /dev/null +++ b/sapi/phpdbg/phpdbg_break.h @@ -0,0 +1,58 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Felipe Pena | + | Authors: Joe Watkins | + | Authors: Bob Weinand | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHPDBG_BREAK_H +#define PHPDBG_BREAK_H + +#include "TSRM.h" +#include "phpdbg_cmd.h" + +#define PHPDBG_BREAK(name) PHPDBG_COMMAND(break_##name) + +/** + * Printer Forward Declarations + */ +PHPDBG_BREAK(file); +PHPDBG_BREAK(func); +PHPDBG_BREAK(method); +PHPDBG_BREAK(address); +PHPDBG_BREAK(at); +PHPDBG_BREAK(op); +PHPDBG_BREAK(on); +PHPDBG_BREAK(lineno); +PHPDBG_BREAK(del); + +/** + * Commands + */ +static const phpdbg_command_t phpdbg_break_commands[] = { + PHPDBG_COMMAND_D_EX(file, "specify breakpoint by file:line", 'F', break_file, NULL, 1), + PHPDBG_COMMAND_D_EX(func, "specify breakpoint by global function name", 'f', break_func, NULL, 1), + PHPDBG_COMMAND_D_EX(method, "specify breakpoint by class::method", 'm', break_method, NULL, 1), + PHPDBG_COMMAND_D_EX(address, "specify breakpoint by address", 'a', break_address, NULL, 1), + PHPDBG_COMMAND_D_EX(op, "specify breakpoint by opcode", 'O', break_op, NULL, 1), + PHPDBG_COMMAND_D_EX(on, "specify breakpoint by condition", 'o', break_on, NULL, 1), + PHPDBG_COMMAND_D_EX(at, "specify breakpoint by location and condition", 'A', break_at, NULL, 1), + PHPDBG_COMMAND_D_EX(lineno, "specify breakpoint by line of currently executing file", 'l', break_lineno, NULL, 1), + PHPDBG_COMMAND_D_EX(del, "delete breakpoint by identifier number", 'd', break_del, NULL, 1), + PHPDBG_END_COMMAND +}; + +#endif /* PHPDBG_BREAK_H */ diff --git a/sapi/phpdbg/phpdbg_cmd.c b/sapi/phpdbg/phpdbg_cmd.c new file mode 100644 index 0000000000000..9f052d6f6f385 --- /dev/null +++ b/sapi/phpdbg/phpdbg_cmd.c @@ -0,0 +1,669 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Felipe Pena | + | Authors: Joe Watkins | + | Authors: Bob Weinand | + +----------------------------------------------------------------------+ +*/ + +#include "phpdbg.h" +#include "phpdbg_cmd.h" +#include "phpdbg_utils.h" +#include "phpdbg_set.h" + +ZEND_EXTERN_MODULE_GLOBALS(phpdbg); + +PHPDBG_API const char *phpdbg_get_param_type(const phpdbg_param_t *param TSRMLS_DC) /* {{{ */ +{ + switch (param->type) { + case EMPTY_PARAM: + return "empty"; + case ADDR_PARAM: + return "address"; + case NUMERIC_PARAM: + return "numeric"; + case METHOD_PARAM: + return "method"; + case NUMERIC_FUNCTION_PARAM: + return "function opline"; + case NUMERIC_METHOD_PARAM: + return "method opline"; + case FILE_PARAM: + return "file or file opline"; + case STR_PARAM: + return "string"; + default: /* this is bad */ + return "unknown"; + } +} + +PHPDBG_API phpdbg_param_type phpdbg_parse_param(const char *str, size_t len, phpdbg_param_t *param TSRMLS_DC) /* {{{ */ +{ + char *class_name, *func_name; + + if (len == 0) { + param->type = EMPTY_PARAM; + goto parsed; + } + + if (phpdbg_is_addr(str)) { + param->addr = strtoul(str, 0, 16); + param->type = ADDR_PARAM; + goto parsed; + + } else if (phpdbg_is_numeric(str)) { + param->num = strtol(str, NULL, 0); + param->type = NUMERIC_PARAM; + goto parsed; + + } else if (phpdbg_is_class_method(str, len+1, &class_name, &func_name)) { + param->method.class = class_name; + param->method.name = func_name; + param->type = METHOD_PARAM; + goto parsed; + } else { + char *line_pos = strrchr(str, ':'); + + if (line_pos && phpdbg_is_numeric(line_pos+1)) { + if (strchr(str, ':') == line_pos) { + char path[MAXPATHLEN]; + + memcpy(path, str, line_pos - str); + path[line_pos - str] = 0; + *line_pos = 0; + param->file.name = phpdbg_resolve_path(path TSRMLS_CC); + param->file.line = strtol(line_pos+1, NULL, 0); + param->type = FILE_PARAM; + + goto parsed; + } + } + + line_pos = strrchr(str, '#'); + + if (line_pos && phpdbg_is_numeric(line_pos+1)) { + if (strchr(str, '#') == line_pos) { + param->num = strtol(line_pos + 1, NULL, 0); + + if (phpdbg_is_class_method(str, line_pos - str, &class_name, &func_name)) { + param->method.class = class_name; + param->method.name = func_name; + param->type = NUMERIC_METHOD_PARAM; + } else { + param->len = line_pos - str; + param->str = estrndup(str, param->len); + param->type = NUMERIC_FUNCTION_PARAM; + } + + goto parsed; + } + } + } + + param->str = estrndup(str, len); + param->len = len; + param->type = STR_PARAM; + +parsed: + phpdbg_debug("phpdbg_parse_param(\"%s\", %lu): %s", + str, len, phpdbg_get_param_type(param TSRMLS_CC)); + return param->type; +} /* }}} */ + +PHPDBG_API void phpdbg_clear_param(phpdbg_param_t *param TSRMLS_DC) /* {{{ */ +{ + if (param) { + switch (param->type) { + case FILE_PARAM: + efree(param->file.name); + break; + case METHOD_PARAM: + efree(param->method.class); + efree(param->method.name); + break; + case STR_PARAM: + efree(param->str); + break; + default: + break; + } + } + +} /* }}} */ + +PHPDBG_API char* phpdbg_param_tostring(const phpdbg_param_t *param, char **pointer TSRMLS_DC) /* {{{ */ +{ + switch (param->type) { + case STR_PARAM: + asprintf(pointer, + "%s", param->str); + break; + + case ADDR_PARAM: + asprintf(pointer, + "%#lx", param->addr); + break; + + case NUMERIC_PARAM: + asprintf(pointer, + "%li", + param->num); + break; + + case METHOD_PARAM: + asprintf(pointer, + "%s::%s", + param->method.class, + param->method.name); + break; + + case FILE_PARAM: + if (param->num) { + asprintf(pointer, + "%s:%lu#%lu", + param->file.name, + param->file.line, + param->num); + } else { + asprintf(pointer, + "%s:%lu", + param->file.name, + param->file.line); + } + break; + + case NUMERIC_FUNCTION_PARAM: + asprintf(pointer, + "%s#%lu", param->str, param->num); + break; + + case NUMERIC_METHOD_PARAM: + asprintf(pointer, + "%s::%s#%lu", + param->method.class, + param->method.name, + param->num); + break; + + default: + asprintf(pointer, + "%s", "unknown"); + } + + return *pointer; +} /* }}} */ + +PHPDBG_API void phpdbg_copy_param(const phpdbg_param_t* src, phpdbg_param_t* dest TSRMLS_DC) /* {{{ */ +{ + switch ((dest->type = src->type)) { + case STR_PARAM: + dest->str = estrndup(src->str, src->len); + dest->len = src->len; + break; + + case ADDR_PARAM: + dest->addr = src->addr; + break; + + case NUMERIC_PARAM: + dest->num = src->num; + break; + + case METHOD_PARAM: + dest->method.class = estrdup(src->method.class); + dest->method.name = estrdup(src->method.name); + break; + + case FILE_PARAM: + dest->file.name = estrdup(src->file.name); + dest->file.line = src->file.line; + if (src->num) + dest->num = src->num; + break; + + case NUMERIC_FUNCTION_PARAM: + dest->str = estrndup(src->str, src->len); + dest->num = src->num; + dest->len = src->len; + break; + + case NUMERIC_METHOD_PARAM: + dest->method.class = estrdup(src->method.class); + dest->method.name = estrdup(src->method.name); + dest->num = src->num; + break; + + case EMPTY_PARAM: { /* do nothing */ } break; + } +} /* }}} */ + +PHPDBG_API zend_ulong phpdbg_hash_param(const phpdbg_param_t *param TSRMLS_DC) /* {{{ */ +{ + zend_ulong hash = param->type; + + switch (param->type) { + case STR_PARAM: + hash += zend_inline_hash_func(param->str, param->len); + break; + + case METHOD_PARAM: + hash += zend_inline_hash_func(param->method.class, strlen(param->method.class)); + hash += zend_inline_hash_func(param->method.name, strlen(param->method.name)); + break; + + case FILE_PARAM: + hash += zend_inline_hash_func(param->file.name, strlen(param->file.name)); + hash += param->file.line; + if (param->num) + hash += param->num; + break; + + case ADDR_PARAM: + hash += param->addr; + break; + + case NUMERIC_PARAM: + hash += param->num; + break; + + case NUMERIC_FUNCTION_PARAM: + hash += zend_inline_hash_func(param->str, param->len); + hash += param->num; + break; + + case NUMERIC_METHOD_PARAM: + hash += zend_inline_hash_func(param->method.class, strlen(param->method.class)); + hash += zend_inline_hash_func(param->method.name, strlen(param->method.name)); + if (param->num) + hash+= param->num; + break; + + case EMPTY_PARAM: { /* do nothing */ } break; + } + + return hash; +} /* }}} */ + +PHPDBG_API zend_bool phpdbg_match_param(const phpdbg_param_t *l, const phpdbg_param_t *r TSRMLS_DC) /* {{{ */ +{ + if (l && r) { + if (l->type == r->type) { + switch (l->type) { + + case NUMERIC_FUNCTION_PARAM: + if (l->num != r->num) { + break; + } + /* break intentionally omitted */ + + case STR_PARAM: + return (l->len == r->len) && + (memcmp(l->str, r->str, l->len) == SUCCESS); + + case NUMERIC_PARAM: + return (l->num == r->num); + + case ADDR_PARAM: + return (l->addr == r->addr); + + case FILE_PARAM: { + if (l->file.line == r->file.line) { + size_t lengths[2] = { + strlen(l->file.name), strlen(r->file.name)}; + + if (lengths[0] == lengths[1]) { + if ((!l->num && !r->num) || (l->num == r->num)) { + return (memcmp( + l->file.name, r->file.name, lengths[0]) == SUCCESS); + } + } + } + } break; + + case NUMERIC_METHOD_PARAM: + if (l->num != r->num) { + break; + } + /* break intentionally omitted */ + + case METHOD_PARAM: { + size_t lengths[2] = { + strlen(l->method.class), strlen(r->method.class)}; + if (lengths[0] == lengths[1]) { + if (memcmp(l->method.class, r->method.class, lengths[0]) == SUCCESS) { + lengths[0] = strlen(l->method.name); + lengths[1] = strlen(r->method.name); + + if (lengths[0] == lengths[1]) { + return (memcmp( + l->method.name, r->method.name, lengths[0]) == SUCCESS); + } + } + } + } break; + + case EMPTY_PARAM: + return 1; + } + } + } + return 0; +} /* }}} */ + +PHPDBG_API phpdbg_input_t **phpdbg_read_argv(char *buffer, int *argc TSRMLS_DC) /* {{{ */ +{ + char *p; + char b[PHPDBG_MAX_CMD]; + int l=0; + enum states { + IN_BETWEEN, + IN_WORD, + IN_STRING + } state = IN_BETWEEN; + phpdbg_input_t **argv = NULL; + + argv = (phpdbg_input_t**) emalloc(sizeof(phpdbg_input_t*)); + (*argc) = 0; + +#define RESET_STATE() do { \ + phpdbg_input_t *arg = emalloc(sizeof(phpdbg_input_t)); \ + if (arg) { \ + b[l]=0; \ + arg->length = l; \ + arg->string = estrndup(b, arg->length); \ + arg->argv = NULL; \ + arg->argc = 0; \ + argv = (phpdbg_input_t**) erealloc(argv, sizeof(phpdbg_input_t*) * ((*argc)+1)); \ + argv[(*argc)++] = arg; \ + l = 0; \ + } \ + state = IN_BETWEEN; \ +} while (0) + + for (p = buffer; *p != '\0'; p++) { + int c = (unsigned char) *p; + switch (state) { + case IN_BETWEEN: + if (isspace(c)) { + continue; + } + if (c == '"') { + state = IN_STRING; + continue; + } + state = IN_WORD; + b[l++]=c; + continue; + + case IN_STRING: + if (c == '"') { + if (buffer[(p - buffer)-1] == '\\') { + b[l-1]=c; + continue; + } + RESET_STATE(); + } else { + b[l++]=c; + } + continue; + + case IN_WORD: + if (isspace(c)) { + RESET_STATE(); + } else { + b[l++]=c; + } + continue; + } + } + + switch (state) { + case IN_WORD: { + RESET_STATE(); + } break; + + case IN_STRING: + phpdbg_error( + "Malformed command line (unclosed quote) @ %ld: %s!", + (p - buffer)-1, &buffer[(p - buffer)-1]); + break; + + case IN_BETWEEN: + break; + } + + if ((*argc) == 0) { + /* not needed */ + efree(argv); + + /* to be sure */ + return NULL; + } + + return argv; +} /* }}} */ + +PHPDBG_API phpdbg_input_t *phpdbg_read_input(char *buffered TSRMLS_DC) /* {{{ */ +{ + phpdbg_input_t *buffer = NULL; + char *cmd = NULL; + + if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { + if ((PHPDBG_G(flags) & PHPDBG_IS_REMOTE) && + (buffered == NULL)) { + fflush(PHPDBG_G(io)[PHPDBG_STDOUT]); + } + + if (buffered == NULL) { +#ifndef HAVE_LIBREADLINE + char buf[PHPDBG_MAX_CMD]; + if ((!(PHPDBG_G(flags) & PHPDBG_IS_REMOTE) && !phpdbg_write(phpdbg_get_prompt(TSRMLS_C))) || + !fgets(buf, PHPDBG_MAX_CMD, PHPDBG_G(io)[PHPDBG_STDIN])) { + /* the user has gone away */ + phpdbg_error("Failed to read console!"); + PHPDBG_G(flags) |= (PHPDBG_IS_QUITTING|PHPDBG_IS_DISCONNECTED); + zend_bailout(); + return NULL; + } + + cmd = buf; +#else + if ((PHPDBG_G(flags) & PHPDBG_IS_REMOTE)) { + char buf[PHPDBG_MAX_CMD]; + if (fgets(buf, PHPDBG_MAX_CMD, PHPDBG_G(io)[PHPDBG_STDIN])) { + cmd = buf; + } else cmd = NULL; + } else cmd = readline(phpdbg_get_prompt(TSRMLS_C)); + + if (!cmd) { + /* the user has gone away */ + phpdbg_error("Failed to read console!"); + PHPDBG_G(flags) |= (PHPDBG_IS_QUITTING|PHPDBG_IS_DISCONNECTED); + zend_bailout(); + return NULL; + } + + if (!(PHPDBG_G(flags) & PHPDBG_IS_REMOTE)) { + add_history(cmd); + } +#endif + } else cmd = buffered; + + /* allocate and sanitize buffer */ + buffer = (phpdbg_input_t*) ecalloc(1, sizeof(phpdbg_input_t)); + if (!buffer) { + return NULL; + } + + buffer->string = phpdbg_trim(cmd, strlen(cmd), &buffer->length); + + /* store constant pointer to start of buffer */ + buffer->start = (char* const*) buffer->string; + + buffer->argv = phpdbg_read_argv( + buffer->string, &buffer->argc TSRMLS_CC); + +#ifdef PHPDBG_DEBUG + if (buffer->argc) { + int arg = 0; + + while (arg < buffer->argc) { + phpdbg_debug( + "argv %d=%s", arg, buffer->argv[arg]->string); + arg++; + } + } +#endif + +#ifdef HAVE_LIBREADLINE + if (!buffered && cmd && + !(PHPDBG_G(flags) & PHPDBG_IS_REMOTE)) { + free(cmd); + } +#endif + + return buffer; + } + + return NULL; +} /* }}} */ + +PHPDBG_API void phpdbg_destroy_argv(phpdbg_input_t **argv, int argc TSRMLS_DC) /* {{{ */ +{ + if (argv) { + if (argc) { + int arg; + for (arg=0; argstring) { + efree((*input)->string); + } + + phpdbg_destroy_argv( + (*input)->argv, (*input)->argc TSRMLS_CC); + + efree(*input); + } +} /* }}} */ + +PHPDBG_API int phpdbg_do_cmd(const phpdbg_command_t *command, phpdbg_input_t *input TSRMLS_DC) /* {{{ */ +{ + int rc = FAILURE; + + if (input->argc > 0) { + while (command && command->name && command->handler) { + if (((command->name_len == input->argv[0]->length) && + (memcmp(command->name, input->argv[0]->string, command->name_len) == SUCCESS)) || + (command->alias && + (input->argv[0]->length == 1) && + (command->alias == *input->argv[0]->string))) { + + phpdbg_param_t param; + + param.type = EMPTY_PARAM; + + if (input->argc > 1) { + if (command->subs) { + phpdbg_input_t sub = *input; + + sub.string += input->argv[0]->length; + sub.length -= input->argv[0]->length; + + sub.string = phpdbg_trim( + sub.string, sub.length, &sub.length); + + sub.argc--; + sub.argv++; + + phpdbg_debug( + "trying sub commands in \"%s\" for \"%s\" with %d arguments", + command->name, sub.argv[0]->string, sub.argc-1); + + if (phpdbg_do_cmd(command->subs, &sub TSRMLS_CC) == SUCCESS) { + efree(sub.string); + return SUCCESS; + } + + efree(sub.string); + } + + /* no sub command found */ + { + char *store = input->string; + + input->string += input->argv[0]->length; + input->length -= input->argv[0]->length; + + input->string = phpdbg_trim( + input->string, input->length, &input->length); + + efree(store); + } + + /* pass parameter on */ + phpdbg_parse_param( + input->string, + input->length, + ¶m TSRMLS_CC); + } + + phpdbg_debug( + "found command %s for %s with %d arguments", + command->name, input->argv[0]->string, input->argc-1); + { + int arg; + for (arg=1; argargc; arg++) { + phpdbg_debug( + "\t#%d: [%s=%zu]", + arg, + input->argv[arg]->string, + input->argv[arg]->length); + } + } + + rc = command->handler(¶m, input TSRMLS_CC); + + /* only set last command when it is worth it! */ + if ((rc != FAILURE) && + !(PHPDBG_G(flags) & PHPDBG_IS_INITIALIZING)) { + PHPDBG_G(lcmd) = (phpdbg_command_t*) command; + phpdbg_clear_param( + &PHPDBG_G(lparam) TSRMLS_CC); + PHPDBG_G(lparam) = param; + } + break; + } + command++; + } + } else { + /* this should NEVER happen */ + phpdbg_error( + "No function executed!!"); + } + + return rc; +} /* }}} */ + diff --git a/sapi/phpdbg/phpdbg_cmd.h b/sapi/phpdbg/phpdbg_cmd.h new file mode 100644 index 0000000000000..e779fd4b55d7d --- /dev/null +++ b/sapi/phpdbg/phpdbg_cmd.h @@ -0,0 +1,169 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Felipe Pena | + | Authors: Joe Watkins | + | Authors: Bob Weinand | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHPDBG_CMD_H +#define PHPDBG_CMD_H + +#include "TSRM.h" + +typedef struct _phpdbg_command_t phpdbg_command_t; + +/* {{{ Command and Parameter */ +enum { + NO_ARG = 0, + REQUIRED_ARG, + OPTIONAL_ARG +}; + +typedef enum { + EMPTY_PARAM = 0, + ADDR_PARAM, + FILE_PARAM, + METHOD_PARAM, + STR_PARAM, + NUMERIC_PARAM, + NUMERIC_FUNCTION_PARAM, + NUMERIC_METHOD_PARAM +} phpdbg_param_type; + +typedef struct _phpdbg_input_t phpdbg_input_t; + +struct _phpdbg_input_t { + char * const *start; + char *string; + size_t length; + phpdbg_input_t **argv; + int argc; +}; + +typedef struct _phpdbg_param { + phpdbg_param_type type; + long num; + zend_ulong addr; + struct { + char *name; + long line; + } file; + struct { + char *class; + char *name; + } method; + char *str; + size_t len; +} phpdbg_param_t; + +typedef int (*phpdbg_command_handler_t)(const phpdbg_param_t*, const phpdbg_input_t* TSRMLS_DC); + +struct _phpdbg_command_t { + const char *name; /* Command name */ + size_t name_len; /* Command name length */ + const char *tip; /* Menu tip */ + size_t tip_len; /* Menu tip length */ + char alias; /* Alias */ + phpdbg_command_handler_t handler; /* Command handler */ + const phpdbg_command_t *subs; /* Sub Commands */ + char arg_type; /* Accept args? */ +}; +/* }}} */ + +/* {{{ misc */ +#define PHPDBG_STRL(s) s, sizeof(s)-1 +#define PHPDBG_MAX_CMD 500 +#define PHPDBG_FRAME(v) (PHPDBG_G(frame).v) +#define PHPDBG_EX(v) (EG(current_execute_data)->v) + +typedef struct { + int num; + zend_execute_data *execute_data; +} phpdbg_frame_t; +/* }}} */ + + + +/* +* Workflow: +* 1) read input +* input takes the line from console, creates argc/argv +* 2) parse parameters into suitable types based on arg_type +* takes input from 1) and arg_type and creates parameters +* 3) do command +* executes commands +* 4) destroy parameters +* cleans up what was allocated by creation of parameters +* 5) destroy input +* cleans up what was allocated by creation of input +*/ + +/* +* Input Management +*/ +PHPDBG_API phpdbg_input_t* phpdbg_read_input(char *buffered TSRMLS_DC); +PHPDBG_API void phpdbg_destroy_input(phpdbg_input_t** TSRMLS_DC); + +/* +* Argument Management +*/ +PHPDBG_API phpdbg_input_t** phpdbg_read_argv(char *buffer, int *argc TSRMLS_DC); +PHPDBG_API void phpdbg_destroy_argv(phpdbg_input_t **argv, int argc TSRMLS_DC); +#define phpdbg_argv_is(n, s) \ + (memcmp(input->argv[n]->string, s, input->argv[n]->length) == SUCCESS) + +/* +* Parameter Management +*/ +PHPDBG_API phpdbg_param_type phpdbg_parse_param(const char*, size_t, phpdbg_param_t* TSRMLS_DC); +PHPDBG_API void phpdbg_clear_param(phpdbg_param_t* TSRMLS_DC); +PHPDBG_API void phpdbg_copy_param(const phpdbg_param_t*, phpdbg_param_t* TSRMLS_DC); +PHPDBG_API zend_bool phpdbg_match_param(const phpdbg_param_t *, const phpdbg_param_t * TSRMLS_DC); +PHPDBG_API zend_ulong phpdbg_hash_param(const phpdbg_param_t * TSRMLS_DC); +PHPDBG_API const char* phpdbg_get_param_type(const phpdbg_param_t* TSRMLS_DC); +PHPDBG_API char* phpdbg_param_tostring(const phpdbg_param_t *param, char **pointer TSRMLS_DC); + +/* +* Command Executor +*/ +PHPDBG_API int phpdbg_do_cmd(const phpdbg_command_t*, phpdbg_input_t* TSRMLS_DC); + +/** + * Command Declarators + */ +#define PHPDBG_COMMAND_HANDLER(name) phpdbg_do_##name + +#define PHPDBG_COMMAND_D_EX(name, tip, alias, handler, children, has_args) \ + {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_##handler, children, has_args} + +#define PHPDBG_COMMAND_D(name, tip, alias, children, has_args) \ + {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_##name, children, has_args} + +#define PHPDBG_COMMAND(name) int phpdbg_do_##name(const phpdbg_param_t *param, const phpdbg_input_t *input TSRMLS_DC) + +#define PHPDBG_COMMAND_ARGS param, input TSRMLS_CC + +#define PHPDBG_END_COMMAND {NULL, 0, NULL, 0, '\0', NULL, NULL, '\0'} + +/* +* Default Switch Case +*/ +#define phpdbg_default_switch_case() \ + default: \ + phpdbg_error("Unsupported parameter type (%s) for command", phpdbg_get_param_type(param TSRMLS_CC)); \ + break + +#endif /* PHPDBG_CMD_H */ diff --git a/sapi/phpdbg/phpdbg_frame.c b/sapi/phpdbg/phpdbg_frame.c new file mode 100644 index 0000000000000..24aff59dd92d8 --- /dev/null +++ b/sapi/phpdbg/phpdbg_frame.c @@ -0,0 +1,206 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Felipe Pena | + | Authors: Joe Watkins | + | Authors: Bob Weinand | + +----------------------------------------------------------------------+ +*/ + +#include "zend.h" +#include "phpdbg.h" +#include "phpdbg_utils.h" +#include "phpdbg_frame.h" +#include "phpdbg_list.h" + +ZEND_EXTERN_MODULE_GLOBALS(phpdbg); + +void phpdbg_restore_frame(TSRMLS_D) /* {{{ */ +{ + if (PHPDBG_FRAME(num) == 0) { + return; + } + + PHPDBG_FRAME(num) = 0; + + /* move things back */ + EG(current_execute_data) = PHPDBG_FRAME(execute_data); + + EG(opline_ptr) = &PHPDBG_EX(opline); + EG(active_op_array) = PHPDBG_EX(op_array); + EG(return_value_ptr_ptr) = PHPDBG_EX(original_return_value); + EG(active_symbol_table) = PHPDBG_EX(symbol_table); + EG(This) = PHPDBG_EX(current_this); + EG(scope) = PHPDBG_EX(current_scope); + EG(called_scope) = PHPDBG_EX(current_called_scope); +} /* }}} */ + +void phpdbg_switch_frame(int frame TSRMLS_DC) /* {{{ */ +{ + zend_execute_data *execute_data = PHPDBG_FRAME(num)?PHPDBG_FRAME(execute_data):EG(current_execute_data); + int i = 0; + + if (PHPDBG_FRAME(num) == frame) { + phpdbg_notice("Already in frame #%d", frame); + return; + } + + while (execute_data) { + if (i++ == frame) { + break; + } + + do { + execute_data = execute_data->prev_execute_data; + } while (execute_data && execute_data->opline == NULL); + } + + if (execute_data == NULL) { + phpdbg_error("No frame #%d", frame); + return; + } + + phpdbg_restore_frame(TSRMLS_C); + + if (frame > 0) { + PHPDBG_FRAME(num) = frame; + + /* backup things and jump back */ + PHPDBG_FRAME(execute_data) = EG(current_execute_data); + EG(current_execute_data) = execute_data; + + EG(opline_ptr) = &PHPDBG_EX(opline); + EG(active_op_array) = PHPDBG_EX(op_array); + PHPDBG_FRAME(execute_data)->original_return_value = EG(return_value_ptr_ptr); + EG(return_value_ptr_ptr) = PHPDBG_EX(original_return_value); + EG(active_symbol_table) = PHPDBG_EX(symbol_table); + EG(This) = PHPDBG_EX(current_this); + EG(scope) = PHPDBG_EX(current_scope); + EG(called_scope) = PHPDBG_EX(current_called_scope); + } + + phpdbg_notice("Switched to frame #%d", frame); + phpdbg_list_file( + zend_get_executed_filename(TSRMLS_C), + 3, + zend_get_executed_lineno(TSRMLS_C)-1, + zend_get_executed_lineno(TSRMLS_C) + TSRMLS_CC + ); +} /* }}} */ + +static void phpdbg_dump_prototype(zval **tmp TSRMLS_DC) /* {{{ */ +{ + zval **funcname, **class, **type, **args, **argstmp; + char is_class; + + zend_hash_find(Z_ARRVAL_PP(tmp), "function", sizeof("function"), + (void **)&funcname); + + if ((is_class = zend_hash_find(Z_ARRVAL_PP(tmp), + "object", sizeof("object"), (void **)&class)) == FAILURE) { + is_class = zend_hash_find(Z_ARRVAL_PP(tmp), "class", sizeof("class"), + (void **)&class); + } else { + zend_get_object_classname(*class, (const char **)&Z_STRVAL_PP(class), + (zend_uint *)&Z_STRLEN_PP(class) TSRMLS_CC); + } + + if (is_class == SUCCESS) { + zend_hash_find(Z_ARRVAL_PP(tmp), "type", sizeof("type"), (void **)&type); + } + + phpdbg_write("%s%s%s(", + is_class == FAILURE?"":Z_STRVAL_PP(class), + is_class == FAILURE?"":Z_STRVAL_PP(type), + Z_STRVAL_PP(funcname) + ); + + if (zend_hash_find(Z_ARRVAL_PP(tmp), "args", sizeof("args"), + (void **)&args) == SUCCESS) { + HashPosition iterator; + const zend_function *func = phpdbg_get_function( + Z_STRVAL_PP(funcname), is_class == FAILURE ? NULL : Z_STRVAL_PP(class) TSRMLS_CC); + const zend_arg_info *arginfo = func ? func->common.arg_info : NULL; + int j = 0, m = func ? func->common.num_args : 0; + zend_bool is_variadic = 0; + + zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(args), &iterator); + while (zend_hash_get_current_data_ex(Z_ARRVAL_PP(args), + (void **) &argstmp, &iterator) == SUCCESS) { + if (j) { + phpdbg_write(", "); + } + if (m && j < m) { +#if PHP_VERSION_ID >= 50600 + is_variadic = arginfo[j].is_variadic; +#endif + phpdbg_write("%s=%s", + arginfo[j].name, is_variadic ? "[": ""); + } + ++j; + + zend_print_flat_zval_r(*argstmp TSRMLS_CC); + zend_hash_move_forward_ex(Z_ARRVAL_PP(args), &iterator); + } + if (is_variadic) { + phpdbg_write("]"); + } + } + phpdbg_write(")"); +} + +void phpdbg_dump_backtrace(size_t num TSRMLS_DC) /* {{{ */ +{ + zval zbacktrace; + zval **tmp; + zval **file, **line; + HashPosition position; + int i = 1, limit = num; + int user_defined; + + if (limit < 0) { + phpdbg_error("Invalid backtrace size %d", limit); + } + + zend_fetch_debug_backtrace( + &zbacktrace, 0, 0, limit TSRMLS_CC); + + zend_hash_internal_pointer_reset_ex(Z_ARRVAL(zbacktrace), &position); + zend_hash_get_current_data_ex(Z_ARRVAL(zbacktrace), (void**)&tmp, &position); + while (1) { + user_defined = zend_hash_find(Z_ARRVAL_PP(tmp), "file", sizeof("file"), (void **)&file); + zend_hash_find(Z_ARRVAL_PP(tmp), "line", sizeof("line"), (void **)&line); + zend_hash_move_forward_ex(Z_ARRVAL(zbacktrace), &position); + + if (zend_hash_get_current_data_ex(Z_ARRVAL(zbacktrace), + (void**)&tmp, &position) == FAILURE) { + phpdbg_write("frame #0: {main} at %s:%ld", Z_STRVAL_PP(file), Z_LVAL_PP(line)); + break; + } + + if (user_defined == SUCCESS) { + phpdbg_write("frame #%d: ", i++); + phpdbg_dump_prototype(tmp TSRMLS_CC); + phpdbg_writeln(" at %s:%ld", Z_STRVAL_PP(file), Z_LVAL_PP(line)); + } else { + phpdbg_write(" => "); + phpdbg_dump_prototype(tmp TSRMLS_CC); + phpdbg_writeln(" (internal function)"); + } + } + + phpdbg_writeln(EMPTY); + zval_dtor(&zbacktrace); +} /* }}} */ diff --git a/sapi/phpdbg/phpdbg_frame.h b/sapi/phpdbg/phpdbg_frame.h new file mode 100644 index 0000000000000..fbccd5404f5b9 --- /dev/null +++ b/sapi/phpdbg/phpdbg_frame.h @@ -0,0 +1,30 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Felipe Pena | + | Authors: Joe Watkins | + | Authors: Bob Weinand | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHPDBG_FRAME_H +#define PHPDBG_FRAME_H + +#include "TSRM.h" + +void phpdbg_restore_frame(TSRMLS_D); +void phpdbg_switch_frame(int TSRMLS_DC); +void phpdbg_dump_backtrace(size_t TSRMLS_DC); + +#endif /* PHPDBG_FRAME_H */ diff --git a/sapi/phpdbg/phpdbg_help.c b/sapi/phpdbg/phpdbg_help.c new file mode 100644 index 0000000000000..edb12659554d1 --- /dev/null +++ b/sapi/phpdbg/phpdbg_help.c @@ -0,0 +1,603 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Felipe Pena | + | Authors: Joe Watkins | + | Authors: Bob Weinand | + +----------------------------------------------------------------------+ +*/ + +#include "phpdbg.h" +#include "phpdbg_help.h" +#include "phpdbg_print.h" +#include "phpdbg_utils.h" +#include "phpdbg_break.h" +#include "phpdbg_list.h" +#include "phpdbg_info.h" +#include "phpdbg_set.h" + +ZEND_EXTERN_MODULE_GLOBALS(phpdbg); + +PHPDBG_HELP(exec) /* {{{ */ +{ + phpdbg_help_header(); + phpdbg_writeln("\tWill attempt execution, if compilation has not yet taken place, it occurs now"); + phpdbg_writeln("The execution context must be set before execution can take place"); + phpdbg_help_footer(); + return SUCCESS; +} /* }}} */ + +PHPDBG_HELP(step) /* {{{ */ +{ + phpdbg_help_header(); + phpdbg_writeln("You can enable and disable stepping at any phpdbg prompt during execution"); + phpdbg_writeln(EMPTY); + phpdbg_notice("Examples"); + phpdbg_writeln("\t%sstepping 1", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%ss 1", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill enable stepping"); + phpdbg_writeln(EMPTY); + phpdbg_writeln("While stepping is enabled you are presented with a prompt after the execution of each opcode"); + phpdbg_help_footer(); + return SUCCESS; +} /* }}} */ + +PHPDBG_HELP(next) /* {{{ */ +{ + phpdbg_help_header(); + phpdbg_write("Step back into the vm and execute the next opcode"); + phpdbg_writeln(EMPTY); + phpdbg_notice("Examples"); + phpdbg_writeln("\t%snext", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%sn", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill cause control to be passed back to the vm, continuing execution"); + phpdbg_writeln(EMPTY); + phpdbg_writeln("Note: is only useful while executing"); + phpdbg_help_footer(); + return SUCCESS; +} /* }}} */ + +PHPDBG_HELP(until) /* {{{ */ +{ + phpdbg_help_header(); + phpdbg_writeln("Step back into the vm, skipping breakpoints until the next source line"); + phpdbg_writeln(EMPTY); + phpdbg_notice("Examples"); + phpdbg_writeln("\t%suntil", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%su", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill cause control to be passed back to the vm, continuing execution"); + phpdbg_writeln(EMPTY); + phpdbg_writeln("Note: is only useful while executing"); + phpdbg_help_footer(); + return SUCCESS; +} /* }}} */ + +PHPDBG_HELP(finish) /* {{{ */ +{ + phpdbg_help_header(); + phpdbg_writeln("Step back into the vm, skipping breakpoints until past the end of the current stack"); + phpdbg_writeln(EMPTY); + phpdbg_notice("Examples"); + phpdbg_writeln("\t%sfinish", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%sF", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill cause control to be passed back to the vm, continuing execution"); + phpdbg_writeln(EMPTY); + phpdbg_writeln("Note: this allows all breakpoints that would otherwise break execution in the current scope to be skipped"); + phpdbg_help_footer(); + return SUCCESS; +} /* }}} */ + +PHPDBG_HELP(leave) /* {{{ */ +{ + phpdbg_help_header(); + phpdbg_writeln("Step back into the vm, skipping breakpoints until the current stack is returning"); + phpdbg_writeln(EMPTY); + phpdbg_notice("Examples"); + phpdbg_writeln("\t%sleave", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%sL", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill cause a break when instructed to leave the current context"); + phpdbg_writeln(EMPTY); + phpdbg_writeln("Note: this allows inspection of the return value before it is returned"); + phpdbg_help_footer(); + return SUCCESS; +} /* }}} */ + +PHPDBG_HELP(compile) /* {{{ */ +{ + phpdbg_help_header(); + phpdbg_writeln("Pre-compilation of the execution context provides the opportunity to inspect opcodes before execution"); + phpdbg_writeln("The execution context must be set for compilation to succeed"); + phpdbg_writeln(EMPTY); + phpdbg_notice("Examples"); + phpdbg_writeln("\t%scompile", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%sc", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill compile the current execution context, populating class/function/constant/etc tables"); + phpdbg_writeln(EMPTY); + phpdbg_writeln("Note: It is a good idea to clean the environment between each compilation"); + phpdbg_help_footer(); + return SUCCESS; +} /* }}} */ + +PHPDBG_HELP(print) /* {{{ */ +{ + phpdbg_help_header(); + phpdbg_writeln("By default, print will show information about the current execution context"); + phpdbg_writeln("Other printing commands give access to instruction information"); + phpdbg_writeln(EMPTY); + phpdbg_notice("Examples"); + phpdbg_writeln("\t%sprint class \\my\\class", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%sp c \\my\\class", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill print the instructions for the methods in \\my\\class"); + phpdbg_writeln(EMPTY); + phpdbg_writeln("\t%sprint method \\my\\class::method", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%sp m \\my\\class::method", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill print the instructions for \\my\\class::method"); + phpdbg_writeln(EMPTY); + phpdbg_writeln("\t%sprint func .getSomething", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%sp f .getSomething", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill print the instructions for ::getSomething in the active scope"); + phpdbg_writeln(EMPTY); + phpdbg_writeln("\t%sprint func my_function", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%sp f my_function", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill print the instructions for the global function my_function"); + phpdbg_writeln(EMPTY); + phpdbg_writeln("\t%sprint opline", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%sp o", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill print the instruction for the current opline"); + phpdbg_writeln(EMPTY); + phpdbg_writeln("\t%sprint exec", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%sp e", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill print the instructions for the execution context"); + phpdbg_writeln(EMPTY); + phpdbg_writeln("\t%sprint stack", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%sp s", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill print the instructions for the current stack"); + phpdbg_writeln(EMPTY); + phpdbg_writeln("Specific printers loaded are show below:"); + phpdbg_notice("Commands"); + { + const phpdbg_command_t *print_command = phpdbg_print_commands; + + phpdbg_writeln("\tAlias\tCommand\t\tPurpose"); + while (print_command && print_command->name) { + if (print_command->alias) { + phpdbg_writeln("\t[%c]\t%s\t\t%s", print_command->alias, print_command->name, print_command->tip); + } else { + phpdbg_writeln("\t[ ]\t%s\t\t%s", print_command->name, print_command->tip); + } + ++print_command; + } + } + phpdbg_help_footer(); + return SUCCESS; +} /* }}} */ + +PHPDBG_HELP(run) /* {{{ */ +{ + phpdbg_help_header(); + phpdbg_writeln("Execute the current context inside the phpdbg vm"); + phpdbg_writeln(EMPTY); + phpdbg_notice("Examples"); + phpdbg_writeln("\t%srun", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%sr", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill cause execution of the context, if it is set."); + phpdbg_writeln(EMPTY); + phpdbg_writeln("Note: The execution context must be set, but not necessarily compiled before execution occurs"); + phpdbg_help_footer(); + return SUCCESS; +} /* }}} */ + +PHPDBG_HELP(eval) /* {{{ */ +{ + phpdbg_help_header(); + phpdbg_writeln("Access to eval() allows you to change the environment during execution, careful though!!"); + phpdbg_writeln(EMPTY); + phpdbg_notice("Examples"); + phpdbg_writeln("\t%seval $variable", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%sE $variable", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill print_r($variable) on the console, if it is defined"); + phpdbg_writeln(EMPTY); + phpdbg_writeln("\t%seval $variable = \"Hello phpdbg :)\"", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%sE $variable = \"Hello phpdbg :)\"", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill set $variable in the current scope"); + phpdbg_writeln(EMPTY); + phpdbg_writeln("Note: eval() will always show the result; do not prefix the code with \"return\""); + phpdbg_help_footer(); + return SUCCESS; +} /* }}} */ + +PHPDBG_HELP(break) /* {{{ */ +{ + phpdbg_help_header(); + phpdbg_writeln("Setting a breakpoint stops execution at a specific stage"); + phpdbg_writeln(EMPTY); + phpdbg_notice("Examples"); + phpdbg_writeln("\t%sbreak [file] test.php:1", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%sb [F] test.php:1", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill break execution on line 1 of test.php"); + phpdbg_writeln(EMPTY); + phpdbg_writeln("\t%sbreak [func] my_function", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%sb [f] my_function", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill break execution on entry to my_function"); + phpdbg_writeln(EMPTY); + phpdbg_writeln("\t%sbreak [method] \\my\\class::method", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%sb [m] \\my\\class::method", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill break execution on entry to \\my\\class::method"); + phpdbg_writeln(EMPTY); + phpdbg_writeln("\t%sbreak [address] 0x7ff68f570e08", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%sb [a] 0x7ff68f570e08", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill break at the opline with the address provided"); + phpdbg_writeln(EMPTY); + phpdbg_writeln("\t%sbreak [address] my_function#1", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%sb [a] my_function#1", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill break at the opline number 1 of the function my_function"); + phpdbg_writeln(EMPTY); + phpdbg_writeln("\t%sbreak [address] \\my\\class::method#2", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%sb [a] \\my\\class::method#2", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill break at the opline number 2 of the method \\my\\class::method"); + phpdbg_writeln(EMPTY); + phpdbg_writeln("\t%sbreak address test.php:3", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%sb a test.php:3", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill break at the opline number 3 of test.php"); + phpdbg_writeln(EMPTY); + phpdbg_writeln("\t%sbreak [lineno] 200", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%sb [l] 200", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill break at line 200 of the currently executing file"); + phpdbg_writeln(EMPTY); + phpdbg_writeln("\t%sbreak on ($expression == true)", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%sb on ($expression == true)", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill break when the condition evaluates to true"); + phpdbg_writeln(EMPTY); + phpdbg_writeln("\t%sbreak at phpdbg::isGreat if ($expression == true)", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill break at every opcode in phpdbg::isGreat when the condition evaluates to true"); + phpdbg_writeln("\t%sbreak at test.php:20 if ($expression == true)", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill break at every opcode on line 20 of test.php when the condition evaluates to true"); + phpdbg_write("\t"); + phpdbg_notice("The location can be anything accepted by file, func, method, or address break commands"); + phpdbg_writeln(EMPTY); + phpdbg_writeln("\t%sbreak op ZEND_ADD", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%sb O ZEND_ADD", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill break on every occurence of the opcode provided"); + phpdbg_writeln(EMPTY); + phpdbg_writeln("\t%sbreak del 1", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%sb d 1", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill remove the breakpoint with the given identifier"); + phpdbg_writeln(EMPTY); + phpdbg_writeln("Note: An address is only valid for the current compilation"); + phpdbg_writeln(EMPTY); + phpdbg_notice("The parameters enclosed by [] are usually optional, but help avoid ambigious commands"); + phpdbg_writeln(EMPTY); + phpdbg_writeln("Specific breakers loaded are show below:"); + phpdbg_notice("Commands"); + { + const phpdbg_command_t *break_command = phpdbg_break_commands; + + phpdbg_writeln("\tAlias\tCommand\t\tPurpose"); + while (break_command && break_command->name) { + if (break_command->alias) { + phpdbg_writeln("\t[%c]\t%s\t\t%s", break_command->alias, break_command->name, break_command->tip); + } else { + phpdbg_writeln("\t[ ]\t%s\t\t%s", break_command->name, break_command->tip); + } + ++break_command; + } + } + phpdbg_writeln("Note: Conditional breaks are costly, use them sparingly!"); + phpdbg_help_footer(); + return SUCCESS; +} /* }}} */ + +PHPDBG_HELP(clean) /* {{{ */ +{ + phpdbg_help_header(); + phpdbg_writeln("While debugging you may experience errors because of attempts to redeclare classes, constants or functions"); + phpdbg_writeln("Cleaning the environment cleans these tables, so that files can be recompiled without exiting phpdbg"); + phpdbg_help_footer(); + return SUCCESS; +} /* }}} */ + +PHPDBG_HELP(clear) /* {{{ */ +{ + phpdbg_help_header(); + phpdbg_writeln("Clearing breakpoints means you can once again run code without interruption"); + phpdbg_writeln("Note: all breakpoints are lost; be sure debugging is complete before clearing"); + phpdbg_help_footer(); + return SUCCESS; +} /* }}} */ + +PHPDBG_HELP(info) /* {{{ */ +{ + phpdbg_help_header(); + phpdbg_writeln("info commands provide quick access to various types of information about the PHP environment"); + phpdbg_writeln("Specific info commands are show below:"); + phpdbg_notice("Commands"); + { + const phpdbg_command_t *info_command = phpdbg_info_commands; + + phpdbg_writeln("\tAlias\tCommand\t\tPurpose"); + while (info_command && info_command->name) { + if (info_command->alias) { + phpdbg_writeln("\t[%c]\t%s\t\t%s", info_command->alias, info_command->name, info_command->tip); + } else { + phpdbg_writeln("\t[ ]\t%s\t\t%s", info_command->name, info_command->tip); + } + ++info_command; + } + } + + phpdbg_help_footer(); + return SUCCESS; +} /* }}} */ + +PHPDBG_HELP(quiet) /* {{{ */ +{ + phpdbg_help_header(); + phpdbg_writeln("Setting quietness on will stop the OPLINE output during execution"); + phpdbg_writeln(EMPTY); + phpdbg_notice("Examples"); + phpdbg_writeln("\t%squiet 1", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%sQ 1", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill silence OPLINE output, while"); + phpdbg_writeln(EMPTY); + phpdbg_writeln("\t%squiet 0", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%sQ 0", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill enable OPLINE output again"); + phpdbg_writeln(EMPTY); + phpdbg_writeln("Note: Quietness is disabled automatically while stepping"); + phpdbg_help_footer(); + return SUCCESS; +} /* }}} */ + +PHPDBG_HELP(back) /* {{{ */ +{ + phpdbg_help_header(); + phpdbg_writeln("The backtrace is built with the default debug backtrace functionality"); + phpdbg_writeln(EMPTY); + phpdbg_notice("Examples"); + phpdbg_writeln("\t%sback 5", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%st 5", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill limit the number of frames to 5, the default is no limit"); + phpdbg_writeln(EMPTY); + phpdbg_writeln("Note: it is not necessary for an exception to be thrown to show a backtrace"); + phpdbg_help_footer(); + return SUCCESS; +} /* }}} */ + +PHPDBG_HELP(frame) /* {{{ */ +{ + phpdbg_help_header(); + phpdbg_writeln("When viewing a backtrace, it is sometimes useful to jump to a frame in that trace"); + phpdbg_writeln(EMPTY); + phpdbg_notice("Examples"); + phpdbg_writeln("\t%sframe 2", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%sf 2", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill go to frame 2, temporarily affecting scope and allowing access to the variables in that frame"); + phpdbg_writeln(EMPTY); + phpdbg_writeln("Note: the current frame is restored when execution continues"); + phpdbg_help_footer(); + return SUCCESS; +} /* }}} */ + +PHPDBG_HELP(list) /* {{{ */ +{ + phpdbg_help_header(); + phpdbg_writeln("The list command displays source code for the given argument"); + phpdbg_writeln(EMPTY); + phpdbg_notice("Examples"); + phpdbg_writeln("\t%slist [lines] 2", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%sl [l] 2", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill print next 2 lines from the current file"); + phpdbg_writeln(EMPTY); + phpdbg_writeln("\t%slist [func] my_function", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%sl [f] my_function", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill print the source of the global function \"my_function\""); + phpdbg_writeln(EMPTY); + phpdbg_writeln("\t%slist [func] .mine", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%sl [f] .mine", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill print the source of the method \"mine\" from the active scope"); + phpdbg_writeln(EMPTY); + phpdbg_writeln("\t%slist [method] my::method", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%sl [m] my::method", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill print the source of \"my::method\""); + phpdbg_writeln(EMPTY); + phpdbg_writeln("\t%slist c myClass", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%sl c myClass", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill print the source of \"myClass\""); + phpdbg_writeln(EMPTY); + phpdbg_writeln("Note: before listing functions you must have a populated function table, try compile!!"); + phpdbg_writeln(EMPTY); + phpdbg_notice("The parameters enclosed by [] are usually optional, but help avoid ambigious commands"); + phpdbg_writeln(EMPTY); + phpdbg_writeln("Specific listers loaded are show below:"); + phpdbg_notice("Commands"); + { + const phpdbg_command_t *list_command = phpdbg_list_commands; + + phpdbg_writeln("\tAlias\tCommand\t\tPurpose"); + while (list_command && list_command->name) { + if (list_command->alias) { + phpdbg_writeln("\t[%c]\t%s\t\t%s", list_command->alias, list_command->name, list_command->tip); + } else { + phpdbg_writeln("\t[ ]\t%s\t\t%s", list_command->name, list_command->tip); + } + ++list_command; + } + } + phpdbg_help_footer(); + return SUCCESS; +} /* }}} */ + +PHPDBG_HELP(oplog) /* {{{ */ +{ + phpdbg_help_header(); + phpdbg_writeln("Even when quietness is enabled you may wish to save opline logs to a file"); + phpdbg_writeln("Setting a new oplog closes the previously open log"); + phpdbg_writeln("The log includes a high resolution timestamp on each entry"); + phpdbg_writeln(EMPTY); + phpdbg_notice("Examples"); + phpdbg_writeln("\t%soplog /path/to/my.oplog", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%sO /path/to/my.oplog", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill open the file /path/to/my.oplog for writing, creating it if it does not exist"); + phpdbg_writeln(EMPTY); + phpdbg_writeln("\t%soplog 0", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%sO 0", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill close the currently open log file, disabling oplog"); + phpdbg_writeln(EMPTY); + phpdbg_writeln("Note: upon failure to open a new oplog, the last oplog is held open"); + phpdbg_help_footer(); + return SUCCESS; +} /* }}} */ + +PHPDBG_HELP(set) /* {{{ */ +{ + phpdbg_help_header(); + phpdbg_writeln("Configure how phpdbg looks and behaves with the set command"); + phpdbg_writeln("Specific set commands are show below:"); + phpdbg_notice("Commands"); + { + const phpdbg_command_t *set_command = phpdbg_set_commands; + + phpdbg_writeln("\tAlias\tCommand\t\tPurpose"); + while (set_command && set_command->name) { + if (set_command->alias) { + phpdbg_writeln("\t[%c]\t%s\t\t%s", set_command->alias, set_command->name, set_command->tip); + } else { + phpdbg_writeln("\t[ ]\t%s\t\t%s", set_command->name, set_command->tip); + } + ++set_command; + } + } +#ifndef _WIN32 + phpdbg_notice("Colors"); + { + const phpdbg_color_t *color = phpdbg_get_colors(TSRMLS_C); + + if (PHPDBG_G(flags) & PHPDBG_IS_COLOURED) { + phpdbg_writeln("\t%-20s\t\tExample", "Name"); + } else { + phpdbg_writeln("\tName"); + } + + while (color && color->name) { + if (PHPDBG_G(flags) & PHPDBG_IS_COLOURED) { + phpdbg_writeln( + "\t%-20s\t\t\033[%smphpdbg rocks :)\033[0m", color->name, color->code); + } else { + phpdbg_writeln("\t%s", color->name); + } + ++color; + } + } + phpdbg_writeln("The for set color can be \"prompt\", \"notice\", or \"error\""); +#endif + phpdbg_help_footer(); + return SUCCESS; +} /* }}} */ + +PHPDBG_HELP(register) /* {{{ */ +{ + phpdbg_help_header(); + phpdbg_writeln("Register any global function for use as a command in phpdbg console"); + phpdbg_writeln(EMPTY); + phpdbg_notice("Examples"); + phpdbg_writeln("\t%sregister scandir", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%sR scandir", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill register the scandir function for use in phpdbg"); + phpdbg_writeln(EMPTY); + phpdbg_writeln("Note: arguments passed as strings, return (if present) print_r'd on console"); + if (zend_hash_num_elements(&PHPDBG_G(registered))) { + HashPosition position; + char *name = NULL; + zend_uint name_len = 0; + + phpdbg_notice("Registered Functions (%d)", zend_hash_num_elements(&PHPDBG_G(registered))); + for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(registered), &position); + zend_hash_get_current_key_ex(&PHPDBG_G(registered), &name, &name_len, NULL, 1, &position) == HASH_KEY_IS_STRING; + zend_hash_move_forward_ex(&PHPDBG_G(registered), &position)) { + phpdbg_writeln("|-------> %s", name); + efree(name); + } + } + + phpdbg_help_footer(); + return SUCCESS; +} /* }}} */ + +PHPDBG_HELP(source) /* {{{ */ +{ + phpdbg_help_header(); + phpdbg_writeln("Sourcing a phpdbginit during your debugging session might save some time"); + phpdbg_writeln("The source command can also be used to export breakpoints to a phpdbginit file"); + phpdbg_writeln(EMPTY); + phpdbg_notice("Examples"); + phpdbg_writeln("\t%ssource /my/init", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%s. /my/init", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill execute the phpdbginit file at /my/init"); + phpdbg_writeln("\t%ssource export /my/init", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%s. export /my/init", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill export breakpoints to /my/init in phpdbginit file format"); + phpdbg_help_footer(); + return SUCCESS; +} /* }}} */ + +PHPDBG_HELP(shell) /* {{{ */ +{ + phpdbg_help_header(); + phpdbg_writeln("Direct access to shell commands saves having to switch windows/consoles"); + phpdbg_writeln(EMPTY); + phpdbg_notice("Examples"); + phpdbg_writeln("\t%sshell ls /usr/src/php-src", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%s- ls /usr/src/php-src", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill execute ls /usr/src/php-src, displaying the output in the console"); + phpdbg_writeln(EMPTY); + phpdbg_writeln("Note: read only commands please!"); + phpdbg_help_footer(); + return SUCCESS; +} /* }}} */ + +PHPDBG_HELP(options) /* {{{ */ +{ + phpdbg_help_header(); + phpdbg_writeln("Below are the command line options supported by phpdbg"); + phpdbg_notice("Command Line Options and Flags"); + phpdbg_writeln(" -c\t-c/my/php.ini\t\tSet php.ini file to load"); + phpdbg_writeln(" -d\t-dmemory_limit=4G\tSet a php.ini directive"); + phpdbg_writeln(" -n\tN/A\t\t\tDisable default php.ini"); + phpdbg_writeln(" -q\tN/A\t\t\tSupress welcome banner"); + phpdbg_writeln(" -e\t-emytest.php\t\tSet execution context"); + phpdbg_writeln(" -v\tN/A\t\t\tEnable oplog output"); + phpdbg_writeln(" -s\tN/A\t\t\tEnable stepping"); + phpdbg_writeln(" -b\tN/A\t\t\tDisable colour"); + phpdbg_writeln(" -i\t-imy.init\t\tSet .phpdbginit file"); + phpdbg_writeln(" -I\tN/A\t\t\tIgnore default .phpdbginit"); + phpdbg_writeln(" -O\t-Omy.oplog\t\tSets oplog output file"); + phpdbg_writeln(" -r\tN/A\t\t\tRun execution context"); + phpdbg_writeln(" -E\tN/A\t\t\tEnable step through eval, careful!"); + phpdbg_writeln(" -S\t-Scli\t\t\tOverride SAPI name, careful!"); +#ifndef _WIN32 + phpdbg_writeln(" -l\t-l4000\t\t\tSetup remote console ports"); + phpdbg_writeln(" -a\t-a192.168.0.3\t\tSetup remote console bind address"); +#endif + phpdbg_writeln(" -V\tN/A\t\t\tVersion number"); + phpdbg_notice("Passing -rr will quit automatically after execution"); +#ifndef _WIN32 + phpdbg_writeln("Remote Console Mode"); + phpdbg_notice("For security, phpdbg will bind only to the loopback interface by default"); + phpdbg_writeln("-a without an argument implies all; phpdbg will bind to all available interfaces."); + phpdbg_writeln("specify both stdin and stdout with -lstdin/stdout; by default stdout is stdin * 2."); + phpdbg_notice("Steps should be taken to secure this service if bound to a public interface/port"); +#endif + phpdbg_help_footer(); + return SUCCESS; +} /* }}} */ diff --git a/sapi/phpdbg/phpdbg_help.h b/sapi/phpdbg/phpdbg_help.h new file mode 100644 index 0000000000000..012a1b49e735b --- /dev/null +++ b/sapi/phpdbg/phpdbg_help.h @@ -0,0 +1,92 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Felipe Pena | + | Authors: Joe Watkins | + | Authors: Bob Weinand | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHPDBG_HELP_H +#define PHPDBG_HELP_H + +#include "TSRM.h" +#include "phpdbg.h" +#include "phpdbg_cmd.h" + +#define PHPDBG_HELP(name) PHPDBG_COMMAND(help_##name) + +/** + * Helper Forward Declarations + */ +PHPDBG_HELP(exec); +PHPDBG_HELP(compile); +PHPDBG_HELP(step); +PHPDBG_HELP(next); +PHPDBG_HELP(run); +PHPDBG_HELP(eval); +PHPDBG_HELP(until); +PHPDBG_HELP(finish); +PHPDBG_HELP(leave); +PHPDBG_HELP(print); +PHPDBG_HELP(break); +PHPDBG_HELP(clean); +PHPDBG_HELP(clear); +PHPDBG_HELP(info); +PHPDBG_HELP(back); +PHPDBG_HELP(frame); +PHPDBG_HELP(quiet); +PHPDBG_HELP(list); +PHPDBG_HELP(set); +PHPDBG_HELP(register); +PHPDBG_HELP(options); +PHPDBG_HELP(source); +PHPDBG_HELP(shell); + +/** + * Commands + */ +static const phpdbg_command_t phpdbg_help_commands[] = { + PHPDBG_COMMAND_D_EX(exec, "the execution context should be a valid path", 'e', help_exec, NULL, 0), + PHPDBG_COMMAND_D_EX(compile, "allow inspection of code before execution", 'c', help_compile, NULL, 0), + PHPDBG_COMMAND_D_EX(step, "step through execution to break at every opcode", 's', help_step, NULL, 0), + PHPDBG_COMMAND_D_EX(next, "continue executing while stepping or after breaking", 'n', help_next, NULL, 0), + PHPDBG_COMMAND_D_EX(run, "execute inside the phpdbg vm", 'r', help_run, NULL, 0), + PHPDBG_COMMAND_D_EX(eval, "access to eval() allows affecting the environment", 'E', help_eval, NULL, 0), + PHPDBG_COMMAND_D_EX(until, "continue until the current line is executed", 'u', help_until, NULL, 0), + PHPDBG_COMMAND_D_EX(finish, "continue until the current function has returned", 'F', help_finish, NULL, 0), + PHPDBG_COMMAND_D_EX(leave, "continue until the current function is returning", 'L', help_leave, NULL, 0), + PHPDBG_COMMAND_D_EX(print, "print context information or instructions", 'p', help_print, NULL, 0), + PHPDBG_COMMAND_D_EX(break, "breakpoints allow execution interruption", 'b', help_break, NULL, 0), + PHPDBG_COMMAND_D_EX(clean, "resetting the environment is useful while debugging", 'X', help_clean, NULL, 0), + PHPDBG_COMMAND_D_EX(clear, "reset breakpoints to execute without interruption", 'c', help_clear, NULL, 0), + PHPDBG_COMMAND_D_EX(info, "quick access to useful information on the console", 'i', help_info, NULL, 0), + PHPDBG_COMMAND_D_EX(back, "show debug backtrace information during execution", 't', help_back, NULL, 0), + PHPDBG_COMMAND_D_EX(frame, "switch to a frame in the current stack for inspection", 'f', help_frame, NULL, 0), + PHPDBG_COMMAND_D_EX(quiet, "be quiet during execution", 'Q', help_quiet, NULL, 0), + PHPDBG_COMMAND_D_EX(list, "list code gives you quick access to code", 'l', help_list, NULL, 0), + PHPDBG_COMMAND_D_EX(set, "configure how phpdbg looks and behaves", 'S', help_set, NULL, 0), + PHPDBG_COMMAND_D_EX(register, "register a function for use as a command", 'R', help_register,NULL, 0), + PHPDBG_COMMAND_D_EX(options, "show information about command line options", 'o', help_options, NULL, 0), + PHPDBG_COMMAND_D_EX(source, "load a phpdbginit file at the console", '.', help_source, NULL, 0), + PHPDBG_COMMAND_D_EX(shell, "execute system commands with direct shell access", '-', help_shell, NULL, 0), + PHPDBG_END_COMMAND +}; + +#define phpdbg_help_header() \ + phpdbg_notice("Welcome to phpdbg, the interactive PHP debugger, v%s", PHPDBG_VERSION); +#define phpdbg_help_footer() \ + phpdbg_notice("Please report bugs to <%s>", PHPDBG_ISSUES); + +#endif /* PHPDBG_HELP_H */ diff --git a/sapi/phpdbg/phpdbg_info.c b/sapi/phpdbg/phpdbg_info.c new file mode 100644 index 0000000000000..1744f59215b4d --- /dev/null +++ b/sapi/phpdbg/phpdbg_info.c @@ -0,0 +1,355 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Felipe Pena | + | Authors: Joe Watkins | + | Authors: Bob Weinand | + +----------------------------------------------------------------------+ +*/ + +#include "php.h" +#include "phpdbg.h" +#include "phpdbg_utils.h" +#include "phpdbg_info.h" +#include "phpdbg_bp.h" + +ZEND_EXTERN_MODULE_GLOBALS(phpdbg); + +PHPDBG_INFO(break) /* {{{ */ +{ + phpdbg_print_breakpoints(PHPDBG_BREAK_FILE TSRMLS_CC); + phpdbg_print_breakpoints(PHPDBG_BREAK_SYM TSRMLS_CC); + phpdbg_print_breakpoints(PHPDBG_BREAK_METHOD TSRMLS_CC); + phpdbg_print_breakpoints(PHPDBG_BREAK_OPLINE TSRMLS_CC); + phpdbg_print_breakpoints(PHPDBG_BREAK_FILE_OPLINE TSRMLS_CC); + phpdbg_print_breakpoints(PHPDBG_BREAK_FUNCTION_OPLINE TSRMLS_CC); + phpdbg_print_breakpoints(PHPDBG_BREAK_METHOD_OPLINE TSRMLS_CC); + phpdbg_print_breakpoints(PHPDBG_BREAK_COND TSRMLS_CC); + phpdbg_print_breakpoints(PHPDBG_BREAK_OPCODE TSRMLS_CC); + + return SUCCESS; +} /* }}} */ + +PHPDBG_INFO(files) /* {{{ */ +{ + HashPosition pos; + char *fname; + + phpdbg_notice("Included files: %d", + zend_hash_num_elements(&EG(included_files))); + + zend_hash_internal_pointer_reset_ex(&EG(included_files), &pos); + while (zend_hash_get_current_key_ex(&EG(included_files), &fname, + NULL, NULL, 0, &pos) == HASH_KEY_IS_STRING) { + phpdbg_writeln("File: %s", fname); + zend_hash_move_forward_ex(&EG(included_files), &pos); + } + + return SUCCESS; +} /* }}} */ + +PHPDBG_INFO(error) /* {{{ */ +{ + if (PG(last_error_message)) { + phpdbg_writeln("Last error: %s at %s line %d", + PG(last_error_message), PG(last_error_file), PG(last_error_lineno)); + } else { + phpdbg_notice("No error found!"); + } + return SUCCESS; +} /* }}} */ + +PHPDBG_INFO(vars) /* {{{ */ +{ + HashTable vars; + HashPosition pos; + char *var; + zval **data; + + if (!EG(active_op_array)) { + phpdbg_error("No active op array!"); + return SUCCESS; + } + + if (!EG(active_symbol_table)) { + zend_rebuild_symbol_table(TSRMLS_C); + + if (!EG(active_symbol_table)) { + phpdbg_error("No active symbol table!"); + return SUCCESS; + } + } + + zend_hash_init(&vars, 8, NULL, NULL, 0); + + zend_hash_internal_pointer_reset_ex(EG(active_symbol_table), &pos); + while (zend_hash_get_current_key_ex(EG(active_symbol_table), &var, + NULL, NULL, 0, &pos) == HASH_KEY_IS_STRING) { + zend_hash_get_current_data_ex(EG(active_symbol_table), (void **)&data, &pos); + if (*var != '_') { + zend_hash_update( + &vars, var, strlen(var)+1, (void**)data, sizeof(zval*), NULL); + } + zend_hash_move_forward_ex(EG(active_symbol_table), &pos); + } + + { + zend_op_array *ops = EG(active_op_array); + + if (ops->function_name) { + if (ops->scope) { + phpdbg_notice( + "Variables in %s::%s() (%d)", ops->scope->name, ops->function_name, zend_hash_num_elements(&vars)); + } else { + phpdbg_notice( + "Variables in %s() (%d)", ops->function_name, zend_hash_num_elements(&vars)); + } + } else { + if (ops->filename) { + phpdbg_notice( + "Variables in %s (%d)", ops->filename, zend_hash_num_elements(&vars)); + } else { + phpdbg_notice( + "Variables @ %p (%d)", ops, zend_hash_num_elements(&vars)); + } + } + } + + if (zend_hash_num_elements(&vars)) { + phpdbg_writeln("Address\t\tRefs\tType\t\tVariable"); + for (zend_hash_internal_pointer_reset_ex(&vars, &pos); + zend_hash_get_current_data_ex(&vars, (void**) &data, &pos) == SUCCESS; + zend_hash_move_forward_ex(&vars, &pos)) { + char *var; + + zend_hash_get_current_key_ex(&vars, &var, NULL, NULL, 0, &pos); + + if (*data) { + phpdbg_write( + "%p\t%d\t", + *data, + Z_REFCOUNT_PP(data)); + + switch (Z_TYPE_PP(data)) { + case IS_STRING: phpdbg_write("(string)\t"); break; + case IS_LONG: phpdbg_write("(integer)\t"); break; + case IS_DOUBLE: phpdbg_write("(float)\t"); break; + case IS_RESOURCE: phpdbg_write("(resource)\t"); break; + case IS_ARRAY: phpdbg_write("(array)\t"); break; + case IS_OBJECT: phpdbg_write("(object)\t"); break; + case IS_NULL: phpdbg_write("(null)\t"); break; + } + + if (Z_TYPE_PP(data) == IS_RESOURCE) { + int type; + + phpdbg_writeln( + "%s$%s", Z_ISREF_PP(data) ? "&": "", var); + if (zend_list_find(Z_RESVAL_PP(data), &type)) { + phpdbg_write( + "|-------(typeof)------> (%s)", + zend_rsrc_list_get_rsrc_type(type TSRMLS_CC)); + } else { + phpdbg_write( + "|-------(typeof)------> (unknown)"); + } + phpdbg_writeln(EMPTY); + } else if (Z_TYPE_PP(data) == IS_OBJECT) { + phpdbg_writeln( + "%s$%s", Z_ISREF_PP(data) ? "&": "", var); + phpdbg_write( + "|-----(instanceof)----> (%s)", Z_OBJCE_PP(data)->name); + phpdbg_writeln(EMPTY); + } else { + phpdbg_write( + "%s$%s", Z_ISREF_PP(data) ? "&": "", var); + } + } else { + phpdbg_write( + "n/a\tn/a\tn/a\t$%s", var); + } + phpdbg_writeln(EMPTY); + } + } + + zend_hash_destroy(&vars); + + return SUCCESS; +} /* }}} */ + +PHPDBG_INFO(literal) /* {{{ */ +{ + if ((EG(in_execution) && EG(active_op_array)) || PHPDBG_G(ops)) { + zend_op_array *ops = EG(active_op_array) ? EG(active_op_array) : PHPDBG_G(ops); + int literal = 0, count = ops->last_literal-1; + + if (ops->function_name) { + if (ops->scope) { + phpdbg_notice( + "Literal Constants in %s::%s() (%d)", ops->scope->name, ops->function_name, count); + } else { + phpdbg_notice( + "Literal Constants in %s() (%d)", ops->function_name, count); + } + } else { + if (ops->filename) { + phpdbg_notice( + "Literal Constants in %s (%d)", ops->filename, count); + } else { + phpdbg_notice( + "Literal Constants @ %p (%d)", ops, count); + } + } + + while (literal < ops->last_literal) { + if (Z_TYPE(ops->literals[literal].constant) != IS_NULL) { + phpdbg_write("|-------- C%u -------> [", literal); + zend_print_zval( + &ops->literals[literal].constant, 0); + phpdbg_write("]"); + phpdbg_writeln(EMPTY); + } + literal++; + } + } else { + phpdbg_error("Not executing!"); + } + + return SUCCESS; +} /* }}} */ + +PHPDBG_INFO(memory) /* {{{ */ +{ + if (is_zend_mm(TSRMLS_C)) { + phpdbg_notice("Memory Manager Information"); + phpdbg_notice("Current"); + phpdbg_writeln("|-------> Used:\t%.3f kB", + (float) (zend_memory_usage(0 TSRMLS_CC)/1024)); + phpdbg_writeln("|-------> Real:\t%.3f kB", + (float) (zend_memory_usage(1 TSRMLS_CC)/1024)); + phpdbg_notice("Peak"); + phpdbg_writeln("|-------> Used:\t%.3f kB", + (float) (zend_memory_peak_usage(0 TSRMLS_CC)/1024)); + phpdbg_writeln("|-------> Real:\t%.3f kB", + (float) (zend_memory_peak_usage(1 TSRMLS_CC)/1024)); + } else { + phpdbg_error("Memory Manager Disabled!"); + } + return SUCCESS; +} /* }}} */ + +static inline void phpdbg_print_class_name(zend_class_entry **ce TSRMLS_DC) /* {{{ */ +{ + phpdbg_write( + "%s %s %s (%d)", + ((*ce)->type == ZEND_USER_CLASS) ? + "User" : "Internal", + ((*ce)->ce_flags & ZEND_ACC_INTERFACE) ? + "Interface" : + ((*ce)->ce_flags & ZEND_ACC_ABSTRACT) ? + "Abstract Class" : + "Class", + (*ce)->name, zend_hash_num_elements(&(*ce)->function_table)); +} /* }}} */ + +PHPDBG_INFO(classes) /* {{{ */ +{ + HashPosition position; + zend_class_entry **ce; + HashTable classes; + + zend_hash_init(&classes, 8, NULL, NULL, 0); + + for (zend_hash_internal_pointer_reset_ex(EG(class_table), &position); + zend_hash_get_current_data_ex(EG(class_table), (void**)&ce, &position) == SUCCESS; + zend_hash_move_forward_ex(EG(class_table), &position)) { + + if ((*ce)->type == ZEND_USER_CLASS) { + zend_hash_next_index_insert( + &classes, ce, sizeof(ce), NULL); + } + } + + phpdbg_notice("User Classes (%d)", + zend_hash_num_elements(&classes)); + + for (zend_hash_internal_pointer_reset_ex(&classes, &position); + zend_hash_get_current_data_ex(&classes, (void**)&ce, &position) == SUCCESS; + zend_hash_move_forward_ex(&classes, &position)) { + + phpdbg_print_class_name(ce TSRMLS_CC); + phpdbg_writeln(EMPTY); + + if ((*ce)->parent) { + zend_class_entry *pce = (*ce)->parent; + do { + phpdbg_write("|-------- "); + phpdbg_print_class_name(&pce TSRMLS_CC); + phpdbg_writeln(EMPTY); + } while ((pce = pce->parent)); + } + + if ((*ce)->info.user.filename) { + phpdbg_writeln( + "|---- in %s on line %u", + (*ce)->info.user.filename, + (*ce)->info.user.line_start); + } else { + phpdbg_writeln("|---- no source code"); + } + phpdbg_writeln(EMPTY); + } + + zend_hash_destroy(&classes); + + return SUCCESS; +} /* }}} */ + +PHPDBG_INFO(funcs) /* {{{ */ +{ + HashPosition position; + zend_function *zf, **pzf; + HashTable functions; + + zend_hash_init(&functions, 8, NULL, NULL, 0); + + for (zend_hash_internal_pointer_reset_ex(EG(function_table), &position); + zend_hash_get_current_data_ex(EG(function_table), (void**)&zf, &position) == SUCCESS; + zend_hash_move_forward_ex(EG(function_table), &position)) { + + if (zf->type == ZEND_USER_FUNCTION) { + zend_hash_next_index_insert( + &functions, (void**) &zf, sizeof(zend_function), NULL); + } + } + + phpdbg_notice("User Functions (%d)", + zend_hash_num_elements(&functions)); + + for (zend_hash_internal_pointer_reset_ex(&functions, &position); + zend_hash_get_current_data_ex(&functions, (void**)&pzf, &position) == SUCCESS; + zend_hash_move_forward_ex(&functions, &position)) { + zend_op_array *op_array = &((*pzf)->op_array); + + phpdbg_writeln( + "|-------- %s in %s on line %d", + op_array->function_name ? op_array->function_name : "{main}", + op_array->filename ? op_array->filename : "(no source code)", + op_array->line_start); + } + + zend_hash_destroy(&functions); + + return SUCCESS; +} /* }}} */ diff --git a/sapi/phpdbg/phpdbg_info.h b/sapi/phpdbg/phpdbg_info.h new file mode 100644 index 0000000000000..5d53812370790 --- /dev/null +++ b/sapi/phpdbg/phpdbg_info.h @@ -0,0 +1,49 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Felipe Pena | + | Authors: Joe Watkins | + | Authors: Bob Weinand | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHPDBG_INFO_H +#define PHPDBG_INFO_H + +#include "phpdbg_cmd.h" + +#define PHPDBG_INFO(name) PHPDBG_COMMAND(info_##name) + +PHPDBG_INFO(files); +PHPDBG_INFO(break); +PHPDBG_INFO(classes); +PHPDBG_INFO(funcs); +PHPDBG_INFO(error); +PHPDBG_INFO(vars); +PHPDBG_INFO(literal); +PHPDBG_INFO(memory); + +static const phpdbg_command_t phpdbg_info_commands[] = { + PHPDBG_COMMAND_D_EX(break, "show breakpoints", 'b', info_break, NULL, 0), + PHPDBG_COMMAND_D_EX(files, "show included files", 'F', info_files, NULL, 0), + PHPDBG_COMMAND_D_EX(classes, "show loaded classes", 'c', info_classes, NULL, 0), + PHPDBG_COMMAND_D_EX(funcs, "show loaded classes", 'f', info_funcs, NULL, 0), + PHPDBG_COMMAND_D_EX(error, "show last error", 'e', info_error, NULL, 0), + PHPDBG_COMMAND_D_EX(vars, "show active variables", 'v', info_vars, NULL, 0), + PHPDBG_COMMAND_D_EX(literal, "show active literal constants", 'l', info_literal, NULL, 0), + PHPDBG_COMMAND_D_EX(memory, "show memory manager stats", 'm', info_memory, NULL, 0), + PHPDBG_END_COMMAND +}; + +#endif /* PHPDBG_INFO_H */ diff --git a/sapi/phpdbg/phpdbg_list.c b/sapi/phpdbg/phpdbg_list.c new file mode 100644 index 0000000000000..b49be857efa35 --- /dev/null +++ b/sapi/phpdbg/phpdbg_list.c @@ -0,0 +1,279 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Felipe Pena | + | Authors: Joe Watkins | + | Authors: Bob Weinand | + +----------------------------------------------------------------------+ +*/ + +#include +#include +#include +#ifndef _WIN32 +# include +# include +#endif +#include +#include "phpdbg.h" +#include "phpdbg_list.h" +#include "phpdbg_utils.h" + +ZEND_EXTERN_MODULE_GLOBALS(phpdbg); + +PHPDBG_LIST(lines) /* {{{ */ +{ + if (!PHPDBG_G(exec) && !zend_is_executing(TSRMLS_C)) { + phpdbg_error("Not executing, and execution context not set"); + return SUCCESS; + } + + switch (param->type) { + case NUMERIC_PARAM: + case EMPTY_PARAM: + phpdbg_list_file(phpdbg_current_file(TSRMLS_C), + param->type == EMPTY_PARAM ? 0 : (param->num < 0 ? 1 - param->num : param->num), + (param->type != EMPTY_PARAM && param->num < 0 ? param->num : 0) + zend_get_executed_lineno(TSRMLS_C), + 0 TSRMLS_CC); + break; + case FILE_PARAM: + phpdbg_list_file(param->file.name, param->file.line, 0, 0 TSRMLS_CC); + break; + + phpdbg_default_switch_case(); + } + + return SUCCESS; +} /* }}} */ + +PHPDBG_LIST(func) /* {{{ */ +{ + switch (param->type) { + case STR_PARAM: + phpdbg_list_function_byname( + param->str, param->len TSRMLS_CC); + break; + + phpdbg_default_switch_case(); + } + + return SUCCESS; +} /* }}} */ + +PHPDBG_LIST(method) /* {{{ */ +{ + switch (param->type) { + case METHOD_PARAM: { + zend_class_entry **ce; + + if (zend_lookup_class(param->method.class, strlen(param->method.class), &ce TSRMLS_CC) == SUCCESS) { + zend_function *function; + char *lcname = zend_str_tolower_dup(param->method.name, strlen(param->method.name)); + + if (zend_hash_find(&(*ce)->function_table, lcname, strlen(lcname)+1, (void**) &function) == SUCCESS) { + phpdbg_list_function(function TSRMLS_CC); + } else { + phpdbg_error("Could not find %s::%s", param->method.class, param->method.name); + } + + efree(lcname); + } else { + phpdbg_error("Could not find the class %s", param->method.class); + } + } break; + + phpdbg_default_switch_case(); + } + + return SUCCESS; +} /* }}} */ + +PHPDBG_LIST(class) /* {{{ */ +{ + switch (param->type) { + case STR_PARAM: { + zend_class_entry **ce; + + if (zend_lookup_class(param->str, param->len, &ce TSRMLS_CC) == SUCCESS) { + if ((*ce)->type == ZEND_USER_CLASS) { + if ((*ce)->info.user.filename) { + phpdbg_list_file( + (*ce)->info.user.filename, + (*ce)->info.user.line_end - (*ce)->info.user.line_start + 1, + (*ce)->info.user.line_start, 0 TSRMLS_CC + ); + } else { + phpdbg_error("The source of the requested class (%s) cannot be found", (*ce)->name); + } + } else { + phpdbg_error("The class requested (%s) is not user defined", (*ce)->name); + } + } else { + phpdbg_error("The requested class (%s) could not be found", param->str); + } + } break; + + phpdbg_default_switch_case(); + } + + return SUCCESS; +} /* }}} */ + +void phpdbg_list_file(const char *filename, long count, long offset, int highlight TSRMLS_DC) /* {{{ */ +{ + unsigned char *mem, *pos, *last_pos, *end_pos; + struct stat st; +#ifndef _WIN32 + int fd; +#else + HANDLE fd, map; +#endif + int all_content = (count == 0); + int line = 0, displayed = 0; + + if (VCWD_STAT(filename, &st) == FAILURE) { + phpdbg_error("Failed to stat file %s", filename); + return; + } + +#ifndef _WIN32 + if ((fd = VCWD_OPEN(filename, O_RDONLY)) == FAILURE) { + phpdbg_error("Failed to open file %s to list", filename); + return; + } + + pos = last_pos = mem = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0); + end_pos = mem + st.st_size; +#else + + fd = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (fd == INVALID_HANDLE_VALUE) { + phpdbg_error("Failed to open file!"); + return; + } + + map = CreateFileMapping(fd, NULL, PAGE_READONLY, 0, 0, NULL); + if (map == NULL) { + phpdbg_error("Failed to map file!"); + CloseHandle(fd); + return; + } + + pos = last_pos = mem = (char*) MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0); + if (mem == NULL) { + phpdbg_error("Failed to map file in memory"); + CloseHandle(map); + CloseHandle(fd); + return; + } + end_pos = mem + st.st_size; +#endif + while (1) { + if (pos == end_pos) { + break; + } + + pos = memchr(last_pos, '\n', end_pos - last_pos); + + if (!pos) { + /* No more line breaks */ + pos = end_pos; + } + + ++line; + + if (!offset || offset <= line) { + /* Without offset, or offset reached */ + if (!highlight) { + phpdbg_writeln("%05u: %.*s", line, (int)(pos - last_pos), last_pos); + } else { + if (highlight != line) { + phpdbg_writeln(" %05u: %.*s", line, (int)(pos - last_pos), last_pos); + } else { + phpdbg_writeln(">%05u: %.*s", line, (int)(pos - last_pos), last_pos); + } + } + ++displayed; + } + + last_pos = pos + 1; + + if (!all_content && displayed == count) { + /* Reached max line to display */ + break; + } + } + +#ifndef _WIN32 + munmap(mem, st.st_size); + close(fd); +#else + UnmapViewOfFile(mem); + CloseHandle(map); + CloseHandle(fd); +#endif +} /* }}} */ + +void phpdbg_list_function(const zend_function *fbc TSRMLS_DC) /* {{{ */ +{ + const zend_op_array *ops; + + if (fbc->type != ZEND_USER_FUNCTION) { + phpdbg_error("The function requested (%s) is not user defined", fbc->common.function_name); + return; + } + + ops = (zend_op_array*)fbc; + + phpdbg_list_file(ops->filename, + ops->line_end - ops->line_start + 1, ops->line_start, 0 TSRMLS_CC); +} /* }}} */ + +void phpdbg_list_function_byname(const char *str, size_t len TSRMLS_DC) /* {{{ */ +{ + HashTable *func_table = EG(function_table); + zend_function* fbc; + char *func_name = (char*) str; + size_t func_name_len = len; + + /* search active scope if begins with period */ + if (func_name[0] == '.') { + if (EG(scope)) { + func_name++; + func_name_len--; + + func_table = &EG(scope)->function_table; + } else { + phpdbg_error("No active class"); + return; + } + } else if (!EG(function_table)) { + phpdbg_error("No function table loaded"); + return; + } else { + func_table = EG(function_table); + } + + /* use lowercase names, case insensitive */ + func_name = zend_str_tolower_dup(func_name, func_name_len); + + if (zend_hash_find(func_table, func_name, func_name_len+1, (void**)&fbc) == SUCCESS) { + phpdbg_list_function(fbc TSRMLS_CC); + } else { + phpdbg_error("Function %s not found", func_name); + } + + efree(func_name); +} /* }}} */ + diff --git a/sapi/phpdbg/phpdbg_list.h b/sapi/phpdbg/phpdbg_list.h new file mode 100644 index 0000000000000..d6180271585ce --- /dev/null +++ b/sapi/phpdbg/phpdbg_list.h @@ -0,0 +1,47 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Felipe Pena | + | Authors: Joe Watkins | + | Authors: Bob Weinand | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHPDBG_LIST_H +#define PHPDBG_LIST_H + +#include "TSRM.h" +#include "phpdbg_cmd.h" + +#define PHPDBG_LIST(name) PHPDBG_COMMAND(list_##name) +#define PHPDBG_LIST_HANDLER(name) PHPDBG_COMMAND_HANDLER(list_##name) + +PHPDBG_LIST(lines); +PHPDBG_LIST(class); +PHPDBG_LIST(method); +PHPDBG_LIST(func); + +void phpdbg_list_function_byname(const char *, size_t TSRMLS_DC); +void phpdbg_list_function(const zend_function* TSRMLS_DC); +void phpdbg_list_file(const char*, long, long, int TSRMLS_DC); + +static const phpdbg_command_t phpdbg_list_commands[] = { + PHPDBG_COMMAND_D_EX(lines, "lists the specified lines", 'l', list_lines, NULL, 1), + PHPDBG_COMMAND_D_EX(class, "lists the specified class", 'c', list_class, NULL, 1), + PHPDBG_COMMAND_D_EX(method, "lists the specified method", 'm', list_method, NULL, 1), + PHPDBG_COMMAND_D_EX(func, "lists the specified function", 'f', list_func, NULL, 1), + PHPDBG_END_COMMAND +}; + +#endif /* PHPDBG_LIST_H */ diff --git a/sapi/phpdbg/phpdbg_opcode.c b/sapi/phpdbg/phpdbg_opcode.c new file mode 100644 index 0000000000000..025d57a08dc49 --- /dev/null +++ b/sapi/phpdbg/phpdbg_opcode.c @@ -0,0 +1,361 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Felipe Pena | + | Authors: Joe Watkins | + | Authors: Bob Weinand | + +----------------------------------------------------------------------+ +*/ + +#include "phpdbg.h" +#include "zend_vm_opcodes.h" +#include "zend_compile.h" +#include "phpdbg_opcode.h" +#include "phpdbg_utils.h" + +ZEND_EXTERN_MODULE_GLOBALS(phpdbg); + +static inline zend_uint phpdbg_decode_literal(zend_op_array *ops, zend_literal *literal TSRMLS_DC) /* {{{ */ +{ + int iter = 0; + + while (iter < ops->last_literal) { + if (literal == &ops->literals[iter]) { + return iter; + } + iter++; + } + + return 0; +} /* }}} */ + +static inline char *phpdbg_decode_op(zend_op_array *ops, znode_op *op, zend_uint type, HashTable *vars TSRMLS_DC) /* {{{ */ +{ + char *decode = NULL; + + switch (type &~ EXT_TYPE_UNUSED) { + case IS_CV: + asprintf(&decode, "$%s", ops->vars[op->var].name); + break; + + case IS_VAR: + case IS_TMP_VAR: { + zend_ulong id = 0, *pid = NULL; + if (zend_hash_index_find(vars, (zend_ulong) ops->vars - op->var, (void**) &pid) != SUCCESS) { + id = zend_hash_num_elements(vars); + zend_hash_index_update( + vars, (zend_ulong) ops->vars - op->var, + (void**) &id, + sizeof(zend_ulong), NULL); + } else id = *pid; + asprintf(&decode, "@%lu", id); + } break; + + case IS_CONST: + asprintf(&decode, "C%u", phpdbg_decode_literal(ops, op->literal TSRMLS_CC)); + break; + + case IS_UNUSED: + asprintf(&decode, ""); + break; + } + return decode; +} /* }}} */ + +char *phpdbg_decode_opline(zend_op_array *ops, zend_op *op, HashTable *vars TSRMLS_DC) /*{{{ */ +{ + char *decode[4] = {NULL, NULL, NULL, NULL}; + + switch (op->opcode) { + case ZEND_JMP: +#ifdef ZEND_GOTO + case ZEND_GOTO: +#endif +#ifdef ZEND_FAST_CALL + case ZEND_FAST_CALL: +#endif + asprintf(&decode[1], "J%ld", op->op1.jmp_addr - ops->opcodes); + goto format; + + case ZEND_JMPZNZ: + decode[1] = phpdbg_decode_op(ops, &op->op1, op->op1_type, vars TSRMLS_CC); + asprintf( + &decode[2], "J%u or J%lu", op->op2.opline_num, op->extended_value); + goto result; + + case ZEND_JMPZ: + case ZEND_JMPNZ: + case ZEND_JMPZ_EX: + case ZEND_JMPNZ_EX: + +#ifdef ZEND_JMP_SET + case ZEND_JMP_SET: +#endif +#ifdef ZEND_JMP_SET_VAR + case ZEND_JMP_SET_VAR: +#endif + decode[1] = phpdbg_decode_op(ops, &op->op1, op->op1_type, vars TSRMLS_CC); + asprintf( + &decode[2], "J%ld", op->op2.jmp_addr - ops->opcodes); + goto result; + + case ZEND_RECV_INIT: + goto result; + + default: { + decode[1] = phpdbg_decode_op(ops, &op->op1, op->op1_type, vars TSRMLS_CC); + decode[2] = phpdbg_decode_op(ops, &op->op2, op->op2_type, vars TSRMLS_CC); +result: + decode[3] = phpdbg_decode_op(ops, &op->result, op->result_type, vars TSRMLS_CC); +format: + asprintf( + &decode[0], + "%-20s %-20s %-20s", + decode[1] ? decode[1] : "", + decode[2] ? decode[2] : "", + decode[3] ? decode[3] : ""); + } + } + + if (decode[1]) + free(decode[1]); + if (decode[2]) + free(decode[2]); + if (decode[3]) + free(decode[3]); + + return decode[0]; +} /* }}} */ + +void phpdbg_print_opline_ex(zend_execute_data *execute_data, HashTable *vars, zend_bool ignore_flags TSRMLS_DC) /* {{{ */ +{ + /* force out a line while stepping so the user knows what is happening */ + if (ignore_flags || + (!(PHPDBG_G(flags) & PHPDBG_IS_QUIET) || + (PHPDBG_G(flags) & PHPDBG_IS_STEPPING) || + (PHPDBG_G(oplog)))) { + + zend_op *opline = execute_data->opline; + char *decode = phpdbg_decode_opline(execute_data->op_array, opline, vars TSRMLS_CC); + + if (ignore_flags || (!(PHPDBG_G(flags) & PHPDBG_IS_QUIET) || (PHPDBG_G(flags) & PHPDBG_IS_STEPPING))) { + /* output line info */ + phpdbg_notice("L%-5u %16p %-30s %s %s", + opline->lineno, + opline, + phpdbg_decode_opcode(opline->opcode), + decode, + execute_data->op_array->filename ? execute_data->op_array->filename : "unknown"); + } + + if (!ignore_flags && PHPDBG_G(oplog)) { + phpdbg_log_ex(PHPDBG_G(oplog), "L%-5u %16p %-30s %s %s", + opline->lineno, + opline, + phpdbg_decode_opcode(opline->opcode), + decode, + execute_data->op_array->filename ? execute_data->op_array->filename : "unknown"); + } + + if (decode) { + free(decode); + } + } +} /* }}} */ + +void phpdbg_print_opline(zend_execute_data *execute_data, zend_bool ignore_flags TSRMLS_DC) /* {{{ */ +{ + phpdbg_print_opline_ex(execute_data, NULL, ignore_flags TSRMLS_CC); +} /* }}} */ + +const char *phpdbg_decode_opcode(zend_uchar opcode) /* {{{ */ +{ +#define CASE(s) case s: return #s + switch (opcode) { + CASE(ZEND_NOP); + CASE(ZEND_ADD); + CASE(ZEND_SUB); + CASE(ZEND_MUL); + CASE(ZEND_DIV); + CASE(ZEND_MOD); + CASE(ZEND_SL); + CASE(ZEND_SR); + CASE(ZEND_CONCAT); + CASE(ZEND_BW_OR); + CASE(ZEND_BW_AND); + CASE(ZEND_BW_XOR); + CASE(ZEND_BW_NOT); + CASE(ZEND_BOOL_NOT); + CASE(ZEND_BOOL_XOR); + CASE(ZEND_IS_IDENTICAL); + CASE(ZEND_IS_NOT_IDENTICAL); + CASE(ZEND_IS_EQUAL); + CASE(ZEND_IS_NOT_EQUAL); + CASE(ZEND_IS_SMALLER); + CASE(ZEND_IS_SMALLER_OR_EQUAL); + CASE(ZEND_CAST); + CASE(ZEND_QM_ASSIGN); + CASE(ZEND_ASSIGN_ADD); + CASE(ZEND_ASSIGN_SUB); + CASE(ZEND_ASSIGN_MUL); + CASE(ZEND_ASSIGN_DIV); + CASE(ZEND_ASSIGN_MOD); + CASE(ZEND_ASSIGN_SL); + CASE(ZEND_ASSIGN_SR); + CASE(ZEND_ASSIGN_CONCAT); + CASE(ZEND_ASSIGN_BW_OR); + CASE(ZEND_ASSIGN_BW_AND); + CASE(ZEND_ASSIGN_BW_XOR); + CASE(ZEND_PRE_INC); + CASE(ZEND_PRE_DEC); + CASE(ZEND_POST_INC); + CASE(ZEND_POST_DEC); + CASE(ZEND_ASSIGN); + CASE(ZEND_ASSIGN_REF); + CASE(ZEND_ECHO); + CASE(ZEND_PRINT); + CASE(ZEND_JMP); + CASE(ZEND_JMPZ); + CASE(ZEND_JMPNZ); + CASE(ZEND_JMPZNZ); + CASE(ZEND_JMPZ_EX); + CASE(ZEND_JMPNZ_EX); + CASE(ZEND_CASE); + CASE(ZEND_SWITCH_FREE); + CASE(ZEND_BRK); + CASE(ZEND_CONT); + CASE(ZEND_BOOL); + CASE(ZEND_INIT_STRING); + CASE(ZEND_ADD_CHAR); + CASE(ZEND_ADD_STRING); + CASE(ZEND_ADD_VAR); + CASE(ZEND_BEGIN_SILENCE); + CASE(ZEND_END_SILENCE); + CASE(ZEND_INIT_FCALL_BY_NAME); + CASE(ZEND_DO_FCALL); + CASE(ZEND_DO_FCALL_BY_NAME); + CASE(ZEND_RETURN); + CASE(ZEND_RECV); + CASE(ZEND_RECV_INIT); + CASE(ZEND_SEND_VAL); + CASE(ZEND_SEND_VAR); + CASE(ZEND_SEND_REF); + CASE(ZEND_NEW); + CASE(ZEND_INIT_NS_FCALL_BY_NAME); + CASE(ZEND_FREE); + CASE(ZEND_INIT_ARRAY); + CASE(ZEND_ADD_ARRAY_ELEMENT); + CASE(ZEND_INCLUDE_OR_EVAL); + CASE(ZEND_UNSET_VAR); + CASE(ZEND_UNSET_DIM); + CASE(ZEND_UNSET_OBJ); + CASE(ZEND_FE_RESET); + CASE(ZEND_FE_FETCH); + CASE(ZEND_EXIT); + CASE(ZEND_FETCH_R); + CASE(ZEND_FETCH_DIM_R); + CASE(ZEND_FETCH_OBJ_R); + CASE(ZEND_FETCH_W); + CASE(ZEND_FETCH_DIM_W); + CASE(ZEND_FETCH_OBJ_W); + CASE(ZEND_FETCH_RW); + CASE(ZEND_FETCH_DIM_RW); + CASE(ZEND_FETCH_OBJ_RW); + CASE(ZEND_FETCH_IS); + CASE(ZEND_FETCH_DIM_IS); + CASE(ZEND_FETCH_OBJ_IS); + CASE(ZEND_FETCH_FUNC_ARG); + CASE(ZEND_FETCH_DIM_FUNC_ARG); + CASE(ZEND_FETCH_OBJ_FUNC_ARG); + CASE(ZEND_FETCH_UNSET); + CASE(ZEND_FETCH_DIM_UNSET); + CASE(ZEND_FETCH_OBJ_UNSET); + CASE(ZEND_FETCH_DIM_TMP_VAR); + CASE(ZEND_FETCH_CONSTANT); + CASE(ZEND_GOTO); + CASE(ZEND_EXT_STMT); + CASE(ZEND_EXT_FCALL_BEGIN); + CASE(ZEND_EXT_FCALL_END); + CASE(ZEND_EXT_NOP); + CASE(ZEND_TICKS); + CASE(ZEND_SEND_VAR_NO_REF); + CASE(ZEND_CATCH); + CASE(ZEND_THROW); + CASE(ZEND_FETCH_CLASS); + CASE(ZEND_CLONE); + CASE(ZEND_RETURN_BY_REF); + CASE(ZEND_INIT_METHOD_CALL); + CASE(ZEND_INIT_STATIC_METHOD_CALL); + CASE(ZEND_ISSET_ISEMPTY_VAR); + CASE(ZEND_ISSET_ISEMPTY_DIM_OBJ); + CASE(ZEND_PRE_INC_OBJ); + CASE(ZEND_PRE_DEC_OBJ); + CASE(ZEND_POST_INC_OBJ); + CASE(ZEND_POST_DEC_OBJ); + CASE(ZEND_ASSIGN_OBJ); + CASE(ZEND_INSTANCEOF); + CASE(ZEND_DECLARE_CLASS); + CASE(ZEND_DECLARE_INHERITED_CLASS); + CASE(ZEND_DECLARE_FUNCTION); + CASE(ZEND_RAISE_ABSTRACT_ERROR); + CASE(ZEND_DECLARE_CONST); + CASE(ZEND_ADD_INTERFACE); + CASE(ZEND_DECLARE_INHERITED_CLASS_DELAYED); + CASE(ZEND_VERIFY_ABSTRACT_CLASS); + CASE(ZEND_ASSIGN_DIM); + CASE(ZEND_ISSET_ISEMPTY_PROP_OBJ); + CASE(ZEND_HANDLE_EXCEPTION); + CASE(ZEND_USER_OPCODE); +#ifdef ZEND_JMP_SET + CASE(ZEND_JMP_SET); +#endif + CASE(ZEND_DECLARE_LAMBDA_FUNCTION); +#ifdef ZEND_ADD_TRAIT + CASE(ZEND_ADD_TRAIT); +#endif +#ifdef ZEND_BIND_TRAITS + CASE(ZEND_BIND_TRAITS); +#endif +#ifdef ZEND_SEPARATE + CASE(ZEND_SEPARATE); +#endif +#ifdef ZEND_QM_ASSIGN_VAR + CASE(ZEND_QM_ASSIGN_VAR); +#endif +#ifdef ZEND_JMP_SET_VAR + CASE(ZEND_JMP_SET_VAR); +#endif +#ifdef ZEND_DISCARD_EXCEPTION + CASE(ZEND_DISCARD_EXCEPTION); +#endif +#ifdef ZEND_YIELD + CASE(ZEND_YIELD); +#endif +#ifdef ZEND_GENERATOR_RETURN + CASE(ZEND_GENERATOR_RETURN); +#endif +#ifdef ZEND_FAST_CALL + CASE(ZEND_FAST_CALL); +#endif +#ifdef ZEND_FAST_RET + CASE(ZEND_FAST_RET); +#endif +#ifdef ZEND_RECV_VARIADIC + CASE(ZEND_RECV_VARIADIC); +#endif + CASE(ZEND_OP_DATA); + default: + return "UNKNOWN"; + } +} /* }}} */ diff --git a/sapi/phpdbg/phpdbg_opcode.h b/sapi/phpdbg/phpdbg_opcode.h new file mode 100644 index 0000000000000..5771488e70748 --- /dev/null +++ b/sapi/phpdbg/phpdbg_opcode.h @@ -0,0 +1,31 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Felipe Pena | + | Authors: Joe Watkins | + | Authors: Bob Weinand | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHPDBG_OPCODE_H +#define PHPDBG_OPCODE_H + +#include "zend_types.h" + +const char *phpdbg_decode_opcode(zend_uchar); +char *phpdbg_decode_opline(zend_op_array *ops, zend_op *op, HashTable *vars TSRMLS_DC); +void phpdbg_print_opline(zend_execute_data *execute_data, zend_bool ignore_flags TSRMLS_DC); +void phpdbg_print_opline_ex(zend_execute_data *execute_data, HashTable *vars, zend_bool ignore_flags TSRMLS_DC); + +#endif /* PHPDBG_OPCODE_H */ diff --git a/sapi/phpdbg/phpdbg_print.c b/sapi/phpdbg/phpdbg_print.c new file mode 100644 index 0000000000000..51edcfbf8dab2 --- /dev/null +++ b/sapi/phpdbg/phpdbg_print.c @@ -0,0 +1,258 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Felipe Pena | + | Authors: Joe Watkins | + | Authors: Bob Weinand | + +----------------------------------------------------------------------+ +*/ + +#include "phpdbg.h" +#include "phpdbg_print.h" +#include "phpdbg_utils.h" +#include "phpdbg_opcode.h" +#include "phpdbg_prompt.h" + +ZEND_EXTERN_MODULE_GLOBALS(phpdbg); + +PHPDBG_PRINT(opline) /* {{{ */ +{ + if (EG(in_execution) && EG(current_execute_data)) { + phpdbg_print_opline(EG(current_execute_data), 1 TSRMLS_CC); + } else { + phpdbg_error("Not Executing!"); + } + + return SUCCESS; +} /* }}} */ + +static inline void phpdbg_print_function_helper(zend_function *method TSRMLS_DC) /* {{{ */ +{ + switch (method->type) { + case ZEND_USER_FUNCTION: { + zend_op_array* op_array = &(method->op_array); + HashTable vars; + + if (op_array) { + zend_op *opline = &(op_array->opcodes[0]); + zend_uint opcode = 0, + end = op_array->last-1; + + if (method->common.scope) { + phpdbg_writeln("\tL%d-%d %s::%s() %s", + op_array->line_start, op_array->line_end, + method->common.scope->name, + method->common.function_name, + op_array->filename ? op_array->filename : "unknown"); + } else { + phpdbg_writeln("\tL%d-%d %s() %s", + method->common.function_name ? op_array->line_start : 0, + method->common.function_name ? op_array->line_end : 0, + method->common.function_name ? method->common.function_name : "{main}", + op_array->filename ? op_array->filename : "unknown"); + } + + zend_hash_init(&vars, op_array->last, NULL, NULL, 0); + do { + char *decode = phpdbg_decode_opline(op_array, opline, &vars TSRMLS_CC); + if (decode != NULL) { + phpdbg_writeln("\t\tL%u\t%p %-30s %s", + opline->lineno, + opline, + phpdbg_decode_opcode(opline->opcode), + decode); + free(decode); + } else { + phpdbg_error("\tFailed to decode opline %16p", opline); + } + opline++; + } while (++opcode < end); + zend_hash_destroy(&vars); + } + } break; + + default: { + if (method->common.scope) { + phpdbg_writeln("\tInternal %s::%s()", method->common.scope->name, method->common.function_name); + } else { + phpdbg_writeln("\tInternal %s()", method->common.function_name); + } + } + } +} /* }}} */ + +PHPDBG_PRINT(exec) /* {{{ */ +{ + if (PHPDBG_G(exec)) { + if (!PHPDBG_G(ops)) { + phpdbg_compile(TSRMLS_C); + } + + if (PHPDBG_G(ops)) { + phpdbg_notice("Context %s", PHPDBG_G(exec)); + + phpdbg_print_function_helper((zend_function*) PHPDBG_G(ops) TSRMLS_CC); + } + } else { + phpdbg_error("No execution context set"); + } + +return SUCCESS; +} /* }}} */ + +PHPDBG_PRINT(stack) /* {{{ */ +{ + zend_op_array *ops = EG(active_op_array); + + if (EG(in_execution) && ops) { + if (ops->function_name) { + if (ops->scope) { + phpdbg_notice("Stack in %s::%s()", ops->scope->name, ops->function_name); + } else { + phpdbg_notice("Stack in %s()", ops->function_name); + } + } else { + if (ops->filename) { + phpdbg_notice("Stack in %s", ops->filename); + } else { + phpdbg_notice("Stack @ %p", ops); + } + } + phpdbg_print_function_helper((zend_function*) ops TSRMLS_CC); + } else { + phpdbg_error("Not Executing!"); + } + + return SUCCESS; +} /* }}} */ + +PHPDBG_PRINT(class) /* {{{ */ +{ + zend_class_entry **ce; + + switch (param->type) { + case STR_PARAM: { + if (zend_lookup_class(param->str, param->len, &ce TSRMLS_CC) == SUCCESS) { + phpdbg_notice("%s %s: %s", + ((*ce)->type == ZEND_USER_CLASS) ? + "User" : "Internal", + ((*ce)->ce_flags & ZEND_ACC_INTERFACE) ? + "Interface" : + ((*ce)->ce_flags & ZEND_ACC_ABSTRACT) ? + "Abstract Class" : + "Class", + (*ce)->name); + + phpdbg_writeln("Methods (%d):", zend_hash_num_elements(&(*ce)->function_table)); + if (zend_hash_num_elements(&(*ce)->function_table)) { + HashPosition position; + zend_function *method; + + for (zend_hash_internal_pointer_reset_ex(&(*ce)->function_table, &position); + zend_hash_get_current_data_ex(&(*ce)->function_table, (void**) &method, &position) == SUCCESS; + zend_hash_move_forward_ex(&(*ce)->function_table, &position)) { + phpdbg_print_function_helper(method TSRMLS_CC); + } + } + } else { + phpdbg_error("The class %s could not be found", param->str); + } + } break; + + phpdbg_default_switch_case(); + } + + return SUCCESS; +} /* }}} */ + +PHPDBG_PRINT(method) /* {{{ */ +{ + switch (param->type) { + case METHOD_PARAM: { + zend_class_entry **ce; + + if (zend_lookup_class(param->method.class, strlen(param->method.class), &ce TSRMLS_CC) == SUCCESS) { + zend_function *fbc; + char *lcname = zend_str_tolower_dup(param->method.name, strlen(param->method.name)); + + if (zend_hash_find(&(*ce)->function_table, lcname, strlen(lcname)+1, (void**)&fbc) == SUCCESS) { + phpdbg_notice("%s Method %s", + (fbc->type == ZEND_USER_FUNCTION) ? "User" : "Internal", + fbc->common.function_name); + + phpdbg_print_function_helper(fbc TSRMLS_CC); + } else { + phpdbg_error("The method %s could not be found", param->method.name); + } + + efree(lcname); + } else { + phpdbg_error("The class %s could not be found", param->method.class); + } + } break; + + phpdbg_default_switch_case(); + } + + return SUCCESS; +} /* }}} */ + +PHPDBG_PRINT(func) /* {{{ */ +{ + switch (param->type) { + case STR_PARAM: { + HashTable *func_table = EG(function_table); + zend_function* fbc; + const char *func_name = param->str; + size_t func_name_len = param->len; + char *lcname; + /* search active scope if begins with period */ + if (func_name[0] == '.') { + if (EG(scope)) { + func_name++; + func_name_len--; + + func_table = &EG(scope)->function_table; + } else { + phpdbg_error("No active class"); + return SUCCESS; + } + } else if (!EG(function_table)) { + phpdbg_error("No function table loaded"); + return SUCCESS; + } else { + func_table = EG(function_table); + } + + lcname = zend_str_tolower_dup(func_name, func_name_len); + + if (zend_hash_find(func_table, lcname, strlen(lcname)+1, (void**)&fbc) == SUCCESS) { + phpdbg_notice("%s %s %s", + (fbc->type == ZEND_USER_FUNCTION) ? "User" : "Internal", + (fbc->common.scope) ? "Method" : "Function", + fbc->common.function_name); + + phpdbg_print_function_helper(fbc TSRMLS_CC); + } else { + phpdbg_error("The function %s could not be found", func_name); + } + + efree(lcname); + } break; + + phpdbg_default_switch_case(); + } + + return SUCCESS; +} /* }}} */ diff --git a/sapi/phpdbg/phpdbg_print.h b/sapi/phpdbg/phpdbg_print.h new file mode 100644 index 0000000000000..1232f544d2975 --- /dev/null +++ b/sapi/phpdbg/phpdbg_print.h @@ -0,0 +1,51 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Felipe Pena | + | Authors: Joe Watkins | + | Authors: Bob Weinand | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHPDBG_PRINT_H +#define PHPDBG_PRINT_H + +#include "phpdbg_cmd.h" + +#define PHPDBG_PRINT(name) PHPDBG_COMMAND(print_##name) + +/** + * Printer Forward Declarations + */ +PHPDBG_PRINT(exec); +PHPDBG_PRINT(opline); +PHPDBG_PRINT(class); +PHPDBG_PRINT(method); +PHPDBG_PRINT(func); +PHPDBG_PRINT(stack); + +/** + * Commands + */ +static const phpdbg_command_t phpdbg_print_commands[] = { + PHPDBG_COMMAND_D_EX(exec, "print out the instructions in the execution context", 'e', print_exec, NULL, 0), + PHPDBG_COMMAND_D_EX(opline, "print out the instruction in the current opline", 'o', print_opline, NULL, 0), + PHPDBG_COMMAND_D_EX(class, "print out the instructions in the specified class", 'c', print_class, NULL, 1), + PHPDBG_COMMAND_D_EX(method, "print out the instructions in the specified method", 'm', print_method, NULL, 1), + PHPDBG_COMMAND_D_EX(func, "print out the instructions in the specified function", 'f', print_func, NULL, 1), + PHPDBG_COMMAND_D_EX(stack, "print out the instructions in the current stack", 's', print_stack, NULL, 0), + PHPDBG_END_COMMAND +}; + +#endif /* PHPDBG_PRINT_H */ diff --git a/sapi/phpdbg/phpdbg_prompt.c b/sapi/phpdbg/phpdbg_prompt.c new file mode 100644 index 0000000000000..f2f482b7eceff --- /dev/null +++ b/sapi/phpdbg/phpdbg_prompt.c @@ -0,0 +1,1328 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Felipe Pena | + | Authors: Joe Watkins | + | Authors: Bob Weinand | + +----------------------------------------------------------------------+ +*/ + +#include +#include +#include "zend.h" +#include "zend_compile.h" +#include "phpdbg.h" +#include "phpdbg_help.h" +#include "phpdbg_print.h" +#include "phpdbg_info.h" +#include "phpdbg_break.h" +#include "phpdbg_bp.h" +#include "phpdbg_opcode.h" +#include "phpdbg_list.h" +#include "phpdbg_utils.h" +#include "phpdbg_prompt.h" +#include "phpdbg_cmd.h" +#include "phpdbg_set.h" +#include "phpdbg_frame.h" + +/* {{{ command declarations */ +const phpdbg_command_t phpdbg_prompt_commands[] = { + PHPDBG_COMMAND_D(exec, "set execution context", 'e', NULL, 1), + PHPDBG_COMMAND_D(compile, "attempt compilation", 'c', NULL, 0), + PHPDBG_COMMAND_D(step, "step through execution", 's', NULL, 1), + PHPDBG_COMMAND_D(next, "continue execution", 'n', NULL, 0), + PHPDBG_COMMAND_D(run, "attempt execution", 'r', NULL, 0), + PHPDBG_COMMAND_D(eval, "evaluate some code", 'E', NULL, 1), + PHPDBG_COMMAND_D(until, "continue past the current line", 'u', NULL, 0), + PHPDBG_COMMAND_D(finish, "continue past the end of the stack", 'F', NULL, 0), + PHPDBG_COMMAND_D(leave, "continue until the end of the stack", 'L', NULL, 0), + PHPDBG_COMMAND_D(print, "print something", 'p', phpdbg_print_commands, 2), + PHPDBG_COMMAND_D(break, "set breakpoint", 'b', phpdbg_break_commands, 1), + PHPDBG_COMMAND_D(back, "show trace", 't', NULL, 0), + PHPDBG_COMMAND_D(frame, "switch to a frame", 'f', NULL, 1), + PHPDBG_COMMAND_D(list, "lists some code", 'l', phpdbg_list_commands, 2), + PHPDBG_COMMAND_D(info, "displays some informations", 'i', phpdbg_info_commands, 1), + PHPDBG_COMMAND_D(clean, "clean the execution environment", 'X', NULL, 0), + PHPDBG_COMMAND_D(clear, "clear breakpoints", 'C', NULL, 0), + PHPDBG_COMMAND_D(help, "show help menu", 'h', phpdbg_help_commands, 2), + PHPDBG_COMMAND_D(quiet, "silence some output", 'Q', NULL, 1), + PHPDBG_COMMAND_D(aliases, "show alias list", 'a', NULL, 0), + PHPDBG_COMMAND_D(set, "set phpdbg configuration", 'S', phpdbg_set_commands, 1), + PHPDBG_COMMAND_D(register,"register a function", 'R', NULL, 1), + PHPDBG_COMMAND_D(source, "execute a phpdbginit", '.', NULL, 1), + PHPDBG_COMMAND_D(shell, "shell a command", '-', NULL, 1), + PHPDBG_COMMAND_D(quit, "exit phpdbg", 'q', NULL, 0), + PHPDBG_END_COMMAND +}; /* }}} */ + +ZEND_EXTERN_MODULE_GLOBALS(phpdbg); + +static inline int phpdbg_call_register(phpdbg_input_t *input TSRMLS_DC) /* {{{ */ +{ + phpdbg_input_t *function = input->argv[0]; + + if (zend_hash_exists( + &PHPDBG_G(registered), function->string, function->length+1)) { + + zval fname, *fretval; + zend_fcall_info fci; + + ZVAL_STRINGL(&fname, function->string, function->length, 1); + + memset(&fci, 0, sizeof(zend_fcall_info)); + + fci.size = sizeof(zend_fcall_info); + fci.function_table = &PHPDBG_G(registered); + fci.function_name = &fname; + fci.symbol_table = EG(active_symbol_table); + fci.object_ptr = NULL; + fci.retval_ptr_ptr = &fretval; + fci.no_separation = 1; + + if (input->argc > 1) { + int param; + zval params; + + array_init(¶ms); + + for (param = 0; param < (input->argc-1); param++) { + add_next_index_stringl( + ¶ms, + input->argv[param+1]->string, + input->argv[param+1]->length, 1); + + phpdbg_debug( + "created param[%d] from argv[%d]: %s", + param, param+1, input->argv[param+1]->string); + } + + zend_fcall_info_args(&fci, ¶ms TSRMLS_CC); + } else { + fci.params = NULL; + fci.param_count = 0; + } + + phpdbg_debug( + "created %d params from %d arguments", + fci.param_count, input->argc); + + zend_call_function(&fci, NULL TSRMLS_CC); + + if (fretval) { + zend_print_zval_r( + fretval, 0 TSRMLS_CC); + phpdbg_writeln(EMPTY); + } + + zval_dtor(&fname); + + return SUCCESS; + } + + return FAILURE; +} /* }}} */ + +void phpdbg_try_file_init(char *init_file, size_t init_file_len, zend_bool free_init TSRMLS_DC) /* {{{ */ +{ + struct stat sb; + + if (init_file && VCWD_STAT(init_file, &sb) != -1) { + FILE *fp = fopen(init_file, "r"); + if (fp) { + int line = 1; + + char cmd[PHPDBG_MAX_CMD]; + size_t cmd_len = 0L; + char *code = NULL; + size_t code_len = 0L; + zend_bool in_code = 0; + + while (fgets(cmd, PHPDBG_MAX_CMD, fp) != NULL) { + cmd_len = strlen(cmd)-1; + + while (cmd_len > 0L && isspace(cmd[cmd_len-1])) + cmd_len--; + + cmd[cmd_len] = '\0'; + + if (*cmd && cmd_len > 0L && cmd[0] != '#') { + if (cmd_len == 2) { + if (memcmp(cmd, "<:", sizeof("<:")-1) == SUCCESS) { + in_code = 1; + goto next_line; + } else { + if (memcmp(cmd, ":>", sizeof(":>")-1) == SUCCESS) { + in_code = 0; + code[code_len] = '\0'; + { + zend_eval_stringl( + code, code_len, NULL, "phpdbginit code" TSRMLS_CC); + } + free(code); + code = NULL; + goto next_line; + } + } + } + + if (in_code) { + if (code == NULL) { + code = malloc(cmd_len + 1); + } else code = realloc(code, code_len + cmd_len + 1); + + if (code) { + memcpy( + &code[code_len], cmd, cmd_len); + code_len += cmd_len; + } + goto next_line; + } + + { + phpdbg_input_t *input = phpdbg_read_input(cmd TSRMLS_CC); + switch (phpdbg_do_cmd(phpdbg_prompt_commands, input TSRMLS_CC)) { + case FAILURE: + if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { + if (phpdbg_call_register(input TSRMLS_CC) == FAILURE) { + phpdbg_error("Unrecognized command in %s:%d: %s!", init_file, line, input->string); + } + } + break; + } + phpdbg_destroy_input(&input TSRMLS_CC); + } + + } +next_line: + line++; + } + + if (code) { + free(code); + } + + fclose(fp); + } else { + phpdbg_error( + "Failed to open %s for initialization", init_file); + } + + if (free_init) { + free(init_file); + } + } +} /* }}} */ + +void phpdbg_init(char *init_file, size_t init_file_len, zend_bool use_default TSRMLS_DC) /* {{{ */ +{ + if (!init_file && use_default) { + char *scan_dir = getenv("PHP_INI_SCAN_DIR"); + int i; + + phpdbg_try_file_init(PHPDBG_STRL(PHP_CONFIG_FILE_PATH "/" PHPDBG_INIT_FILENAME), 0 TSRMLS_CC); + + if (!scan_dir) { + scan_dir = PHP_CONFIG_FILE_SCAN_DIR; + } + while (*scan_dir != 0) { + i = 0; + while (scan_dir[i] != ':') { + if (scan_dir[i++] == 0) { + i = -1; + break; + } + } + if (i != -1) { + scan_dir[i] = 0; + } + + asprintf( + &init_file, "%s/%s", scan_dir, PHPDBG_INIT_FILENAME); + phpdbg_try_file_init(init_file, strlen(init_file), 1 TSRMLS_CC); + if (i == -1) { + break; + } + scan_dir += i + 1; + } + + phpdbg_try_file_init(PHPDBG_STRL(PHPDBG_INIT_FILENAME), 0 TSRMLS_CC); + } else { + phpdbg_try_file_init(init_file, init_file_len, 1 TSRMLS_CC); + } +} + +PHPDBG_COMMAND(exec) /* {{{ */ +{ + switch (param->type) { + case STR_PARAM: { + struct stat sb; + + if (VCWD_STAT(param->str, &sb) != FAILURE) { + if (sb.st_mode & (S_IFREG|S_IFLNK)) { + char *res = phpdbg_resolve_path(param->str TSRMLS_CC); + size_t res_len = strlen(res); + + if ((res_len != PHPDBG_G(exec_len)) || (memcmp(res, PHPDBG_G(exec), res_len) != SUCCESS)) { + + if (PHPDBG_G(exec)) { + phpdbg_notice("Unsetting old execution context: %s", PHPDBG_G(exec)); + efree(PHPDBG_G(exec)); + PHPDBG_G(exec) = NULL; + PHPDBG_G(exec_len) = 0L; + } + + if (PHPDBG_G(ops)) { + phpdbg_notice("Destroying compiled opcodes"); + phpdbg_clean(0 TSRMLS_CC); + } + + PHPDBG_G(exec) = res; + PHPDBG_G(exec_len) = res_len; + + phpdbg_notice("Set execution context: %s", PHPDBG_G(exec)); + } else { + phpdbg_notice("Execution context not changed"); + } + } else { + phpdbg_error("Cannot use %s as execution context, not a valid file or symlink", param->str); + } + } else { + phpdbg_error("Cannot stat %s, ensure the file exists", param->str); + } + } break; + + phpdbg_default_switch_case(); + } + + return SUCCESS; +} /* }}} */ + +int phpdbg_compile(TSRMLS_D) /* {{{ */ +{ + zend_file_handle fh; + + if (EG(in_execution)) { + phpdbg_error("Cannot compile while in execution"); + return FAILURE; + } + + phpdbg_notice("Attempting compilation of %s", PHPDBG_G(exec)); + + if (php_stream_open_for_zend_ex(PHPDBG_G(exec), &fh, + USE_PATH|STREAM_OPEN_FOR_INCLUDE TSRMLS_CC) == SUCCESS) { + + PHPDBG_G(ops) = zend_compile_file(&fh, ZEND_INCLUDE TSRMLS_CC); + zend_destroy_file_handle(&fh TSRMLS_CC); + + phpdbg_notice("Success"); + return SUCCESS; + } else { + phpdbg_error("Could not open file %s", PHPDBG_G(exec)); + } + + return FAILURE; +} /* }}} */ + +PHPDBG_COMMAND(compile) /* {{{ */ +{ + if (!PHPDBG_G(exec)) { + phpdbg_error("No execution context"); + return SUCCESS; + } + + if (!EG(in_execution)) { + if (PHPDBG_G(ops)) { + phpdbg_error("Destroying previously compiled opcodes"); + phpdbg_clean(0 TSRMLS_CC); + } + } + + phpdbg_compile(TSRMLS_C); + + return SUCCESS; +} /* }}} */ + +PHPDBG_COMMAND(step) /* {{{ */ +{ + switch (param->type) { + case EMPTY_PARAM: + case NUMERIC_PARAM: { + if (param->type == NUMERIC_PARAM && param->num) { + PHPDBG_G(flags) |= PHPDBG_IS_STEPPING; + } else { + PHPDBG_G(flags) &= ~PHPDBG_IS_STEPPING; + } + + phpdbg_notice("Stepping %s", + (PHPDBG_G(flags) & PHPDBG_IS_STEPPING) ? "on" : "off"); + } break; + + phpdbg_default_switch_case(); + } + + return SUCCESS; +} /* }}} */ + +PHPDBG_COMMAND(next) /* {{{ */ +{ + return PHPDBG_NEXT; +} /* }}} */ + +PHPDBG_COMMAND(until) /* {{{ */ +{ + if (!EG(in_execution)) { + phpdbg_error("Not executing"); + return SUCCESS; + } + + PHPDBG_G(flags) |= PHPDBG_IN_UNTIL; + { + zend_uint next = 0, + self = (EG(current_execute_data)->opline - EG(active_op_array)->opcodes); + zend_op *opline = &EG(active_op_array)->opcodes[self]; + + for (next = self; next < EG(active_op_array)->last; next++) { + if (EG(active_op_array)->opcodes[next].lineno != opline->lineno) { + zend_hash_index_update( + &PHPDBG_G(seek), + (zend_ulong) &EG(active_op_array)->opcodes[next], + &EG(active_op_array)->opcodes[next], + sizeof(zend_op), NULL); + break; + } + } + } + + return PHPDBG_UNTIL; +} /* }}} */ + +PHPDBG_COMMAND(finish) /* {{{ */ +{ + if (!EG(in_execution)) { + phpdbg_error("Not executing"); + return SUCCESS; + } + + PHPDBG_G(flags) |= PHPDBG_IN_FINISH; + { + zend_uint next = 0, + self = (EG(current_execute_data)->opline - EG(active_op_array)->opcodes); + + for (next = self; next < EG(active_op_array)->last; next++) { + switch (EG(active_op_array)->opcodes[next].opcode) { + case ZEND_RETURN: + case ZEND_THROW: + case ZEND_EXIT: +#ifdef ZEND_YIELD + case ZEND_YIELD: +#endif + zend_hash_index_update( + &PHPDBG_G(seek), + (zend_ulong) &EG(active_op_array)->opcodes[next], + &EG(active_op_array)->opcodes[next], + sizeof(zend_op), NULL); + break; + } + } + } + + return PHPDBG_FINISH; +} /* }}} */ + +PHPDBG_COMMAND(leave) /* {{{ */ +{ + if (!EG(in_execution)) { + phpdbg_error("Not executing"); + return SUCCESS; + } + + PHPDBG_G(flags) |= PHPDBG_IN_LEAVE; + { + zend_uint next = 0, + self = (EG(current_execute_data)->opline - EG(active_op_array)->opcodes); + + for (next = self; next < EG(active_op_array)->last; next++) { + switch (EG(active_op_array)->opcodes[next].opcode) { + case ZEND_RETURN: + case ZEND_THROW: + case ZEND_EXIT: +#ifdef ZEND_YIELD + case ZEND_YIELD: +#endif + zend_hash_index_update( + &PHPDBG_G(seek), + (zend_ulong) &EG(active_op_array)->opcodes[next], + &EG(active_op_array)->opcodes[next], + sizeof(zend_op), NULL); + break; + } + } + } + + return PHPDBG_LEAVE; +} /* }}} */ + +PHPDBG_COMMAND(frame) /* {{{ */ +{ + switch (param->type) { + case NUMERIC_PARAM: + phpdbg_switch_frame(param->num TSRMLS_CC); + break; + + case EMPTY_PARAM: + phpdbg_notice("Currently in frame #%d", PHPDBG_G(frame).num); + break; + + phpdbg_default_switch_case(); + } + + return SUCCESS; +} /* }}} */ + +static inline void phpdbg_handle_exception(TSRMLS_D) /* }}} */ +{ + zend_fcall_info fci; + + zval fname, + *trace, + exception; + + /* get filename and linenumber before unsetting exception */ + const char *filename = zend_get_executed_filename(TSRMLS_C); + zend_uint lineno = zend_get_executed_lineno(TSRMLS_C); + + /* copy exception */ + exception = *EG(exception); + zval_copy_ctor(&exception); + EG(exception) = NULL; + + phpdbg_error( + "Uncaught %s!", + Z_OBJCE(exception)->name); + + /* call __toString */ + ZVAL_STRINGL(&fname, "__tostring", sizeof("__tostring")-1, 1); + fci.size = sizeof(fci); + fci.function_table = &Z_OBJCE(exception)->function_table; + fci.function_name = &fname; + fci.symbol_table = NULL; + fci.object_ptr = &exception; + fci.retval_ptr_ptr = &trace; + fci.param_count = 0; + fci.params = NULL; + fci.no_separation = 1; + zend_call_function(&fci, NULL TSRMLS_CC); + + if (trace) { + phpdbg_writeln( + "Uncaught %s", Z_STRVAL_P(trace)); + /* remember to dtor trace */ + zval_ptr_dtor(&trace); + } + + /* output useful information about address */ + phpdbg_writeln( + "Stacked entered at %p in %s on line %u", + EG(active_op_array)->opcodes, filename, lineno); + + zval_dtor(&fname); + zval_dtor(&exception); +} /* }}} */ + +PHPDBG_COMMAND(run) /* {{{ */ +{ + if (EG(in_execution)) { + phpdbg_error("Cannot start another execution while one is in progress"); + return SUCCESS; + } + + if (PHPDBG_G(ops) || PHPDBG_G(exec)) { + zend_op **orig_opline = EG(opline_ptr); + zend_op_array *orig_op_array = EG(active_op_array); + zval **orig_retval_ptr = EG(return_value_ptr_ptr); + + if (!PHPDBG_G(ops)) { + if (phpdbg_compile(TSRMLS_C) == FAILURE) { + phpdbg_error("Failed to compile %s, cannot run", PHPDBG_G(exec)); + goto out; + } + } + + EG(active_op_array) = PHPDBG_G(ops); + EG(return_value_ptr_ptr) = &PHPDBG_G(retval); + if (!EG(active_symbol_table)) { + zend_rebuild_symbol_table(TSRMLS_C); + } + + /* clean seek state */ + PHPDBG_G(flags) &= ~PHPDBG_SEEK_MASK; + zend_hash_clean( + &PHPDBG_G(seek)); + + /* reset hit counters */ + phpdbg_reset_breakpoints(TSRMLS_C); + + zend_try { + php_output_activate(TSRMLS_C); + PHPDBG_G(flags) ^= PHPDBG_IS_INTERACTIVE; + zend_execute(EG(active_op_array) TSRMLS_CC); + PHPDBG_G(flags) ^= PHPDBG_IS_INTERACTIVE; + php_output_deactivate(TSRMLS_C); + } zend_catch { + EG(active_op_array) = orig_op_array; + EG(opline_ptr) = orig_opline; + EG(return_value_ptr_ptr) = orig_retval_ptr; + + if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { + phpdbg_error("Caught exit/error from VM"); + goto out; + } + } zend_end_try(); + + if (EG(exception)) { + phpdbg_handle_exception(TSRMLS_C); + } + + EG(active_op_array) = orig_op_array; + EG(opline_ptr) = orig_opline; + EG(return_value_ptr_ptr) = orig_retval_ptr; + + } else { + phpdbg_error("Nothing to execute!"); + } + +out: + PHPDBG_FRAME(num) = 0; + return SUCCESS; +} /* }}} */ + +PHPDBG_COMMAND(eval) /* {{{ */ +{ + switch (param->type) { + case STR_PARAM: { + zend_bool stepping = ((PHPDBG_G(flags) & PHPDBG_IS_STEPPING)==PHPDBG_IS_STEPPING); + zval retval; + + if (!(PHPDBG_G(flags) & PHPDBG_IS_STEPONEVAL)) { + PHPDBG_G(flags) &= ~ PHPDBG_IS_STEPPING; + } + + /* disable stepping while eval() in progress */ + PHPDBG_G(flags) |= PHPDBG_IN_EVAL; + zend_try { + if (zend_eval_stringl(param->str, param->len, + &retval, "eval()'d code" TSRMLS_CC) == SUCCESS) { + zend_print_zval_r( + &retval, 0 TSRMLS_CC); + phpdbg_writeln(EMPTY); + zval_dtor(&retval); + } + } zend_end_try(); + PHPDBG_G(flags) &= ~PHPDBG_IN_EVAL; + + /* switch stepping back on */ + if (stepping && + !(PHPDBG_G(flags) & PHPDBG_IS_STEPONEVAL)) { + PHPDBG_G(flags) |= PHPDBG_IS_STEPPING; + } + + CG(unclean_shutdown) = 0; + } break; + + phpdbg_default_switch_case(); + } + + return SUCCESS; +} /* }}} */ + +PHPDBG_COMMAND(back) /* {{{ */ +{ + if (!EG(in_execution)) { + phpdbg_error("Not executing!"); + return SUCCESS; + } + + switch (param->type) { + case EMPTY_PARAM: + case NUMERIC_PARAM: + phpdbg_dump_backtrace( + (param->type == NUMERIC_PARAM) ? param->num : 0 TSRMLS_CC); + break; + + phpdbg_default_switch_case(); + } + + return SUCCESS; +} /* }}} */ + +PHPDBG_COMMAND(print) /* {{{ */ +{ + switch (param->type) { + case EMPTY_PARAM: { + phpdbg_writeln(SEPARATE); + phpdbg_notice("Execution Context Information"); +#ifdef HAVE_LIBREADLINE + phpdbg_writeln("Readline\tyes"); +#else + phpdbg_writeln("Readline\tno"); +#endif + + phpdbg_writeln("Exec\t\t%s", PHPDBG_G(exec) ? PHPDBG_G(exec) : "none"); + phpdbg_writeln("Compiled\t%s", PHPDBG_G(ops) ? "yes" : "no"); + phpdbg_writeln("Stepping\t%s", (PHPDBG_G(flags) & PHPDBG_IS_STEPPING) ? "on" : "off"); + phpdbg_writeln("Quietness\t%s", (PHPDBG_G(flags) & PHPDBG_IS_QUIET) ? "on" : "off"); + phpdbg_writeln("Oplog\t\t%s", PHPDBG_G(oplog) ? "on" : "off"); + + if (PHPDBG_G(ops)) { + phpdbg_writeln("Opcodes\t\t%d", PHPDBG_G(ops)->last); + + if (PHPDBG_G(ops)->last_var) { + phpdbg_writeln("Variables\t%d", PHPDBG_G(ops)->last_var-1); + } else { + phpdbg_writeln("Variables\tNone"); + } + } + + phpdbg_writeln("Executing\t%s", EG(in_execution) ? "yes" : "no"); + if (EG(in_execution)) { + phpdbg_writeln("VM Return\t%d", PHPDBG_G(vmret)); + } + + phpdbg_writeln("Classes\t\t%d", zend_hash_num_elements(EG(class_table))); + phpdbg_writeln("Functions\t%d", zend_hash_num_elements(EG(function_table))); + phpdbg_writeln("Constants\t%d", zend_hash_num_elements(EG(zend_constants))); + phpdbg_writeln("Included\t%d", zend_hash_num_elements(&EG(included_files))); + + phpdbg_writeln(SEPARATE); + } break; + + phpdbg_default_switch_case(); + } + + return SUCCESS; +} /* }}} */ + +PHPDBG_COMMAND(info) /* {{{ */ +{ + phpdbg_error( + "No information command selected!"); + + return SUCCESS; +} /* }}} */ + +PHPDBG_COMMAND(set) /* {{{ */ +{ + phpdbg_error( + "No information command selected!"); + + return SUCCESS; +} /* }}} */ + +PHPDBG_COMMAND(break) /* {{{ */ +{ + switch (param->type) { + case EMPTY_PARAM: + phpdbg_set_breakpoint_file( + zend_get_executed_filename(TSRMLS_C), + zend_get_executed_lineno(TSRMLS_C) TSRMLS_CC); + break; + case ADDR_PARAM: + phpdbg_set_breakpoint_opline(param->addr TSRMLS_CC); + break; + case NUMERIC_PARAM: + if (PHPDBG_G(exec)) { + phpdbg_set_breakpoint_file(phpdbg_current_file(TSRMLS_C), param->num TSRMLS_CC); + } else { + phpdbg_error("Execution context not set!"); + } + break; + case METHOD_PARAM: + phpdbg_set_breakpoint_method(param->method.class, param->method.name TSRMLS_CC); + break; + case NUMERIC_METHOD_PARAM: + phpdbg_set_breakpoint_method_opline(param->method.class, param->method.name, param->num TSRMLS_CC); + break; + case NUMERIC_FUNCTION_PARAM: + phpdbg_set_breakpoint_function_opline(param->str, param->num TSRMLS_CC); + break; + case FILE_PARAM: + phpdbg_set_breakpoint_file(param->file.name, param->file.line TSRMLS_CC); + break; + case STR_PARAM: + phpdbg_set_breakpoint_symbol(param->str, param->len TSRMLS_CC); + break; + + phpdbg_default_switch_case(); + } + + return SUCCESS; +} /* }}} */ + +PHPDBG_COMMAND(shell) /* {{{ */ +{ + /* don't allow this to loop, ever ... */ + switch (param->type) { + case STR_PARAM: { + FILE *fd = NULL; + if ((fd=VCWD_POPEN((char*)param->str, "w"))) { + /* do something perhaps ?? do we want input ?? */ + fclose(fd); + } else { + phpdbg_error( + "Failed to execute %s", param->str); + } + } break; + + phpdbg_default_switch_case(); + } + return SUCCESS; +} /* }}} */ + +PHPDBG_COMMAND(source) /* {{{ */ +{ + switch (param->type) { + case STR_PARAM: { + if (input->argc > 2) { + if (phpdbg_argv_is(1, "export")) { + FILE *h = VCWD_FOPEN(input->argv[2]->string, "w+"); + if (h) { + phpdbg_export_breakpoints(h TSRMLS_CC); + fclose(h); + } else phpdbg_error("Failed to open %s", input->argv[1]->string); + } else { + phpdbg_error( + "Incorrect usage of source command, see help"); + } + } else { + struct stat sb; + if (VCWD_STAT(param->str, &sb) != -1) { + phpdbg_try_file_init(param->str, param->len, 0 TSRMLS_CC); + } else phpdbg_error("Cannot stat %s", param->str); + } + } break; + + phpdbg_default_switch_case(); + } + return SUCCESS; +} /* }}} */ + +PHPDBG_COMMAND(register) /* {{{ */ +{ + switch (param->type) { + case STR_PARAM: { + zend_function *function; + char *lcname = zend_str_tolower_dup(param->str, param->len); + size_t lcname_len = strlen(lcname); + + if (!zend_hash_exists(&PHPDBG_G(registered), lcname, lcname_len+1)) { + if (zend_hash_find(EG(function_table), lcname, lcname_len+1, (void**) &function) == SUCCESS) { + zend_hash_update( + &PHPDBG_G(registered), lcname, lcname_len+1, (void*)&function, sizeof(zend_function), NULL); + function_add_ref(function); + + phpdbg_notice( + "Registered %s", lcname); + } else { + phpdbg_error("The requested function (%s) could not be found", param->str); + } + } else { + phpdbg_error( + "The requested name (%s) is already in use", lcname); + } + + efree(lcname); + } break; + + phpdbg_default_switch_case(); + } + return SUCCESS; +} /* }}} */ + +PHPDBG_COMMAND(quit) /* {{{ */ +{ + /* don't allow this to loop, ever ... */ + if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { + + phpdbg_destroy_input((phpdbg_input_t**)&input TSRMLS_CC); + + PHPDBG_G(flags) |= PHPDBG_IS_QUITTING; + zend_bailout(); + } + + return SUCCESS; +} /* }}} */ + +PHPDBG_COMMAND(clean) /* {{{ */ +{ + if (EG(in_execution)) { + phpdbg_error("Cannot clean environment while executing"); + return SUCCESS; + } + + phpdbg_notice("Cleaning Execution Environment"); + + phpdbg_writeln("Classes\t\t\t%d", zend_hash_num_elements(EG(class_table))); + phpdbg_writeln("Functions\t\t%d", zend_hash_num_elements(EG(function_table))); + phpdbg_writeln("Constants\t\t%d", zend_hash_num_elements(EG(zend_constants))); + phpdbg_writeln("Includes\t\t%d", zend_hash_num_elements(&EG(included_files))); + + phpdbg_clean(1 TSRMLS_CC); + + return SUCCESS; +} /* }}} */ + +PHPDBG_COMMAND(clear) /* {{{ */ +{ + phpdbg_notice("Clearing Breakpoints"); + + phpdbg_writeln("File\t\t\t%d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE])); + phpdbg_writeln("Functions\t\t%d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM])); + phpdbg_writeln("Methods\t\t\t%d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD])); + phpdbg_writeln("Oplines\t\t\t%d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE])); + phpdbg_writeln("File oplines\t\t\t%d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE])); + phpdbg_writeln("Function oplines\t\t\t%d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE])); + phpdbg_writeln("Method oplines\t\t\t%d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE])); + phpdbg_writeln("Conditionals\t\t%d", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_COND])); + + phpdbg_clear_breakpoints(TSRMLS_C); + + return SUCCESS; +} /* }}} */ + +PHPDBG_COMMAND(aliases) /* {{{ */ +{ + const phpdbg_command_t *prompt_command = phpdbg_prompt_commands; + + phpdbg_help_header(); + phpdbg_writeln("Below are the aliased, short versions of all supported commands"); + while (prompt_command && prompt_command->name) { + if (prompt_command->alias) { + if (prompt_command->subs) { + const phpdbg_command_t *sub_command = prompt_command->subs; + phpdbg_writeln(EMPTY); + phpdbg_writeln(" %c -> %9s", prompt_command->alias, prompt_command->name); + while (sub_command && sub_command->name) { + if (sub_command->alias) { + phpdbg_writeln(" |-------- %c -> %15s\t%s", sub_command->alias, + sub_command->name, sub_command->tip); + } + ++sub_command; + } + phpdbg_writeln(EMPTY); + } else { + phpdbg_writeln(" %c -> %9s\t\t\t%s", prompt_command->alias, + prompt_command->name, prompt_command->tip); + } + } + + ++prompt_command; + } + phpdbg_help_footer(); + + return SUCCESS; +} /* }}} */ + +PHPDBG_COMMAND(help) /* {{{ */ +{ + switch (param->type) { + case EMPTY_PARAM: { + const phpdbg_command_t *prompt_command = phpdbg_prompt_commands; + const phpdbg_command_t *help_command = phpdbg_help_commands; + + phpdbg_help_header(); + phpdbg_writeln("To get help regarding a specific command type \"help command\""); + + phpdbg_notice("Commands"); + + while (prompt_command && prompt_command->name) { + phpdbg_writeln( + " %10s\t%s", prompt_command->name, prompt_command->tip); + ++prompt_command; + } + + phpdbg_notice("Help Commands"); + + while (help_command && help_command->name) { + phpdbg_writeln(" %10s\t%s", help_command->name, help_command->tip); + ++help_command; + } + + phpdbg_help_footer(); + } break; + + default: { + phpdbg_error( + "No help can be found for the subject \"%s\"", param->str); + } + } + + return SUCCESS; +} /* }}} */ + +PHPDBG_COMMAND(quiet) /* {{{ */ +{ + switch (param->type) { + case NUMERIC_PARAM: { + if (param->num) { + PHPDBG_G(flags) |= PHPDBG_IS_QUIET; + } else { + PHPDBG_G(flags) &= ~PHPDBG_IS_QUIET; + } + phpdbg_notice("Quietness %s", + (PHPDBG_G(flags) & PHPDBG_IS_QUIET) ? "enabled" : "disabled"); + } break; + + phpdbg_default_switch_case(); + } + + return SUCCESS; +} /* }}} */ + +PHPDBG_COMMAND(list) /* {{{ */ +{ + switch (param->type) { + case NUMERIC_PARAM: + case EMPTY_PARAM: + return PHPDBG_LIST_HANDLER(lines)(PHPDBG_COMMAND_ARGS); + + case FILE_PARAM: + return PHPDBG_LIST_HANDLER(lines)(PHPDBG_COMMAND_ARGS); + + case STR_PARAM: + phpdbg_list_function_byname(param->str, param->len TSRMLS_CC); + break; + + case METHOD_PARAM: + return PHPDBG_LIST_HANDLER(method)(PHPDBG_COMMAND_ARGS); + + phpdbg_default_switch_case(); + } + + return SUCCESS; +} /* }}} */ + +int phpdbg_interactive(TSRMLS_D) /* {{{ */ +{ + int ret = SUCCESS; + phpdbg_input_t *input; + + PHPDBG_G(flags) |= PHPDBG_IS_INTERACTIVE; + + input = phpdbg_read_input(NULL TSRMLS_CC); + + if (input && input->length > 0L) { + do { + switch (ret = phpdbg_do_cmd(phpdbg_prompt_commands, input TSRMLS_CC)) { + case FAILURE: + if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { + if (phpdbg_call_register(input TSRMLS_CC) == FAILURE) { + phpdbg_error("Failed to execute %s!", input->string); + } + } + break; + + case PHPDBG_LEAVE: + case PHPDBG_FINISH: + case PHPDBG_UNTIL: + case PHPDBG_NEXT: { + if (!EG(in_execution)) { + phpdbg_error("Not running"); + } + goto out; + } + } + + phpdbg_destroy_input(&input TSRMLS_CC); + } while ((input = phpdbg_read_input(NULL TSRMLS_CC)) && (input->length > 0L)); + + if (input && !input->length) + goto last; + + } else { +last: + if (PHPDBG_G(lcmd)) { + ret = PHPDBG_G(lcmd)->handler( + &PHPDBG_G(lparam), input TSRMLS_CC); + goto out; + } + } + +out: + phpdbg_destroy_input(&input TSRMLS_CC); + + if (EG(in_execution)) { + phpdbg_restore_frame(TSRMLS_C); + } + + PHPDBG_G(flags) &= ~PHPDBG_IS_INTERACTIVE; + + return ret; +} /* }}} */ + +void phpdbg_clean(zend_bool full TSRMLS_DC) /* {{{ */ +{ + /* this is implicitly required */ + if (PHPDBG_G(ops)) { + destroy_op_array(PHPDBG_G(ops) TSRMLS_CC); + efree(PHPDBG_G(ops)); + PHPDBG_G(ops) = NULL; + } + + if (full) { + PHPDBG_G(flags) |= PHPDBG_IS_CLEANING; + + zend_bailout(); + } +} /* }}} */ + +static inline zend_execute_data *phpdbg_create_execute_data(zend_op_array *op_array, zend_bool nested TSRMLS_DC) /* {{{ */ +{ +#if PHP_VERSION_ID >= 50500 + return zend_create_execute_data_from_op_array(op_array, nested TSRMLS_CC); +#else + +#undef EX +#define EX(element) execute_data->element +#undef EX_CV +#define EX_CV(var) EX(CVs)[var] +#undef EX_CVs +#define EX_CVs() EX(CVs) +#undef EX_T +#define EX_T(offset) (*(temp_variable *)((char *) EX(Ts) + offset)) +#undef EX_Ts +#define EX_Ts() EX(Ts) + + zend_execute_data *execute_data = (zend_execute_data *)zend_vm_stack_alloc( + ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data)) + + ZEND_MM_ALIGNED_SIZE(sizeof(zval**) * op_array->last_var * (EG(active_symbol_table) ? 1 : 2)) + + ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * op_array->T TSRMLS_CC); + + EX(CVs) = (zval***)((char*)execute_data + ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data))); + memset(EX(CVs), 0, sizeof(zval**) * op_array->last_var); + EX(Ts) = (temp_variable *)(((char*)EX(CVs)) + ZEND_MM_ALIGNED_SIZE(sizeof(zval**) * op_array->last_var * (EG(active_symbol_table) ? 1 : 2))); + EX(fbc) = NULL; + EX(called_scope) = NULL; + EX(object) = NULL; + EX(old_error_reporting) = NULL; + EX(op_array) = op_array; + EX(symbol_table) = EG(active_symbol_table); + EX(prev_execute_data) = EG(current_execute_data); + EG(current_execute_data) = execute_data; + EX(nested) = nested; + + if (!op_array->run_time_cache && op_array->last_cache_slot) { + op_array->run_time_cache = ecalloc(op_array->last_cache_slot, sizeof(void*)); + } + + if (op_array->this_var != -1 && EG(This)) { + Z_ADDREF_P(EG(This)); /* For $this pointer */ + if (!EG(active_symbol_table)) { + EX_CV(op_array->this_var) = (zval**)EX_CVs() + (op_array->last_var + op_array->this_var); + *EX_CV(op_array->this_var) = EG(This); + } else { + if (zend_hash_add(EG(active_symbol_table), "this", sizeof("this"), &EG(This), sizeof(zval *), (void**)&EX_CV(op_array->this_var))==FAILURE) { + Z_DELREF_P(EG(This)); + } + } + } + + EX(opline) = UNEXPECTED((op_array->fn_flags & ZEND_ACC_INTERACTIVE) != 0) && EG(start_op) ? EG(start_op) : op_array->opcodes; + EG(opline_ptr) = &EX(opline); + + EX(function_state).function = (zend_function *) op_array; + EX(function_state).arguments = NULL; + + return execute_data; +#endif +} /* }}} */ + +#if PHP_VERSION_ID >= 50500 +void phpdbg_execute_ex(zend_execute_data *execute_data TSRMLS_DC) /* {{{ */ +{ +#else +void phpdbg_execute_ex(zend_op_array *op_array TSRMLS_DC) /* {{{ */ +{ + long long flags = 0; + zend_ulong address = 0L; + zend_execute_data *execute_data; + zend_bool nested = 0; +#endif + zend_bool original_in_execution = EG(in_execution); + HashTable vars; + +#if PHP_VERSION_ID < 50500 + if (EG(exception)) { + return; + } +#endif + + EG(in_execution) = 1; + +#if PHP_VERSION_ID >= 50500 + if (0) { +zend_vm_enter: + execute_data = phpdbg_create_execute_data(EG(active_op_array), 1 TSRMLS_CC); + } + zend_hash_init(&vars, EG(active_op_array)->last, NULL, NULL, 0); +#else +zend_vm_enter: + execute_data = phpdbg_create_execute_data(op_array, nested TSRMLS_CC); + nested = 1; + zend_hash_init(&vars, EG(active_op_array)->last, NULL, NULL, 0); +#endif + + while (1) { + + if ((PHPDBG_G(flags) & PHPDBG_BP_RESOLVE_MASK)) { + /* resolve nth opline breakpoints */ + phpdbg_resolve_op_array_breaks(EG(active_op_array) TSRMLS_CC); + } + +#ifdef ZEND_WIN32 + if (EG(timed_out)) { + zend_timeout(0); + } +#endif + +#define DO_INTERACTIVE() do { \ + if (!(PHPDBG_G(flags) & PHPDBG_IN_EVAL)) { \ + phpdbg_list_file( \ + zend_get_executed_filename(TSRMLS_C), \ + 3, \ + zend_get_executed_lineno(TSRMLS_C)-1, \ + zend_get_executed_lineno(TSRMLS_C) \ + TSRMLS_CC \ + ); \ + } \ + \ + do { \ + switch (phpdbg_interactive(TSRMLS_C)) { \ + case PHPDBG_LEAVE: \ + case PHPDBG_FINISH: \ + case PHPDBG_UNTIL: \ + case PHPDBG_NEXT:{ \ + goto next; \ + } \ + } \ + } while (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)); \ +} while (0) + + /* allow conditional breakpoints and + initialization to access the vm uninterrupted */ + if ((PHPDBG_G(flags) & PHPDBG_IN_COND_BP) || + (PHPDBG_G(flags) & PHPDBG_IS_INITIALIZING)) { + /* skip possible breakpoints */ + goto next; + } + + /* perform seek operation */ + if (PHPDBG_G(flags) & PHPDBG_SEEK_MASK) { + /* current address */ + zend_ulong address = (zend_ulong) execute_data->opline; + + /* run to next line */ + if (PHPDBG_G(flags) & PHPDBG_IN_UNTIL) { + if (zend_hash_index_exists(&PHPDBG_G(seek), address)) { + PHPDBG_G(flags) &= ~PHPDBG_IN_UNTIL; + zend_hash_clean( + &PHPDBG_G(seek)); + } else { + /* skip possible breakpoints */ + goto next; + } + } + + /* run to finish */ + if (PHPDBG_G(flags) & PHPDBG_IN_FINISH) { + if (zend_hash_index_exists(&PHPDBG_G(seek), address)) { + PHPDBG_G(flags) &= ~PHPDBG_IN_FINISH; + zend_hash_clean( + &PHPDBG_G(seek)); + } + /* skip possible breakpoints */ + goto next; + } + + /* break for leave */ + if (PHPDBG_G(flags) & PHPDBG_IN_LEAVE) { + if (zend_hash_index_exists(&PHPDBG_G(seek), address)) { + PHPDBG_G(flags) &= ~PHPDBG_IN_LEAVE; + zend_hash_clean( + &PHPDBG_G(seek)); + phpdbg_notice( + "Breaking for leave at %s:%u", + zend_get_executed_filename(TSRMLS_C), + zend_get_executed_lineno(TSRMLS_C) + ); + DO_INTERACTIVE(); + } else { + /* skip possible breakpoints */ + goto next; + } + } + } + + /* not while in conditionals */ + phpdbg_print_opline_ex( + execute_data, &vars, 0 TSRMLS_CC); + + /* search for breakpoints */ + { + phpdbg_breakbase_t *brake; + + if ((PHPDBG_G(flags) & PHPDBG_BP_MASK) && + (brake = phpdbg_find_breakpoint(execute_data TSRMLS_CC))) { + phpdbg_hit_breakpoint( + brake, 1 TSRMLS_CC); + DO_INTERACTIVE(); + } + } + + if (PHPDBG_G(flags) & PHPDBG_IS_STEPPING) { + DO_INTERACTIVE(); + } + +next: + if (PHPDBG_G(flags) & PHPDBG_IS_SIGNALED) { + phpdbg_writeln(EMPTY); + phpdbg_notice("Program received signal SIGINT"); + PHPDBG_G(flags) &= ~PHPDBG_IS_SIGNALED; + DO_INTERACTIVE(); + } + + PHPDBG_G(vmret) = execute_data->opline->handler(execute_data TSRMLS_CC); + + if (PHPDBG_G(vmret) > 0) { + switch (PHPDBG_G(vmret)) { + case 1: + EG(in_execution) = original_in_execution; + zend_hash_destroy(&vars); + return; + case 2: +#if PHP_VERSION_ID < 50500 + op_array = EG(active_op_array); +#endif + zend_hash_destroy(&vars); + goto zend_vm_enter; + break; + case 3: + execute_data = EG(current_execute_data); + break; + default: + break; + } + } + } + zend_error_noreturn(E_ERROR, "Arrived at end of main loop which shouldn't happen"); +} /* }}} */ diff --git a/sapi/phpdbg/phpdbg_prompt.h b/sapi/phpdbg/phpdbg_prompt.h new file mode 100644 index 0000000000000..e6706c7d5b1eb --- /dev/null +++ b/sapi/phpdbg/phpdbg_prompt.h @@ -0,0 +1,68 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Felipe Pena | + | Authors: Joe Watkins | + | Authors: Bob Weinand | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHPDBG_PROMPT_H +#define PHPDBG_PROMPT_H + +/* {{{ */ +void phpdbg_init(char *init_file, size_t init_file_len, zend_bool use_default TSRMLS_DC); +void phpdbg_try_file_init(char *init_file, size_t init_file_len, zend_bool free_init TSRMLS_DC); +int phpdbg_interactive(TSRMLS_D); +int phpdbg_compile(TSRMLS_D); +void phpdbg_clean(zend_bool full TSRMLS_DC); /* }}} */ + +/* {{{ phpdbg command handlers */ +PHPDBG_COMMAND(exec); +PHPDBG_COMMAND(compile); +PHPDBG_COMMAND(step); +PHPDBG_COMMAND(next); +PHPDBG_COMMAND(run); +PHPDBG_COMMAND(eval); +PHPDBG_COMMAND(until); +PHPDBG_COMMAND(finish); +PHPDBG_COMMAND(leave); +PHPDBG_COMMAND(frame); +PHPDBG_COMMAND(print); +PHPDBG_COMMAND(break); +PHPDBG_COMMAND(back); +PHPDBG_COMMAND(list); +PHPDBG_COMMAND(info); +PHPDBG_COMMAND(clean); +PHPDBG_COMMAND(clear); +PHPDBG_COMMAND(help); +PHPDBG_COMMAND(quiet); +PHPDBG_COMMAND(aliases); +PHPDBG_COMMAND(shell); +PHPDBG_COMMAND(set); +PHPDBG_COMMAND(source); +PHPDBG_COMMAND(register); +PHPDBG_COMMAND(quit); /* }}} */ + +/* {{{ prompt commands */ +extern const phpdbg_command_t phpdbg_prompt_commands[]; /* }}} */ + +/* {{{ */ +#if PHP_VERSION_ID >= 50500 +void phpdbg_execute_ex(zend_execute_data *execute_data TSRMLS_DC); +#else +void phpdbg_execute_ex(zend_op_array *op_array TSRMLS_DC); +#endif /* }}} */ + +#endif /* PHPDBG_PROMPT_H */ diff --git a/sapi/phpdbg/phpdbg_set.c b/sapi/phpdbg/phpdbg_set.c new file mode 100644 index 0000000000000..2472e1868c0a2 --- /dev/null +++ b/sapi/phpdbg/phpdbg_set.c @@ -0,0 +1,208 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Felipe Pena | + | Authors: Joe Watkins | + | Authors: Bob Weinand | + +----------------------------------------------------------------------+ +*/ + +#include "phpdbg.h" +#include "phpdbg_cmd.h" +#include "phpdbg_set.h" +#include "phpdbg_utils.h" +#include "phpdbg_bp.h" + +ZEND_EXTERN_MODULE_GLOBALS(phpdbg); + +PHPDBG_SET(prompt) /* {{{ */ +{ + switch (param->type) { + case EMPTY_PARAM: + phpdbg_writeln("%s", phpdbg_get_prompt(TSRMLS_C)); + break; + + case STR_PARAM: + phpdbg_set_prompt(param->str TSRMLS_CC); + break; + + phpdbg_default_switch_case(); + } + + return SUCCESS; +} /* }}} */ + +PHPDBG_SET(break) /* {{{ */ +{ + switch (param->type) { + case EMPTY_PARAM: + phpdbg_writeln("%s", + PHPDBG_G(flags) & PHPDBG_IS_BP_ENABLED ? "on" : "off"); + break; + + case STR_PARAM: + if (strncasecmp(param->str, PHPDBG_STRL("on")) == 0) { + phpdbg_enable_breakpoints(TSRMLS_C); + } else if (strncasecmp(param->str, PHPDBG_STRL("off")) == 0) { + phpdbg_disable_breakpoints(TSRMLS_C); + } + break; + + case NUMERIC_PARAM: { + if (input->argc > 2) { + if (phpdbg_argv_is(2, "on")) { + phpdbg_enable_breakpoint(param->num TSRMLS_CC); + } else if (phpdbg_argv_is(2, "off")) { + phpdbg_disable_breakpoint(param->num TSRMLS_CC); + } + } else { + phpdbg_breakbase_t *brake = phpdbg_find_breakbase(param->num TSRMLS_CC); + if (brake) { + phpdbg_writeln( + "%s", brake->disabled ? "off" : "on"); + } else { + phpdbg_error("Failed to find breakpoint #%lx", param->num); + } + } + } break; + + default: + phpdbg_error( + "set break used incorrectly: set break [id] "); + } + + return SUCCESS; +} /* }}} */ + +#ifndef _WIN32 +PHPDBG_SET(color) /* {{{ */ +{ + if ((param->type == STR_PARAM) && (input->argc == 3)) { + const phpdbg_color_t *color = phpdbg_get_color( + input->argv[2]->string, input->argv[2]->length TSRMLS_CC); + int element = PHPDBG_COLOR_INVALID; + + /* @TODO(anyone) make this consistent with other set commands */ + if (color) { + if (phpdbg_argv_is(1, "prompt")) { + phpdbg_notice( + "setting prompt color to %s (%s)", color->name, color->code); + element = PHPDBG_COLOR_PROMPT; + if (PHPDBG_G(prompt)[1]) { + free(PHPDBG_G(prompt)[1]); + PHPDBG_G(prompt)[1]=NULL; + } + } else if (phpdbg_argv_is(1, "error")) { + phpdbg_notice( + "setting error color to %s (%s)", color->name, color->code); + element = PHPDBG_COLOR_ERROR; + + } else if (phpdbg_argv_is(1, "notice")) { + phpdbg_notice( + "setting notice color to %s (%s)", color->name, color->code); + element = PHPDBG_COLOR_NOTICE; + + } else goto usage; + + /* set color for element */ + phpdbg_set_color(element, color TSRMLS_CC); + } else { + phpdbg_error( + "Failed to find the requested color (%s)", input->argv[2]->string); + } + } else { +usage: + phpdbg_error( + "set color used incorrectly: set color "); + } + return SUCCESS; +} /* }}} */ + +PHPDBG_SET(colors) /* {{{ */ +{ + switch (param->type) { + case EMPTY_PARAM: { + phpdbg_writeln( + "%s", PHPDBG_G(flags) & PHPDBG_IS_COLOURED ? "on" : "off"); + goto done; + } + + case STR_PARAM: { + if (strncasecmp(param->str, PHPDBG_STRL("on")) == 0) { + PHPDBG_G(flags) |= PHPDBG_IS_COLOURED; + goto done; + } else if (strncasecmp(param->str, PHPDBG_STRL("off")) == 0) { + PHPDBG_G(flags) &= ~PHPDBG_IS_COLOURED; + goto done; + } + } + + default: + phpdbg_error( + "set colors used incorrectly: set colors "); + } + +done: + return SUCCESS; +} /* }}} */ +#endif + +PHPDBG_SET(oplog) /* {{{ */ +{ + switch (param->type) { + case EMPTY_PARAM: + phpdbg_notice( + "Oplog %s", PHPDBG_G(oplog) ? "enabled" : "disabled"); + break; + + case NUMERIC_PARAM: switch (param->num) { + case 1: + phpdbg_error( + "An output file must be provided to enable oplog"); + break; + + case 0: { + if (PHPDBG_G(oplog)) { + phpdbg_notice("Disabling oplog"); + fclose( + PHPDBG_G(oplog)); + } else { + phpdbg_error("Oplog is not enabled!"); + } + } break; + } break; + + case STR_PARAM: { + /* open oplog */ + FILE *old = PHPDBG_G(oplog); + + PHPDBG_G(oplog) = fopen(param->str, "w+"); + if (!PHPDBG_G(oplog)) { + phpdbg_error("Failed to open %s for oplog", param->str); + PHPDBG_G(oplog) = old; + } else { + if (old) { + phpdbg_notice("Closing previously open oplog"); + fclose(old); + } + phpdbg_notice("Successfully opened oplog %s", param->str); + } + } break; + + phpdbg_default_switch_case(); + } + + return SUCCESS; +} /* }}} */ + diff --git a/sapi/phpdbg/phpdbg_set.h b/sapi/phpdbg/phpdbg_set.h new file mode 100644 index 0000000000000..1c48786c66cad --- /dev/null +++ b/sapi/phpdbg/phpdbg_set.h @@ -0,0 +1,47 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Felipe Pena | + | Authors: Joe Watkins | + | Authors: Bob Weinand | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHPDBG_SET_H +#define PHPDBG_SET_H + +#include "phpdbg_cmd.h" + +#define PHPDBG_SET(name) PHPDBG_COMMAND(set_##name) + +PHPDBG_SET(prompt); +#ifndef _WIN32 +PHPDBG_SET(color); +PHPDBG_SET(colors); +#endif +PHPDBG_SET(oplog); +PHPDBG_SET(break); + +static const phpdbg_command_t phpdbg_set_commands[] = { + PHPDBG_COMMAND_D_EX(prompt, "usage: set prompt ", 'p', set_prompt, NULL, 0), +#ifndef _WIN32 + PHPDBG_COMMAND_D_EX(color, "usage: set color ", 'c', set_color, NULL, 1), + PHPDBG_COMMAND_D_EX(colors, "usage: set colors ", 'C', set_colors, NULL, 1), +#endif + PHPDBG_COMMAND_D_EX(oplog, "usage: set oplog ", 'O', set_oplog, NULL, 0), + PHPDBG_COMMAND_D_EX(break, "usage: set break [id] ", 'b', set_break, NULL, 0), + PHPDBG_END_COMMAND +}; + +#endif /* PHPDBG_SET_H */ diff --git a/sapi/phpdbg/phpdbg_utils.c b/sapi/phpdbg/phpdbg_utils.c new file mode 100644 index 0000000000000..86c17a71beee4 --- /dev/null +++ b/sapi/phpdbg/phpdbg_utils.c @@ -0,0 +1,386 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Felipe Pena | + | Authors: Joe Watkins | + | Authors: Bob Weinand | + +----------------------------------------------------------------------+ +*/ + +#include +#include +#include +#include "zend.h" +#include "php.h" +#include "spprintf.h" +#include "phpdbg.h" +#include "phpdbg_opcode.h" +#include "phpdbg_utils.h" + +#ifdef _WIN32 +# include "win32/time.h" +#endif + +ZEND_EXTERN_MODULE_GLOBALS(phpdbg); + +/* {{{ color structures */ +const static phpdbg_color_t colors[] = { + PHPDBG_COLOR_D("none", "0;0"), + + PHPDBG_COLOR_D("white", "0;64"), + PHPDBG_COLOR_D("white-bold", "1;64"), + PHPDBG_COLOR_D("white-underline", "4;64"), + PHPDBG_COLOR_D("red", "0;31"), + PHPDBG_COLOR_D("red-bold", "1;31"), + PHPDBG_COLOR_D("red-underline", "4;31"), + PHPDBG_COLOR_D("green", "0;32"), + PHPDBG_COLOR_D("green-bold", "1;32"), + PHPDBG_COLOR_D("green-underline", "4;32"), + PHPDBG_COLOR_D("yellow", "0;33"), + PHPDBG_COLOR_D("yellow-bold", "1;33"), + PHPDBG_COLOR_D("yellow-underline", "4;33"), + PHPDBG_COLOR_D("blue", "0;34"), + PHPDBG_COLOR_D("blue-bold", "1;34"), + PHPDBG_COLOR_D("blue-underline", "4;34"), + PHPDBG_COLOR_D("purple", "0;35"), + PHPDBG_COLOR_D("purple-bold", "1;35"), + PHPDBG_COLOR_D("purple-underline", "4;35"), + PHPDBG_COLOR_D("cyan", "0;36"), + PHPDBG_COLOR_D("cyan-bold", "1;36"), + PHPDBG_COLOR_D("cyan-underline", "4;36"), + PHPDBG_COLOR_D("black", "0;30"), + PHPDBG_COLOR_D("black-bold", "1;30"), + PHPDBG_COLOR_D("black-underline", "4;30"), + PHPDBG_COLOR_END +}; /* }}} */ + +PHPDBG_API int phpdbg_is_numeric(const char *str) /* {{{ */ +{ + if (!str) + return 0; + + for (; *str; str++) { + if (isspace(*str) || *str == '-') { + continue; + } + return isdigit(*str); + } + return 0; +} /* }}} */ + +PHPDBG_API int phpdbg_is_empty(const char *str) /* {{{ */ +{ + if (!str) + return 1; + + for (; *str; str++) { + if (isspace(*str)) { + continue; + } + return 0; + } + return 1; +} /* }}} */ + +PHPDBG_API int phpdbg_is_addr(const char *str) /* {{{ */ +{ + return str[0] && str[1] && memcmp(str, "0x", 2) == 0; +} /* }}} */ + +PHPDBG_API int phpdbg_is_class_method(const char *str, size_t len, char **class, char **method) /* {{{ */ +{ + char *sep = NULL; + + if (strstr(str, "#") != NULL) + return 0; + + if (strstr(str, " ") != NULL) + return 0; + + sep = strstr(str, "::"); + + if (!sep || sep == str || sep+2 == str+len-1) { + return 0; + } + + if (class != NULL) { + + if (str[0] == '\\') { + str++; + len--; + } + + *class = estrndup(str, sep - str); + (*class)[sep - str] = 0; + } + + if (method != NULL) { + *method = estrndup(sep+2, str + len - (sep + 2)); + } + + return 1; +} /* }}} */ + +PHPDBG_API char *phpdbg_resolve_path(const char *path TSRMLS_DC) /* {{{ */ +{ + char resolved_name[MAXPATHLEN]; + + if (expand_filepath(path, resolved_name TSRMLS_CC) == NULL) { + return NULL; + } + + return estrdup(resolved_name); +} /* }}} */ + +PHPDBG_API const char *phpdbg_current_file(TSRMLS_D) /* {{{ */ +{ + const char *file = zend_get_executed_filename(TSRMLS_C); + + if (memcmp(file, "[no active file]", sizeof("[no active file]")) == 0) { + return PHPDBG_G(exec); + } + + return file; +} /* }}} */ + +PHPDBG_API const zend_function *phpdbg_get_function(const char *fname, const char *cname TSRMLS_DC) /* {{{ */ +{ + zend_function *func = NULL; + size_t fname_len = strlen(fname); + char *lcname = zend_str_tolower_dup(fname, fname_len); + + if (cname) { + zend_class_entry **ce; + size_t cname_len = strlen(cname); + char *lc_cname = zend_str_tolower_dup(cname, cname_len); + int ret = zend_lookup_class(lc_cname, cname_len, &ce TSRMLS_CC); + + efree(lc_cname); + + if (ret == SUCCESS) { + zend_hash_find(&(*ce)->function_table, lcname, fname_len+1, + (void**)&func); + } + } else { + zend_hash_find(EG(function_table), lcname, fname_len+1, + (void**)&func); + } + + efree(lcname); + return func; +} /* }}} */ + +PHPDBG_API char *phpdbg_trim(const char *str, size_t len, size_t *new_len) /* {{{ */ +{ + const char *p = str; + char *new = NULL; + + while (p && isspace(*p)) { + ++p; + --len; + } + + while (*p && isspace(*(p + len -1))) { + --len; + } + + if (len == 0) { + new = estrndup("", sizeof("")); + *new_len = 0; + } else { + new = estrndup(p, len); + *(new + len) = '\0'; + + if (new_len) { + *new_len = len; + } + } + + return new; + +} /* }}} */ + +PHPDBG_API int phpdbg_print(int type TSRMLS_DC, FILE *fp, const char *format, ...) /* {{{ */ +{ + int rc = 0; + char *buffer = NULL; + va_list args; + + if (format != NULL && strlen(format) > 0L) { + va_start(args, format); + vspprintf(&buffer, 0, format, args); + va_end(args); + } + + /* TODO(anyone) colours */ + + switch (type) { + case P_ERROR: + if (PHPDBG_G(flags) & PHPDBG_IS_COLOURED) { + rc = fprintf(fp, + "\033[%sm[%s]\033[0m\n", + PHPDBG_G(colors)[PHPDBG_COLOR_ERROR]->code, buffer); + } else { + rc = fprintf(fp, "[%s]\n", buffer); + } + break; + + case P_NOTICE: + if (PHPDBG_G(flags) & PHPDBG_IS_COLOURED) { + rc = fprintf(fp, + "\033[%sm[%s]\033[0m\n", + PHPDBG_G(colors)[PHPDBG_COLOR_NOTICE]->code, buffer); + } else { + rc = fprintf(fp, "[%s]\n", buffer); + } + break; + + case P_WRITELN: { + if (buffer) { + rc = fprintf(fp, "%s\n", buffer); + } else { + rc = fprintf(fp, "\n"); + } + } break; + + case P_WRITE: + if (buffer) { + rc = fprintf(fp, "%s", buffer); + } + break; + + /* no formatting on logging output */ + case P_LOG: + if (buffer) { + struct timeval tp; + if (gettimeofday(&tp, NULL) == SUCCESS) { + rc = fprintf(fp, "[%ld %.8F]: %s\n", tp.tv_sec, tp.tv_usec / 1000000.00, buffer); + } else { + rc = FAILURE; + } + } + break; + } + + if (buffer) { + efree(buffer); + } + + return rc; +} /* }}} */ + +PHPDBG_API int phpdbg_rlog(FILE *fp, const char *fmt, ...) { /* {{{ */ + int rc = 0; + + va_list args; + struct timeval tp; + + va_start(args, fmt); + if (gettimeofday(&tp, NULL) == SUCCESS) { + char friendly[100]; + char *format = NULL, *buffer = NULL; + + strftime(friendly, 100, "%a %b %d %T.%%04d %Y", localtime(&tp.tv_sec)); + asprintf( + &buffer, friendly, tp.tv_usec/1000); + asprintf( + &format, "[%s]: %s\n", buffer, fmt); + rc = vfprintf( + fp, format, args); + + free(format); + free(buffer); + } + va_end(args); + + return rc; +} /* }}} */ + +PHPDBG_API const phpdbg_color_t *phpdbg_get_color(const char *name, size_t name_length TSRMLS_DC) /* {{{ */ +{ + const phpdbg_color_t *color = colors; + + while (color && color->name) { + if (name_length == color->name_length && + memcmp(name, color->name, name_length) == SUCCESS) { + phpdbg_debug( + "phpdbg_get_color(%s, %lu): %s", name, name_length, color->code); + return color; + } + ++color; + } + + phpdbg_debug( + "phpdbg_get_color(%s, %lu): failed", name, name_length); + + return NULL; +} /* }}} */ + +PHPDBG_API void phpdbg_set_color(int element, const phpdbg_color_t *color TSRMLS_DC) /* {{{ */ +{ + PHPDBG_G(colors)[element] = color; +} /* }}} */ + +PHPDBG_API void phpdbg_set_color_ex(int element, const char *name, size_t name_length TSRMLS_DC) /* {{{ */ +{ + const phpdbg_color_t *color = phpdbg_get_color(name, name_length TSRMLS_CC); + + if (color) { + phpdbg_set_color(element, color TSRMLS_CC); + } else PHPDBG_G(colors)[element] = colors; +} /* }}} */ + +PHPDBG_API const phpdbg_color_t* phpdbg_get_colors(TSRMLS_D) /* {{{ */ +{ + return colors; +} /* }}} */ + +PHPDBG_API void phpdbg_set_prompt(const char *prompt TSRMLS_DC) /* {{{ */ +{ + /* free formatted prompt */ + if (PHPDBG_G(prompt)[1]) { + free(PHPDBG_G(prompt)[1]); + PHPDBG_G(prompt)[1] = NULL; + } + /* free old prompt */ + if (PHPDBG_G(prompt)[0]) { + free(PHPDBG_G(prompt)[0]); + PHPDBG_G(prompt)[0] = NULL; + } + + /* copy new prompt */ + PHPDBG_G(prompt)[0] = strdup(prompt); +} /* }}} */ + +PHPDBG_API const char *phpdbg_get_prompt(TSRMLS_D) /* {{{ */ +{ + /* find cached prompt */ + if (PHPDBG_G(prompt)[1]) { + return PHPDBG_G(prompt)[1]; + } + + /* create cached prompt */ + if ((PHPDBG_G(flags) & PHPDBG_IS_COLOURED)) { + asprintf( + &PHPDBG_G(prompt)[1], "\033[%sm%s\033[0m ", + PHPDBG_G(colors)[PHPDBG_COLOR_PROMPT]->code, + PHPDBG_G(prompt)[0]); + } else { + asprintf( + &PHPDBG_G(prompt)[1], "%s ", + PHPDBG_G(prompt)[0]); + } + + return PHPDBG_G(prompt)[1]; +} /* }}} */ diff --git a/sapi/phpdbg/phpdbg_utils.h b/sapi/phpdbg/phpdbg_utils.h new file mode 100644 index 0000000000000..fbc17b78dd347 --- /dev/null +++ b/sapi/phpdbg/phpdbg_utils.h @@ -0,0 +1,110 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Felipe Pena | + | Authors: Joe Watkins | + | Authors: Bob Weinand | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHPDBG_UTILS_H +#define PHPDBG_UTILS_H + +/** + * Input scan functions + */ +PHPDBG_API int phpdbg_is_numeric(const char*); +PHPDBG_API int phpdbg_is_empty(const char*); +PHPDBG_API int phpdbg_is_addr(const char*); +PHPDBG_API int phpdbg_is_class_method(const char*, size_t, char**, char**); +PHPDBG_API const char *phpdbg_current_file(TSRMLS_D); +PHPDBG_API char *phpdbg_resolve_path(const char* TSRMLS_DC); +PHPDBG_API char *phpdbg_trim(const char*, size_t, size_t*); +PHPDBG_API const zend_function *phpdbg_get_function(const char*, const char* TSRMLS_DC); + +/** + * Error/notice/formatting helpers + */ +enum { + P_ERROR = 1, + P_NOTICE, + P_WRITELN, + P_WRITE, + P_LOG +}; + +#ifdef ZTS +PHPDBG_API int phpdbg_print(int TSRMLS_DC, FILE*, const char*, ...) PHP_ATTRIBUTE_FORMAT(printf, 4, 5); +#else +PHPDBG_API int phpdbg_print(int TSRMLS_DC, FILE*, const char*, ...) PHP_ATTRIBUTE_FORMAT(printf, 3, 4); +#endif + +PHPDBG_API int phpdbg_rlog(FILE *stream, const char *fmt, ...); + +#define phpdbg_error(fmt, ...) phpdbg_print(P_ERROR TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT], fmt, ##__VA_ARGS__) +#define phpdbg_notice(fmt, ...) phpdbg_print(P_NOTICE TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT], fmt, ##__VA_ARGS__) +#define phpdbg_writeln(fmt, ...) phpdbg_print(P_WRITELN TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT], fmt, ##__VA_ARGS__) +#define phpdbg_write(fmt, ...) phpdbg_print(P_WRITE TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT], fmt, ##__VA_ARGS__) +#define phpdbg_log(fmt, ...) phpdbg_print(P_LOG TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDOUT], fmt, ##__VA_ARGS__) + +#define phpdbg_error_ex(out, fmt, ...) phpdbg_print(P_ERROR TSRMLS_CC, out, fmt, ##__VA_ARGS__) +#define phpdbg_notice_ex(out, fmt, ...) phpdbg_print(P_NOTICE TSRMLS_CC, out, fmt, ##__VA_ARGS__) +#define phpdbg_writeln_ex(out, fmt, ...) phpdbg_print(P_WRITELN TSRMLS_CC, out, fmt, ##__VA_ARGS__) +#define phpdbg_write_ex(out, fmt, ...) phpdbg_print(P_WRITE TSRMLS_CC, out, fmt, ##__VA_ARGS__) +#define phpdbg_log_ex(out, fmt, ...) phpdbg_print(P_LOG TSRMLS_CC, out, fmt, ##__VA_ARGS__) + +#if PHPDBG_DEBUG +# define phpdbg_debug(fmt, ...) phpdbg_print(P_LOG TSRMLS_CC, PHPDBG_G(io)[PHPDBG_STDERR], fmt, ##__VA_ARGS__) +#else +# define phpdbg_debug(fmt, ...) +#endif + +/* {{{ For writing blank lines */ +#define EMPTY NULL /* }}} */ + +/* {{{ For prompt lines */ +#define PROMPT "phpdbg>" /* }}} */ + +/* {{{ For separation */ +#define SEPARATE "------------------------------------------------" /* }}} */ + +/* {{{ Color Management */ +#define PHPDBG_COLOR_LEN 12 +#define PHPDBG_COLOR_D(color, code) \ + {color, sizeof(color)-1, code} +#define PHPDBG_COLOR_END \ + {NULL, 0L, {0}} + +#define PHPDBG_COLOR_INVALID -1 +#define PHPDBG_COLOR_PROMPT 0 +#define PHPDBG_COLOR_ERROR 1 +#define PHPDBG_COLOR_NOTICE 2 +#define PHPDBG_COLORS 3 + +typedef struct _phpdbg_color_t { + char *name; + size_t name_length; + const char code[PHPDBG_COLOR_LEN]; +} phpdbg_color_t; + +PHPDBG_API const phpdbg_color_t *phpdbg_get_color(const char *name, size_t name_length TSRMLS_DC); +PHPDBG_API void phpdbg_set_color(int element, const phpdbg_color_t *color TSRMLS_DC); +PHPDBG_API void phpdbg_set_color_ex(int element, const char *name, size_t name_length TSRMLS_DC); +PHPDBG_API const phpdbg_color_t* phpdbg_get_colors(TSRMLS_D); /* }}} */ + +/* {{{ Prompt Management */ +PHPDBG_API void phpdbg_set_prompt(const char* TSRMLS_DC); +PHPDBG_API const char *phpdbg_get_prompt(TSRMLS_D); /* }}} */ + +#endif /* PHPDBG_UTILS_H */ diff --git a/sapi/phpdbg/test.php b/sapi/phpdbg/test.php new file mode 100644 index 0000000000000..5fdbcbe1a4544 --- /dev/null +++ b/sapi/phpdbg/test.php @@ -0,0 +1,51 @@ +isGreat("PHP Rocks!!")); + +foreach (test(1,2) as $gen) + continue; + +echo "it works!\n"; + +if (isset($dump)) + var_dump($_SERVER); + +function phpdbg_test_ob() +{ + echo 'Start'; + ob_start(); + echo 'Hello'; + $b = ob_get_clean(); + echo 'End'; + echo $b; +} diff --git a/sapi/phpdbg/tests/commands/0001_basic.test b/sapi/phpdbg/tests/commands/0001_basic.test new file mode 100644 index 0000000000000..08aa9ab664460 --- /dev/null +++ b/sapi/phpdbg/tests/commands/0001_basic.test @@ -0,0 +1,8 @@ +####################################################### +# name: basic +# purpose: check basic functionality of phpdbg console +# expect: TEST::EXACT +# options: -rr +####################################################### +# [Nothing to execute!] +####################################################### diff --git a/sapi/phpdbg/tests/commands/0002_set.test b/sapi/phpdbg/tests/commands/0002_set.test new file mode 100644 index 0000000000000..7720f94fff61d --- /dev/null +++ b/sapi/phpdbg/tests/commands/0002_set.test @@ -0,0 +1,23 @@ +################################################# +# name: set +# purpose: tests for set commands +# expect: TEST::CISTRING +# options: -rr +################################################# +# setting prompt color +# setting error color +# setting notice color +# Failed to find breakpoint #0 +# oplog disabled +# not enabled +# opened oplog test.log +# nothing +################################################# +set color prompt none +set color error none +set color notice none +set prompt promot> +set break 0 +set oplog +set oplog 0 +set oplog test.log diff --git a/sapi/phpdbg/tests/commands/0101_info.test b/sapi/phpdbg/tests/commands/0101_info.test new file mode 100644 index 0000000000000..397a45c99275a --- /dev/null +++ b/sapi/phpdbg/tests/commands/0101_info.test @@ -0,0 +1,19 @@ +################################################# +# name: info +# purpose: test info commands +# expect: TEST::FORMAT +# options: -rr +################################################# +#[User Classes (%d)] +#User Class test (3) +#|---- in phpdbginit code on line %d +################################################# +<: +class test { + public function testMethod(){} + private function testPrivateMethod(){} + protected function testProtectedMethod(){} +} +:> +info classes +q diff --git a/sapi/phpdbg/tests/commands/0102_print.test b/sapi/phpdbg/tests/commands/0102_print.test new file mode 100644 index 0000000000000..de4acb7651b0c --- /dev/null +++ b/sapi/phpdbg/tests/commands/0102_print.test @@ -0,0 +1,28 @@ +################################################# +# name: print +# purpose: test print commands +# expect: TEST::FORMAT +# options: -rr +################################################# +#[User Class: test] +#Methods (3): +#L%d-%d test::testMethod() %s +# L%d %s ZEND_RETURN C%d +# L%d-%d test::testPrivateMethod() %s +# L%d %s ZEND_RETURN C%d +# L%d-%d test::testProtectedMethod() %s +# L%d %s ZEND_RETURN C%d +#[User Method testMethod] +# L%d-%d test::testMethod() %s +# L%d %s ZEND_RETURN C%d +################################################# +<: +class test { + public function testMethod(){} + private function testPrivateMethod(){} + protected function testProtectedMethod(){} +} +:> +print class test +print method test::testMethod +q diff --git a/sapi/phpdbg/tests/commands/0103_register.test b/sapi/phpdbg/tests/commands/0103_register.test new file mode 100644 index 0000000000000..38841591caf7f --- /dev/null +++ b/sapi/phpdbg/tests/commands/0103_register.test @@ -0,0 +1,28 @@ +################################################# +# name: register +# purpose: test registration functions +# expect: TEST::FORMAT +# options: -rr +################################################# +#[Registered test_function] +#array(5) { +# [0]=> +# string(1) "1" +# [1]=> +# string(1) "2" +# [2]=> +# string(1) "3" +# [3]=> +# string(1) "4" +# [4]=> +# string(1) "5" +#} +################################################# +<: +function test_function() { + var_dump(func_get_args()); +} +:> +R test_function +test_function 1 2 3 4 5 +q diff --git a/sapi/phpdbg/tests/commands/0104_clean.test b/sapi/phpdbg/tests/commands/0104_clean.test new file mode 100644 index 0000000000000..c7a579be17926 --- /dev/null +++ b/sapi/phpdbg/tests/commands/0104_clean.test @@ -0,0 +1,15 @@ +################################################# +# name: clean +# purpose: test cleaning environment +# expect: TEST::FORMAT +# options: -rr +################################################# +#[Cleaning Execution Environment] +#Classes %d +#Functions %d +#Constants %d +#Includes %d +#[Nothing to execute!] +################################################# +clean +quit diff --git a/sapi/phpdbg/tests/commands/0105_clear.test b/sapi/phpdbg/tests/commands/0105_clear.test new file mode 100644 index 0000000000000..b547b0d6ba1b1 --- /dev/null +++ b/sapi/phpdbg/tests/commands/0105_clear.test @@ -0,0 +1,18 @@ +################################################# +# name: clear +# purpose: test clearing breakpoints +# expect: TEST::FORMAT +# options: -rr +################################################# +#[Clearing Breakpoints] +#File%w%d +#Functions%w%d +#Methods%w%d +#Oplines%w%d +#File oplines%w%d +#Function oplines%w%d +#Method oplines%w%d +#Conditionals%w%d +################################################# +clear +quit diff --git a/sapi/phpdbg/tests/commands/0106_compile.test b/sapi/phpdbg/tests/commands/0106_compile.test new file mode 100644 index 0000000000000..d79211ddf75d7 --- /dev/null +++ b/sapi/phpdbg/tests/commands/0106_compile.test @@ -0,0 +1,19 @@ +################################################# +# name: compile +# purpose: test compiling code +# expect: TEST::FORMAT +# options: -rr +################################################# +#[Attempting compilation of %s] +#[Success] +#Hello World +################################################# +<: +define('OUT', + tempnam(null, "phpdbg")); +file_put_contents(OUT, ""); +phpdbg_exec(OUT); +:> +compile +run +quit diff --git a/sapi/phpdbg/tests/run-tests.php b/sapi/phpdbg/tests/run-tests.php new file mode 100644 index 0000000000000..1fb6fa12242fa --- /dev/null +++ b/sapi/phpdbg/tests/run-tests.php @@ -0,0 +1,583 @@ +config = array_shift($argv); + $this->message = vsprintf( + array_shift($argv), $argv); + } + } + } + + /** + * + * @package phpdbg + * @subpackage testing + */ + class TestsConfiguration implements \ArrayAccess { + + /** + * + * @param array basic configuration + * @param array argv + */ + public function __construct($config, $cmd) { + $this->options = $config; + while (($key = array_shift($cmd))) { + switch (substr($key, 0, 1)) { + case '-': switch(substr($key, 1, 1)) { + case '-': { + $arg = substr($key, 2); + if (($e=strpos($arg, '=')) !== false) { + $key = substr($arg, 0, $e); + $value = substr($arg, $e+1); + } else { + $key = $arg; + $value = array_shift($cmd); + } + + if (isset($key) && isset($value)) { + switch ($key) { + case 'phpdbg': + case 'width': + $this->options[$key] = $value; + break; + + default: { + if (isset($config[$key])) { + if (is_array($config[$key])) { + $this->options[$key][] = $value; + } else { + $this->options[$key] = array($config[$key], $value); + } + } else { + $this->options[$key] = $value; + } + } + } + + } + } break; + + default: + $this->flags[] = substr($key, 1); + } break; + } + } + + if (!is_executable($this->options['phpdbg'])) { + throw new TestConfigurationException( + $this->options, 'phpdbg could not be found at the specified path (%s)', $this->options['phpdbg']); + } else $this->options['phpdbg'] = realpath($this->options['phpdbg']); + + $this->options['width'] = (integer) $this->options['width']; + + /* display properly, all the time */ + if ($this->options['width'] < 50) { + $this->options['width'] = 50; + } + + /* calculate column widths */ + $this->options['lwidth'] = ceil($this->options['width'] / 3); + $this->options['rwidth'] = ceil($this->options['width'] - $this->options['lwidth']) - 5; + } + + public function hasFlag($flag) { + return in_array( + $flag, $this->flags); + } + + public function offsetExists($offset) { return isset($this->options[$offset]); } + public function offsetGet($offset) { return $this->options[$offset]; } + public function offsetUnset($offset) { unset($this->options[$offset]); } + public function offsetSet($offset, $data) { $this->options[$offset] = $data; } + + protected $options = array(); + protected $flags = array(); + } + + /** + * Tests is the console programming API for the test suite + * + * @package phpdbg + * @subpackage testing + */ + class Tests { + + /** + * Construct the console object + * + * @param array basic configuration + * @param array command line + */ + public function __construct(TestsConfiguration &$config) { + $this->config = &$config; + + if ($this->config->hasFlag('help') || + $this->config->hasFlag('h')) { + $this->showUsage(); + exit; + } + } + + /** + * Find valid paths as specified by configuration + * + */ + public function findPaths($in = null) { + $paths = array(); + $where = ($in != null) ? array($in) : $this->config['path']; + + foreach ($where as &$path) { + if ($path) { + if (is_dir($path)) { + $paths[] = $path; + foreach (scandir($path) as $child) { + if ($child != '.' && $child != '..') { + $paths = array_merge( + $paths, $this->findPaths("$path/$child")); + } + } + } + } + } + + return $paths; + } + + /** + * + * @param string the path to log + */ + public function logPath($path) { + printf( + '%s [%s]%s', + str_repeat( + '-', $this->config['width'] - strlen($path)), + $path, PHP_EOL); + } + + /** + * + * @param string the path to log + */ + public function logPathStats($path) { + if (!isset($this->stats[$path])) { + return; + } + + $total = array_sum($this->stats[$path]); + + if ($total) { + @$this->totals[true] += $this->stats[$path][true]; + @$this->totals[false] += $this->stats[$path][false]; + + $stats = @sprintf( + "%d/%d %%%d", + $this->stats[$path][true], + $this->stats[$path][false], + (100 / $total) * $this->stats[$path][true]); + + printf( + '%s [%s]%s', + str_repeat( + ' ', $this->config['width'] - strlen($stats)), + $stats, PHP_EOL); + + printf("%s%s", str_repeat('-', $this->config['width']+3), PHP_EOL); + printf("%s", PHP_EOL); + } + } + + /** + * + */ + public function logStats() { + $total = array_sum($this->totals); + $stats = @sprintf( + "%d/%d %%%d", + $this->totals[true], + $this->totals[false], + (100 / $total) * $this->totals[true]); + printf( + '%s [%s]%s', + str_repeat( + ' ', $this->config['width'] - strlen($stats)), + $stats, PHP_EOL); + + } + + /** + * + */ + protected function showUsage() { + printf('usage: php %s [flags] [options]%s', $this->config['exec'], PHP_EOL); + printf('[options]:%s', PHP_EOL); + printf("\t--path\t\tadd a path to scan outside of tests directory%s", PHP_EOL); + printf("\t--width\t\tset line width%s", PHP_EOL); + printf("\t--options\toptions to pass to phpdbg%s", PHP_EOL); + printf("\t--phpdbg\tpath to phpdbg binary%s", PHP_EOL); + printf('[flags]:%s', PHP_EOL); + printf("\t-nodiff\t\tdo not write diffs on failure%s", PHP_EOL); + printf("\t-nolog\t\tdo not write logs on failure%s", PHP_EOL); + printf('[examples]:%s', PHP_EOL); + printf("\tphp %s --phpdbg=/usr/local/bin/phpdbg --path=/usr/src/phpdbg/tests --options -n%s", + $this->config['exec'], PHP_EOL); + + } + + /** + * Find valid tests at the specified path (assumed valid) + * + * @param string a valid path + */ + public function findTests($path) { + $tests = array(); + + foreach (scandir($path) as $file) { + if ($file == '.' || $file == '..') + continue; + + $test = sprintf('%s/%s', $path, $file); + + if (preg_match('~\.test$~', $test)) { + yield new Test($this->config, $test); + } + } + } + + /** + * + * @param Test the test to log + */ + public function logTest($path, Test $test) { + @$this->stats[$path][($result=$test->getResult())]++; + + printf( + "%-{$this->config['lwidth']}s %-{$this->config['rwidth']}s [%s]%s", + $test->name, + $test->purpose, + $result ? "PASS" : "FAIL", + PHP_EOL); + } + + protected $config; + } + + class Test { + /* + * Expect exact line for line match + */ + const EXACT = 0x00000001; + + /* + * Expect strpos() !== false + */ + const STRING = 0x00000010; + + /* + * Expect stripos() !== false + */ + const CISTRING = 0x00000100; + + /* + * Formatted output + */ + const FORMAT = 0x00001000; + + /** + * Format specifiers + */ + private static $format = array( + 'search' => array( + '%e', + '%s', + '%S', + '%a', + '%A', + '%w', + '%i', + '%d', + '%x', + '%f', + '%c', + '%t', + '%T' + ), + 'replace' => array( + DIR_SEP, + '[^\r\n]+', + '[^\r\n]*', + '.+', + '.*', + '\s*', + '[+-]?\d+', + '\d+', + '[0-9a-fA-F]+', + '[+-]?\.?\d+\.?\d*(?:[Ee][+-]?\d+)?', + '.', + '\t', + '\t+' + ) + ); + + /** + * Constructs a new Test object given a specilized phpdbginit file + * + * @param array configuration + * @param string file + */ + public function __construct(TestsConfiguration &$config, &$file) { + if (($handle = fopen($file, 'r'))) { + while (($line = fgets($handle))) { + $trim = trim($line); + + switch (substr($trim, 0, 1)) { + case '#': if (($chunks = array_map('trim', preg_split('~:~', substr($trim, 1), 2)))) { + if (property_exists($this, $chunks[0])) { + switch ($chunks[0]) { + case 'expect': { + if ($chunks[1]) { + switch (strtoupper($chunks[1])) { + case 'TEST::EXACT': + case 'EXACT': { $this->expect = TEST::EXACT; } break; + + case 'TEST::STRING': + case 'STRING': { $this->expect = TEST::STRING; } break; + + case 'TEST::CISTRING': + case 'CISTRING': { $this->expect = TEST::CISTRING; } break; + + case 'TEST::FORMAT': + case 'FORMAT': { $this->expect = TEST::FORMAT; } break; + + default: + throw new TestConfigurationException( + $this->config, "unknown type of expectation (%s)", $chunks[1]); + } + } + } break; + + default: { + $this->$chunks[0] = $chunks[1]; + } + } + } else switch(substr($trim, 1, 1)) { + case '#': { /* do nothing */ } break; + + default: { + $line = preg_replace( + "~(\r\n)~", "\n", substr($trim, 1)); + + $line = trim($line); + + switch ($this->expect) { + case TEST::FORMAT: + $this->match[] = str_replace( + self::$format['search'], + self::$format['replace'], preg_quote($line)); + break; + + default: $this->match[] = $line; + } + } + } + } break; + + default: + break 2; + } + } + fclose($handle); + + $this->config = &$config; + $this->file = &$file; + } + } + + /** + * Obvious!! + * + */ + public function getResult() { + $options = sprintf( + '-i%s -qb', $this->file); + + if ($this->options) { + $options = sprintf( + '%s %s %s', + $options, + $this->config['options'], + $this->options + ); + } else { + $options = sprintf( + '%s %s', $options, $this->config['options'] + ); + } + + $result = `{$this->config['phpdbg']} {$options}`; + + if ($result) { + foreach (preg_split('~(\r|\n)~', $result) as $num => $line) { + if (!$line && !isset($this->match[$num])) + continue; + + switch ($this->expect) { + case TEST::EXACT: { + if (strcmp($line, $this->match[$num]) !== 0) { + $this->diff['wants'][$num] = &$this->match[$num]; + $this->diff['gets'][$num] = $line; + } + } continue 2; + + case TEST::STRING: { + if (strpos($line, $this->match[$num]) === false) { + $this->diff['wants'][$num] = &$this->match[$num]; + $this->diff['gets'][$num] = $line; + } + } continue 2; + + case TEST::CISTRING: { + if (stripos($line, $this->match[$num]) === false) { + $this->diff['wants'][$num] = &$this->match[$num]; + $this->diff['gets'][$num] = $line; + } + } continue 2; + + case TEST::FORMAT: { + $line = trim($line); + if (!preg_match("/^{$this->match[$num]}\$/s", $line)) { + $this->diff['wants'][$num] = &$this->match[$num]; + $this->diff['gets'][$num] = $line; + } + } continue 2; + } + } + } + + $this->writeLog($result); + $this->writeDiff(); + + return (count($this->diff) == 0); + } + + /** + * Write diff to disk if configuration allows it + * + */ + protected function writeDiff() { + $diff = sprintf( + '%s/%s.diff', + dirname($this->file), basename($this->file)); + + if (count($this->diff['wants'])) { + if (!in_array('nodiff', $this->config['flags'])) { + if (($diff = fopen($diff, 'w+'))) { + + foreach ($this->diff['wants'] as $line => $want) { + $got = $this->diff['gets'][$line]; + + fprintf( + $diff, '(%d) -%s%s', $line+1, $want, PHP_EOL); + fprintf( + $diff, '(%d) +%s%s', $line+1, $got, PHP_EOL); + } + + fclose($diff); + } + } + } else unlink($diff); + } + + /** + * Write log to disk if configuration allows it + * + */ + protected function writeLog(&$result = null) { + $log = sprintf( + '%s/%s.log', + dirname($this->file), basename($this->file)); + + if (count($this->diff) && $result) { + if (!in_array('nolog', $this->config['flags'])) { + @file_put_contents( + $log, $result); + } + } else unlink($log); + } + + public $name; + public $purpose; + public $file; + public $options; + public $expect; + + protected $match; + protected $diff; + protected $stats; + protected $totals; + } +} + +namespace { + use \phpdbg\Testing\Test; + use \phpdbg\Testing\Tests; + use \phpdbg\Testing\TestsConfiguration; + + $cwd = dirname(__FILE__); + $cmd = $_SERVER['argv']; + { + $config = new TestsConfiguration(array( + 'exec' => realpath(array_shift($cmd)), + 'phpdbg' => realpath(sprintf( + '%s/../phpdbg', $cwd + )), + 'path' => array( + realpath(dirname(__FILE__)) + ), + 'flags' => array(), + 'width' => 75 + ), $cmd); + + $tests = new Tests($config); + + foreach ($tests->findPaths() as $path) { + $tests->logPath($path); + + foreach ($tests->findTests($path) as $test) { + $tests->logTest($path, $test); + } + + $tests->logPathStats($path); + } + + $tests->logStats(); + } +} +?> diff --git a/sapi/phpdbg/travis/ci.sh b/sapi/phpdbg/travis/ci.sh new file mode 100755 index 0000000000000..44d56a01ffe86 --- /dev/null +++ b/sapi/phpdbg/travis/ci.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env sh +git clone https://github.com/php/php-src +cd php-src/sapi +git clone https://github.com/krakjoe/phpdbg.git +cd ../ +./buildconf --force +./configure --disable-all --enable-phpdbg --enable-maintainer-zts +make +make test-phpdbg diff --git a/sapi/phpdbg/web-bootstrap.php b/sapi/phpdbg/web-bootstrap.php new file mode 100644 index 0000000000000..7b8c5d30de8dc --- /dev/null +++ b/sapi/phpdbg/web-bootstrap.php @@ -0,0 +1,64 @@ + 'localhost', + 'HTTP_CONNECTION' => 'keep-alive', + 'HTTP_ACCEPT' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', + 'HTTP_USER_AGENT' => 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.65 Safari/537.36', + 'HTTP_ACCEPT_ENCODING' => 'gzip,deflate,sdch', + 'HTTP_ACCEPT_LANGUAGE' => 'en-US,en;q=0.8', + 'HTTP_COOKIE' => 'tz=Europe%2FLondon; __utma=1.347100075.1384196523.1384196523.1384196523.1; __utmc=1; __utmz=1.1384196523.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)', + 'PATH' => '/usr/local/bin:/usr/bin:/bin', + 'SERVER_SIGNATURE' => '
Apache/2.4.6 (Ubuntu) Server at phpdbg.com Port 80
', + 'SERVER_SOFTWARE' => 'Apache/2.4.6 (Ubuntu)', + 'SERVER_NAME' => 'localhost', + 'SERVER_ADDR' => '127.0.0.1', + 'SERVER_PORT' => '80', + 'REMOTE_ADDR' => '127.0.0.1', + 'DOCUMENT_ROOT' => PHPDBG_BOOTPATH, + 'REQUEST_SCHEME' => 'http', + 'CONTEXT_PREFIX' => '', + 'CONTEXT_DOCUMENT_ROOT' => PHPDBG_BOOTPATH, + 'SERVER_ADMIN' => '[no address given]', + 'SCRIPT_FILENAME' => sprintf( + '%s/%s', PHPDBG_BOOTPATH, PHPDBG_BOOTSTRAP + ), + 'REMOTE_PORT' => '47931', + 'GATEWAY_INTERFACE' => 'CGI/1.1', + 'SERVER_PROTOCOL' => 'HTTP/1.1', + 'REQUEST_METHOD' => 'GET', + 'QUERY_STRING' => '', + 'REQUEST_URI' => PHPDBG_BOOTSTRAPPED, + 'SCRIPT_NAME' => PHPDBG_BOOTSTRAPPED, + 'PHP_SELF' => PHPDBG_BOOTSTRAPPED, + 'REQUEST_TIME' => time(), +); + +$_GET = array(); +$_REQUEST = array(); +$_POST = array(); +$_COOKIE = array(); +$_FILES = array(); + +chdir(PHPDBG_BOOTPATH); diff --git a/sapi/pi3web/pi3web_sapi.c b/sapi/pi3web/pi3web_sapi.c index 64eb2a6c99526..b9076f17d8637 100644 --- a/sapi/pi3web/pi3web_sapi.c +++ b/sapi/pi3web/pi3web_sapi.c @@ -385,7 +385,7 @@ MODULE_API DWORD PHP5_wrapper(LPCONTROL_BLOCK lpCB) } if ( open_file_for_scanning( &file_handle TSRMLS_CC ) == SUCCESS ) { - zend_indent(); + zend_indent(TSRMLS_C); } else { diff --git a/sapi/roxen/roxen.c b/sapi/roxen/roxen.c index c897ef62be6f6..2b93cc5e913e2 100644 --- a/sapi/roxen/roxen.c +++ b/sapi/roxen/roxen.c @@ -387,13 +387,12 @@ php_roxen_sapi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC) * the client. Used for POST/PUT requests. */ -INLINE static int php_roxen_low_read_post(char *buf, uint count_bytes) +INLINE static int php_roxen_low_read_post(char *buf, uint count_bytes TSRMLS_DC) { uint total_read = 0; #ifdef ROXEN_USE_ZTS GET_THIS(); #endif - TSRMLS_FETCH(); if(!MY_FD_OBJ->prog) { @@ -417,7 +416,7 @@ static int php_roxen_sapi_read_post(char *buf, uint count_bytes TSRMLS_DC) { uint total_read = 0; - THREAD_SAFE_RUN(total_read = php_roxen_low_read_post(buf, count_bytes), "read post"); + THREAD_SAFE_RUN(total_read = php_roxen_low_read_post(buf, count_bytes TSRMLS_CC), "read post"); return total_read; } diff --git a/sapi/thttpd/thttpd.c b/sapi/thttpd/thttpd.c index 548bcda170abe..b136b71d7b201 100644 --- a/sapi/thttpd/thttpd.c +++ b/sapi/thttpd/thttpd.c @@ -349,11 +349,12 @@ static zend_module_entry php_thttpd_module = { STANDARD_MODULE_PROPERTIES }; -static int php_thttpd_startup(sapi_module_struct *sapi_module) +static int php_thttpd_startup(sapi_module_struct *sapi_module TSRMLS_DC) { #if PHP_API_VERSION >= 20020918 if (php_module_startup(sapi_module, &php_thttpd_module, 1) == FAILURE) { #else + /* No TSRMLS_CC here to zend_startup_module() as 5.6 and older does not have that parameter */ if (php_module_startup(sapi_module) == FAILURE || zend_startup_module(&php_thttpd_module) == FAILURE) { #endif diff --git a/sapi/tux/php_tux.c b/sapi/tux/php_tux.c index 968dd9eb91b2c..1dbcf3882ebdf 100644 --- a/sapi/tux/php_tux.c +++ b/sapi/tux/php_tux.c @@ -96,7 +96,7 @@ static int sapi_tux_ub_write(const char *str, uint str_length TSRMLS_DC) return n; } -static int sapi_tux_send_headers(sapi_headers_struct *sapi_headers) +static int sapi_tux_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC) { char buf[1024]; struct iovec *vec; @@ -107,7 +107,6 @@ static int sapi_tux_send_headers(sapi_headers_struct *sapi_headers) size_t len; char *status_line; int locate_cl; - TSRMLS_FETCH(); max_headers = 30; n = 1; @@ -158,11 +157,10 @@ static int sapi_tux_send_headers(sapi_headers_struct *sapi_headers) return SAPI_HEADER_SENT_SUCCESSFULLY; } -static int sapi_tux_read_post(char *buffer, uint count_bytes) +static int sapi_tux_read_post(char *buffer, uint count_bytes TSRMLS_DC) { #if 0 int amount = 0; - TSRMLS_FETCH(); TG(req)->objectlen = count_bytes; TG(req)->object_addr = buffer; @@ -177,10 +175,8 @@ static int sapi_tux_read_post(char *buffer, uint count_bytes) #endif } -static char *sapi_tux_read_cookies(void) +static char *sapi_tux_read_cookies(TSRMLS_D) { - TSRMLS_FETCH(); - return TG(req)->cookies; } diff --git a/tests/classes/autoload_021.phpt b/tests/classes/autoload_021.phpt new file mode 100644 index 0000000000000..13562b40005dd --- /dev/null +++ b/tests/classes/autoload_021.phpt @@ -0,0 +1,13 @@ +--TEST-- +Validation of class names in the autoload process +--FILE-- + +--EXPECTF-- +Fatal error: Class '../BUG' not found in %sautoload_021.php on line 6 diff --git a/tests/classes/bug65768.phpt b/tests/classes/bug65768.phpt new file mode 100644 index 0000000000000..17ec93cf249c3 --- /dev/null +++ b/tests/classes/bug65768.phpt @@ -0,0 +1,36 @@ +--TEST-- +Bug #65768: date_diff accepts only DateTime instance even though docs say about DateTimeInterface +--INI-- +date.timezone=Europe/London +--FILE-- +diff($dti1); +echo $diff1->y, " ", $diff1->m, " ", $diff1->d, " ", + $diff1->h, " ", $diff1->i, " ", $diff1->s, "\n"; + +$diff2 = $dti1->diff($dti2); +echo $diff2->y, " ", $diff2->m, " ", $diff2->d, " ", + $diff2->h, " ", $diff2->i, " ", $diff2->s, "\n"; + +$diff3 = date_diff($dt1, $dti2); +echo $diff3->y, " ", $diff3->m, " ", $diff3->d, " ", + $diff3->h, " ", $diff3->i, " ", $diff3->s, "\n"; + +class cdt1 extends DateTime implements DateTimeInterface {} + +class cdt2 extends DateTimeImmutable implements DateTimeInterface {} + +class cdt3 implements DateTimeInterface {} + +?> +--EXPECTF-- +0 0 5 0 0 0 +0 0 3 0 0 0 +0 0 8 0 0 0 + +Fatal error: DateTimeInterface can't be implemented by user classes in %sbug65768.php on line %d diff --git a/tests/lang/bug24640.phpt b/tests/lang/bug24640.phpt index 919b38e29e44a..d02889101e6f9 100644 --- a/tests/lang/bug24640.phpt +++ b/tests/lang/bug24640.phpt @@ -2,6 +2,7 @@ Bug #24640 (var_export and var_dump can't output large float) --INI-- precision=12 +serialize_precision=17 --FILE-- --EXPECTF-- -1.7E+300 +1.7000000000000001E+300 float(1.7E+300) 1.7E+300 1.7E+300 ------ -1.7E-300 +1.7000000000000001E-300 float(1.7E-300) 1.7E-300 1.7E-300 ------ -1.7E+79 +1.7000000000000002E+79 float(1.7E+79) 1.7E+79 1.7E+79 ------ -1.7E-79 +1.6999999999999999E-79 float(1.7E-79) 1.7E-79 1.7E-79 @@ -71,7 +72,7 @@ float(1.7E+81) 1.7E+81 1.7E+81 ------ -1.7E-81 +1.6999999999999999E-81 float(1.7E-81) 1.7E-81 1.7E-81 @@ -81,7 +82,7 @@ float(I%s) I%s I%s ------ -1.69998107421E-319 +1.6999810742105611E-319 float(1.69998107421E-319) 1.69998107421E-319 1.69998107421E-319 @@ -91,7 +92,7 @@ float(I%s) I%s I%s ------ -1.70007988734E-320 +1.7000798873397294E-320 float(1.70007988734E-320) 1.70007988734E-320 1.70007988734E-320 @@ -101,7 +102,7 @@ float(I%s) I%s I%s ------ -1.69958582169E-321 +1.6995858216938881E-321 float(1.69958582169E-321) 1.69958582169E-321 1.69958582169E-321 diff --git a/tests/run-test/test011.phpt b/tests/run-test/test011.phpt new file mode 100644 index 0000000000000..17f1f7aee6c9e --- /dev/null +++ b/tests/run-test/test011.phpt @@ -0,0 +1,6 @@ +--TEST-- +EXPECT_EXTERNAL +--FILE-- +abc +--EXPECT_EXTERNAL-- +test011.txt diff --git a/tests/run-test/test011.txt b/tests/run-test/test011.txt new file mode 100644 index 0000000000000..8baef1b4abc47 --- /dev/null +++ b/tests/run-test/test011.txt @@ -0,0 +1 @@ +abc diff --git a/tests/run-test/test012.phpt b/tests/run-test/test012.phpt new file mode 100644 index 0000000000000..8213aa2a5610e --- /dev/null +++ b/tests/run-test/test012.phpt @@ -0,0 +1,12 @@ +--TEST-- +EXPECTF_EXTERNAL +--FILE-- +123 +-123 ++123 ++1.1 +abc +0abc +x +--EXPECTF_EXTERNAL-- +test012.txt diff --git a/tests/run-test/test012.txt b/tests/run-test/test012.txt new file mode 100644 index 0000000000000..bb293214b1da9 --- /dev/null +++ b/tests/run-test/test012.txt @@ -0,0 +1,7 @@ +%d +%i +%i +%f +%s +%x +%c diff --git a/tests/run-test/test013.phpt b/tests/run-test/test013.phpt new file mode 100644 index 0000000000000..79ccd20de218c --- /dev/null +++ b/tests/run-test/test013.phpt @@ -0,0 +1,6 @@ +--TEST-- +EXPECTREGEX_EXTERNAL +--FILE-- +abcde12314235xyz34264768286abcde +--EXPECTREGEX_EXTERNAL-- +test013.txt diff --git a/tests/run-test/test013.txt b/tests/run-test/test013.txt new file mode 100644 index 0000000000000..6c280ece4d44f --- /dev/null +++ b/tests/run-test/test013.txt @@ -0,0 +1 @@ +[abcde]+[0-5]*xyz[2-8]+abcde diff --git a/tests/strings/001.phpt b/tests/strings/001.phpt index 3bfd3dbc30e0f..98ceceb350e29 100644 --- a/tests/strings/001.phpt +++ b/tests/strings/001.phpt @@ -177,9 +177,23 @@ if ($ss == "\$'") { } -echo "Testing uniqid: "; +echo "Testing uniqid(true): "; +$str = "prefix"; +$ui1 = uniqid($str, true); +$ui2 = uniqid($str, true); + +$len = 29; + +if (strlen($ui1) == strlen($ui2) && strlen($ui1) == $len && $ui1 != $ui2) { + echo("passed\n"); +} else { + echo("failed!\n"); +} + +echo "Testing uniqid(false): "; $str = "prefix"; $ui1 = uniqid($str); +usleep( 1 ); $ui2 = uniqid($str); $len = strncasecmp(PHP_OS, 'CYGWIN', 6) ? 19 : 29; @@ -207,4 +221,5 @@ Testing ufirst: passed Testing strtr: passed Testing addslashes: passed Testing stripslashes: passed -Testing uniqid: passed +Testing uniqid(true): passed +Testing uniqid(false): passed diff --git a/win32/build/config.w32 b/win32/build/config.w32 index 3401205c8fc1e..6e19c48967681 100644 --- a/win32/build/config.w32 +++ b/win32/build/config.w32 @@ -364,7 +364,7 @@ ADD_SOURCES("Zend", "zend_language_parser.c zend_language_scanner.c \ zend_stream.c zend_iterators.c zend_interfaces.c zend_objects.c \ zend_object_handlers.c zend_objects_API.c \ zend_default_classes.c zend_execute.c zend_strtod.c zend_gc.c zend_closures.c \ - zend_float.c zend_string.c zend_generators.c"); + zend_float.c zend_string.c zend_generators.c zend_virtual_cwd.c zend_ast.c"); if (VCVERS == 1200) { AC_DEFINE('ZEND_DVAL_TO_LVAL_CAST_OK', 1); diff --git a/win32/build/libs_version.txt b/win32/build/libs_version.txt index 123a75d783090..44420ddec82da 100644 --- a/win32/build/libs_version.txt +++ b/win32/build/libs_version.txt @@ -1,12 +1,11 @@ bz2-1.0.6 cclient-2007f freetype-2.4.10 -icu-50.1.2 +icu-51.2 jpeglib-9 libcurl-7.30.0 libiconv-1.14 libmcrypt-2.5.8 -libmpir-2.5.1 libmpir-2.6.0 libpng-1.5.14 libpq-9.2.2 diff --git a/win32/readdir.c b/win32/readdir.c index 9525fc0d6b499..0edd5764d4988 100644 --- a/win32/readdir.c +++ b/win32/readdir.c @@ -45,6 +45,7 @@ DIR *opendir(const char *dir) dp = (DIR *) malloc(sizeof(DIR)); if (dp == NULL) { + free(filespec); return NULL; } dp->offset = 0;